In AppScript it is difficult to get the last modified date of a single cell. One can get the historical values via the revisions of the sheet itself. This is not a straightforward task. Tracking the last modified date via a onEdit scheduled functions seems like an easier solution to deploy.
I have the following script that attempts to do this. Note that it tries to avoid calling the SpreadsheetApp.getActiveSpreadsheet() step as much as possible. I assume that doing so is slow. However, despite my attempt at optimization this script still takes about 36 seconds to complete. Is this just the way things are or have I missed a crucial part on the script that is to blame for such long runtimes? Any ideas on optimizing the speed of this function will be greatly appreciated. It is going to be deployed to a sheet that has multiple users working on it.
function onEdit(event){
Logger.log('Edit event detected.');
if (event.range.getSheet().getName() !== 'Reference Number Generator'){
Logger.log('Edit event not relevant: different sheet');
return null;
}
if (event.range.getColumn()!== 13){
Logger.log('Edit event not relevant: different column');
return null;
}
if (event.value !== 'Yes'){
Logger.log('Edit event not relevant: not changed to YES');
return null;
}
Logger.log(`Logging change to row ${event.range.getRow()}`);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reference Number Generator');
var date = new Date();
sheet.getRange(event.range.getRow(),16).setValue(date);
Logger.log('...done!')
}
Response to comments
Thank you very much @dataful.tech for the insights and debugging suggestions. I have the following answers to the queries which I think are useful to include in the body of the question.
- Is it persistent? On average, the function takes about 36 seconds. Sometimes longer. This is always the case. It also times out.
- Please send screenshot of the delay. I have attached a screenshot of the logs. It seems that it lags after logging "Edit event detected" and only gets to one of the case statements much later. To me that suggests an issue with
event.rangeand its related class methods such asgetSheet(). These are probably retrieving a lot. - Are there any formulas in the data? No formulas, only dropdown boxes for the user to select on of the available options.
- How big is the document? It is probably quite large at 22,478 rows and 25 columns.
I think that step 4 might be the case and that very little could be done about that.
Logging: identifying the bottleneck
I followed the suggestions that @dataful.tech have after the above section. The renaming of the function to anything that is not onEdit significantly reduced the amount of timeouts. The function remains the same thought. Following the next suggestion to log all steps, the following script was executed. I included event.value as a sanity check even though it does not call anything.
function test(event){
Logger.log('event.range.getSheet()...');
var sheet = event.range.getSheet();
Logger.log('..done!');
Logger.log('sheet.getName()...');
sheet.getName();
Logger.log('..done!');
Logger.log('event.range.getColumn()...');
event.range.getColumn();
Logger.log('..done!');
Logger.log('event.value...');
event.value;
Logger.log('..done!');
Logger.log('event.range.getRow()...');
event.range.getRow();
Logger.log('..done!');
}
The script produced the following logs that expose sheet.getName() to be the bottleneck. How very strange. It was intended to actually be a form of optimization such that we can reject edits that are not on the relevant worksheet. I am quite curious was to why retrieving the name might take so long. I think that all of this perhaps reinforces the quote by Donald Knuth: "Premature optimization is root of all evil!"



Since you already know you are on the right sheet from this line of code:
Try this: