Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
For loop 使用For循环进行库存更新_For Loop_If Statement_Google Apps Script_Google Sheets - Fatal编程技术网

For loop 使用For循环进行库存更新

For loop 使用For循环进行库存更新,for-loop,if-statement,google-apps-script,google-sheets,For Loop,If Statement,Google Apps Script,Google Sheets,我正试图制作一个脚本,根据另一张图纸上的零件清单更新我的库存。我希望它检查一张工作表上一列的每一行,检查它是否与另一张工作表上另一列中的任何单元格匹配(就像查找表一样)。如果该语句为真,我希望它从库存中的编号中减去明细表上的编号 现在,我将检查零件列表上的零件是否与库存列表上同一行的零件匹配。这确实有效。不起作用的是,如果没有匹配项,让它检查下一行的零件号 我认为if/else语句应该这样做,但我不知道如何表达它。我使用文件迭代器在文件夹中搜索,这个概念似乎很相似,但我不确定如何使它在行上迭代

我正试图制作一个脚本,根据另一张图纸上的零件清单更新我的库存。我希望它检查一张工作表上一列的每一行,检查它是否与另一张工作表上另一列中的任何单元格匹配(就像查找表一样)。如果该语句为真,我希望它从库存中的编号中减去明细表上的编号

现在,我将检查零件列表上的零件是否与库存列表上同一行的零件匹配。这确实有效。不起作用的是,如果没有匹配项,让它检查下一行的零件号

我认为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');