我试图让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代码完成后发生的,但我不确定。
答案 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)
。这样,可以在更新值之前检索值。另一方面,我认为可以更新电子表格。
为避免此问题,请进行以下修改。我认为您的情况有两种模式。请选择其中之一。并且请将此答案视为几个答案之一。
在这种模式下,只修改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){
在这种模式下,对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()
检索更新的值。如果我误解了您的问题,而这不是您想要的结果,我深表歉意。