Javascript 优化代码-getValue()和循环

Javascript 优化代码-getValue()和循环,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我在编码方面有点新手,尤其是Javascript/Google脚本语言。我已经创建了下面的代码,它可以工作了,但是现在我有了一个可以工作的代码,我想看看如何优化它。在我看来,所有的getValue()调用都是对性能的重大打击,而且我从来没有真正擅长于优化循环。有人知道一种更好的方法来完成这段代码吗 它的作用:检查我的一个文件夹中的每个电子表格,看看是否需要运行脚本的其余部分。如果为true,它将打开该工作表并统计包含数据的行数,使用该数据限制它在循环中检查的行数。然后,它会查找标记为push的任

我在编码方面有点新手,尤其是Javascript/Google脚本语言。我已经创建了下面的代码,它可以工作了,但是现在我有了一个可以工作的代码,我想看看如何优化它。在我看来,所有的getValue()调用都是对性能的重大打击,而且我从来没有真正擅长于优化循环。有人知道一种更好的方法来完成这段代码吗

它的作用:检查我的一个文件夹中的每个电子表格,看看是否需要运行脚本的其余部分。如果为true,它将打开该工作表并统计包含数据的行数,使用该数据限制它在循环中检查的行数。然后,它会查找标记为push的任何行,并将该范围复制到驱动器中的另一个电子表格中。然后,它继续到文件夹中的下一个文件,并执行相同的操作

这是我的密码:

function myVupdate() {  
  try {
    var folder = DriveApp.getFolderById("123abc"),
        files = folder.getFiles();
  while (files.hasNext()) {
    var file = files.next(),
        sss = SpreadsheetApp.open(file);
    SpreadsheetApp.setActiveSpreadsheet(sss);

    //Work orders update
    var ss = sss.getSheetByName("Sheet2"),
        refresh = ss.getRange("W3").getValue();
    if (refresh == 0) {continue};
    var avals = ss.getRange("D5:D").getValues(),
        count = avals.filter(String).length,
        rows = count + 5
    var val = ss.getDataRange().getValues();  
  for (var row=5; row < rows; row++) {
    var cell = ss.getDataRange().getCell(row, 23).getValue();
    if (cell == 0) {        
      var cells = [["v" + "WO-" + val[row-1][3] + "_" + val[row-1][2],val[row-1][13],val[row-1][14],val[row-1][15],new Date()]];
      var tss = SpreadsheetApp.openById("target_spreadsheet"),
          ts = tss.getSheetByName("Sheet5");
      ts.insertRowBefore(2);
      var last_hmy = ts.getRange(3,1).getValue();
      ts.getRange(2,1).setValue(last_hmy+1);
      ts.getRange(2,2,cells.length,cells[0].length).setValues(cells);
      ts.getRange(2,7).setValue(sss.getName());
      ss.getRange(row,17).setValue(last_hmy+1);
      ss.getRange(row,18,cells.length,cells[0].length).setValues(cells);

      //Turnover update
    var ss = sss.getSheetByName("Sheet1"),
        avals = ss.getRange("D5:D").getValues(),
        count = avals.filter(String).length,
        rows = count + 5
    var val = ss.getDataRange().getValues();
    }
  }  
  for (var row=5; row < rows; row++) {
    var cell = ss.getDataRange().getCell(row, 24).getValue();
    if (cell == 0) {

      var cells = [["v" + val[row-1][3] + "_" + val[row-1][2],val[row-1][12],val[row-1][15],val[row-1][16],new Date()]];
      var tss = SpreadsheetApp.openById("target_spreadsheet"),
          ts = tss.getSheetByName("Sheet5");
      ts.insertRowBefore(2);
      var last_hmy = ts.getRange(3,1).getValue();
      ts.getRange(2,1).setValue(last_hmy+1);
      ts.getRange(2,2,cells.length,cells[0].length).setValues(cells);
      ts.getRange(2,7).setValue(sss.getName());
      ss.getRange(row,18).setValue(last_hmy+1);
      ss.getRange(row,19,cells.length,cells[0].length).setValues(cells);
    }
  }
  }
 }
  catch(e) {
   // Browser.msgBox("An error occured. A log has been sent for review.");
    var errorSheet = SpreadsheetApp.openById ("target_sheet").getSheetByName("Error Log"),
    source = sss.getName();
    lastRow = errorSheet.getLastRow();
    var cell = errorSheet.getRange('A1');
    cell.offset(lastRow, 0).setValue(e.message);
    cell.offset(lastRow, 1).setValue(e.fileName);
    cell.offset(lastRow, 2).setValue(e.lineNumber);
    cell.offset(lastRow, 3).setValue(source);
    cell.offset(lastRow, 4).setValue(new Date());
    MailApp.sendEmail("my@email.com", "Error report - " + new Date(),
      "\r\nSource: " + source + "\r\n"
      + "\r\nMessage: " + e.message
      + "\r\nFile: " + e.fileName
      + "\r\nLine: " + e.lineNumber
      );
  }
}
函数myVupdate(){
试一试{
var folder=DriveApp.getFolderById(“123abc”),
files=folder.getFiles();
while(files.hasNext()){
var file=files.next(),
sss=SpreadsheetApp.open(文件);
SpreadsheetApp.setActiveSpreadsheet(sss);
//工作指令更新
var ss=sss.getSheetByName(“Sheet2”),
refresh=ss.getRange(“W3”).getValue();
如果(刷新==0){continue};
var avals=ss.getRange(“D5:D”).getValues(),
计数=avals.filter(String).length,
行数=计数+5
var val=ss.getDataRange().getValues();
对于(变量行=5;行<行;行++){
var cell=ss.getDataRange().getCell(第23行).getValue();
如果(单元格==0){
var单元格=[“v”+“WO-”+val[第1行][3]+“"”+val[第1行][2]、val[第1行][13]、val[第1行][14]、val[第1行][15]、新日期();
var tss=电子表格应用程序.openById(“目标电子表格”),
ts=tss.getSheetByName(“Sheet5”);
ts.insertRowBefore(2);
var last_hmy=ts.getRange(3,1).getValue();
ts.getRange(2,1).setValue(最后一次+1);
ts.getRange(2,2,cells.length,cells[0].length).setValues(cells);
ts.getRange(2,7).setValue(sss.getName());
ss.getRange(第17行).setValue(最后一次+1);
ss.getRange(第18行,单元格.length,单元格[0].length).setValues(单元格);
//营业额更新
var ss=sss.getSheetByName(“Sheet1”),
avals=ss.getRange(“D5:D”).getValues(),
计数=avals.filter(String).length,
行数=计数+5
var val=ss.getDataRange().getValues();
}
}  
对于(变量行=5;行<行;行++){
var cell=ss.getDataRange().getCell(第24行).getValue();
如果(单元格==0){
变量单元格=[“v”+val[第1行][3]+“”+val[第1行][2]、val[第1行][12]、val[第1行][15]、val[第1行][16]、新日期();
var tss=电子表格应用程序.openById(“目标电子表格”),
ts=tss.getSheetByName(“Sheet5”);
ts.insertRowBefore(2);
var last_hmy=ts.getRange(3,1).getValue();
ts.getRange(2,1).setValue(最后一次+1);
ts.getRange(2,2,cells.length,cells[0].length).setValues(cells);
ts.getRange(2,7).setValue(sss.getName());
ss.getRange(第18行).setValue(最后一次+1);
ss.getRange(行,19,cells.length,cells[0].length).setValues(cells);
}
}
}
}
捕获(e){
//msgBox(“发生错误。已发送日志以供查看。”);
var errorSheet=SpreadsheetApp.openById(“target_sheet”).getSheetByName(“错误日志”),
source=sss.getName();
lastRow=errorSheet.getLastRow();
var cell=errorSheet.getRange('A1');
cell.offset(lastRow,0).setValue(e.message);
cell.offset(lastRow,1).setValue(e.fileName);
单元偏移量(lastRow,2).setValue(如行号);
单元格.offset(最后一行,3).setValue(源);
cell.offset(lastRow,4).setValue(new Date());
MailApp.sendEmail(“my@email.com“,”错误报告-“+新日期(),
\r\n源:“+source+”\r\n
+“\r\n消息:”+e.message
+“\r\n文件:”+e.fileName
+“\r\n行:”+e.lineNumber
);
}
}

大家好,欢迎来到Stack Overflow

首先,你是对的。调用的
getValue()
setValue()
越多,性能越差,请阅读更多有关最佳实践的信息。谷歌建议你尽可能多地批处理这些内容。一件立即引起注意的事情是:

var val = ss.getDataRange().getValues();
现在,您已经将图纸上的所有值设置为二维数组。这意味着在下面的位中

var ss = sss.getSheetByName("Sheet2"),
        refresh = ss.getRange("W3").getValue();
    if (refresh == 0) {continue};
    var avals = ss.getRange("D5:D").getValues(),
        count = avals.filter(String).length,
        rows = count + 5
    var val = ss.getDataRange().getValues();  
  for (var row=5; row < rows; row++) {
    var cell = ss.getDataRange().getCell(row, 23).getValue();
var ss=sss.getSheetByName(“Sheet2”),
refresh=ss.getRange(“W3”).getValue();
如果(刷新==0){continue};
var avals=ss.getRange(“D5:D”).getValues(),
计数=avals.filter(String).length,
行数=计数+5
var val=ss.getDataRange().getValues();
对于(变量行=5;行<行;行++){
var cell=ss.getDataRange().getCell(第23行).getValue();
不再需要每个
getValue()
getValues()
。相反,您知道
refresh=val[2][22]
,因为您需要第3行和第23列,因为您已经拥有该工作表中数据的整个范围

avals
相同,因为范围
D5:D
中的所有值都在
vals[n][3]
中,其中
n
4
开始请记住,数组索引从0开始(因此第一行和第一列是
vals[0][0]

因此,无论您在哪里尝试使用
ss
电子表格中的
getValues()
,您都已经拥有了该数据。您还可以操作您拥有的数组,因此您总是只更改该数组中的值。使用完该数组后,您将使用
ss.getDataRange().setValues(VAL)
将整个数组推回相同的范围(您只需将范围存储在变量中,如
datRange=ss.getDataRange()
,然后执行
datRange.setValues(VAL)

您只需要为任何其他工作表使用单独的数据数组