Google Apps脚本电子表格范围处理(Get-Process-Set;设置不起作用)

时间:2013-05-22 15:38:23

标签: google-apps-script range google-sheets

我再次回到SO处理GAS问题,因为我对Javascript / GAS还不太熟悉。基于处理函数调用的方法,我在运行脚本的速度有点麻烦。

我在几个地方读过(啊,它是here),为获取解析设置值做“read-all”然后“write-all” (至少在Spreadsheets中)比“get-one,write-one”方法 更快(出于显而易见的原因,这是有道理的)。

我知道如何获取Range中的所有值,但我不确定如何通过(多维)数组,处理数据,并相应地设置新的Range

问题:启动该功能大约需要2秒钟,大约需要5秒才能运行50行。问题是,我可能在这个电子表格中有数千行,并且让这个功能运行到确保数据被正确地进行后处理,以便Boomerang日历正确地获取时间数据有点在我看来是荒谬的。对于需要处理的每一列数据,脚本需要两倍的时间,这是可怕的。我担心在下一学期学期我经常会超过我的“GAS处理时限”。

以下是起始代码(糟糕,我承认):

function fixApostrophes() {
  // Get the active spreadsheet to run the script on
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // Get the active sheet within the document to run the script on
  var sheet = spreadsheet.getActiveSheet();

  // Get max number of rows needed to process
  var maxRows = sheet.getLastRow();

  // Get the range for the startTime column and endTime column
  var apostropheRange = sheet.getRange(1, 10, maxRows, 2);

  // Get the value in each cell, remove apostrophes from the start,
  // and replace the value in that cell
  for (var i = 1; i < apostropheRange.getNumRows(); ++i) {

    // Get the cells for startTime and endTime to speed things up a bit
    var startCell = apostropheRange.getCell(i, 1);
    var endCell = apostropheRange.getCell(i, 2);

    // Get the values for startTime and endTime
    var startTime = startCell.getValue();
    var endTime = endCell.getValue();

    // Remove apostrophes from start of startTime
    while(startTime.charAt(0) == "'") {
      startTime = startTime.substring(1);
    }

    // Remove apostrophes from start of startTime
    while(endTime.charAt(0) == "'") {
      endTime = endTime.substring(1);
    }

    // Set the values for startTime and endTime
    startCell.setValue(startTime);
    endCell.setValue(endTime);
  }
}

这与我的previous question高度相关,关于修复时间格式撇号问题,该问题打破了Boomerang日历功能以安排事件。

解决方案:使用Range.getValues()函数将Range中的值拉入2D数组。处理2D数组中的每个值(逐行可能是最合理的方法),然后使用新值更新编辑值的索引(请参阅代码中的Srik-answer注释)。之后,使用Range.setValues(2Darray)将2D数组中的元素放回原始Range中。如果遇到它,我希望这可以帮到你!这比我原始代码中多次调用API还要快

function myNewLibraryFunction(startCol, numColumns) {

  // Get the active spreadsheet to run the script on
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // Get the active sheet within the document to run the script on
  var sheet = spreadsheet.getActiveSheet();

  // Get max number of rows needed to process
  var maxRows = sheet.getLastRow();

  // Get the range for the startTime column and endTime column
  var dataRange = sheet.getRange(1, startCol, maxRows, numColumns);
  var values = dataRange.getValues();

  // Get the value in each cell, remove apostrophes from the start,
  // and replace the value in that cell
  for (var i = 1; i < maxRows; ++i) {

// Get the values for startTime and endTime
var startTime = values[i][0];
var endTime = values[i][1];

    // Remove apostrophes from start of startTime
    while(startTime.charAt(0) == "'") {
      startTime = startTime.substring(1);
    }

    // Remove apostrophes from start of startTime
    while(endTime.charAt(0) == "'") {
      endTime = endTime.substring(1);
    }

    values[i][0] = startTime; // New stuff from Srik's answer
    values[i][1] = endTime; // New stuff from Srik's answer
  }
  dataRange.setValues(values);
  SpreadsheetApp.flush(); // New stuff from Srik's answer
}

1 个答案:

答案 0 :(得分:3)

基本上,您对GAS中列出的API所做的大多数函数调用都需要比常规JavaScript更多的时间。在您的情况下,减少对Range和Sheet类的调用次数

function fixApostrophes() {
  // Get the active spreadsheet to run the script on
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // Get the active sheet within the document to run the script on
  var sheet = spreadsheet.getActiveSheet();

  // 1. Replace two calls and many other calls later with one. 
  var dataRange = sheet.getDataRange(); 
  var values = dataRange.getValues();// a 2D array

  // Get the value in each cell, remove apostrophes from the start,
  // and replace the value in that cell
  for (var i = 1; i < values .length ; ++i) {

    // Get the values for startTime and endTime
    var startTime = values [i][0];
    var endTime = values [i][1];

    // Remove apostrophes from start of startTime
    // These are okay. Regular Javascript - not time consuming
    while(startTime.charAt(0) == "'") {
      startTime = startTime.substring(1);
    }

    // Remove apostrophes from start of startTime
    while(endTime.charAt(0) == "'") {
      endTime = endTime.substring(1);
    }

  }

  dataRange.setValues(values);
}

提示:您可以看到每次通话在执行记录中花费了多少时间