首页 > 解决方案 > 从脚本属性和字符串获取电子表格时的不同行为

问题描述

假设我有一个主电子表格,其中包含一些写入辅助电子表格的代码。要获得气体中的主要和次要电子表格,我们必须使用以下基本代码:

var ss_main = SpreadsheetApp.openById("fake_id_main_8889D4");
var ss_secondary = SpreadsheetApp.openById("fake_id_secondary_1A2Z");

当我想复制整个系统(主 + 代码 + 辅助)时,我必须在任何地方编辑以前的代码,以设置新复制的辅助电子表格的新 ID。为了避免这种情况,我尝试使用脚本属性:在 gas 框架中,在菜单文件 > 脚本属性中,我为所有重复系统设置了两个属性 id_main_spreadsheet 和 id_secondary_spreadsheet 及其 id:

脚本属性

在代码中,而不是上一行,我写了这个来获取电子表格:

var scriptProperties = PropertiesService.getScriptProperties();

var id_ss_main      = scriptProperties.getProperty('id_main_spreadsheet');
var id_ss_secondary = scriptProperties.getProperty('id_secondary_spreadsheet');

var ss_main     = SpreadsheetApp.openById(id_ss_main  );
var ss_secondary= SpreadsheetApp.openById(id_ss_secondary);

通过这个过程,当我想复制系统时,我什至根本不需要编辑代码,我只需要设置脚本属性。但。我的问题是:在我的单一测试代码中的某个时刻,我在主电子表格的一个单元格中写入,下面的单元格通过公式获得一些值,我读取这个新值以测试它是否是预期值。是这样的:

ss_main.getActiveSheet().getRange(1,1).setValue(10);
// lets say the following cell in getRange(2,1) as the formula "=A1*2"
var test_value = ss_main.getActiveSheet().getRange(2,1).getValue();
// then I test if I found what I expected, the 10*2=20, and I write the result
// into the secondary spreadsheet 
var result = (test_value==20) ? "OK" : "ERROR";
ss_secondary.getSheetByName("Result").getRange(1,1).setValue(result);

但是有了这个新代码,当我逐步调试时,当我运行 setValue(10) 时,它在电子表格中生效之前有一些延迟,当我继续编写代码并读取第二个单元格时,新的value 尚未生成(因为第一个单元格尚未编辑延迟),因此测试失败,然后仅几行后(​​随机),setValue() 有效,第二个单元格更改为良好的值20,但是在代码中测试已经来不及了……

当我用经典的 getActive() 代替最后一个代码时,我在逐步调试时仍然有延迟,但即使 setValue() 没有在我的屏幕上进行,也必须在服务器,因为我不再遇到问题,并且测试成功,而且,我完全没有任何问题,辅助电子表格仍然从脚本属性返回!

var ss_main = SpreadsheetApp.getActive();
var scriptProperties = PropertiesService.getScriptProperties();
var id_ss_secondary = scriptProperties.getProperty('id_secondary_spreadsheet');    
var ss_secondary= SpreadsheetApp.openById(id_ss_secondary);

有谁明白为什么 openByID 函数和 getActive() 函数返回给我的电子表格具有不同的行为(两者都有效,但方式不同!!)?

标签: google-apps-script

解决方案


查看 Apps 脚本最佳实践文档。

它会告诉您尽量减少对其他服务的调用,因为调用这些服务(甚至是位于 Google 服务器上的服务 - 这也包括属性服务)会使您的脚本变慢。

如果您觉得必须将 SpreadsheetId 存储在脚本属性中 - 请确保在调用 PropertiesService 的每一行代码之后,您使用flush()方法等待调用完成,然后再执行其余代码跑。


推荐阅读