首页 > 解决方案 > 满足条件后for循环再次运行

问题描述

我正在开发一个函数,该函数在 Google Sheets 文档中添加来自众多工作表的数据。该函数创建具有名称和数据槽以及该函数将粘贴到“打印”表中的数据的列标题的生产表。我遇到了一个问题,即 for 循环似乎运行了额外的时间,即使据我所知满足条件。这是我到目前为止的代码,它很难看,但我只是为自己构建它。

function pasteToPrint(){

  var ui = SpreadsheetApp.getUi()

  var spreadsheet = SpreadsheetApp.getActive();

  var sheetName;

  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();

  var lastCol;

  var lastRow;

  var a;

  var x;

  var y;

  var z;

  var array1 = [];

  var array2 = [];

  function getNextPage(){ // spreads subsequent data set to page break for printing 
    x = spreadsheet.getSheetByName("Print").getLastRow();
    y = x/32;
    y = Math.ceil(y);
    z = 32*y;
    return z;
  }

  for(var i = sheets.length-1; i > 4; i--){ // loops through the appropriate sheets and pushes to array1
    lastCol = spreadsheet.getSheetByName(sheets[i].getName()).getLastColumn()+1;
    lastRow = spreadsheet.getSheetByName(sheets[i].getName()).getLastRow()+1;
    array1.push(spreadsheet.getSheetByName(sheets[i].getName()).getRange(1, 1, lastRow, lastCol).getValues());
  }

  for(var i = 0; i < array1.length; i++){ 
    for(var j = 0; j < array1[i].length; j++){
      // Looking for data that has a value grater than 0 at .slice(2,3)
      if(array1[i][j].slice(2,3) > 0){ // Ref1
        for(var k = 0; k < array1[i].length; k++){ // here I push that data to array2
          if(array1[i][k].slice(2,3) > 0){ // ref 2
            array2.push(array1[i][k]);
          }
        }
        ui.alert(array2+" test 1"); // lets me know the content of array2
        ui.alert(array2.length); // tells me the length just to be sure
        for(var l = 0; l < array2.length; l++){ // decides where to paste the next data set
          if(spreadsheet.getSheetByName("Print").getLastRow()>1){ // ref 3
            a = getNextPage(); // returns the next 32nd line
          }
          else {
            a = 1; // starts at row 1
          } 
          // this next section is column formatting for the beginning of the production sheet
          // ref 4
          spreadsheet.getSheetByName("Print").getRange(a,1).setValue("Name:");    
          spreadsheet.getSheetByName("Print").getRange(a,3).setValue("Date:");
          a++; // moves to the next row
          spreadsheet.getSheetByName("Print").getRange(a,1).setValue("Product");
          spreadsheet.getSheetByName("Print").getRange(a,2).setValue("Work Order");
          spreadsheet.getSheetByName("Print").getRange(a,3).setValue("Planned Production");
          spreadsheet.getSheetByName("Print").getRange(a,4).setValue("Product Produced");
          spreadsheet.getSheetByName("Print").getRange(a,5).setValue("Steel Shortage");
          spreadsheet.getSheetByName("Print").getRange(a,6).setValue("Notes");
          a++ // moves to the next row
          // ref 5
          for(var m = 0; m < array2[l].length-1; m++){ // HERE IS THE PROBLEM LOOP
            ui.alert(array2[m]+" test 2"); // I see this run an additional time after m = length
            spreadsheet.getSheetByName("Print").getRange(a,1).setValue(array2[m][0]);
            spreadsheet.getSheetByName("Print").getRange(a,2).setValue(array2[m][4]);
            spreadsheet.getSheetByName("Print").getRange(a,3).setValue(array2[m][2]);
            a++; 
          }
        }
        array2 = []; // array2 is emptied 
        break; // First if statement checking .slice(2,3) now has the function go to the next sheet
      }
    }
  }

  ui.alert("Function ended"); // just letting me know

};

想象一下这个文档中有很多表,其中的数据如下

Material  Req Planned Quantity MTs Planned Order
AI UPC300 1   1                86  12744851

Plan Quantity 列是 .slice(2,3) 正在寻找的内容。默认情况下,当我将原始数据从库存系统粘贴到工作表时,Planned Quantity 的值将为 0。在我浏览完文档并计划生产后,这意味着我为计划数量分配了一个大于 0 的值,我将运行将数据粘贴到打印表的函数。可能有数百个项目,但我只会计划其中的一部分,这就是为什么这很方便。我无法共享我正在使用的完整文档,因为其中包含敏感数据。如果您创建一个 google 工作表,其中一张名为 print,另一张名为任何您想要的工作表,您可以将示例数据粘贴到第二张工作表的第 1 行和第 2 行,您将看到我得到的错误

TypeError:无法读取未定义的属性“0”(第 138 行,文件“arrayTest”)

您还必须更改for(var i = sheets.length-1; i > 4; i--)for(var i = sheets.length-1; i > 1; i--),将 4 更改为 1。我的文档中有更多代码,但它由与此函数不同的函数组成。

我在下面添加了一张图片,展示了在我使用该功能之前它的外观以及该功能运行后打印表的外观。不幸的是,我不得不截屏,以便压缩数据。想象一下,您看到的每个数据部分(绿色、蓝色和白色)都在各自的工作表上。为清楚起见,绿色数据将包含在 TestSheet1 中,蓝色数据包含在 TestSheet2 中,并且在此函数运行之前打印表将完全空白。在 TestSheet 1 和 2 的计划数量列中输入计划数量后,我将运行该函数。这将导致数据被粘贴到打印页面。我在代码中添加了“ref”注释,以显示以下说明的每个步骤发生的位置。该函数按以下顺序运行:1) 该函数将确定工作表在“计划数量”列“参考 1”中是否有任何大于零的值。2)该函数将循环遍历工作表并将满足此条件的任何行推送到array2,“ref 2”。3) 该函数将根据可能已经粘贴到工作表、第 1 行、第 32 行、第 64 行等“参考 3”的数据来确定将数据粘贴到打印工作表的位置。4) 该函数将在即将粘贴的数据上方粘贴一个标题。此标题包括名称、日期和列标题。5) 放置标题后,该函数将循环遍历 array2 并将内容粘贴到打印表“ref 5”。6) 该函数将设置 array2 以便 2)该函数将循环遍历工作表并将满足此条件的任何行推送到array2,“ref 2”。3) 该函数将根据可能已经粘贴到工作表、第 1 行、第 32 行、第 64 行等“参考 3”的数据来确定将数据粘贴到打印工作表的位置。4) 该函数将在即将粘贴的数据上方粘贴一个标题。此标题包括名称、日期和列标题。5) 放置标题后,该函数将循环遍历 array2 并将内容粘贴到打印表“ref 5”。6) 该函数将设置 array2 以便 2)该函数将循环遍历工作表并将满足此条件的任何行推送到array2,“ref 2”。3) 该函数将根据可能已经粘贴到工作表、第 1 行、第 32 行、第 64 行等“参考 3”的数据来确定将数据粘贴到打印工作表的位置。4) 该函数将在即将粘贴的数据上方粘贴一个标题。此标题包括名称、日期和列标题。5) 放置标题后,该函数将循环遍历 array2 并将内容粘贴到打印表“ref 5”。6) 该函数将设置 array2 以便 4) 该函数将在即将粘贴的数据上方粘贴一个标题。此标题包括名称、日期和列标题。5) 放置标题后,该函数将循环遍历 array2 并将内容粘贴到打印表“ref 5”。6) 该函数将设置 array2 以便 4) 该函数将在即将粘贴的数据上方粘贴一个标题。此标题包括名称、日期和列标题。5) 放置标题后,该函数将循环遍历 array2 并将内容粘贴到打印表“ref 5”。6) 该函数将设置 array2 以便array2 = []然后将对下一张纸重复该过程,直到所有纸都已完成并且没有更多数据可以粘贴到打印中,“参考 6”。

电子表格的图像:

标签: for-loopgoogle-apps-scriptgoogle-sheets

解决方案


m循环是不必要的。它正在循环当前行(ls)列。mcve看起来像这样

const array2d = [1, 2, 3].map(num => new Array(6).fill(num));//boilerplate to simulate array2
console.log({array2d});
for (var l = 0; l < array2d.length; l++) {
  for (var m = 0; m < array2d[l].length - 1; m++) {
    // HERE IS THE PROBLEM LOOP
    // alert(array2d[m] + ' test 2'); // I see this run an additional time after m = length
    console.log(array2d[m][0], array2d[m][2], array2d[m][4]);
  }
}

解决方案:

完全移除循环。

a++; // moves to the next row
//          for(var m = 0; m < array2[l].length-1; m++){ // HERE IS THE PROBLEM LOOP
//           ui.alert(array2[m]+" test 2"); // I see this run an additional time after m = length
spreadsheet
  .getSheetByName('Print')
  .getRange(a, 1)
  .setValue(array2[l][0]);
spreadsheet
  .getSheetByName('Print')
  .getRange(a, 2)
  .setValue(array2[l][4]);
spreadsheet
  .getSheetByName('Print')
  .getRange(a, 3)
  .setValue(array2[l][2]);
a++;
//          }

    }

最佳实践:


推荐阅读