Как вызвать функцию Google Script внутри цикла Javascript For - PullRequest
1 голос
/ 11 апреля 2019

У меня есть функция 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();
}

1 Ответ

2 голосов
/ 12 апреля 2019
  • Вы хотите отправить значения на стороне HTML на сторону скрипта Google Apps, используя google.script.run().

Если мое понимание верно, как насчет этой модификации? Пожалуйста, подумайте об этом как об одном из нескольких ответов.

Сначала о вашей следующей проблеме, я думаю, что причина вашей проблемы в том, что google.script.run() работает асинхронной обработкой.

По волшебству, после завершения цикла For функция GS начинает заполнять соответствующие ячейки (каким-то образом она запоминает все динамические значения). Однако не все ожидаемые ячейки заполняются и также не в правильном порядке.

Чтобы избежать этого, я думаю, что для вашей ситуации есть 2 шаблона.

Шаблон 1:

В этом шаблоне после получения всех значений они отправляются в скрипт Служб Google. При тестировании этого шаблона, пожалуйста, измените его следующим образом.

Сценарий Google Apps:

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

HTML и Javascript:

В качестве примера значений я использовал <select>...</select>. В этом примере при открытии 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:

В этом шаблоне значение отправляется каждое значение в Google Apps Script с использованием цикла for. При тестировании этого шаблона, пожалуйста, измените его следующим образом.

Сценарий Google Apps:

В этом шаблоне скрипт Служб Google не изменяется.

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 - это асинхронный клиентский API-интерфейс JavaScript, доступный на страницах службы HTML, который может вызывать функции скрипта Apps на стороне сервера.

Если это не помогло в вашей ситуации, я прошу прощения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...