【问题标题】:Cell value changed with setValue not being recognized by getDataRange().getValues()单元格值更改为 setValue 未被 getDataRange().getValues() 识别
【发布时间】:2019-10-04 03:24:13
【问题描述】:

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

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

当我“刷新” HTML 页面时,它再次正确。我需要做的是在提示中输入新值后,设置单元格值并将新值反映在列表框中。

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

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

我在setValue 之后也尝试了SpreadsheetApp.flush,但没有任何区别。

.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 代码出于某种原因完成后发生的,但我不确定。

【问题讨论】:

  • @TheMaster 对不起,我忘了提。我添加了 SpreadsheetApp.flush();就在 setValue(qty) 之后,不得不走运。它会去别的地方吗?

标签: google-apps-script google-sheets web-applications


【解决方案1】:

问题原因:

我认为您的问题的原因是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){

模式2:

在此模式中,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;
}
  • 在这种情况下,我认为即使不使用flush(),也可以在getBom() 处检索到更新后的值。

参考:

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

【讨论】:

    猜你喜欢
    • 2016-05-12
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 2021-05-20
    相关资源
    最近更新 更多