如何单步执行谷歌脚本

时间:2018-06-09 16:19:39

标签: google-apps-script

我正在尝试编写Google表格脚本宏。如何逐步理解为什么超出时间? 我的问题是循环,当我将迭代max(scenario)设置为46时,代码似乎运行正常,大约需要1-2秒。当max设置为47时,它会在超过最大执行时间(4-5分钟)时死亡。怎么回事?

function testing() {

  var aa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Run 
  Program");

  var scenarios = aa.getRange("H19").getValue();



  for (i = 1; i <= scenarios; i++){

  var ss = 
  SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet6");

  var range = ss.getRange("b6:u6");
  var min = 1  ;
  var max = 20 ; 
  var numbers = []
    for (var i = min; i <= max; i++) {             
      numbers.push(i);
  }  


  shuffleArray(numbers)
  var counter = 0;
  for (var x = 1; x <= range.getWidth(); x++) {
    for (var y = 1; y <= range.getHeight(); y++) {
      range.getCell(y, x).setValue(numbers[counter]);
      counter++;
    }
  }
  var range = ss.getRange("v6:ao6");
  var min = 21  ;
  var max = 40  ;
  var numbers = []
    for (var i = min; i <= max; i++) {
     numbers.push(i);
  }
  shuffleArray(numbers)
  var counter = 0;
  for (var x = 1; x <= range.getWidth(); x++) {
    for (var y = 1; y <= range.getHeight(); y++) {
      range.getCell(y, x).setValue(numbers[counter]);
      counter++;
    }
  }
  var range = ss.getRange("ap6:at6");
  var min = 41  ;
  var max = 45  ;
  var numbers = []
    for (var i = min; i <= max; i++) {
     numbers.push(i);
  }
  shuffleArray(numbers)
  var counter = 0;
  for (var x = 1; x <= range.getWidth(); x++) {
    for (var y = 1; y <= range.getHeight(); y++) {
      range.getCell(y, x).setValue(numbers[counter]);
      counter++;
    }
  }
  }
//  function Chart4() {
  var spreadsheet = SpreadsheetApp.getActive();
      spreadsheet.getRange('A1').activate();
      spreadsheet.getSheetByName('Chart4').showSheet()
     .activate();
      spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Chart4'), 
true);
};

2 个答案:

答案 0 :(得分:1)

您的代码需要很多帮助。这是帮助你入门的一个提示。

正如其他人所提到的那样,你应该在整个范围内调用.getValues(),这会给你一个二维的单元格数组[[A1value,B1value,...],[A2val,B2val ...], ...]。您应首先获取宽度和长度并分配给变量。引用该变量而不是在循环条件中调用API。实际上,由于您提前了解了范围,因此您应该定义主要for循环以外的所有范围以及电子表格(ss):

var aa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Run Program");
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet6");
var range1 = ss.getRange("b6:u6");
var range2 = ss.getRange("v6:ao6");
for (i = 1; i <= scenarios; i++) { ...

如果您重复调用API,脚本会花费很长时间。

不确定您的宏正在尝试做什么,但这里有一个用于运行此类循环的模板以及您应该如何考虑它。

var range = ss.getRange(A1-style-address);
var values = range1.getValues();

var width = range1[0].length;
var height = range1.length;

var new_values = new Array(); 

for (var i = 0; i < height; i++) {
    for (var j = 0; j < width; j++) {

       //do something with values[i][j], like push to new_values

    }
}
//something like:
//var new_range = ss.getRange(different A1-style address) 
//new_range.setValues(new_array)  

您必须确保新数组包含二维数组中的值,该数组的尺寸与您将它们放入的范围相同,否则会引发错误。

我会留给你弄清楚如何修改循环中的new_values数组,以确保它的大小合适。

如果这对您来说是新的link to an overview of arrays,那么这里有array documentation

答案 1 :(得分:-1)

Range.getCell()调用有时会很昂贵,应该避免。使用Range.getValues()并迭代二维数组。此外,不是使用Id的活动电子表格打开电子表格进行单元测试。这样您就可以直接从GAS编辑器调试/运行。 GAS编辑器通常会在代码中捕获此类性能问题,并显示指向代码中行号的警告。