【问题标题】:Creating a backup of data entered into a sheet via Google App Scripts通过 Google App Scripts 创建输入到工作表中的数据的备份
【发布时间】:2021-06-26 17:12:05
【问题描述】:

我有一个电子表格,用户可以在其中输入数据,然后在单击按钮时执行功能。单击该按钮时,它会记录时间并在该电子表格的另一张工作表的新行中输入数据。

为确保用户不会意外编辑该工作表,我想创建该数据的非共享备份。

我将范围导入到另一个电子表格,但仅导入范围意味着如果原始工作表被编辑/擦除,则数据也将被编辑/擦除,因此我编写了以下脚本来记录这些更改。

    function onEdit(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var incomingSheet = ss.getSheetByName('Incoming');
var lastRow = incomingSheet.getLastRow();
var incomingData = incomingSheet.getRange(lastRow,1,1,7);

var permanentSheet = ss.getSheetByName('PermanentLog')
var newdataRow = permanentSheet.getLastRow();

incomingData.copyTo(permanentSheet.getRange(newdataRow+1,1));
}

这在从 Apps 脚本编辑器运行时有效,但是,当我输入新数据并单击原始电子表格上的按钮时,它会将数据记录到那里的日志表中,并将范围导入到“传入”表中的新电子表格,但数据不会复制到“永久日志”表中(除非我从 Apps 脚本编辑器中手动运行它)。如果我从第一张表中删除 ImportRange 函数,然后在“传入”表中手动输入数据,它也可以工作。

这是否意味着导入范围中的新行不会触发 onEdit?解决方案是什么?我不想在定时触发器上运行它,我想永久捕获每一个新的数据行。

另外,我是否忽略了对整个问题的更优雅和简单的解决方案?

感谢您的宝贵时间。

【问题讨论】:

  • 想出了一个更简单的解决方案,让原始按钮单击同时执行SpreadsheetApp.openById 并将数据直接附加到单独的电子表格中。仍然想知道 onEdit 是否不能被 ImportRange 函数中的新行触发。
  • 您的代码的一个问题是它在每张工作表的每次编辑时都会运行。如果你想简化它,你可以这样写:function onEdit(e){ const sh=e.range.getSheet(); const ash=e.soure.getSheetByName('PermanentLog'); sh.getRange(sh.getLastRow(),1,1,7).copyTo(ash.getRange(ash.getLastRow()+1,1));} 但是你不能从脚本编辑器运行它,除非你将事件对象传递给它。此外,您的代码不会访问另一个电子表格。
  • 对不起。我应该澄清一下,上面的脚本存在于单独的电子表格中,该电子表格在第一个单元格中有一个带有 IMPORTRANGE 函数的“传入”工作表,因此它复制了我要存档的工作表。由于它仅从另一个电子表格上的记录表导入,并且每次数据都记录为一整行,因此避免了每个单元格条目触发 onEdit 的问题。 . .但失败了,因为 onEdit 不能被 ImportRange 函数触发。在下面查看您的解决方案。

标签: google-apps-script google-sheets


【解决方案1】:

每当您编辑第 7 列时,此函数都会将数据复制到新的电子表格中,我认为这是您数据中的最后一列。它仅适用于您在名称数组中指定的工作表。注意:除非您提供替换 e 的事件对象,否则您无法从脚本编辑器运行它而不会出现错误。我使用了一个可安装的 onEdit 触发器。

该函数还将时间戳和行号附加到存档数据行的开头

function onMyEdit(e) {
  e.source.toast('entry');//just a toast showing that the function is working for debug purposes
  const sh = e.range.getSheet();//active sheet name
  const names = ['Sheet1', 'Sheet2'];//sheetname this function operates in
  if (~names.indexOf(sh.getName()) && e.range.columnStart == 7) {
    const ass = SpreadsheetApp.openById('ssid');//archive spreadsheet
    const ash = ass.getSheetByName('PermanentLog');//archive sheet
    let row = sh.getRange(e.range.rowStart, 1, 1, 7).getValues()[0];
    let ts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy/MM/dd HH:mm:ss");//timestamp
    row.unshift(ts, e.range.rowStart);//add timestamp and row number to beginning
    Logger.log(row);//logs the row for debug purposes
    ash.appendRow(row);//appends row to bottom of data with ts and row

  }
  Logger.log(JSON.stringify(e));
}

【讨论】:

    【解决方案2】:

    限制

    脚本执行和 API 请求不会导致触发器运行。例如,调用Range.setValue() 编辑单元格不会导致电子表格的onEdit 触发器运行。

    https://developers.google.com/apps-script/guides/triggers

    是的,据我了解,你不能那样做。

    【讨论】:

    • 谢谢。我第一次错过了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多