我正在创建一个函数,该函数可以从Google表格文档中的众多表格中添加数据。该功能创建具有名称和数据插槽的生产工作表,以及将粘贴到“打印”工作表中的数据的列标题。我遇到的一个问题是,即使据我所知,满足条件的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
.slice(2,3)查找的是“计划数量”列。默认情况下,当我从库存系统将原始数据粘贴到工作表中时,“计划数量”的值将为0。经过文档并计划生产后,这意味着我为“计划数量”分配了一个大于0的值,将运行该功能以将数据粘贴到打印纸上。可能有数百个项目,但我只会计划其中的一部分,因此这很方便。我无法共享正在使用的完整文档,因为其中包含敏感数据。如果您使用一个名为print的工作表创建一个Google工作表,然后将第二个工作表命名为您想要的工作表,则可以将示例数据粘贴到第二个工作表的第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中,并且在运行此函数之前,Print页将完全空白。在TestSheet 1和2的“计划数量”列中输入计划数量后,我将运行该功能。这将导致数据粘贴到打印页面上。我在代码中添加了“ ref”注释,以显示以下解释的每个步骤在何处发生。该功能按以下顺序运行:1)该功能将确定工作表中“计划数量”列“参考1”中的值是否大于零。 2)函数将使它们循环通过工作表并将符合此条件的任何行推送到array2,即“ ref 2”。 3)该函数将根据可能已经在页上第1行,第32行,第64行等等(参考3)的数据来确定将数据粘贴到打印页的位置。 4)该函数将在即将粘贴的数据上方粘贴标题。该标题包括名称,日期和列标题。 5)放置标题后,该函数将遍历array2并将其内容粘贴到“ ref 5”打印页上。 6)该函数将把array2设置为array2 = []
,然后对下一张纸重复该过程,直到所有纸都过去了,并且没有更多数据可粘贴到“参考6”打印中。
答案 0 :(得分:1)
m
循环是不必要的。它遍历当前行(l
s)列。 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++;
// }
}