1
votes

I have a staff training database in Google Sheets in the link below:

Link to Google Spreadsheet

A Google Form populates columns A to J of the "Add Employee Form Responses" sheet with Employee info. That data is transferred to the "Qualifications" sheet by simple =cell functions. The issue is, and I can't work out why, is that when each new form is completed and the form answers populate the "Add Employee Form Responses" sheet, it changes the cell number in the next empty row in the Qualifications sheet to the next ensuing row numbers which link to blank cells in the "Add Employee Form Responses" sheet. For example, before the form is completed all of the cells in row 4 of the Qualifications sheet are drawing from row 4 of the "Add Employee Form Responses" sheet but after the form is populated row 4 of the Qualifications sheet is drawing from row 5 "Add Employee Form Responses" sheet which remains null.

I used to have another sheet with a Query function in between the two sheets which worked perfectly but I have since added the following apps script (rows 1 to 24 of the Script Editor) to cut the row when a date is entered in column B of the "Qualifications" sheet and paste it into the "Qualifications - Employees Left" sheet. The issue with this is that the Query just retrieves the data again from the "Add Employee Form Responses" sheet and repopulates the "Qualifications" sheet. In other words, the data that was just cut and pasted from the "Qualifications" sheet into the "Qualifications - Employees Left" sheet returns to the "Qualifications" sheet from the "Add Employee Form Responses" sheet by way of the Query.


// Cut Employees Left from Qualifications sheet and 
// paste in Qualifications - Employees Left sheet
function onEdit(e) {
  var ss = e.source;
  var sheet = ss.getActiveSheet();
  var sheetName = "Qualifications"
  var range = e.range;
  var editedColumn = range.getColumn();
  var editedRow = range.getRow();
  var column = 2;
  var date = range.getValue();
  // Object.prototype.toString.call(date) === '[object Date]' --> checks if value is date
  // editedColumn == column && editedRow > 4 --> checks if edited cell is from 'Date Left'
  // sheet.getName() == sheetName --> checks if edited sheet is 'Qualifications'
  if(Object.prototype.toString.call(date) === '[object Date]' && editedColumn == column && editedRow > 4 && sheet.getName() == sheetName) {
    var numCols = sheet.getLastColumn();
    var row = sheet.getRange(editedRow, 1, 1, numCols).getValues();
    var destinationSheet = ss.getSheetByName("Qualifications - Employees Left");
    // Get first empty row:
    var emptyRow = destinationSheet.getLastRow() + 1;
    // Copy values from 'Qualifications'
    destinationSheet.getRange(emptyRow, 1, 1, numCols).setValues(row);
    sheet.deleteRow(editedRow);
    sheet.hideColumns(column);
  }

I will be happy if there is a simple fix for the row numbering issue between the "Qualifications" sheet and the "Add Employee Form Responses" sheet. Otherwise, the only way I believe this can be fixed is to reinstate the Query function and then get the apps script to remove the data from the "Add Employee Form Responses" sheet also. I would appreciate any suggestions. I really would like everything to be automated because there will be many computer illiterate users.

1
May I clarify? Your form "Add Employee Form Responses" (the form) notifies new employees. Your sheet "Qualifications" has formulaic "links", updated manually when a new employee is added, to the form and includes additional employee data. Your sheet "Qualifications - Employees Left" is updated from "Qualifications" by a script that deletes the employee row from "Qualifications" and pastes the values into the sheet. Question: Why not just leave "Add Employee Form Responses" as a form and as each new response is received, copy the employee details into "Qualifications"?Tedinoz
Your statements are correct. I would prefer to automate if it could be done then I will lock it all down because there will be a number of users who, I have no doubt, will mess everything up. Things like the name which I want to be displayed in a single format which I have done through the formula in column A of the Qualifications sheet.McChief

1 Answers

2
votes

You are looking for a better way to dynamically record new employees, notified on the "Add Employee Form Responses" sheet, on your "Qualifications" sheet. At present you use simple formulae but these do not necessarily automatically pickup new employees.

In this answer, I suggest you look at a scenario where the data on "Qualifications" is physically copied from the Form Response sheet to the "Qualifications" sheet.

For development purposes, the following steps were made:

  • created a duplicate of the "Qualifications" sheet
  • named the duplicate sheet "staff".
  • displayed ALL rows on "staff"
  • copied (copy/paste values) one existing employee to row 5
  • deleted contents of ALL cells from Row 6 to the last row - to the last column
  • copied the script into the bound Project
  • installed the function as an installable trigger - event = Spreadsheet/On form submit
  • processed some new employee for testing.
  • confirmed that new employee data was added to the last row plus one of the "staff"

    function so5882862602(e) {

      //58828626
      // setup spreadsheet and sheets
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var formsheetname = "Add Employee Form Responses";
      var form = ss.getSheetByName(formsheetname);
      var staffsheetname = "staff";
      var staff = ss.getSheetByName(staffsheetname);

      // get Form Response
      //Logger.log(JSON.stringify(e));
      var row = e.range.getRow();
      var range = form.getRange(row,1,1,10);
      //Logger.log("DEBUG: The range is "+range.getA1Notation());  
      var values = range.getValues();  
      var formSurname = values[0][1]
      var formFirstName = values[0][2];
      var formaka = values[0][3];
      var formType = values[0][4]
      var formBranch = values[0][5];
      var formDOB = values[0][6];
      var formGender = values[0][7]
      var formNSN = values[0][8];
      var formNZQA = values[0][9];
      //var formTimeStamp = values[0][0];
      Logger.log("DEBUG: Employee="+formSurname+", "+formFirstName+",aka="+formaka+", Type="+formType+", Branch="+formBranch+", DOB="+formDOB+", Gender="+formGender+", NSN="+formNSN+", NZQA="+formNZQA);


      //update the staff sheet
      var staffupdate = [];
      var staffinal=[];

      // check the value of formaka and adjust name accordingly
      var staffname = "";
      // check the value of formaka
      if (formaka != ""){
        staffname = formSurname.toUpperCase()+", "+formFirstName+" ("+formaka+")";// name
      }
      else{
        staffname = formSurname.toUpperCase()+", "+formFirstName;// name
      }

      // push the values to a blank array
      staffupdate.push(staffname); // name
      staffupdate.push(""); // left
      staffupdate.push(formType);// TYPE
      staffupdate.push(formBranch); // branch
      staffupdate.push(formDOB); // DOB
      staffupdate.push(formGender);// Gender
      staffupdate.push(formNSN);// National Student Number
      staffupdate.push(formNZQA); // NZQA Unit Standards

      //push the array to a second array to create 2D
      staffinal.push(staffupdate);

      // get staff data
      var staffLR = staff.getLastRow();
      var staffupdaterange = staff.getRange(staffLR+1,1,1,8);
      Logger.log("DEBUG: The staff range = "+staffupdaterange.getA1Notation());


        // update the form values to the staff sheet
      staffupdaterange.setValues(staffinal);

    }