检测用户在Google电子表格中插入行或列并在脚本中作出反应

Vic*_*yew 9 google-sheets google-apps-script google-apps-script-addon

在Google Apps脚本中,其中一个基本工具是电子表格中的onEdit触发器,它使我们能够检测用户何时编辑单元格并对其作出反应.

用户何时插入行或列怎么样?有没有办法检测到它?

这会触发onEdit吗?如果是这样,我想在ScriptDb中维护行数或列数,然后检查每次都会这样做,但是时间成本很高,因为getMaxRows()已经很慢了,并且接触到ScriptDb就像好.

你怎么看 ?

Chr*_*unt 22

Google添加了一个"On Change"事件,可以检测行/列的插入/删除以及其他类型的更改,您可以在此处看到的类型允许的值changeType.以下是此处的说明,详细说明如何向项目添加触发器,以便在"On Change"事件发生时调用您的函数.

要通过脚本编辑器中的对话框手动创建可安装触发器,请按照下列步骤操作:

  1. 从脚本编辑器中,选择" 编辑">"当前项目的触发器".
  2. 单击以下链接:未设置触发器.点击此处立即添加一个.
  3. "运行"下,选择要触发的功能名称.
  4. 在" 事件"下,选择" 时间驱动"或脚本绑定的Google App (例如," 从电子表格").
  5. 选择和配置您要创建(例如,触发类型小时定时运行每隔一小时在开放的触发).
  6. (可选)单击" 通知"以配置触发功能失败时通过电子邮件联系的方式和时间.
  7. 单击保存.

在步骤4中,您将选择" 从电子表格",在步骤5中,您将选择"更改时".这应该具有您正在寻找的效果.如果您尝试在附加组件中使用此选项以分发给用户,还可以选择以编程方式添加触发器并请求授权.两者都在Installable Triggers文档中有详细说明.


Mog*_*dad 16

有许多编辑操作不会触发onEdit(),这不是一个全面的列表,还有更多报告的排除:

如果您确实想知道电子​​表格中有多少行,则执行大约需要120毫秒:

var numCols = SpreadsheetApp.getActiveSheet().getRange("1:1").getLastColumn();
var numRows = SpreadsheetApp.getActiveSheet().getRange("A:A").getLastRow();
Run Code Online (Sandbox Code Playgroud)

我已经表明,将值写入工作表比使用ScriptDB更快.你可以期待一个微不足道的时间写一个小范围,大约1ms.

因此,如果您可以检测到要添加的行或列,则注册更改将花费您不到十分之二秒.这onEdit()演示了一种测量电子表格范围的技术,并报告了图纸尺寸的变化.(要测试,添加或删除行或列,然后进行触发编辑onEdit().)它还包含计时器 - 随意尝试其他测量和/或存储值的方法,以查看最适合您的方法.

function onEdit() {
  // Use start & stop to time operations
  var start = new Date().getTime();

  // We want the size of the sheet, so will select ranges across and down the
  // whole sheet. Cannot use getDataRange(), as it selects only occupied cells.
  var numCols = SpreadsheetApp.getActiveSheet().getRange("1:1").getLastColumn()
  var numRows = SpreadsheetApp.getActiveSheet().getRange("A:A").getLastRow();

  var stop = new Date().getTime();
  var timeToMeasure = (stop-start);

  // Did things change?
  var oldSize = SpreadsheetApp.getActiveSheet().getRange("A1:B1").getValues();
  if (oldSize[0][0] != numCols || oldSize[0][1] != numRows) {
    // Yes, they did - Let's store the new dimensions
    start = new Date().getTime();

    SpreadsheetApp.getActiveSheet().getRange("A1:B1").setValues([[numCols,numRows]]);

    var stop = new Date().getTime();
    var timeToStore = (stop-start);  

    Browser.msgBox("Sheet is "+numCols+" by "+numRows+"."
                  +" ("+timeToMeasure+"ms to measure, "+timeToStore+"ms to store.)");
  }
}
Run Code Online (Sandbox Code Playgroud)