Значение ячейки изменилось, так как setValue не распознается getDataRange (). GetValues ​​() - PullRequest
3 голосов
/ 16 мая 2019

Я пытаюсь, чтобы скрипт приложения установил значение в таблице, а затем в случае успеха перешел к функции BOMOnSuccess, где он перезагрузит значения измененной таблицы. Проблема, с которой я сталкиваюсь, заключается в том, что кажется, что код продолжается до фактического задания значения, поэтому извлекаемая таблица не обновлена, и то, что отображается на моей html-странице, не является точным. Когда я «обновляю» html-страницу, она снова верна. Что мне нужно сделать, так это ввести новое значение в приглашение, чтобы значение ячейки было установлено и это новое значение было отражено в списке.

Я пробовал всевозможные паузы как в .gs (Utilities.sleep), так и в javascript. Ни один из которых, кажется, не имеет значения. Иногда он фактически приостанавливает установку сервером значения, даже если у меня есть sleep после строки, которая его устанавливает. В других случаях, если мне удастся сделать паузу правильно, в ней останутся старые данные. Я также попробовал SpreadsheetApp.flush (); однако после setValue это не имело значения.

.gs:

var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();

function showForm() {
  var html = HtmlService.createTemplateFromFile('Form')
      .evaluate();
  html
      .setTitle('AP Pricing Form')
      .setWidth(600)
      .setHeight(500);
  var dialog = ui.showModalDialog(html, "AP Pricing App")
}

function getBom(){
  var sheet = ss.getSheets()[4]
  var vals = sheet.getDataRange().getValues();
  return vals
}

function updateMaterialQuantity(qty,prod,mat){
  var sheet = ss.getSheets()[4]
  var values = sheet.getDataRange().getValues();

  for(var i = 1; i<values.length; i++){
    if(values[i][0] == prod){
      if(values[i][1] == mat){
        sheet.getRange(i+1,3).setValue(qty);
        SpreadsheetApp.flush();
        return;
      }
    }
  }
}

 function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename)
    .getContent();
};

ЯШ:

//get BOM from BOM table
function refreshBOM(prodOption){
  for (a in document.getElementById("productMaterials").options) { document.getElementById("productMaterials").options.remove(a); }
  prod = prodOption
  function filterBOM(array){
    var newBom = [];
    for(var i = 1; i<array.length; i++){
      if(array[i][0] == prod){
        newBom.push(array[i])
      }
    }
    return newBom;
  }

  function BOMOnSuccess(array){
    bom = array
    bom = filterBOM(bom);
    for(var i = 0; i < bom.length; i ++){
      var opt = document.createElement("option");
      opt.text = bom[i][2] + " - " + String(bom[i][1]);
      opt.text = opt.text.toUpperCase();
      opt.value = bom[i][1];
      document.getElementById("productMaterials").options.add(opt);
    }
  }
  google.script.run.withSuccessHandler(BOMOnSuccess).getBom();
}


//edit materials 
function editProductQty(material){
if(material != ""){
  var qty = prompt("Enter new quantity");
  var prod = document.getElementById("productsSelect").value
  google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material);
}
else{
  alert("Please choose a product and material");
}

}

Ожидается, что для editProductQty будет работать при нажатии кнопки. Это заставит пользователя ввести новое значение. Затем запустится updateMaterialQuantity. Это перейдет к .gs и диапазон будет найден и новое значение установлено. Затем запускается refreshBOM, где он получает обновленный диапазон, и новое значение будет отображаться на странице html.

В действительности, когда вызывается getBOM, он каким-то образом получает старую не обновленную версию таблицы. Я считаю, что проблема заключается в том, что фактическая установка значения происходит после того, как код js по какой-то причине завершается, но я не уверен.

1 Ответ

2 голосов
/ 17 мая 2019

Причина проблемы:

Я думаю, что причина вашей проблемы refreshBOM(prod) из google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material).

Когда используется google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material), сначала refreshBOM(prod)запустить, тогда updateMaterialQuantity(qty,prod,material) выполняется.Таким образом, значения извлекаются до их обновления.С другой стороны, я думаю, что электронную таблицу можно обновить.

Решение:

Чтобы избежать этой проблемы, измените ее следующим образом.Я думаю, что есть две модели для вашей ситуации.Пожалуйста, выберите один из них.И, пожалуйста, воспринимайте этот ответ как один из нескольких ответов.

Шаблон 1:

В этом шаблоне изменен только Javascript.

От:
google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material);
До:
google.script.run.withSuccessHandler(refreshBOM).withUserObject(prod).updateMaterialQuantity(qty,prod,material);

и

С:
function refreshBOM(prodOption){
Кому:
function refreshBOM(temp, prodOption){

Шаблон 2:

В этом шаблоне Javascript и Google Apps Script изменены.

Сторона Javascript

От:
google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material);
До:
google.script.run.withSuccessHandler(refreshBOM).updateMaterialQuantity(qty,prod,material);

и

Сторона скрипта Google Apps

От:
if(values[i][1] == mat){
  sheet.getRange(i+1,3).setValue(qty);
  SpreadsheetApp.flush();
  return;
}
До:
if(values[i][1] == mat){
  sheet.getRange(i+1,3).setValue(qty);
  return prod;
}
  • В этом случае, я думаю, что обновленные значения можно будет получить в getBom(), даже если flush() не используется.

Ссылка:

Если я неправильно понял ваш вопрос и это не тот результат, который вам нужен, я приношу свои извинения.

...