【GAS】スプレッドシートをデータベースとして使用しているときの検索 (indexOfの使い方)

2021年1月20日

スプレッドシートのデータを検索する際に、遅いと感じたことはありませんか?

for構文でセルの内容を確認して条件にあるセルを見つける方法は非常に遅いです。

A列のIDを検索してB列やC列にデータを入れたい

for構文を使用した検索

function myFunction() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sample');

  //検索したいID
  const id = [400,450,500,550,300,350,200,250,150,100] ;

  //データの最終行取得
  const lastRow2 = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();

  //現在時間
  let start = new Date();
  let now ;
  
  //for 構文での検索
  for (j = 0 ; j < id.length ; j++){
    for (i = 1 ; i <= lastRow2 ; i++){
      if (sheet.getRange(i,1).getValue()===id[j]){
        now = new Date();
        sheet.getRange(i,2).setValue(now-start);
        break;
      } 
    }
  }
}

for構文で検索するIDを一致する行を検索しデータを入力していく。
データ数600 検索データ数10件で10938ミリ秒かかった。

indexOfを利用した検索

function myFunction2() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sample');

  //検索したいID
  const id = [400,450,500,550,300,350,200,250,150,100] ;

  //データの最終行取得
  const lastRow2 = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  let start = new Date();
  
  //現在時間
  let now ;
  let result;
  
  //二次配列の行数入替関数
  const transpose = a => a[0].map((_, c) => a.map(r => r[c]));

  //ID列を配列に入れる
  let data = sheet.getRange(1,1,lastRow2,1).getValues();

  //配列の行数入替
  data = transpose(data);

  //indexOfを利用した検索
  for (j = 0 ; j < id.length ; j++){
    result = data[0].indexOf(id[j]);
    now = new Date();
    sheet.getRange(result+1,3).setValue(now-start);
  }
}

同条件で171ミリ秒となった。

データが増えれば増えるほど時間がかかり、GASの制限時間が問題となってくるのでこの方法は助かります。



GAS

Posted by Next-k