Google apps script 在编辑触发器上启动函数的延迟时间-谷歌应用程序脚本

Google apps script 在编辑触发器上启动函数的延迟时间-谷歌应用程序脚本,google-apps-script,triggers,lag,Google Apps Script,Triggers,Lag,我一直在谷歌应用程序脚本中使用On-Edit触发器。在编写这个脚本时,我注意到从用户完成对google工作表的编辑到On edit触发器调用的函数开始执行之间有一段很短的时间。虽然此延迟时间很短,但足够长,用户可以在运行On Edit触发器调用的函数之前快速对工作表进行其他编辑 是否有任何方法可以减少/消除此延迟时间,或防止用户在等待功能开始时对工作表进行任何更改 我知道函数中的代码可能会在函数运行时导致延迟,但我可以通过在函数运行时临时保护工作表,并在函数结束时取消保护来解决该问题。这仍然存在

我一直在谷歌应用程序脚本中使用On-Edit触发器。在编写这个脚本时,我注意到从用户完成对google工作表的编辑到On edit触发器调用的函数开始执行之间有一段很短的时间。虽然此延迟时间很短,但足够长,用户可以在运行On Edit触发器调用的函数之前快速对工作表进行其他编辑

是否有任何方法可以减少/消除此延迟时间,或防止用户在等待功能开始时对工作表进行任何更改

我知道函数中的代码可能会在函数运行时导致延迟,但我可以通过在函数运行时临时保护工作表,并在函数结束时取消保护来解决该问题。这仍然存在触发器的延迟时间问题,因为在函数开始运行之前,我无法保护工作表

我可以用下面的代码证明滞后时间的存在。当On Edit触发器调用此函数时,首先将单元格G1的值设置为69。如果删除G1中的69,可以快速键入不同的数字,然后在函数再次将值更改回69之前输入。附加代码和工作表上的其他内容只是为了演示我正试图用它实现什么以及为什么。以下是相关google工作表的链接(当被编辑触发时,它会运行下面代码块中的函数):

//此函数的目标是只允许用户在A列中填写D列中的项目。用户应该只能输入D列中的每个项目一次,但他们可以
//可以随意移动和更换。
函数触发器测试(){
//这两行只是为了快速证明滞后时间。与此代码的其余部分无关。。。
设testCell=SpreadsheetApp.getActiveSheet().getRange('G1');
testCell.setValue(69);
//接下来的4行只是将A列和D列中的值放入数组(getDisplayValues()返回一个2d数组)
//cleanArray函数从数组中删除空白单元格,使其成为1d数组
让databaseValues=SpreadsheetApp.getActiveSheet().getRange('D2:D11').getDisplayValues();
让cleanDatabaseValues=cleanArray(databaseValues);
让itemsColumnValues=SpreadsheetApp.getActiveSheet().getRange('A2:A11').getDisplayValues();
让cleanItemsColumnValues=cleanArray(itemsColumnValues);
//这些for循环查找D列中不在A列中的所有项,并将它们放入一个新数组-valuesInDatabaseAndNotInItemsColumn[]
让valuesInDatabaseAndNotInItemsColumn=cleanDatabaseValues;

对于(设i=0;iAFAIK,无
恐怕这个时间延迟是不可避免的。如果您想确保用户在运行
onEdit
之前不能编辑多个单元格,也许您可以使用PropertiesService存储上次的单元格值,将它们与新值进行比较,如果检测到多个更改,它们将被还原。您认为这些更改有什么意义吗es可能是一个有效的解决方法?好的,没有
恐怕这个时间延迟是不可避免的。如果您想确保用户在运行
onEdit
之前不能编辑多个单元格,也许您可以使用PropertiesService存储上次的单元格值,将它们与新值进行比较,如果检测到多个更改,它们将被还原。您认为这些更改有什么意义吗es可能是一个有效的解决方法?
// The goal of this function is to only allow the user to fill in column A with items from column D. The user should only be able to enter each item from column D once, but they can
// be moved around and replaced at will. 
function triggerTest() {

  //These two lines are just to quickly prove lag time. Nothing to do with the rest of this code...
  let testCell = SpreadsheetApp.getActiveSheet().getRange('G1');
  testCell.setValue(69);

  //These next 4 lines are just putting the values in column A and column D into arrays (getDisplayValues() returns a 2d array)
  //The cleanArray function deletes blank cells from the array and makes it a 1d array
  let databaseValues = SpreadsheetApp.getActiveSheet().getRange('D2:D11').getDisplayValues();
  let cleanDatabaseValues = cleanArray(databaseValues);
  let itemsColumnValues = SpreadsheetApp.getActiveSheet().getRange('A2:A11').getDisplayValues();
  let cleanItemsColumnValues = cleanArray(itemsColumnValues);

  //These for loops find all items in the column D that are not already in column A and puts them into a new array - valuesInDatabaseAndNotInItemsColumn[]
  let valuesInDatabaseAndNotInItemsColumn = cleanDatabaseValues;
  for(let i=0; i<cleanItemsColumnValues.length; i++){
    for(let j=0; j<valuesInDatabaseAndNotInItemsColumn.length; j++){
      if(valuesInDatabaseAndNotInItemsColumn[j] === cleanItemsColumnValues[i]){
        valuesInDatabaseAndNotInItemsColumn.splice(j,1);
        j--;
      }
    }
  }

  //This is the data validation for column A. It only allows values that are in Database column and NOT already in the Items column. If there is a duplicate both entries are invalid.
  //Since every cell undergoes validation, the cells that already contain entries must be allowed to keep them which is the reason for the .concat on line 44. Duplicate cells are not
  //allowed to contain their current value, hence the absence of .concat on line 41.
  for(let i=0; i<itemsColumnValues.length; i++){
    let cellIndex = (i + 2).toString();
    let cell = SpreadsheetApp.getActiveSheet().getRange('A'+ cellIndex);
    let duplicate = false;
    let cellValidation = SpreadsheetApp.newDataValidation();
    for(let j=0; j<itemsColumnValues.length; j++){ //This for loop tests to see if there is a duplicate of the entry 
      if(j != i && itemsColumnValues[j][0] === itemsColumnValues[i][0]){
        duplicate = true;
      }
    }
    if(duplicate === true){
      cellValidation.requireValueInList(valuesInDatabaseAndNotInItemsColumn, true).setAllowInvalid(false).build();
    }
    else{
      cellValidation.requireValueInList(valuesInDatabaseAndNotInItemsColumn.concat(itemsColumnValues[i][0]), true).setAllowInvalid(false).build();
    }
    cell.setDataValidation(cellValidation);
  }
}