循环迭代后增量器未更新



我对stackover流和编码是个新手。我编写了一个从数组中提取信息的脚本,该数组从主表中提取信息。脚本从模板中提取要提取的工作表类型,并根据数组数据进行填充。它可以很好地处理第一行数据,但我的变量在执行增量命令后不会更新,所以它会停留在第一个条目上。如果我解释得不好,我道歉。功能:1.根据Arraydata的第4排推出房型2.根据数组数据的第4行重命名3.填充数组数据第4行的数据4.增加行的变量,这样就可以在第5行再次运行脚本,直到没有更多的数组数据为止。

我已经替换了安全的实际工作表ID

function createautomation() {
do{
var roomlist = SpreadsheetApp.getActiveSheet().getRange("Room List!A1:G100").getValues();
var i = 4
var ss = SpreadsheetApp.getActiveSpreadsheet();
var commissioning_template = SpreadsheetApp.openById('ID')
var roomtype = roomlist[i][5]
var copyroom = (`Copy of ${roomtype}`)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var first = ss.getSheetByName(copyroom);
var roomname = roomlist[i][1]
var tab = (`${roomname} - ${roomtype}`)
var second = ss.getSheetByName(tab)
var room1 = (`${tab}!B1`)
var roomnum = (`${tab}!B2`)
var floor = (`${tab}!D2`)
var address = (`${tab}!B3`)
var siteName = (`${tab}!D3`)
var siteCode = (`${tab}!E3`)
var sourcenum = roomlist[i][0]
var sourceflr = roomlist [i][4];
//Copy The spreadsheet
commissioning_template.getSheetByName(roomtype).copyTo(ss);
//Rename Sheet
ss.getSheetByName(copyroom).setName(tab);
//Set Room Name
ss.getRange(room1).setValue(roomname);
//Set Room Number
ss.getRange(roomnum).setValue(sourcenum);
//Set Floor
ss.getRange(floor).setValue(sourceflr);
//Set Address
ss.getRange(address).setValue(roomlist[1][2]);
//Set Site Name
ss.getRange(siteName).setValue(roomlist[0][2]);
//Set Site Code
ss.getRange(siteCode).setValue(roomlist[2][2])
//increment the value of i
i++;
console.log(i)}
while(roomname !="")
}

Marc和Cooper关于您的函数的评论实际上是正确的。鉴于这些评论,我试图改进你的剧本。这将提高性能,但考虑到您正在处理的数据,我不太确定它是否会对性能产生那么大的影响,但这是一个很好的做法,因为这种方法在大型数据集中肯定会更好。

这些都是你可以改进的地方,所以如果你有时间,请检查一下。

function createautomation() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var roomlist = ss.getSheetByName("Room List") // get sheet separately from range
.getRange('A1:G100')         // you can also use A1:G if the column can grow past 100 and not sure until where           
.getValues()
.filter(row => row[1]);      // only include rows that have values on second column
// pull all variables that are static in the loop
var address = roomlist[1][2];
var sitename = roomlist[0][2];
var sitecode = roomlist[2][2];
// separated tab as it varies between rows
// combined the ranges that are in the same column
var room1_roomnum_address = 'B1:B3';
var floor_siteName = 'D2:D3';
var siteCode = 'E3';

var commissioning_template = SpreadsheetApp.openById('ID');
// for all data to start at index 4, remove index 0 to 3 of roomlist
roomlist.splice(0, 4);
// loop all data remaining (this should start at 4th index which is 5th row of sheets data)
roomlist.forEach(row => {
// assign columns A, B, E and F each row to the following variables
// other columns that weren't used are assigned to colC, colD, and colG
var [sourcenum, roomname, colC, colD, sourceflr, roomtype, colG] = row;
var copyroom = `Copy of ${roomtype}`;
var tab = `${roomname} - ${copyroom}`;
var tabSheet = ss.getSheetByName(tab);
commissioning_template.getSheetByName(roomtype).copyTo(ss);
ss.getSheetByName(copyroom).setName(tab);
// set room1, roomnum and address at the same time
tabSheet.getRange(room1_roomnum_address).setValues([[roomname],[sourcenum],[address]]);
// set floor and siteName
tabSheet.getRange(floor_siteName).setValues([[sourceflr],[sitename]]);
// set siteCode
tabSheet.getRange(siteCode).setValue(sitecode);
});
}

注:

  • 个人偏好将选项卡名称与范围分开,但当它们分开时,我更容易阅读代码
  • 由于您正在检查do循环,如果roomname为空并停止,所以我在getValues之后使用filter来删除列B值为空的行。尽管在看到空白行之后,这仍然会得到B列中有值的行。我假设您的数据是连续的,并且中间没有空白行,所以这将起作用。如果没有,请在下面评论,以便我可以修改此内容
  • splice将永久删除所指示的行。因此,考虑到我选择删除前4行,请在拼接命令之前将需要的每个单元格值保存到变量中。或者,您可以修改这种方法,使用slice来代替不删除它,然后使用forEach,但如果我对上面的行没有使用,我更喜欢这种方法
  • 目前,我们正在forEach中循环A5:G100row包含所有值。我更喜欢使用forEach,因为我不需要考虑迭代器,因为它会迭代数组本身而不会出现任何问题
  • 正如库珀所提到的,在每个循环中读写都很慢。所以我尝试将多个setValue组合成setValues。这接受一个2D数组,所以在写入之前请确保正确格式化数据。
    • 如果将数据写入单列,则数组应为以下形式:[[A1], [A2], [A3]]
    • 如果将数据写入单行,则数组应为以下形式:[[A1, B1, C1]]
    • 若写入多行/多列,则数组应为以下形式:[[A1, B1, C1], [A2, B2, C2], [A3, B3, C3]]
  • 在您的情况下,我需要分离setValues,因为您可能在B列和D列之间有数据,它会覆盖这些值。所以我选择按列进行,这仍然是对多个setValue的改进

最新更新