I don't know much about programming but I created a script for one of my spreadsheets which worked very well a few months ago.
But lately it is impracticable to use any script, however simple it may be. Sometimes it runs perfectly in 1 or 2 seconds and most of the time it just times out and fails. 90% of executions result in "timed out".
In summary, the function must be executed every time column B or C of the spreadsheet is edited. For this I used the function OnEdit ().
When column B is edited, the date and time is inserted in column D in the respective line where the change occurred.
When column C is edited, the date and time is inserted in column E in the respective line where the change occurred.
Here is the code:
function onEdit(e)
{
var column = e.range.getColumn();
var aba = e.source.getActiveSheet().getName();
if (column == 2 && aba == "Controle")
{
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell();
if(cell.getValue() != "")
{
var add = cell.offset(0, 2);
var data = new Date();
data = Utilities.formatDate(data, "GMT-03:00","dd/MM/yyyy' 'HH:mm' '");
add.setValue(data);
}
else
{
var add = cell.offset(0, 2);
var data = new Date();
data = "";
add.setValue(data);
}
}
if (column == 3 && aba == "Controle")
{
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell();
if(cell.getValue() == true)
{
var add = cell.offset(0, 2);
var data = new Date();
data = Utilities.formatDate(data, "GMT-03:00","dd/MM/yyyy' 'HH:mm' '");
add.setValue(data);
}
else
{
var add = cell.offset(0, 2);
var data = new Date();
data = "";
add.setValue(data);
}
}
}
Even super simple recorded macros like applying a filter are showing this problem.
I would like to know if there is something that can be done in the code to make it more efficient to solve this problem or if the timeout problem reached is related to something else.
Thanks
Try this:
function onEdit(e) {
const sh=e.range.getSheet();
if(sh.getName()=='Controle' && e.range.columnStart>1 && e.range.columnStart<4) {
if(e.range.columnStart==2) {
if(e.value='') {
e.range.offset(0,2).setValue(Utilities.formatDate(new Date(), "GMT-3", "dd/MM/yyyy' 'HH:mm' '"));
}else{
e.range.offset(0,2).setValue(new Date());
}
}
if(e.range.columnStart==3) {
if(e.value==true) {
e.range.offset(0,2).setValue(Utilities.formatDate(new Date(), "GMT-3", "dd/MM/yyyy' 'HH:mm' '"));
}else{
e.range.offset(0,2).setValue(new Date());
}
}
}
}
Based on your logs, your script is reaching quota for exceeding maximum execution time, although it is also possible from your scenario to have more than 30 simultaneous executions, which will make the script fail to run too.
One workaround, as Cooper have said in the comments, is to implement a lock on parts of the script, especially on sections that make changes to the spreadsheet, to make subsequent executions wait on one script to complete.
Sample code:
function onEdit(e)
{
var column = e.range.getColumn();
var aba = e.source.getActiveSheet().getName();
var lock = LockService.getScriptLock();
try { lock.waitLock(10000); } // wait 10 sec
if (column == 2 && aba == "Controle")
{
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell();
if(cell.getValue() != "")
{
var add = cell.offset(0, 2);
var data = new Date();
data = Utilities.formatDate(data, "GMT-03:00","dd/MM/yyyy' 'HH:mm' '");
add.setValue(data);
}
else
{
var add = cell.offset(0, 2);
var data = new Date();
data = "";
add.setValue(data);
}
}
if (column == 3 && aba == "Controle")
{
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell();
if(cell.getValue() == true)
{
var add = cell.offset(0, 2);
var data = new Date();
data = Utilities.formatDate(data, "GMT-03:00","dd/MM/yyyy' 'HH:mm' '");
add.setValue(data);
}
else
{
var add = cell.offset(0, 2);
var data = new Date();
data = "";
add.setValue(data);
}
}
SpreadsheetApp.flush(); // applies all pending spreadsheet changes
lock.releaseLock();
}
References:
Quotas for Google Services
Class Lock
Related
I'm trying to have TIMEVALUE set off a script. I have column P which is a Timer column that is subtracting a time from NOW to get a time value and then I am converting that to a TIMEVALUE in column O. When that value is either below or above certain values I want column N to then have a value so it would trigger my checkboxes script. But for some reason I can't get the TIMEVALUE to trigger. I tried to put it in another column and have the values CopyAndPasted Values Only into a column with that run on a time trigger of every minute, but apparently that doesn't count as an Edit or it's not reading the DisplayValue.
function onEdit(e) {
timeValue(e);
checkboxes(e);
rangerTime(e);
}
function rangerTime(e){
var editRow = e.range.getRow();
var editColumn = e.range.getColumn();
if (editColumn === 13 && e.value == "TRUE") {
const sh = e.range.getSheet();
sh.getRange(editRow, 25).setValue(sh.getRange(editRow, 25).getValue()+1);
sh.getRange(editRow, 13).setValue(" ")
}
}
function timeValue(e) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var editRow = e.range.getRow();
var editColumn = e.range.getColumn();
if(editRow > 3) {
var rowRange = sheet.getRange("O" + editRow);
var kCell = sheet.getRange("K" + editRow);
var kValue = kCell.getValue();
var nCell = sheet.getRange("N" + editRow);
var kHasValue = kValue != "";
if(editColumn > 10) {
if(rowRange.getDisplayValue()<0.02 && !kHasValue){
nCell.setValue(1);
}
if (rowRange.getDisplayValue()>0.5 && !kHasValue){
nCell.setValue(1);
}
if(kHasValue) {
nCell.setValue(" ");
}
}
}
}
function checkboxes(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ui = SpreadsheetApp.getUi();
var names = ss.getRange("N4:N");
var namesValues = names.getValues();
var checkboxes = ss.getRange("M4:M");
var cbRows = checkboxes.getHeight();
var cbValues = checkboxes.getValues();
var newCBValues = new Array(cbRows);
for (var row = 0; row < cbRows; row++) {
newCBValues[row] = new Array(0);
if (namesValues[row] == "" || namesValues[row] == " ") {
newCBValues[row][0] = " ";
}else{
if (cbValues[row][0] === true) {
newCBValues[row][0] = true;
}else{
newCBValues[row][0] = false;
}
}
}
checkboxes.setValues(newCBValues);
}
This part is run on the every minute Time Trigger:
function CopyandPaste() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('AA4').activate();
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
spreadsheet.getRange('O4').activate();
currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
spreadsheet.getRange('AA4:AA202').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
Column AA = TIMEVALUE(Column P)
From the question
I tried to put it in another column and have the values CopyAndPasted Values Only into a column with that run on a time trigger of every minute, but apparently that doesn't count as an Edit or it's not reading the DisplayValue.
You are right, only actions done by a user directly through the Google Sheets user interface will cause the edit trigger to be triggered.
One option is to make that your time-driven trigger besides changing the checkboxes also call the timeValue function but you have to refactor it or to mock the edit event object to pass it as the timeValue parameter.
Reference
https://developers.google.com/apps-script/guides/triggers
I've got the following Google Apps Script code which is triggered by an edit to a cell that has a dropdown data validation (Pick from List) on it. Occasionally it adds two duplicate rows to the target table instead of the desired single row. I've added Logging in a variety of locations to see if I can detect when/where/why some piece of code is running twice. The logs don't show any sections of the script running unexpectedly. I've added Locking as well. It didn't help with this issue, although it did make the script run in a more reliable fashion. I really want to get to the bottom of this although it is really just a nuisance at this point. Please let me know if you need any additional info:
function onEdit(e) {
Logger.log('Running onEdit');
var lock = LockService.getUserLock();
lock.waitLock(10000);
var cache = CacheService.getUserCache();
var spreadsheet = SpreadsheetApp.getActive().getActiveSheet();
var range = e.range;
var col = range.columnStart;
var row = range.rowStart;
var status = range.getDisplayValue();
if (col == 7 && row >= 13 && row <= 53) { //Ongoing Block
cache.put("oldStatus", e.oldValue);
Logger.log(row,col,status, e.oldValue);
if (status == 'ToVendor') { //Send to Vendor Block
copyEquipRow(spreadsheet,row,col,1,true);
Logger.log(row,col,cache.get("equipID"),cache.get("dateAdded"),cache.get("priority"),cache.get("problem"),cache.get("location"),cache.get("targetDate"));
pasteToVendor(spreadsheet);
}
if (status == 'AddReq') { //Add Related Req to the Req Block
copyEquipRow(spreadsheet,row,col,1,false);
Logger.log(row,col,cache.get("equipID"),cache.get("dateAdded"),cache.get("priority"),cache.get("problem"),cache.get("location"),cache.get("targetDate"));
addReq(spreadsheet);
spreadsheet.getRange(row, col).setValue(e.oldValue)
}
}
if (col == 16 && row >= 31 && row <= 37) { //Vendor Block
cache.put("oldStatus", e.oldValue);
Logger.log(row,col,status, e.oldValue);
if (status == 'ToOngoing') {
copyEquipRow(spreadsheet,row,col,0,true);
Logger.log(row,col,cache.get("equipID"),cache.get("dateAdded"),cache.get("priority"),cache.get("problem"),cache.get("location"),cache.get("targetDate"));
pasteToOngoing(spreadsheet);
}
}
lock.releaseLock();
}
function copyEquipRow(spreadsheet,row,col,problemCol,deleteRow) { //Status Equip # Date Added Priority Problem Location Target Date
Logger.log('Running CopyEquipRow');
var cache = CacheService.getUserCache();
var locationCol = 5 + problemCol;
var targetCol = 6 + problemCol;
var clearCol = 7 + problemCol;
var dateAdded = Utilities.formatDate(spreadsheet.getCurrentCell().offset(0, 2).getValue(), "EST", "M/d/yyyy");
var targetDate = Utilities.formatDate(spreadsheet.getCurrentCell().offset(0, targetCol).getValue(), "EST", "M/d/yyyy");
cache.put("equipID", spreadsheet.getCurrentCell().offset(0, 1).getValue());
cache.put("dateAdded",dateAdded);
cache.put("priority",spreadsheet.getCurrentCell().offset(0, 3).getValue());
cache.put("problem",spreadsheet.getCurrentCell().offset(0, 4).getValue());
cache.put("location",spreadsheet.getCurrentCell().offset(0, locationCol).getValue());
cache.put("targetDate",targetDate);
if (deleteRow == true ) {
spreadsheet.getRange(row, col, 1, clearCol).clearContent();
}
}
function pasteRow(spreadsheet,startCell,problemCol,includeStatus,dateOverride) {
Logger.log('Running pasteRow');
var cache = CacheService.getUserCache();
var currentCell = spreadsheet.getRange(startCell).activate();
var row = 0;
while (currentCell.offset(row, 1).isBlank() == false) {
row = ++row;
}
var oldStatus = cache.get("oldStatus");
var equipID = cache.get("equipID");
var dateAdded = cache.get("dateAdded");
var priority = cache.get("priority");
var problem = cache.get("problem");
var location = cache.get("location");
var targetDate = cache.get("targetDate");
var locationcol = 5 + problemCol;
var targetcol = 6 + problemCol;
Logger.log(equipID,dateAdded,priority,problem,location,targetDate);
if (includeStatus == true) {
currentCell.offset(row, 0).setValue(oldStatus);
}
currentCell.offset(row, 1).setValue(equipID);
if (dateOverride == true ){
currentCell.offset(row, 2).setValue(Utilities.formatDate(new Date(), "EST", "M/d/yyyy"));
}
else {
currentCell.offset(row, 2).setValue(dateAdded);
}
currentCell.offset(row, 3).setValue(priority);
currentCell.offset(row, 4).setValue(problem);
currentCell.offset(row, locationcol).setValue(location);
currentCell.offset(row, targetcol).setValue(targetDate);
}
function pasteToVendor(spreadsheet) {
Logger.log('Running pasteToVendor');
pasteRow(spreadsheet,'P30',0,true);
}
function pasteToOngoing(spreadsheet) {
Logger.log('Running pasteToOngoing');
pasteRow(spreadsheet,'G12',1,true);
}
function addReq(spreadsheet) {
Logger.log('Running addReq');
pasteRow(spreadsheet,'O12',1,false,true);
}
The onEdit(e) function responds to the simple trigger which cannot perform operations that require permission.
The instable onEdit trigger is tied to a function of you choice and it gets the same event object as the simple trigger. If you don't rename the installable trigger to something other than onEdit() then you're definitely getting two triggers all of the time.
Also keep in mind onEdit triggered functions must complete within 30 seconds.
Simple Triggers
installable triggers
Event Objects
I have two functions in my Google Sheet script which are each triggered by means of a checkbox (since Google Sheets on mobile can't use images as buttons). They work on PC (rather slowly), but on tablets, they tend to fail more often than not, which then also affects PC users.
The script is set up to perform an onEdit check of two checkbox cells. If the checkbox in cell C3 is checked, the AUTOFILL function should run (which displays the A cell value of the last row on the Info sheet plus 1 in cell C4 of the Data Entry sheet, and then clears the checkbox), and if the checkbox in cell C12 is checked, the SUBMIT function should run (which takes the range of data entered on the Data Entry sheet and updates an existing row/adds a new row on the Data sheet with the information from the Data Entry sheet, adding a timestamp if cell C11 on the Data Entry sheet contains the word 'CLEANED', and then clears the checkbox).
I've tried experimenting with various WIFI signal strengths and more powerful tablets, but I am unable to pinpoint the exact culprit here - sometimes this will run, most often the checkbox will just remain checked and nothing happens. Laptops and desktop computers all seem to run, but if a tablet tries to run and fails, the computers will sometimes not run either, until I go into the script itself and manually force once of the functions to run, which seems to reset things and lets the computers work again.
Is it because of the processing required in order to run this code? I've tried to optimize it as much as possible, but is there something else that I might change here which would make this work, every time?
Here is the example sheet, and here is the script:
function onEdit(e) {
if (e.range.getSheet().getName() != "Data Entry") {
return
}
var isAutofill = SpreadsheetApp.getActiveSheet().getRange("C3").getValue();
var isSubmit = SpreadsheetApp.getActiveSheet().getRange("C12").getValue();
if (isAutofill && isSubmit) {
Browser.msgBox("You cannot autofill and submit data at the same time!");
SpreadsheetApp.getActiveSheet().getRange("C3").setValue(false);
SpreadsheetApp.getActiveSheet().getRange("C12").setValue(false);
} else if (isAutofill) {
AUTOFILL();
SpreadsheetApp.getActiveSheet().getRange("C3").setValue(false);
} else if (isSubmit) {
SUBMIT();
SpreadsheetApp.getActiveSheet().getRange("C12").setValue(false);
}
}
function AUTOFILL() {
var sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Info');
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data Entry');
var valueOfData = sheet1.getRange(sheet1.getLastRow(), 1).getValue();
sheet2.getRange('C4').setValue(valueOfData + 1);
}
function SUBMIT() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Data Entry");
var dataSheet = ss.getSheetByName("Info");
var values = formSS.getRange("C4:C11").getValues().reduce(function(a, b) {
return a.concat(b)
});
var partNum = values[0];
var row;
dataSheet.getDataRange().getValues().forEach(function(r, i) {
if (r[0] === partNum) {
row = i + 1
}
})
row = row ? row : dataSheet.getLastRow() + 1;
var data = dataSheet.getRange(row, 1, 1, 8).getValues()[0].map(function (el, ind){
return el = values[ind] ? values[ind] : el;
})
var statusValue = formSS.getRange("C11").getValue();
if (statusValue != 'CLEANED') {
dataSheet.getRange(row, 1, 1, 8).setValues([data]);
}
if (statusValue == 'CLEANED') {
var now = [new Date()];
var newData = data.concat(now)
dataSheet.getRange(row, 1, 1, 9).setValues([newData]);
}
formSS.getRange("C4:C11").clearContent()
}
I made a few changes. Take a look. Hopefully you can use them to speed up the function.
function onEdit(e) {
var sh=e.range.getSheet();
if (sh.getName() != "Data Entry") {return;}
var rgC3=SpreadsheetApp.getActiveSheet().getRange("C3");
var rgC12=SpreadsheetApp.getActiveSheet().getRange("C12");
var isAutofill = rgC3.getValue();
var isSubmit = rgC12.getValue();
if (isAutofill && isSubmit) {
e.source.toast("You cannot autofill and submit data at the same time!");
rgC3.setValue(false);
rgC12.setValue(false);
} else if (isAutofill) {
AUTOFILL(e.source);
rgC3.setValue(false);
} else if (isSubmit) {
SUBMIT(e.source);
rgC12.setValue(false);
}
}
function AUTOFILL(ss) {
var sheet1 = ss.getSheetByName('Info');
var sheet2 = ss.getSheetByName('Data Entry');
var valueOfData = sheet1.getRange(sheet1.getLastRow(), 1).getValue();
sheet2.getRange('C4').setValue(valueOfData + 1);
}
function SUBMIT(ss) {
var formSS=ss.getSheetByName("Data Entry");
var dataSheet=ss.getSheetByName("Info");
var values=formSS.getRange("C4:C11").getValues().reduce(function(a, b) {return a.concat(b)});
var partNum = values[0];
var row;
var data=dataSheet.getDataRange().getValues()
for(var i=0;i<data.length;i++) {
if(data[i][0]==partNum) {
row=i+1;
break;
}
}
row = row ? row : dataSheet.getLastRow() + 1;
var data = dataSheet.getRange(row, 1, 1, 8).getValues()[0].map(function (el, ind){return el = values[ind] ? values[ind] : el;})
var statusValue = formSS.getRange("C11").getValue();
if (statusValue != 'CLEANED') {dataSheet.getRange(row, 1, 1, 8).setValues([data]);}
if (statusValue == 'CLEANED') {var now = [new Date()];var newData=data.concat(now);dataSheet.getRange(row, 1, 1, 9).setValues([newData]);}
formSS.getRange("C4:C11").clearContent();
}
I'm trying to develop a simple script to create a log table to show certain information when a checkbox is marked on one of the Sheets.
The script works correctly (it does what it needs to do) but sometimes works slow. If more than one user 'edits' the Sheet at the same time some entries get lost because the last edit overwrites the previous one. I need to optimize the script as much as possible to avoid losing information.
I think there are 2 possible ways to do it. One is using a function to identify the next available row and the other one is using a countA function within the sheet and get the value from the code (...getRange('whatever').getValue()).
Both of them turned to be slow, so I guess the issue is elsewhere.
I have also tried to use onEdit(e) and getting the active range by e.range but it is also too slow.
Please, find below the code.
function onEdit() {
var ss = SpreadsheetApp.getActive();
var user = Session.getActiveUser().getEmail();
var activeCell = ss.getActiveRange();
var sheet = activeCell.getSheet();
var row = activeCell.getRow();
var column = activeCell.getColumn();
var activeCellValue = activeCell.getValue();
if(!isSupervisor(user) && activeCellValue == true && sheet.getName() != "Activities" && sheet.getName() != "Edit Log" && row >= 10 && column >= 2 && column <= 26 && column % 2 != 0){
var editLog = ss.getSheetByName("Edit Log");
var nextRow = 4 + editLog.getRange('P1').getValue();
var date = new Date();
var language = sheet.getRange(4, column - 1).getValue();
var assignedTo = sheet.getRange(3, column - 1).getValue();
var startHour = sheet.getRange(row, 1).getValue();
var startHourHour = sheet.getRange(row, 27).getValue();
var startHourMinutes = sheet.getRange(row, 28).getValue();
var activity = sheet.getRange(row, column - 1).getValue();
var note = activeCell.getNote();
var generatingID = sheet.getName()+"_"+language+"_"+activity+"_"+startHourHour;
//var shortID = language+"_"+activity+"_"+startHour;
if(!isAlreadyAdded(generatingID, editLog.getRange("A4:A").getValues())) {
editLog.getRange("B1").setValue("Not added");
editLog.getRange("B2").setValue(generatingID);
editLog.getRange(nextRow, 1).setValue(generatingID);
editLog.getRange(nextRow, 3).setValue(date);
editLog.getRange(nextRow, 4).setValue(user);
editLog.getRange(nextRow, 5).setValue(sheet.getName());
editLog.getRange(nextRow, 6).setValue(activeCellValue);
editLog.getRange(nextRow, 7).setValue(language);
editLog.getRange(nextRow, 8).setValue(activity);
editLog.getRange(nextRow, 9).setValue(assignedTo);
editLog.getRange(nextRow, 10).setValue(startHour);
editLog.getRange(nextRow, 13).setValue(note);
} else {
editLog.getRange("B1").setValue("Already added");
editLog.getRange("B2").setValue(generatingID);
}
}
}
function isAlreadyAdded(generatingID, values) {
for(var i = 0; i < values.length; i++) {
if(values[i] == generatingID) {
return true;
}
}
return false;
}
function getFirstEmptyRow(data) {
for(var i = 0; i < data.length; i++) {
if(data[i][0] == null || data[i][0] == '') {
return i;
}
}
}
function isSupervisor(user) {
var supervisors = getSupervisors();
for(var i = 0; i < supervisors.length; i++) {
if(user == supervisors[i]) {
return true;
}
}
return false;
}
function getSupervisors() {
var supervisors = [];
//real values are hidden due to confidential information
supervisors.push("???");
supervisors.push("???");
supervisors.push("???");
supervisors.push("???");
supervisors.push("???");
supervisors.push("???");
supervisors.push("???");
supervisors.push("???");
return supervisors;
}
As previously mentioned, I need to make this script as fast as possible. I can't lose any entry due to the slowness of the script. Do you have any suggestion?
Thanks for your help :)
My spreadsheet is composed of a main sheet that is populated using a form plus several other sheets for the people who work with the responses submitted through the form. A script delegates the form responses to these other sheets depending on the type of item described in the response.
The problem is, when Person A deletes an item from their respective sheet, it doesn't delete in the main sheet.
My idea is that when you type a set password into the corresponding cell in row 'Q' in Person A's sheet, it matches the item by timestamp to the original form submission and deletes both the version of the item in Person A's sheet as well as the main sheet. However, I can't figure out what to set the range to to get it to point to the row in the array. Everything I have tried has sent back "undefined" in the debugger and won't delete anything. I think the problem is that I don't know how to get the row from the array that I have made. See my code below:
function onEdit() {//copies edited items from individual selector sheets back onto main spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actSheet = ss.getActiveSheet();
var responseSheet = ss.getSheetByName("Item Request");
var actCell = actSheet.getActiveCell();
var actRow = actCell.getRow();
var actVal = actCell.getValue();
var actLoc = actCell.getA1Notation();
var last = actSheet.getLastRow();
var respLast = responseSheet.getLastRow();
var dataA = responseSheet.getRange(1, 1, respLast, 1).getValues(); //compiles an array of data found in column A through last row in response sheet
var tstamp1 = actSheet.getRange(actCell.getRow(), 1);
var tsVal1 = tstamp1.getValue();
var colEdit = actCell.getColumn();
//===========THIS IS WHERE I'M STUCK=======================
if ((actVal == "p#ssword") && (colEdit == 17)) {
for (i = 1; i < dataA.length; i++) {
if (dataA[i][0].toString == tsVal1.toString()) {
responseSheet.deleteRow(i + 1);
actSheet.deleteRow(actRow);
break;
}
}
}
else if (colEdit == 15) { //checks the array to see if the edit was made to the "O" column
for (i = 1; i < dataA.length; i++) {//checking for timestamp match and copies entry
if (dataA[i][0].toString() == tsVal1.toString()) {
var toEdit = responseSheet.getRange(i + 1, 16);
toEdit.setValue(actVal);
}
}
}
else if (colEdit == 16) { // checks the array to see if the edit was made in the "P" column
for (i = 1; i < dataA.length; i++) {//checking for timestamp match and copies entry
if (dataA[i][0].toString() == tsVal1.toString()) {
var toEdit = responseSheet.getRange(i + 1, 17);
toEdit.setValue(actVal);
}
}
}
else {return;}
}//end onEdit
I don't believe these are proper commands delRow.deleteRow();actCell.deleteRow(); Take a look at the documentation;
Okay I rewrote that function for you a bit but I'm stilling wondering about a couple of lines.
function onEdit(e)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actSheet = ss.getActiveSheet();
var responseSheet = ss.getSheetByName("Item Request");
var actCell = actSheet.getActiveCell();
var actRow = actCell.getRow();
var actVal = actCell.getValue();
var colEdit = actCell.getColumn();
var respLast = responseSheet.getLastRow();
var dataA = responseSheet.getRange(1, 1, respLast, 1).getValues();
var tstamp1 = actSheet.getRange(actRow, 1);
var tsVal1 = tstamp1.getValue();
for(var i=0;i<dataA.length;i++)
{
if(new Date(dataA[i][0]).valueOf()==new Date(tsVal1).valueOf())
{
if (actVal=="p#ssword" && colEdit==17)
{
responseSheet.deleteRow(i + 1);
actSheet.deleteRow(actRow);
}
else if(colEdit==15)
{
var toEdit = responseSheet.getRange(i + 1, 16);//?
toEdit.setValue(actVal);//?
}
else if (colEdit == 16)
{
var toEdit = responseSheet.getRange(i + 1, 17);//?
toEdit.setValue(actVal);//?
}
}
}
}
Can you explain the function of the lines with question marked comments?