0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GAS】繰り返し処理で スプレッドシート呼び出し回数を節約する2つのメソッド

Last updated at Posted at 2020-09-27

概要

GASを、ちょっとしたお役立ちツールくらいとしてしか使っていないので実感することが少ないけど、スプレッドシートを呼び出す回数が少ないほど処理速度が上がるらしい。

同じ結果になるなら呼び出し回数を節約する書き方をしてみようと言う事で、A列を読み込み、その2倍,3倍を計算し、それぞれB列,C列に書き込むスクリプトを例に、スプレッドシートを呼び出す回数を減らす書き方を考える。
image.png
こんな感じの実行結果になるやつ。

まずは手計算するような順番で書く

取りあえず何のひねりも無しに書いて、スプレッドシートの呼び出し回数(sheetオブジェクトの実行回数)を数えてみる。

function KUMONshiki() { 
   
  var sheet = SpreadsheetApp.getActiveSheet(); 
   
  //最終行をget 
  var lastRow = sheet.getLastRow(); 
   
  var input, double, triple; 
   
  for(i=1; i<=lastRow; i++){ 
     
    //セルを読み込み(for内1回目) 
    input = sheet.getRange(i, 1).getValue(); 
     
    //2倍を書き込み(for内2回目) 
    double = input * 2; 
    sheet.getRange(i, 2).setValue(double); 
     
    //3倍を書き込み(for内3回目) 
    triple = input * 3; 
    sheet.getRange(i, 3).setValue(triple); 
     
  } 

}

個人的にとても安心な見た目(*´・ω・)

スプレッドシートを呼び出した回数は、最終行getで1回、for文の(読み込み1回+書き込み2回)×6回で ⇒ 計19回

節約メソッド①「getValues」

セルを1つずつ読み込むのではなく、範囲で読み込む事で呼び出し回数を節約する。

function getValues() { 
   
  //シートのデータを一気にgetValues 
  var sheet = SpreadsheetApp.getActiveSheet(); 
  var data = sheet.getDataRange().getValues(); 
   
  //最終行をget 
  var lastRow = sheet.getLastRow(); 
   
  var input, double, triple; 
   
  for(i=1; i<=lastRow; i++){ 
     
    //getValuesから必要なデータを呼び出し 
    input = data[i-1][0]; 
     
    //2倍を書き込み(for内1回目) 
    double = input * 2; 
    sheet.getRange(i, 2).setValue(double); 
     
    //3倍を書き込み(for内2回目) 
    triple = input * 3; 
    sheet.getRange(i, 3).setValue(triple); 
     
  } 
   
}

getValues、最終行get、for文の書き込み2回×6回で ⇒ 計13回

範囲で一気に読み込んでいるので、for文の中でA列を扱うのにスプレッドシートを呼び出さなくて良くなった^^)b

(i, 1)[i][1]の示す要素が違う為、i の取扱に注意が必要。この辺が苦手(ToT)

節約メソッド②「push」&「setValues」

表題を裏切り3つ目のメソッドが・・・表題は「方法」的な意味って事で^^;

読み込みをまとめたので、今度は書き込みをまとめようって事。pushメソッドを使い計算結果を1つの配列に格納、setValuesメソッドで一気に書き込む。

function push() {  
   
  //シートのデータを一気にgetValues 
  var sheet = SpreadsheetApp.getActiveSheet(); 
  var data = sheet.getDataRange().getValues(); 
   
  //最終行をget 
  var lastRow = sheet.getLastRow(); 
   
  var input, double, triple; 
  var output = []; 
   
  for(i=0; i<lastRow; i++){ 
     
    //getValuesから必要なデータを呼び出し 
    input = data[i][0]; 
     
    double = input * 2; 
    triple = input * 3; 
     
    //予め作っておいた2次元配列へpush 
    output.push([double, triple]); 
         
  } 
   
  //計算結果を格納した2次元配列を一気にsetValues 
  sheet.getRange(1, 2, 6, 3).setValues(output); 
   
}

getValues、最終行get、 setValuesで ⇒ 計3回

[i][1]的な記述だけになったので、for文の式も修正。

19回が3回まで減らせることを考えると、こういう書き方を癖にするべきなんだろうなと思う。

更に省略

メソッドではなく、工夫でget.lastRowも省略する。

今回の計算は、getValuesした要素全てが対象だから、for_of文で対応可能。もしくは= sheet.getLastRow();= data.length;としても代用可能。

乱暴だけど、for文の条件式の終わりを大きな数字にしておいて、if文を使って「空欄だったらbreak」させることでも省略できる。

最終行の取得を省略することで、最初19回だったスプレッドシートの呼び出し回数が、2回まで省略できた∩(´∀`)∩ワァイ♪

検討

スクリプトの最初と最後にLogger.logを挟んで実行して、開始時間と終了時間を表示させたところ、19回呼び出しのスクリプトは約1.7秒、2回呼び出しのスクリプトは約0.4秒で完了していた。

データ量が増えると、かなりの時間差が発生しそう・・・気を付けます(m。_ _)/ ハンセイ

おしまい

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?