3

我正在尝试让应用程序脚本在表中设置一个值,然后在成功时转到BOMOnSuccess它将重新加载已修改表的值的函数。

我遇到的问题是代码在实际设置值之前似乎继续运行,因此检索到的表不是最新的,并且我的 HTML 页面中显示的内容不准确。

当我“刷新” HTML 页面时,它又是正确的。我需要做的是在提示符中输入新值,以便设置单元格值并且该新值反映在列表框中。

Utilities.sleep我在 .gs ( ) 和 javascript中都尝试过各种不同的暂停。这些似乎都没有什么不同。

有时它实际上会暂停服务器设置值,即使我在设置它的行之后睡眠也是如此。其他时候,如果我让它正确暂停,它仍然有旧数据。

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();
};

js:

//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代码完成后会发生值的实际设置,但我不确定。

4

1 回答 1

2

问题原因:

我认为你的问题的原因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)运行。这样,在更新值之前检索值。另一方面,我认为电子表格可以更新。

解决方案:

为了避免这个问题,请进行如下修改。我认为您的情况有两种模式。请选择其中之一。请将此答案视为几个答案之一。

模式一:

在此模式中,仅修改了 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){

模式二:

在此模式中,Javascript 和 Google Apps 脚本被修改。

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()不使用。

参考:

如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

于 2019-05-17T01:37:42.097 回答