getRangeメソッドでセルの範囲を取得する【GAS/JavaScript】

JavaScript

Google Apps Script(GAS)は、Googleが提供しているプログラミング言語です。
自分は主にGoogleスプレッドシートを操作する為に使いますが、GmailやGoogleカレンダー、Googleフォームなど、Googleサービスには大体連携しているっぽいです。

JavaScriptがベースになっている言語なので、敷居が低いのもありがたいです。

今回、セルの値を操作できるgetRangeメソッドについて、特に範囲指定に関してまとめたのでメモ。

操作するスプレットシートを指定する

まず操作するスプレットシートを指定します。
例として、このスプレットシートの見出し行を除いた黄色い部分を全て取得したいと思います。

一番簡単な取得方法は、現在アクティブなシートを指定する方法です。
取得するコードは次の通りになります。

const sheet = SpreadsheetApp.getActiveSheet(); 

変数「sheet」に、現在アクティブなスプレットシートを代入しました。
これ以降、スプレットシートの操作は変数名「sheet」で可能になります。

データが入力されているセルの最終行と最終列を取得する

次に、シートでデータが入力されているセルの最終行を取得します。
こちらはgetLastRowメソッドを使います。

const lastRow = sheet.getLastRow();

同じようにシートの最終列を取得します。

const lastColumn = sheet.getLastColumn();

ログ(+Enter)で値を確認したところ、最終行は11、最終列は7になりました。

getRangeメソッドでセル範囲を取得する

先ほど取得した最終行と最終列の数字を使って、getRangeメソッドでセルの範囲を取得します。書式はこうなります。

Sheetオプジェクト.getRange(開始行番号,開始列番号,取得する行数,取得する列数)

開始行番号と列番号は一番上の見出し行を省くので(2,1)です。
このセルを起点にして、何行、何列分のセルを取得するか指定します。
図にするとこんな感じでしょうか。。


取得する行数の数は、変数「lastRow」で取得した最終行の数から、見出し行1行分をマイナスした値です。
列数の数は変数「lastColumn」の値をそのまま使います。

コードに変数を当てはめると、sheet.getRange(2, 1, lastRow-1,lastColumn)になります。セルの値を取得するには、getValuesメソッドを追加します。
最終的には、itemValues変数に取得したセルの値を代入してこうなりました。

const itemValues = sheet.getRange(2, 1, lastRow-1,lastColumn).getValues();

試しにログを出力して、問題なく値が取得できていることを確認できました!

取得した二次元配列を利用する

取得した値を確認する(二次元配列)

値を取得できましたが、こんなカンジでカッコ[…]が入れ子になっています。

[ [ 1,
    '男',
    Mon Aug 09 1993 00:00:00 GMT+0900 (日本標準時),
    26,
    '岐阜県',
    'B',
    18 ],
  [ 2,
    '女',
    Wed Jan 06 1999 00:00:00 GMT+0900 (日本標準時),
    21,
    '徳島県',
    'O',
    17 ],
  [ 3,
    '女',
    Tue Feb 13 1990 00:00:00 GMT+0900 (日本標準時),
    30,
    '香川県',
    'O',
    15 ],
  [ 4,
    '男',
    Sat Mar 24 1962 00:00:00 GMT+0900 (日本標準時),
    58,
    '山口県',
    'B',
    5 ],
  [ 5,
    '女',
    Mon Feb 24 1975 00:00:00 GMT+0900 (日本標準時),
    45,
    '大分県',
    'O',
    4  ] ]

見やすくする為に、最初の1,2番目のデータを抜き出しました。
元の取得した表と比べると、1列ごとに[ .. ](ここでは緑)で括られ、セルごとにカンマ(,)で区切られているのがわかります。[ .. ]で括られているのは配列で、1つの変数の中に複数の値をカンマで区切って保持できます。

各行が、更に[ .. ](ここでは赤色)で括られていますが、こういった二重に入れ子になった配列のことを二次元配列といいます。

for文を使ってデータを表示させてみる

取得したデータは別のところで使うのがセオリーなので、試しに表示させてみます。
シート1にある元データの値を取得して、シート2に表示させます。

表を別シートにコピーするような感じですね。需要はないでしょうが、これも練習です。。

まず、二次元配列の値は次のように取得します。インデックスは何番めかを表し、通常0から始まります。今回に限っては、次のような意味になります。

配列[行番号][列番号]
※0から開始

今回、変数「itemValues」に二次元配列を入れたので、値はこのように入っています。

itemValues[0][0] → 1;
itemValues[0][1] → '男';
itemValues[0][2] →'1993/08/09';
itemValues[0][3] →'26;

ソースコードを確認(全体)

まず全体のコードを確認します。

function myFunction() {
  const spSheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet1 = spSheet.getSheetByName("シート1");
  const sheet2 = spSheet.getSheetByName("シート2");
  const lastRow = sheet1.getLastRow();
  const lastColumn = sheet1.getLastColumn();
  const itemValues = sheet1.getRange(2, 1, lastRow-1,lastColumn).getValues();
  
  for(let i = 0; i < lastRow-1; i++) {
    for(let j = 0; j < lastColumn;j++) {
      sheet2.getRange(i+1,j+1).setValue(itemValues[i][j]);
    }
  }
  
}

シート1のデータを取得してシート2に表示させるので、先ほど、アクティブシートを操作対象としていたところ、今回は別々のオブジェクトとして変数に格納しています。具体的にはこの部分です。

const spSheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet1 = spSheet.getSheetByName("シート1");
const sheet2 = spSheet.getSheetByName("シート2");

違いはそれくらいで、あとはitemValuesに入っている二次元配列の値をfor文で1つずつ取り出しています。

  for(let i = 0; i < lastRow-1; i++) {
    for(let j = 0; j < lastColumn;j++) {
      sheet2.getRange(i+1,j+1).setValue(itemValues[i][j]);
    }
  }

気をつけるところは、配列の始まりは0なのに対して、getRangeのセル指定の始まりが1であるところです。

この件については、getRange(i+1,j+1)で値をプラス1することで対応します。

まとめ

getRangeメソッドは、セルの範囲だけではなく単一セルの値を取得したり、書き換えたりすることができます。

今回、範囲指定の際の引数がイマイチ分かり辛かったのでまとめました。
よく使うメソッドなのでマスターしたいと思います!