简体   繁体   English

Google脚本说-超过最大执行时间

[英]Google script says - Exceeded maximum execution time

I am using the below script to delete duplicate rows from the google spreadsheet. 我正在使用以下脚本从Google电子表格中删除重复的行。 The script was working good but as the data in the spreadsheet is being added daily, now the script is throwing "Exceeded maximum execution time" error. 该脚本运行良好,但是由于每天都在添加电子表格中的数据,因此该脚本抛出“超出最大执行时间”错误。 As I am new to scripting I don't understand what is my problem. 由于我是脚本新手,所以我不明白我的问题是什么。

Could someone help me in solving this problem of mine. 有人可以帮助我解决我的这个问题。

    function Deleteduplicates() {
  var SpreadSheetKey = "My key";
  var sheetD = SpreadsheetApp.openById(SpreadSheetKey).getSheetByName("Daily");
  var sheetW = SpreadsheetApp.openById(SpreadSheetKey).getSheetByName("Weekly");
  var dataD = sheetD.getDataRange().getValues();
  var dataW = sheetW.getDataRange().getValues();
  //Daily
  var newDataD = new Array();
  for(i in dataD){
    var row = dataD[i];
    var duplicate = false;
    for(j in newDataD){
      if(row.join() == newDataD[j].join()){
        duplicate = true;
      }
    }
    if(!duplicate){
      newDataD.push(row);
    }
  }
  //weekly
  var newDataW = new Array();
  for(i in dataW){
    var row = dataW[i];
    var duplicate = false;
    for(j in newDataW){
      if(row.join() == newDataW[j].join()){
        duplicate = true;
      }
    }
    if(!duplicate){
      newDataW.push(row);
    }
  }
  sheetD.clearContents();
  sheetW.clearContents();
  sheetD.getRange(1, 1, newDataD.length, newDataD[0].length).setValues(newDataD);
  sheetW.getRange(1, 1, newDataW.length, newDataW[0].length).setValues(newDataW);
}

Conceptually, this should be quite a bit faster. 从概念上讲,这应该更快一些。 I have not tried it on a large data set. 我没有在大型数据集上尝试过。 The first version will leave the rows sorted as they were originally. 第一个版本将保留行的原始顺序。 The second version will be faster but will leave the rows sorted according to the columns from first to last on first text. 第二个版本将更快,但是将使行根据第一个文本的从头到尾的顺序进行排序。

function Deleteduplicates() {
  var SpreadSheetKey = "My key";
  var ss = SpreadsheetApp.openById(SpreadSheetKey);
  var sheetD = ss.getSheetByName("Daily");
  var sheetW = ss.getSheetByName("Weekly");
  var sheets = [sheetD, sheetW];
  var toSs = {};
  for(s in sheets) {
    var data = sheets[s].getDataRange().getValues();
    for(i in data){
      // EDIT: remove commas from join("") for blank test
      data[i].unshift(data[i].join(""),(1000000 + i).toString());
      }
    data.sort();
    // remove blank rows -- Edit
    var blank = 0;
    while(data[blank][0].trim().length == 0) {blank++};
    if(blank > 0) data.splice(0, blank);
    // end Edit
    var len = data.length - 1;
    for(var x = len; x > 0; x-- ) {
      if(data[x][0] == data[x-1][0]) {
        data.splice(x, 1);
        };
      };
    for(i in data) {
      data[i].splice( 0, 1);
      };
    data.sort();
    for(i in data) {
      data[i].splice(0, 1);
      };
    toSs[sheets[s].getSheetName()] = data;
  };
  for(s in sheets) {
    var data = toSs[sheets[s].getSheetName()];
    sheets[s].clearContents();
    sheets[s].getRange(1, 1, data.length, data[0].length).setValues(data);
  }
}

Faster leaving rows sorted by join() created to test for duplicates 更快创建按join()排序以测试重复项的行

function Deleteduplicates() {
  var SpreadSheetKey = "My key";
  var ss = SpreadsheetApp.openById(SpreadSheetKey);
  var sheetD = ss.getSheetByName("Daily");
  var sheetW = ss.getSheetByName("Weekly");
  var sheets = [sheetD, sheetW];
  var toSs = {};
  for(s in sheets) {
    var data = sheets[s].getDataRange().getValues();
    for(i in data){
      // EDIT: remove commas from join("") for blank test
      data[i].unshift(data[i].join(""));
      }
    data.sort();
    // remove blank rows -- Edit
    var blank = 0;
    while(data[blank][0].trim().length == 0) {blank++};
    if(blank > 0) data.splice(0, blank);
    // end Edit
    var len = data.length - 1;
    for(var x = len; x > 0; x-- ) {
      if(data[x][0] == data[x-1][0]) {
        data.splice(x, 1);
        };
      };
    for(i in data) {
      data[i].splice( 0, 1);
      };
    toSs[sheets[s].getSheetName()] = data;
    };
  for(s in sheets) {
    var data = toSs[sheets[s].getSheetName()];
    sheets[s].clearContents();
    sheets[s].getRange(1, 1, data.length, data[0].length).setValues(data);
  }
}

Edited per Henrique's comment. 根据Henrique的评论进行编辑。

Edited 5/8: Remove blank rows(2 edited areas marked) 编辑的5/8:删除空白行(已标记2个编辑区域)

There is no problem with your script. 您的脚本没有问题。 It is just exceeding the "maximum execution time" allowed for any script (which is currently 6 minutes). 它仅超过任何脚本允许的“最大执行时间”(当前为6分钟)。

To workaround this problem you'll have to split your problem into "less than 6 minutes" parts. 要变通解决此问题,您必须将问题分成“少于6分钟”的部分。

For example, in your code you're clearing duplicates from 2 sheets. 例如,在您的代码中,您要清除2张纸上的重复项。 Trying creating two functions, one for each, and run them separately. 尝试创建两个函数,每个函数一个,然后分别运行。

Also, there could be some performance enhancements that could make the script run under 6 minutes. 另外,可能会有一些性能增强可以使脚本在6分钟内运行。 For example, I'm not sure joining each row is the best way (performance-wise) to do an array comparison. 例如,我不确定加入每一行是进行数组比较的最佳方式(性能方面)。

Creating a new array to re-set the data might not be optimal either, I'd probably go with a map verification, which is constant-time, instead of O(n^2) double array checking you're doing. 创建一个新的数组来重置数据可能也不是最佳选择,我可能会进行固定时间的地图验证,而不是执行O(n ^ 2)双数组检查。

Bottom line, this is a limitation you have to live with in Apps Script. 底线是您必须在Apps脚本中使用的限制。 And any solution anyone proposes is just a workaround, that will also eventually fail if your data gets overly big. 任何人提出的任何解决方案都只是一种解决方法,如果您的数据过大,最终也将失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM