如何避免在使用getValue/activate时重新计算rand()函数



我有一个谷歌电子表格,随机选择的一行总是显示在第3行:

A3:

=round(rand() * 808 + 1)

B3:

=VLOOKUP(A3;A8:B815;2)

当我点击一个按钮时,我想重新加载公式并跳到那一行,所以我做了一个宏:

function Refresh() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').setValue("");
SpreadsheetApp.flush();
spreadsheet.getRange("A7").offset(spreadsheet.getRange('A3').getValue(),0).activate()
};

我没有将随机计算放入宏中的原因是,我还希望在禁用宏的电子表格中使用这一随机行(移动+不知道的用户(。

当我运行宏时,A3中会计算出一个新值(从flush开始(,然后激活相应的行。问题是,对于宏的最后一行,A3的值会被重新计算,因为有些东西发生了变化,然后数字与激活的行不再匹配。

有没有办法阻止计算?或者滚动到行而不激活重新计算?

Tl;Dr:无法避免RAND()或任何其他Google Sheets易失性函数(NOW()TODAY()RANDBETWEEN()(的重新计算。

RAND()是一个易失性函数,每次打开电子表格、进行编辑以及在电子表格设置中设置的特定时间,都会重新计算这种函数。此外,当在谷歌应用程序脚本中获取/打开电子表格时,它会在谷歌服务器上重新计算。

您可以尝试使用编辑时触发器而不是"编辑时"触发器;宏";。简单的编辑触发器不需要授权即可运行,可安装触发器需要安装触发器的用户的授权,因此它们将由任何用户进行的任何编辑触发,但在执行宏或脚本时不会触发。

下面是一个简单的编辑触发器示例。它设置Sheet1的值!A1转换为一个随机数。

function onEdit(e){ 
const value = Math.random();
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.getRange('Sheet1!A1').setValue(value);
}

相关

  • Google Sheets是否有"挥发性";像Excel这样的函数

除了鲁本的答案,我还想添加

  1. 像onEdit这样的一些宏可以在移动应用程序上运行
  2. 尽管如此,activate()在移动应用程序上不起作用
  3. 在测试过程中,我还可以看到,对于相同公式的同一单元格,手机应用程序中显示的随机数与桌面上显示的完全不同。这个数字也与登录应用程序的脚本完全不同。这表明它们没有正确同步

最新更新