【问题标题】:How to call Google Script function inside the Javascript For loop如何在 Javascript For 循环中调用 Google Script 函数
【发布时间】:2019-09-02 12:01:24
【问题描述】:

我有一个 Google Script 函数,它根据来自 Javascript 的值填充单元格 GS 函数在 Javascript 'For' 循环中调用。 当我运行代码时,直到 'For' 循环的所有增量都完成运行后,才会填充单元格。

神奇的是,在 For 循环结束后,GS 函数开始填充相关单元格(不知何故它会记住所有动态值)。但是,并非所有预期的单元格都会被填充,而且顺序也不正确。

尝试使用 .flush() - 没有帮助

GS函数:

function rolesInputer(role, i){
    var rolesInputer = role;
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var column = 3+i;
    var cell = sheet.getRange(17,column);
    cell.setValue(role);
}

JS函数:

function saveInput() {
    var i;
    for (i = 1; i <= dataEncoded; i++) {
        sleep(1000);
        var temprole = "role" + (i);
        var roleSelect = document.getElementById(temprole);
        var roleSelected = roleSelect.options[roleSelect.selectedIndex].value;
        google.script.run.withSuccessHandler(roleSelected, i).rolesInputer(roleSelected, i);
        alert("executed");
    }
    google.script.host.close();
}

【问题讨论】:

  • 手动刷新写缓冲区。另外,考虑实现一个批处理方法来一次处理所有输入。
  • 感谢您的回复。我尝试添加 SpreadsheetApp.flush();在我的 GS 函数的底部,但它并没有解决问题。难道我做错了什么?稍后我会研究优化,谢谢您的建议。
  • 我也很好奇你为什么将非函数值传递给withSuccessHandler。考虑查看google.script.run 客户端 API 的文档

标签: javascript google-apps-script


【解决方案1】:
  • 您希望使用 google.script.run() 将 HTML 端的值发送到 Google Apps 脚本端。

如果我的理解是正确的,那么这个修改呢?请认为这只是几个答案之一。

首先,关于您的以下问题,我认为您的问题的原因是google.script.run()通过异步处理工作。

神奇的是,在 For 循环结束后,GS 函数开始填充相关单元格(不知何故,它记住了所有动态值)。但是,并非所有预期的单元格都会被填充,而且顺序也不正确。

为了避免这种情况,我认为您的情况有两种模式。

模式一:

在此模式中,检索完所有值后,会将这些值发送到 Google Apps 脚本。当您测试此模式时,请进行如下修改。

Google Apps 脚本:

function rolesInputer(values){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  sheet.getRange(17, 3, 1, values.length).setValues([values]);
}

HTML 和 Javascript:

我使用&lt;select&gt;...&lt;/select&gt; 作为示例值。在此示例中,当打开 HTML 时,脚本会运行。

<select id="role1"><option value="role1" selected>role1</option></select>
<select id="role2"><option value="role2" selected>role2</option></select>
<select id="role3"><option value="role3" selected>role3</option></select>
<select id="role4"><option value="role4" selected>role4</option></select>
<select id="role5"><option value="role5" selected>role5</option></select>

<script>
  function saveInput() {
    var dataEncoded = 5;
    var values = [];
    for (var i = 1; i <= dataEncoded; i++) {
      var temprole = "role" + (i);
      var roleSelect = document.getElementById(temprole);
      var roleSelected = roleSelect.options[roleSelect.selectedIndex].value;
      values.push(roleSelected);
    }
    google.script.run.withSuccessHandler(() => {google.script.host.close()}).rolesInputer(values);
  }
  saveInput();
</script>

模式 2:

在此模式中,使用 for 循环将每个值发送到 Google Apps 脚本。当您测试此模式时,请进行如下修改。

Google Apps 脚本:

在此模式中,Google Apps 脚本不会被修改。

HTML 和 Javascript:

在此示例中,当打开 HTML 时,脚本会运行。

<select id="role1"><option value="role1" selected>role1</option></select>
<select id="role2"><option value="role2" selected>role2</option></select>
<select id="role3"><option value="role3" selected>role3</option></select>
<select id="role4"><option value="role4" selected>role4</option></select>
<select id="role5"><option value="role5" selected>role5</option></select>

<script>
  function work(roleSelected, i) {
    return new Promise((resolve, reject) => {
      google.script.run.withSuccessHandler(() => resolve()).rolesInputer(roleSelected, i);
    });
  }

  async function saveInput() {
    var dataEncoded = 5;
    for (var i = 1; i <= dataEncoded; i++) {
      var temprole = "role" + (i);
      var roleSelect = document.getElementById(temprole);
      var roleSelected = roleSelect.options[roleSelect.selectedIndex].value;
      await work(roleSelected, i);
    }
  }

  saveInput().then(() => google.script.host.close());
</script>

注意:

  • 考虑流程成本时,我认为模式1更好。

参考资料:

  • google.script.run

    google.script.run 是一种异步客户端 JavaScript API,可用于 HTML 服务页面,可以调用服务器端 Apps 脚本函数。

如果这对您的情况没有帮助,我深表歉意。

【讨论】:

  • @Ilya Perelman 感谢您的回复。很高兴您的问题得到解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 2021-11-20
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多