getDataRange()。getValues()无法识别setValue更改的单元格值

时间:2019-05-16 19:36:39

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

我试图让apps脚本在表中设置一个值,然后成功转到BOMONSuccess函数,它将在该函数中重新加载已修改表的值。我遇到的问题是,似乎在实际设置值之前代码仍在继续,因此要检索的表不是最新的,并且html页面中显示的内容不正确。当我“刷新” HTML页面时,它又是正确的。我需要在提示中输入新值时进行设置,以设置单元格值并将新值反映在列表框中。

我在.gs(Utilities.sleep)和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代码完成后发生的,但我不确定。

1 个答案:

答案 0 :(得分:2)

问题原因:

我认为您出问题的原因是shell=True中的refreshBOM(prod)

使用google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material)时,首先运行google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material),然后运行refreshBOM(prod)。这样,可以在更新值之前检索值。另一方面,我认为可以更新电子表格。

解决方案:

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

模式1:

在这种模式下,只修改Javascript。

从:
updateMaterialQuantity(qty,prod,material)
至:
google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material);

从:
google.script.run.withSuccessHandler(refreshBOM).withUserObject(prod).updateMaterialQuantity(qty,prod,material);
至:
function refreshBOM(prodOption){

模式2:

在这种模式下,对Javascript和Google Apps脚本进行了修改。

JavaScript端

从:
function refreshBOM(temp, prodOption){
至:
google.script.run.withSuccessHandler(refreshBOM(prod)).updateMaterialQuantity(qty,prod,material);

Google Apps脚本方面

从:
google.script.run.withSuccessHandler(refreshBOM).updateMaterialQuantity(qty,prod,material);
至:
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()检索更新的值。

参考:

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