For loop 使用For循环进行库存更新
我正试图制作一个脚本,根据另一张图纸上的零件清单更新我的库存。我希望它检查一张工作表上一列的每一行,检查它是否与另一张工作表上另一列中的任何单元格匹配(就像查找表一样)。如果该语句为真,我希望它从库存中的编号中减去明细表上的编号 现在,我将检查零件列表上的零件是否与库存列表上同一行的零件匹配。这确实有效。不起作用的是,如果没有匹配项,让它检查下一行的零件号 我认为if/else语句应该这样做,但我不知道如何表达它。我使用文件迭代器在文件夹中搜索,这个概念似乎很相似,但我不确定如何使它在行上迭代 可能还有一种更简单/更干净的方法来设置它,但我对谷歌脚本还相当陌生,我是在以前完成的类似任务的基础上设计的For loop 使用For循环进行库存更新,for-loop,if-statement,google-apps-script,google-sheets,For Loop,If Statement,Google Apps Script,Google Sheets,我正试图制作一个脚本,根据另一张图纸上的零件清单更新我的库存。我希望它检查一张工作表上一列的每一行,检查它是否与另一张工作表上另一列中的任何单元格匹配(就像查找表一样)。如果该语句为真,我希望它从库存中的编号中减去明细表上的编号 现在,我将检查零件列表上的零件是否与库存列表上同一行的零件匹配。这确实有效。不起作用的是,如果没有匹配项,让它检查下一行的零件号 我认为if/else语句应该这样做,但我不知道如何表达它。我使用文件迭代器在文件夹中搜索,这个概念似乎很相似,但我不确定如何使它在行上迭代
var ss = SpreadsheetApp.getActive().getId()
var bomtactics = Sheets.Spreadsheets.Values.get(ss, 'BOM!A5:M2004')
var invtactics = Sheets.Spreadsheets.Values.get(ss, 'Inv Temp!A2:Q1658')
var invpartno = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
for(var i = 0; i < bomtactics.values.length; i++){
var BOMquantity = bomtactics.values[i][0];
var BOMpartnum = bomtactics.values[i][1];
var invpartnum = invtactics.values[i][0];
var invquantity = invtactics.values[i][12];
var newqty = invquantity - BOMquantity
Logger.log("New Quantity: ", newqty)
//This works if the Bill of Materials list is an exact match in placement with the inventory list
if(BOMpartnum == invpartnum){
SpreadsheetApp.openById(ss).getRange('Inv Temp!M'+(i+2)).setValue(newqty).setFontColor('Red');
SpreadsheetApp.flush();
}
else
{
// How to get it to check multiple records like a lookup table.
}
var ss=SpreadsheetApp.getActive().getId()
var bomtactics=Sheets.Spreadsheets.Values.get(ss'BOM!A5:M2004')
var invtractics=Sheets.Spreadsheets.Values.get(ss,“Inv Temp!A2:Q1658”)
var invpartno=Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty=Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
对于(var i=0;i
链接到示例电子表格:
我希望它每隔一行检查一次,直到找到匹配项 在这种情况下,我认为嵌套的for循环将比if-else语句工作得更好
var ss = SpreadsheetApp.getActive().getId()
var bomtactics = Sheets.Spreadsheets.Values.get(ss, 'BOM!A5:M2004')
var invtactics = Sheets.Spreadsheets.Values.get(ss, 'Inv Temp!A2:Q1658')
var invpartno = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
for(var i = 0; i < bomtactics.values.length; i++){
var BOMquantity = bomtactics.values[i][0];
var BOMpartnum = bomtactics.values[i][1];
for (var j = 0; j < invtactics.values.length; j++) {
var invpartnum = invtactics.values[j][0];
var invquantity = invtactics.values[j][12];
if(BOMpartnum == invpartnum) {
var newqty = invquantity - BOMquantity
Logger.log("New Quantity: ", newqty)
SpreadsheetApp.openById(ss).getRange('Inv Temp!M'+(j+2)).setValue(newqty).setFontColor('Red');
SpreadsheetApp.flush();
break;
}
}
var ss=SpreadsheetApp.getActive().getId()
var bomtactics=Sheets.Spreadsheets.Values.get(ss'BOM!A5:M2004')
var invtractics=Sheets.Spreadsheets.Values.get(ss,“Inv Temp!A2:Q1658”)
var invpartno=Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty=Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
对于(var i=0;i
注意:当找到匹配项时,嵌套循环将停止,并使用break;
显然,这种方法的缺点是速度较慢且效率较低,尤其是当匹配通常位于同一行时。但是,如果这是一个小数据集,性能可能并不重要。这将更快一些,因为您没有分别为每个零件号写入更新的数量。相反,您需要保存将Ange写入数组,并在脚本末尾一次性写入所有数组
function noName() {
var ss=SpreadsheetApp.getActive();
var bomsh=ss.getSheetByName('BOM');
var bomrg=bomsh.getRange(5,1,bomsh.getLastRow()-4,bomsh.getLastColumn())
var bomvA=bomrg.getValues();
var invsh=ss.getSheetByName('Inv Temp');
var invrg=invsh.getRange(2,1,invsh.getLastRow()-1,invsh.getLastColumn());
var invvA=invrg.getValues();
var invAdj=invsh.getRange(2,13,invsh.getLastRow()-1,1).getValues();
var invAdjfA=invsh.getRange(2,13,invsh.getLastRow()-1,1).getBackgrounds();
invAdjfA.forEach(function(r){r[0]='#ffffff'});//resetting the background to white
for(var i=0;i<bomvA.length;i++) {
for(var j=0;j<invvA.length;j++) {
//compare part numbers
if(bomvA[i][1]==invvA[j][0]) {
//if match is found update quantities
invAdj[j][0]-=bomvA[i][0];
invAdjfA[j][0]="#ff0000";
}
}
}
//Load all quantity adjustments
invsh.getRange(2,13,invsh.getLastRow()-1,1).setValues(invAdj);
invsh.getRange(2,13,invsh.getLastRow()-1,1).setBackgrounds(invAdjfA);
}
如果要从库存表中的所有行进行搜索,则可以在要查找的范围内使用。这将为您提供一个直接的答案,而无需遍历所有行
function test() {
var ss = SpreadsheetApp.getActive().getId()
var bomtactics = Sheets.Spreadsheets.Values.get(ss, 'BOM!A5:M2004')
var invtactics = Sheets.Spreadsheets.Values.get(ss, 'Inv Temp!A2:Q1658')
var invpartno = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
var lookupRange = SpreadsheetApp.openById(ss).getRange('Inv Temp!A2:Q1658');
for(var i = 0; i < bomtactics.values.length; i++){
var BOMquantity = bomtactics.values[i][0];
var BOMpartnum = bomtactics.values[i][1];
var invpartnum = invtactics.values[i][0];
var invquantity = invtactics.values[i][12];
var textFinder = lookupRange.createTextFinder(BOMpartnum);
var foundRange = textFinder.findNext();
var newqty = invquantity - BOMquantity
Logger.log("New Quantity: ", newqty)
//This works if the Bill of Materials list is an exact match in placement with the inventory list
if(foundRange != null){
SpreadsheetApp.openById(ss).getRange('Inv Temp!M'+(foundRange.getRow())).setValue(newqty).setFontColor('Red');
SpreadsheetApp.flush();
}else{
// How to get it to check multiple records like a lookup table.
}
}
}
您可以尝试直接通过应用程序脚本类来实现这一点,更具体地说:
快速澄清问题。当你说“如果没有匹配的零件号,让它检查下一行的零件号不起作用”,如果在同一行中找不到匹配项,是否需要它检查库存列表中的每一行,还是只检查下一行?我希望它检查每一行,直到找到匹配项。查看示例电子表格会很有帮助。它似乎可以很快地处理我的完整库存列表,约1500项。其中一项是他列出了我们有过的更大的零件清单。我确实有一个问题。我在一张有相同零件号的重复实例的样本表上尝试了这个方法。第二个实例没有重复这个过程。我可能会想出一些方法来自动压缩和汇总第一张表,但有没有更简单的方法呢?@StephenSchonewolf-如果您需要在找到1个匹配项后继续检查,只需删除
中断;
行,内部循环将继续,直到它穿过整个库存表。删除中断项并没有做到这一点。我在脚本运行时从Inv Temp选项卡上看到了这一点。它减去了第一个实例,然后又减去了第二个实例第二个实例来自原始值(因此5-2=3,然后5-1=4),而不是(5-2=3,然后3-1=2)。我试图在中断后刷新另一个电子表格,这只会导致脚本在一个永无止境的循环中运行。我明白了。让我问几个后续问题:同一部分在库存表上多次出现是否有原因?同一项目的所有实例的起始数量是否始终相同?您可以更新编码,以便首先在内部for循环外部声明newqty
,然后当循环遇到零件的新实例时,更新内部for循环内部的newqty
。也就是说,这是添加逻辑来调整同一零件的多行数量,而最好只是清理库存
function test() {
var ss = SpreadsheetApp.getActive().getId()
var bomtactics = Sheets.Spreadsheets.Values.get(ss, 'BOM!A5:M2004')
var invtactics = Sheets.Spreadsheets.Values.get(ss, 'Inv Temp!A2:Q1658')
var invpartno = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
var lookupRange = SpreadsheetApp.openById(ss).getRange('Inv Temp!A2:Q1658');
for(var i = 0; i < bomtactics.values.length; i++){
var BOMquantity = bomtactics.values[i][0];
var BOMpartnum = bomtactics.values[i][1];
var invpartnum = invtactics.values[i][0];
var invquantity = invtactics.values[i][12];
var textFinder = lookupRange.createTextFinder(BOMpartnum);
var foundRange = textFinder.findNext();
var newqty = invquantity - BOMquantity
Logger.log("New Quantity: ", newqty)
//This works if the Bill of Materials list is an exact match in placement with the inventory list
if(foundRange != null){
SpreadsheetApp.openById(ss).getRange('Inv Temp!M'+(foundRange.getRow())).setValue(newqty).setFontColor('Red');
SpreadsheetApp.flush();
}else{
// How to get it to check multiple records like a lookup table.
}
}
}
var ss = SpreadsheetApp.getActive().getId()
var bomtactics = Sheets.Spreadsheets.Values.get(ss, 'BOM!A5:M2004')
var invtactics = Sheets.Spreadsheets.Values.get(ss, 'Inv Temp!A2:Q1658')
var invpartno = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!A2:A1658');
var invpartqty = Sheets.Spreadsheets.Values.get(ss,'Inv Temp!M2:M1658');
var lookupRange = SpreadsheetApp.openById(ss).getRange('Inv Temp!A2:Q1658');
var ss = SpreadsheetApp.getActive();
var bomtactics = ss.getRange('BOM!A5:M2004').getValues();
var invtactics = ss.getRange(ss, 'Inv Temp!A2:Q1658').getValues() ;
var invpartno = ss.getRange(ss,'Inv Temp!A2:A1658').getValues();
var invpartqty = ss.getRange(ss,'Inv Temp!M2:M1658').getValues();
var lookupRange = ss.getRange('Inv Temp!A2:Q1658');