Google Apps Scriptでスプレッドシートの内容をオブジェクトの配列として取得する

Apps Scriptでスプレッドシートをテーブル的に使いたい時に、シートの内容をオブジェクトの配列として取得したいケースがよくある。

シート全体のセルの値はgetValues()もしくはgetDisplayValues()メソッドを使って取得することができる。

取得した値のうち、一行目をヘッダー行(keyの配列)として取り出し、残りの行を値として取り出すことで、オブジェクトの配列を作る。

function getRowsAsObjects(sheet) {
  var data = sheet.getDataRange().getDisplayValues();
  
  const header = data.shift();
  
  var rows = data.map(function(row) {
    var dic = {}
    header.forEach((h, idx) => {
      dic[h] = row[idx];
    });
    return dic;
  });

  return rows;
}

すると、このような結果が得られる。

[{name=Apple, date=2024/01/01}, {date=2024-03-13, name=Orange}]

よく書くコードなので、GASのライブラリとしてまとめた。

https://script.google.com/home/projects/1igMdPkdNu4Yg7u_rnBrXYTh7x15KotD0IpikNvrP52fCLV67ClXJ81ut

スクリプトID: 1igMdPkdNu4Yg7u_rnBrXYTh7x15KotD0IpikNvrP52fCLV67ClXJ81ut

使い方

var objects = SheetValues.getRowsAsObjects(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TestSheet"))

Apps Scriptでスプレッドシートのセルの値を画面に表示された文字列そのままの形で取得したい

Apps ScriptでSpreadsheet Serviceを使うと、Spreadsheet内の任意のセルの値を取得できる。

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app

処理の内容によって、画面に表示されている内容を文字列としてそのまま取得したい場合と、日付などその文字列が差している内容を適切な型で取得したい場合があるが、Spreadsheetにはそれぞれの目的に合わせて値を取得する関数が用意されている。

getValues

https://developers.google.com/apps-script/reference/spreadsheet/range#getValues()

上のような値が入った状態で、getValues()を使って値を取得すると、下記のような結果が得られる。

values = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TestSheet").getDataRange().getValues();

>> [[name, date], [Apple, Mon Jan 01 00:00:00 GMT+09:00 2024], [Orange, Wed Mar 13 00:00:00 GMT+09:00 2024]]

date欄に入力した値は 2024-01-01 という文字列だが、この文字列はSpreadsheet内では自動的に日付として認識されており、getValues()で取得した値は文字列ではなくdate型の値になっている。この挙動は時々厄介だ。ユーザが入力した文字列の値を想定していたら違う値が返ってきていることに気づかず、混乱の原因になったりする。

getDisplayValues

https://developers.google.com/apps-script/reference/spreadsheet/range#getdisplayvalues

getValues()の代わりにgetDisplayValues() を使うと、画面に表示されている内容をそのまま文字列として取得できる。

values = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TestSheet").getDataRange().getDisplayValues();

>> [[name, date], [Apple, 2024-01-01], [Orange, 2024-03-13]]

どちらを使うべきか

どちらを使うのが良いかはケースバイケースで判断が難しい。

例えば、date欄で日付を入力してもらうことを想定している場合、上記のようにユーザがもし特定の行の表示フォーマットを変更してしまったとしても、getValues() では表示フォーマットの影響を受けずに日時の値を取得できる。

[[name, date], [Apple, Mon Jan 01 00:00:00 GMT+09:00 2024], [Orange, Wed Mar 13 00:00:00 GMT+09:00 2024]]

一方で、getDisplayValues()では、画面に表示されている内容がそのまま返されるため、これを日時として処理したい場合はどちらのフォーマットで入力されても対応できるように実装する必要が出てくる。

[[name, date], [Apple, 2024/01/01], [Orange, 2024-03-13]]

従って一概にどちらを使うべきとは言えず、ユーザにどのような形式での入力をしてもらうか、運用と合わせて実装方法を考えるしかなさそうだ。

AndroidアプリのCI/CD – Google Play Developer APIs

Apple StoreにXcode Cloudが登場してから、iOS / macOSの世界ではアプリのCI/CDのハードルが一気に下がった。一度その快適さが当たり前になってしまうと、Androidアプリのリリースを手動で行うのが余計にストレスに感じられるようになってしまったので、CI/CD環境を作った。

残念ながらGoogle PlayにはまだXcode CloudにあたるようなマネージドなCI/CD環境はないが、公式APIが用意されているのでGitHub Actionsなどと組み合わせれば自力でCI/CD環境を作ることはできる。ただし、CI/CD環境を構築するにあたって押さえておかなければいけない使い方・仕組みが色々ある。一度に説明しようとすると多少ハードルが高いので、まずはAPIから。

“AndroidアプリのCI/CD – Google Play Developer APIs” の続きを読む

Xcode Cloudでビルドの前後に処理を行う

今更だが、Xcode Cloudが便利だ。Apple純正のCI/CD環境ということもあって、設定で複雑なことをする必要がなく、やれることも限られている分わかりやすい。

大抵のアプリのビルドでは、Xcode Cloudの標準の機能だけで問題なくApp Storeへの申請/TestFlightでの配布ができているのだが、稀にビルドの前後に何らかの処理を行いたいケースがある。

https://developer.apple.com/documentation/xcode/writing-custom-build-scripts

Xcode Cloudには、Custom Build Scriptという仕組みが用意されており、このルールに従ってスクリプトを用意すると、下記のタイミングで任意の処理を実行できる。

  • レポジトリからのCloneが終わった直後(ci_post_clone.sh)
  • xcodebuildが実行される直前(ci_pre_xcodebuild.sh)
  • xcodebuildが終わった直後(ci_post_xcodebuild.sh) ※失敗時も呼ばれる

ビルド番号(CI_BUILD_NUMBER)や何をトリガーにワークフローが開始されたのか(CI_START_CONDITION)などの情報を環境変数として参照できるようになっている。

https://developer.apple.com/documentation/xcode/environment-variable-reference

デバッグ用の情報(COMMIT HASHなど)をアプリ内で参照できるようにする、など色々使える場面があって、覚えておくと何かと便利。