3

私はまだ Javascript/GAS に慣れていないので、GAS の問題について SO に戻ります。関数呼び出しを効率的に処理する方法に基づいて、スクリプトの実行速度が遅いことに少し問題があります。

私はいくつかの場所で(ああ、それはここにありました)、取得解析設定値(少なくともスプレッドシートでは)に対して「すべて読み取り」を実行してから「すべて書き込み」を実行する方が「取得- one, write-one」方式(明らかな理由から、これは理にかなっています)。

Range 内のすべての値を取得する方法は知っていますが、(多次元) 配列を調べてデータを処理し、それに応じて新しい Range を設定する方法がよくわかりません。

問題: 関数の起動に約 2 秒かかり、50 行の実行に約 5 秒かかります。問題は、このスプレッドシートに何千行もある可能性が高いことです。この関数を実行しデータが正しく後処理され、Boomerang Calendar が時刻データを正しく取得できるようにすることは、私の意見では少しばかげています。スクリプトは、処理に必要なデータの列ごとに 2 倍の時間がかかります。これは恐ろしいことです。次の学期中に、「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);
  }
}

これは、イベントをスケジュールするための Boomerang カレンダーの機能を壊していた時間形式のアポストロフィの問題を修正するという以前の質問に大きく関連しています。

解決策: 関数を使用して、Range から 2D 配列に値を取得しRange.getValues()ます。2D 配列の各値を処理し (行単位がおそらく最も論理的な方法です)、編集した値のインデックスを新しい値で更新します (コード内の Srik-answer コメントを参照してください)。その後、 を使用して、2D 配列の要素を元の Range に戻しRange.setValues(2Darray)ます。あなたがそれに遭遇した場合、これがあなたの助けになることを願っています!これは、元のコードに見られるように、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
}
4

1 に答える 1

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);
}

ヒント: 各呼び出しにかかった時間は、実行トランスクリプトで確認できます。

于 2013-05-22T17:47:01.673 に答える