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]]

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