【GAS】スプレッドシートの行を絞り込む方法

GASでスプレッドシートのデータを取得するときに、特定の値を含む行だけを絞り込みたい場面が多々あると思います。

今回は、スプレッドシートの行を絞り込む方法をご紹介します。

スプレッドシートの行を絞り込む方法

このような社員の名前と所属部署のリストがあったとします。

このリストをサンプルデータとして、行の絞り込み処理を見ていきます。

ひとつの条件での絞り込み

まずは所属1が「営業本部」の行で絞り込んでみます。

function main() {
  const spreadsheet = SpreadsheetApp.openById([id])
  const dataSheet = spreadsheet.getSheetByName("データ")

  // データ読み込み
  const dataArray = dataSheet.getRange(2, 1, 10, 5).getValues()
  console.log(dataArray)

  // 「営業本部」で絞り込み
  const salesArray = dataArray.filter(record => record[2] === "営業本部")
  console.log("===========")
  console.log(salesArray)
}

実行結果

[ [ 1, 'テストデータ1', '営業本部', '営業一課', '法人チーム' ],
  [ 2, 'テストデータ2', '営業本部', '営業一課', '法人チーム' ],
  [ 3, 'テストデータ3', '営業本部', '営業二課', '法人チーム' ],
  [ 4, 'テストデータ4', '経営本部', '経営企画', 'データ管理チーム' ],
  [ 5, 'テストデータ5', '経営本部', '経営企画', 'データ管理チーム' ],
  [ 6, 'テストデータ6', '経営本部', '経営企画', '経営企画チーム' ],
  [ 7, 'テストデータ7', '開発本部', '開発部', 'サーバチーム' ],
  [ 8, 'テストデータ8', '開発本部', '開発部', 'サーバチーム' ],
  [ 9, 'テストデータ9', '開発本部', '開発部', 'クライアントチーム' ],
  [ 10, 'テストデータ10', '開発本部', '開発部', 'インフラチーム' ] ]
===========
[ [ 1, 'テストデータ1', '営業本部', '営業一課', '法人チーム' ],
  [ 2, 'テストデータ2', '営業本部', '営業一課', '法人チーム' ],
  [ 3, 'テストデータ3', '営業本部', '営業二課', '法人チーム' ] ]

二つ目のデータのかたまりが、絞り込み後のデータです。

,(カンマ)で区切られた値の3つ目が所属1の値で、営業本部の3行で絞り込まれているのがわかると思います。

サンプルプログラムの解説

絞り込みをしている処理はここの部分です。

const salesArray = dataArray.filter(record => record[2] === "営業本部")

getValuesで取得した配列dataArrayをfilterという関数を呼び出して、その中で”営業本部”という値と同じかどうかを比較しているように見えます。

filter関数は、引数に渡された関数がtrueを返す要素を新しい配列にして返却する関数です。

・・・と急に言われてもピンとこないですよね。

なので、具体的にfilter関数の動作をステップごとに解説していきます。

ステップごとの動作

まずは処理対象の元データをもう一度見てみましょう。

データは全部で10件。

このうち、「営業本部」のデータがある所属1列は左から3番目の列に格納されています。

サンプルプログラムのこの部分のdataArrayにはスプレッドシートのデータ全件が格納されています。

const salesArray = dataArray.filter(record => record[2] === "営業本部")

filter関数では、このデータの1行をループ処理のように各々として受け取ることができます

サンプルプログラムでは行のデータを受け取り、所属1に対応した値を”営業本部”と比較して同じ値(true)かどうかを判定しています。

filter関数内の1行目の処理

イメージしやすいように具体的にデータの1行目を処理しているときのイメージを示します。

filter関数内のrecord変数の部分を実際の1行目のデータで置き換えてみました。

const salesArray = dataArray.filter(
  [ 1, 'テストデータ1', '営業本部', '営業一課', '法人チーム' ] => '営業本部' === "営業本部"
)

record変数には、dataArrayのうち1行ずつが先頭から順番に読み込まれます。

dataArrayの中身

[ [ 1, 'テストデータ1', '営業本部', '営業一課', '法人チーム' ],
  [ 2, 'テストデータ2', '営業本部', '営業一課', '法人チーム' ],
  [ 3, 'テストデータ3', '営業本部', '営業二課', '法人チーム' ],
  [ 4, 'テストデータ4', '経営本部', '経営企画', 'データ管理チーム' ],
  [ 5, 'テストデータ5', '経営本部', '経営企画', 'データ管理チーム' ],
  [ 6, 'テストデータ6', '経営本部', '経営企画', '経営企画チーム' ],
  [ 7, 'テストデータ7', '開発本部', '開発部', 'サーバチーム' ],
  [ 8, 'テストデータ8', '開発本部', '開発部', 'サーバチーム' ],
  [ 9, 'テストデータ9', '開発本部', '開発部', 'クライアントチーム' ],
  [ 10, 'テストデータ10', '開発本部', '開発部', 'インフラチーム' ] ]

1行目一番上のデータがrecord変数に読み込まれます。

その後「=>」の右側のrecord[2]変数には、配列の中の0から数えて3つ目の「営業本部」という値が格納されています。

この時、左辺と右辺は同じ(===)値なので、trueが返ります。

'営業本部' === "営業本部" // -> true

ここで一度、filter関数の動作を思い出してみましょう。

filter関数は、引数に渡された関数がtrueを返す要素を新しい配列にして返却する関数です。

引数に渡された関数、今回でいうところこの部分ですね。

この関数が今解説した通り、左辺と右辺は同じ(===)値なので、trueが返りました。

record => record[2] === "営業本部"

なので、戻り値予定の新しい配列にこの行のデータが追加されます。

2行目、3行目のデータも営業本部の社員で「ture」が返るため同様に戻り値に追加されます。

この関数ってfunctionで定義するものと違うの?

関数と紹介しましたが「先頭にfunctionを付けて定義するのが関数では?」と思う方もいらっしゃると思います。

今回の関数の定義方法はアロー関数式と呼ばれ、簡易的な関数の定義方法です。

詳しくはこちらの記事をご参照ください。

filter関数内の4行目の処理

1~3行目の動作は理解できたと思います。

次に4行目のデータを見てみましょう

[ 4, 'テストデータ4', '経営本部', '経営企画', 'データ管理チーム' ]

filter関数内のrecord変数の部分を4行目のデータで置き換えます。

const salesArray = dataArray.filter(
  [ 4, 'テストデータ4', '経営本部', '経営企画', 'データ管理チーム' ] => '経営本部' === "営業本部"
)

この時、左辺と右辺は異なる値なので、falseが返ります。

'経営本部' === "営業本部" // -> false

この場合は、この行は戻り値の配列には含まれません。

また、4行目以降は営業本部の社員はいないため、同じ動作になります。

複数条件での絞り込み

「営業本部」、「営業二課」の社員を抽出したい場合はどのようにして絞り込めば良いでしょうか?

データを眺めると所属1と所属2をAND条件として絞り込みをすれば良いさそうです。

複数条件で絞り込むサンプルプログラム

function main() {
  const spreadsheet = SpreadsheetApp.openById("1U9idk8SovaiQZWyKtctyaV2PN7AiL7PPvzX8dHua1kA")
  const dataSheet = spreadsheet.getSheetByName("データ")

  // データ読み込み
  const dataArray = dataSheet.getRange(2, 1, 10, 5).getValues()
  console.log(dataArray)

  // 「営業本部」AND「営業二課」で絞り込み
  const salesArray = dataArray.filter(
    record => record[2] === "営業本部" && record[3] === "営業二課"
  )
  console.log("===========")
  console.log(salesArray)
}

実行結果

[ [ 1, 'テストデータ1', '営業本部', '営業一課', '法人チーム' ],
  [ 2, 'テストデータ2', '営業本部', '営業一課', '法人チーム' ],
  [ 3, 'テストデータ3', '営業本部', '営業二課', '法人チーム' ],
  [ 4, 'テストデータ4', '経営本部', '経営企画', 'データ管理チーム' ],
  [ 5, 'テストデータ5', '経営本部', '経営企画', 'データ管理チーム' ],
  [ 6, 'テストデータ6', '経営本部', '経営企画', '経営企画チーム' ],
  [ 7, 'テストデータ7', '開発本部', '開発部', 'サーバチーム' ],
  [ 8, 'テストデータ8', '開発本部', '開発部', 'サーバチーム' ],
  [ 9, 'テストデータ9', '開発本部', '開発部', 'クライアントチーム' ],
  [ 10, 'テストデータ10', '開発本部', '開発部', 'インフラチーム' ] ]
===========
[ [ 3, 'テストデータ3', '営業本部', '営業二課', '法人チーム' ] ]

「営業本部」、「営業二課」の社員が抽出できていることが確認できます。

複数条件での絞り込みをしている処理はここです。

filterのtureを返す関数をAND条件で判断するように変更しています。

record => record[2] === "営業本部" && record[3] === "営業二課"

他にも関数がtureを返せば抽出の対象となるので、様々な条件の組み合わせを試してみてください。

まとめ

今回は、 スプレッドシートの行を絞り込む方法をご紹介しました。

絞り込みはスプレッドシートとGASの組み合わせでは必ずと言っていいほど登場する処理です。

ぜひ、サンプルプログラムを自分で書き換えて、動作を確認し自分で使いこなせるようにしてみてください。

参考

Array.prototype.filter() – JavaScript _ MDN

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

アロー関数式 – JavaScript _ MDN

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions