当单元格值由于内置函数而变化时,onEdit(e)不生成触发事件

时间:2019-12-11 13:06:27

标签: google-apps-script google-sheets google-apps-script-simple-triggers

下面的代码监视单元格值之间的变化(行1到行5,列1到列5),并在不同的工作表中跟踪和记录事件。 仅当在电子表格单元格中手动进行更改时,该选项才有效。 (因为onEdit(e)函数仅跟踪手动编辑的单元格值更改,而未由任何其他函数跟踪)

如果单元格值由于某些内置的数学函数而发生更改(例如:B2 = C2 + D2,其中C2 / D2更改时B2的单元格值将自动更改),但是使用此代码,我无法看到事件触发了B2的值单元格。

任何人都可以使用下面的代码来帮助找到解决方案或解决方法。

谢谢

代码:

function onEdit(e) {
  if (
    e.source.getSheetName() == "SheetA" &&
    e.range.columnStart >= 1 &&
    e.range.columnEnd <= 5 &&
    e.range.rowStart >= 1 &&
    e.range.rowEnd <= 5
      ) {
    //Logger.log("the cell is in range");
      var sheetsToWatch = ['SheetA'];
      var changelogSheetName = "Changelog";  
      var timestamp = new Date();
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var cell = sheet.getActiveCell();
      var sheetName = sheet.getName();

        // if it is the changelog sheet that is being edited, do not record the change
      if (sheetName == changelogSheetName) return;

        // if the sheet name does not appear in sheetsToWatch, do not record the change
      var matchFound = false;
      for (var i = 0; i < sheetsToWatch.length; i++) {
      if (sheetName.match(sheetsToWatch[i])) matchFound = true;
       }
      if (!matchFound) return;


      var columnLabel = sheet.getRange(/* row 1 */ 1, cell.getColumn()).getValue();
      var rowLabel = sheet.getRange(cell.getRow(), /* column A */ 1).getValue();

      var changelogSheet = ss.getSheetByName(changelogSheetName);
      if (!changelogSheet) {
      // no changelog sheet found, create it as the last sheet in the spreadsheet
      changelogSheet = ss.insertSheet(changelogSheetName, ss.getNumSheets());
      // Utilities.sleep(2000); // give time for the new sheet to render before going back
      // ss.setActiveSheet(sheet);
      changelogSheet.appendRow(["Timestamp", "Sheet name", "Cell address", "Column label", "Row label", "Value entered"]);
      changelogSheet.setFrozenRows(1);
       }
     changelogSheet.appendRow([timestamp, sheetName, cell.getA1Notation(), columnLabel, rowLabel, cell.getValue()]);
}
  }

1 个答案:

答案 0 :(得分:1)

有一种解决方法:

  1. 创建两个单独的电子表格-电子表格编号1包含您的原始数据和公式,电子表格编号2包含您的脚本和一个空的SheetA
  2. A1的{​​{1}}中的单元格SheetA分配公式Spreadsheet2,其中=IMPORTRANGE(IMPORTRANGE(spreadsheet_url, range_string)spreadsheet_url和{{1 }}感兴趣的范围(例如Spreadsheet 1
  3. 使用Scriptproperties存储单元格值
  4. 每当感兴趣的工作表发生变化时,通过将旧值与新值进行比较来找到修改后的单元格
  5. 按如下所示修改脚本:
range_string
  1. "SheetA!A1:E"installable trigger var ss=SpreadsheetApp.getActive(); var sheetsToWatch = ['SheetA']; function initialSetUp(){//run this function only once, unless your range of interest changes for (var k = 0; k < sheetsToWatch.length; k++) { var sheet=ss.getSheetByName(sheetsToWatch[k]); var range=sheet.getRange(1,1,5,5); //change if required var values=range.getValues(); for(var i=0;i<values.length;i++){ for(var j=0;j<values[0].length;j++){ PropertiesService.getScriptProperties().setProperty('values '+sheet.getSheetName()+i+"-"+j,values[i][j]); } } } } function Edit() { var sheet=ss.getActiveSheet(); var sheetName = sheet.getName(); var matchFound = false; for (var k = 0; k < sheetsToWatch.length; k++) { if (sheetName.match(sheetsToWatch[k])) matchFound = true; } if (matchFound == true) { var range=sheet.getRange(1,1,5,5); //change if required var values=range.getValues(); for(var i=0;i<values.length;i++){ for(var j=0;j<values[0].length;j++){ var scriptValue=PropertiesService.getScriptProperties().getProperty('values '+sheetName+i+"-"+j); var newValue=sheet.getRange(i+1,j+1).getValue(); Logger.log(scriptValue); Logger.log(newValue); if(newValue!=scriptValue){ var cell=sheet.getRange(i+1,j+1); var timestamp = new Date(); var columnLabel = sheet.getRange(1, cell.getColumn()).getValue(); var rowLabel = sheet.getRange(cell.getRow(), /* column A */ 1).getValue(); var changelogSheetName = "Changelog"; var changelogSheet = ss.getSheetByName(changelogSheetName); if (!changelogSheet) { changelogSheet = ss.insertSheet(changelogSheetName, ss.getNumSheets()); //Utilities.sleep(2000); // give time for the new sheet to render before going back changelogSheet.appendRow(["Timestamp", "Sheet name", "Cell address", "Column label", "Row label", "Value entered"]); changelogSheet.setFrozenRows(1); } changelogSheet.appendRow([timestamp, sheetName, cell.getA1Notation(), columnLabel, rowLabel, cell.getValue()]); PropertiesService.getScriptProperties().setProperty('values '+i+"-"+j,newValue); } } } } } 中添加新功能。
  

解释:

     
      
  • onEdit触发器无法检测到公式触发的值的变化
  •   
  • onChange无法检测由单元格公式引起的更改,但可以检测由IMPORTRANGE触发的更改
  •