Employee Attendance System in Google Sheets with Apps Script (Login / Logout + Free Code)

Employee Attendance System in Google Sheets + Apps Script

Create a smart Login / Logout attendance tracker using Google Form, Google Sheets and Apps Script. Perfect for office, shop, warehouse, startup & HR teams.

⚡ Smart Login

Employees submit only Employee ID + Login / Logout.

๐Ÿ“Š Auto Attendance Log

Name, department, hours, late mark and status updated automatically.

๐Ÿš€ Dashboard Ready

Use Looker Studio for premium visual dashboard.

๐Ÿ’ฏ Free Setup

Build complete system using free Google tools.

๐Ÿ”ฅ Features

Login / Logout Tracking Working Hours Late Mark Half Day Active / Inactive Check Looker Dashboard

๐Ÿ“‹ Required Sheets

Sheet Name Purpose
Form Responses 1 Google Form submissions
Emp Master Employee master data + settings
Attendance_Log Processed attendance records

๐Ÿ‘จ‍๐Ÿ’ผ Emp Master Structure

Setting Value
Standard Login9:00 AM
Standard Logout6:00 PM
Working Hours9
Half Day Min4.5

Employee Data from Row 7

Emp ID Name Email Manager Department Status
EMP001 Rajat Sharma abc@gmail.com mgr@gmail.com HR Active
EMP002 Rushikesh Godbole xyz@gmail.com mgr@gmail.com SCM Active

๐Ÿ“ Google Form Setup

Only 2 Questions required:
  • Employee ID (Dropdown)
  • Login / Logout (Dropdown)

⚙️ Apps Script Code

Go to Extensions → Apps Script and paste your code.

function onFormSubmit(e) {

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const masterSheet = ss.getSheetByName("Emp Master");
  const logSheet = ss.getSheetByName("Attendance_Log");

  const row = e.values;

  const timestamp = new Date(row[0]);
  const empId = row[2].toString().trim();
  const action = row[3].toString().replace("-", "").trim(); // Login / Logout

  const tz = Session.getScriptTimeZone();

  const dateOnly = Utilities.formatDate(timestamp, tz, "dd-MMM-yyyy");
  const timeOnly = Utilities.formatDate(timestamp, tz, "HH:mm");

  // SETTINGS FROM EMP MASTER
  const stdLogin = masterSheet.getRange("B1").getDisplayValue();
  const halfDayMin = Number(masterSheet.getRange("B4").getValue());

  // EMP MASTER DATA
  const lastRow = masterSheet.getLastRow();
  const masterData = masterSheet.getRange(7, 1, lastRow - 6, 6).getValues();

  let empName = "";
  let dept = "";
  let empStatus = "";

  for (let i = 0; i < masterData.length; i++) {

    if (masterData[i][0] == empId) {

      empName = masterData[i][1];
      dept = masterData[i][4];
      empStatus = masterData[i][5];
      break;

    }

  }

  // INVALID OR INACTIVE EMPLOYEE
  if (empName == "") return;
  if (empStatus != "Active") return;

  // CHECK EXISTING ENTRY
  const logData = logSheet.getDataRange().getValues();

  let foundRow = -1;

  for (let i = 1; i < logData.length; i++) {

    let sheetDate = logSheet.getRange(i + 1, 1).getDisplayValue();
    let sheetEmp = logData[i][1];

    if (sheetDate == dateOnly && sheetEmp == empId) {
      foundRow = i + 1;
      break;
    }

  }

  // ==========================
  // NEW ENTRY
  // ==========================
  if (foundRow == -1) {

    // LOGIN FIRST
    if (action == "Login") {

      let lateMark = checkLate(timeOnly, stdLogin);

      logSheet.appendRow([
        dateOnly,        // A Date
        empId,           // B Emp ID
        empName,         // C Name
        dept,            // D Dept
        timeOnly,        // E Login Time
        "",              // F Logout Time
        "",              // G Total Hours
        lateMark,        // H Late
        "",              // I Half Day
        "Working"        // J Status
      ]);

    }

    // LOGOUT FIRST
    if (action == "Logout") {

      logSheet.appendRow([
        dateOnly,
        empId,
        empName,
        dept,
        "",
        timeOnly,
        "",
        "",
        "",
        "Login Missing"
      ]);

    }

  }

  // ==========================
  // UPDATE EXISTING ENTRY
  // ==========================
  else {

    const loginTime = logSheet.getRange(foundRow, 5).getDisplayValue();
    const logoutTime = logSheet.getRange(foundRow, 6).getDisplayValue();

    // LOGIN UPDATE
    if (action == "Login" && loginTime == "") {

      let lateMark = checkLate(timeOnly, stdLogin);

      logSheet.getRange(foundRow, 5).setValue(timeOnly);
      logSheet.getRange(foundRow, 8).setValue(lateMark);
      logSheet.getRange(foundRow, 10).setValue("Working");

    }

    // LOGOUT UPDATE
    if (action == "Logout" && logoutTime == "") {

      logSheet.getRange(foundRow, 6).setValue(timeOnly);

      if (loginTime != "") {

        let total = calculateHours(loginTime, timeOnly);

        logSheet.getRange(foundRow, 7).setValue(total);

        let halfDay = total < halfDayMin ? "Yes" : "No";

        logSheet.getRange(foundRow, 9).setValue(halfDay);
        logSheet.getRange(foundRow, 10).setValue("Complete");

      } else {

        logSheet.getRange(foundRow, 10).setValue("Login Missing");

      }

    }

  }

}



// ==========================
// CHECK LATE MARK
// ==========================
function checkLate(actual, standard) {

  let a = new Date("1/1/2000 " + actual);
  let b = new Date("1/1/2000 " + standard);

  return a > b ? "Yes" : "No";

}



// ==========================
// CALCULATE HOURS
// ==========================
function calculateHours(login, logout) {

  let inTime = new Date("1/1/2000 " + login);
  let outTime = new Date("1/1/2000 " + logout);

  let diff = (outTime - inTime) / (1000 * 60 * 60);

  return diff.toFixed(2);

}

⏰ Trigger Setup

  • Open Apps Script
  • Click Triggers
  • Add Trigger
  • Select onFormSubmit
  • Event Type = On Form Submit

๐Ÿ“Š Dashboard Upgrade

Connect Attendance_Log sheet to Looker Studio for a premium live dashboard.

Watch Full Video Tutorial

๐ŸŽฏ SEO Keywords

google sheets attendance system, apps script attendance tracker, employee login logout tracker, google form attendance system, attendance dashboard in looker studio, office attendance system free

๐Ÿ’ฌ Final Words

If you want advanced version with auto absent marking, email alerts, biometric style punch logic or manager approval system, comment below.

Subscribe Scripted Success Master

Comments

Popular posts from this blog