循环脚本复制和粘贴数据,如何优化

时间:2016-12-30 09:39:38

标签: google-apps-script

我每天都会自动刷新数据表。结构如下:

data1  data2  data3  data4  data5 etc...
a1     a2     a3     a4     a5    etc...
b1     b2     b3     b4     b5    etc...
c1     c2     c3     c4     c5    etc...

我写了一个脚本,每天将这些数据保存在另一张表中。这是我的剧本:

 function savedata() {
    var sheet = SpreadsheetApp.openById('my_id').getSheetByName('Sheet1');
    var numRows = sheet.getLastRow()-1;

 for(var i = 0; i < numRows; i++) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2")
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1")

  var data1 = sheet.getRange('Sheet1!A2:G2').getValues();

  sheet.appendRow(data1[0]);
  ss.deleteRow(2)
  }
}

你可以理解我循环遍历我的所有行,复制它们并逐个删除它们,直到没有任何东西为止。一切都被添加到第二张纸上。

有没有更有效的方法来完成这项工作?

1 个答案:

答案 0 :(得分:2)

确实,我们可以优化此代码。

要记住几点

  • 总是尝试首先使用内置的appscript函数而不是循环,因为循环比服务器端的内置函数消耗更多的时间,并且当数据变得庞大时,最终你的脚本会很慢。

  • 此外,在for循环中,您已编写SpreadsheetApp.getActiveSpreadsheet()。每次循环运行时它都会得到电子表格,你不必这样做,在循环之外声明它们仍然会得到相同的结果。除非您的数据被修改为运行时,否则您不希望这样做。

另外,我不认为您的data1变量正在为for循环的新迭代获取新范围,我认为它会带来相同的行值,您将在目标中的多行中写入相同的数据片材。

现在,你可以编写类似这样的代码来有效地获得类似的结果:

var sheet1 = SpreadsheetApp.openById("ID1").getSheetByName("Sheet1");
var sheet2 = SpreadsheetApp.openById("ID2").getSheetByName("Sheet2");

var content = sheet1.getRange(1, 1, sheet1.getLastRow(), sheet1.getLastColumn()).getValues();  //Get all the values starting from 1st row 1st column and till end of rows and columns

sheet2.getRange(1, 1,sheet1.getLastRow(), sheet1.getLastColumn()).setValues(content);  //Get the same length and width to paste the data

sheet1.clear();  //You can put a condition here to make sure that all the data is copied successfully by checking if no. of rows in sheet1 and sheet2 is same
  • 此外,sheet1.clear()sheet1.deleteRow()之间存在差异。如果使用clear,则只会使电子表格单元格为空白。如果您使用删除,它将完全删除行,如果您只有5行,则删除后会显示警告您无法删除所有单元格。

  • 还有一件事,如果您没有使用这些行,则删除完全空白的行和列,因为电子表格中包含20万个单元格,其中包含所有选项卡中的单元格。

修改

if(sheet2.getRange(1, 1).getValue().trim() == "")
{
  var startIndex = 0;  //I'm assuming your destination sheet is blank in first iteration
}
else 
  var startIndex = sheet2.getLastRow();

sheet2.getRange(startIndex+1, 1,sheet1.getLastRow(), sheet1.getLastColumn()).setValues(content);
  • 还有一件我刚刚添加的重要内容,请参阅我在if语句中使用.trim()。原因是,假设您通过按目标表的A1单元格中的空格键输入了4-5个空格,然后它将被视为写入行,getLastRow()将返回1而不是任何错误。因此,trim()这里将删除A1单元格的所有空格并检查它是否仍为空白。当您检查空白单元格或值时,它非常有用,因此没有一次可以绕过代码。