MENU

【GAS】PropertiesServiceとは?CacheServiceとの違い・3つのスコープの使い分けを解説

GASのPropertiesServiceを解説(CacheServiceとの違い・3つのスコープ)
目次

はじめに

GASでセルベースの進捗表示×時間主導型トリガーの連鎖で6分の壁を回避できるか(以下「トリガー連鎖の記事」)では、トリガーをまたいでもHIT件数や開始時刻が消えないように、PropertiesServiceをサラッと使いました。直前のGASの進捗表示2方式をVBA目線で比較(以下「比較記事」)の次回予告でも触れたとおり、今回はこのPropertiesServiceを深掘りし、よく似たCacheServiceとの違いや、PropertiesServiceが持つ3つのスコープ(Script/User/Document)の使い分けを整理します。

VBAのSaveSetting/GetSettingに近い機能ですが、GASには「全ユーザー共通」「ユーザーごと」「ドキュメント単位」という3つの保存範囲が用意されている点がVBAにはない発想です。この違いを理解しておくと、ダイアログ方式・トリガー連鎖方式のような進捗表示以外の場面(APIキーの保存、最終実行日時の記録など)でもPropertiesServiceを活用しやすくなります。

前回までの記事:

このシリーズでは、以下の順でVBAからGASへの移行を検証してきました。今回の記事では特に3本目・4本目の内容を前提に話を進めます。

PropertiesServiceとは?

PropertiesServiceは、GASのプロジェクトに「キーと値のペア」を永続的に保存できるサービスです。実行が終わってもデータが消えず、次に実行したときも同じ値を読み書きできます。

VBAでいうと、SaveSetting/GetSetting(Windowsレジストリへの読み書き)や、設定用のiniファイルに近い役割です。前述のトリガー連鎖の記事では、トリガーの連鎖をまたいでもHIT件数や処理開始時刻を保持するために利用しました。

CacheServiceとの違い

似たサービスにCacheServiceがあります。ダイアログ方式の記事ではHIT件数の一時保存にCacheServiceを使っていましたが、トリガー連鎖の記事ではPropertiesServiceに切り替えています。両者の違いを整理すると次のとおりです。

項目CacheServicePropertiesService
データの持続期間最大6時間(21,600秒)で自動的に消える(デフォルトは600秒=10分)明示的に削除するまで消えない(永続的)
値1件あたりの最大サイズ100KB9KB
容量・件数の上限1つのキャッシュあたり最大1,000件(超過時は期限が近いものから自動的に破棄される)1つのプロパティストアあたり合計500KB
主な用途一時的なデータの高速キャッシュ設定値・状態の永続保存
VBAに近い概念プロシージャレベルの一時変数(実行中のみ有効)SaveSetting/GetSetting、レジストリ、iniファイル

トリガー連鎖の記事で切り替えた理由: CacheServiceには最長6時間という有効期限があり、トリガーの起動間隔やレグ数が増えた場合に途中で値が消えるリスクがあります。長時間・複数回の実行をまたいで確実に値を保持したかったため、有効期限のないPropertiesServiceを選びました(詳しくは同記事のポイント①を参照)。

VBAとの対比: VBAのプロシージャ内変数は実行終了と同時に消えますが、Static変数やモジュールレベル変数はExcelを閉じるまで(=ブックを開いている間だけ)保持されます。CacheServiceはこの「一定時間だけ保持される」感覚に近く、PropertiesServiceSaveSettingのようにアプリケーションを閉じても(GASの場合はブラウザを閉じても)残り続ける点が対応します。

3つのスコープ:Script/User/Document Properties

PropertiesServiceには、保存範囲が異なる3種類の「プロパティストア」があります。

スコープ取得メソッド共有される範囲利用できるスクリプトVBAに近い概念
ScriptPropertiesgetScriptProperties()同じスクリプトを実行する全ユーザーで共有すべてのスクリプト共通の設定ファイル・Public定数
UserPropertiesgetUserProperties()実行するGoogleアカウントごとに独立すべてのスクリプトユーザーごとのSaveSetting(現在のユーザーのレジストリ)
DocumentPropertiesgetDocumentProperties()そのスプレッドシート(ドキュメント)に紐づき、開く全ユーザーで共有コンテナバインドスクリプトのみ(スタンドアロンスクリプトでは使用不可)ブックのカスタムドキュメントプロパティ

ここまでのGASシリーズで使ってきたスクリプトはすべてスプレッドシートに紐づく「コンテナバインドスクリプト」なので、3つとも利用できます。トリガー連鎖の記事のHIT件数・開始時刻の保存には、スクリプトを実行する人が変わっても同じ値を参照できるようにScriptPropertiesを使いました。

基本的な使い方

3つのスコープはいずれも同じメソッド(setProperty/getProperty/deletePropertyなど)を持っているため、取得するオブジェクトを変えるだけで使い分けられます。

// ScriptProperties:全ユーザー共通の設定値
const scriptProps = PropertiesService.getScriptProperties();
scriptProps.setProperty('API_KEY', 'xxxxxxxx');
const apiKey = scriptProps.getProperty('API_KEY');

// UserProperties:実行ユーザーごとの設定値
const userProps = PropertiesService.getUserProperties();
userProps.setProperty('LAST_RUN_DATE', new Date().toISOString());

// DocumentProperties:このスプレッドシート固有の設定値
const docProps = PropertiesService.getDocumentProperties();
docProps.setProperty('SHEET_VERSION', '1.2');

// 複数のプロパティをまとめて設定・取得
scriptProps.setProperties({ THRESHOLD: '100', MODE: 'auto' });
const all = scriptProps.getProperties(); // { THRESHOLD: '100', MODE: 'auto', ... }

// 削除
scriptProps.deleteProperty('API_KEY');
scriptProps.deleteAllProperties(); // 全件削除

注意:保存できるのは文字列のみ
PropertiesServiceは値を文字列(string)としてしか保存できません。数値や真偽値は自動的に文字列化されますが、オブジェクトや配列をそのまま渡すとエラーになります。保存する前にJSON.stringify()で文字列化し、読み込むときにJSON.parse()で戻す必要があります(この制約はCacheServiceも同様です)。

const settings = { chunkSize: 200, autoMode: true };
scriptProps.setProperty('SETTINGS', JSON.stringify(settings));

const restored = JSON.parse(scriptProps.getProperty('SETTINGS'));

コードを書かずに確認・編集する方法

Apps Scriptエディタには、ScriptPropertiesの値をGUIで確認・編集できる画面があります。

  1. Apps Scriptエディタ左側の「プロジェクトの設定」(歯車アイコン)を開く
  2. 下にスクロールすると「スクリプト プロパティ」という項目がある
  3. 「スクリプト プロパティを追加」から、コードを書かずにキーと値を直接追加・編集・削除できる

デバッグ時に値を直接書き換えたい場合や、コードを実行せずに現在の設定値を確認したい場合に便利です(UserPropertiesDocumentPropertiesはこの画面には表示されず、コード側から確認する必要があります)。

機密情報(APIキーなど)を保存する際の注意点

PropertiesService、特にScriptPropertiesは、APIキーのような機密情報を保存する用途でもよく紹介されています。なぜ向いているのか、そしてどこまで「安全」なのかを整理しておきます。

なぜ.gsファイルへの直書きより安全か

APIキーをコードに直接書いてしまうと(例:const API_KEY = 'xxxxxxxx';)、そのスクリプトを共有・コピーした人全員にキーがそのまま見えてしまいます。ScriptPropertiesに保存しておけば、コード上にはscriptProps.getProperty('API_KEY')という取得処理だけが残り、値そのものはコードから切り離されます。

サンプルスプレッドシートを「コピーして使ってください」という形式で配布する場合は、特にこの違いが重要です。 スプレッドシートを「ファイル→コピーを作成」しても、PropertiesServiceに保存した値(Script/User/Documentのいずれのプロパティも)は新しいコピー先には一切引き継がれません。つまりAPIキーをScriptProperties側に保存しておけば、コピーしても読者にキーが漏れることはなく、読者は自分のキーを別途設定する形になります。逆にコードへ直書きしていた場合は、コピーと同時にキーもそのまま読者に渡ってしまいます。ダイアログ方式の記事・トリガー連鎖の記事・比較記事のようにサンプルスプレッドシートへのコピー用リンクを配布する記事では、覚えておきたいポイントです。

「完全に安全」ではない点に注意

ただしScriptPropertiesは暗号化されているわけではありません。そのスクリプトの編集権限を持つ共同編集者からは、コードを書かなくても「プロジェクトの設定」画面から値がそのまま見えてしまいます。 あくまで「ソースコードに直書きしない」「コピー時に意図せず漏れない」という意味での安全性であり、他人と共同編集する可能性がある場合や、非常に重要な認証情報を扱う場合は、Googleが案内しているSecret Manager(Google Cloud側の、より堅牢なアクセス制御・監査ログ付きの秘密情報管理サービス)の利用が推奨されています。個人利用や小規模な業務マクロであればScriptPropertiesで十分ですが、この使い分けは覚えておくとよいでしょう。

容量制限・クォータに注意

公式ドキュメントによると、PropertiesServiceには次の制限があります。

  • 値1件あたりの最大サイズ:9KB
  • プロパティストア1つあたりの合計サイズ:500KB(Script/User/Documentそれぞれ別枠)

この容量は、ダイアログ方式・トリガー連鎖方式の記事で扱ったような大量データ(1000〜2000件の転記データそのもの)を保存するには全く足りません。PropertiesServiceはあくまで設定値や進捗状態など、小さなデータを保持するための仕組みと割り切って使うのが適切です。トリガー連鎖の記事でHIT件数(数値)や開始時刻(タイムスタンプ文字列)だけを保存したのも、この容量制限を踏まえた設計です。

VBAとの対応関係

VBAの機能GASでの近い機能補足
SaveSetting/GetSetting/DeleteSettingUserPropertiessetProperty/getProperty/deletePropertyどちらも「現在のユーザー」に紐づく点が対応する
(標準機能としては存在しない・共有iniファイル等で代用)ScriptProperties全ユーザー共通の設定を持てるのはGAS側の発想。VBAでは共有ドライブ上のiniファイルや共通DBで代用するのが近い
ThisWorkbook.CustomDocumentPropertiesDocumentPropertiesブック単位で値を持たせる考え方はVBAにもあるが、GASではコンテナバインドスクリプト限定という制約がある

VBAとの対比: VBAのSaveSettingはレジストリのHKEY_CURRENT_USER配下に保存されるため、実質的に「今ログインしているWindowsユーザーごと」の設定です。この感覚はUserPropertiesに近いといえます。一方で「マクロを実行する人が誰であっても同じ設定を参照する」(ScriptProperties)という発想は、VBA標準機能にはあまり出てきません。複数人で同じブックを使う業務マクロで共通設定を持たせたい場合、VBAでは共有フォルダ上の設定ファイルやレジストリのHKEY_LOCAL_MACHINEを使うなど、一手間かける必要がありました。GASではScriptPropertiesを呼ぶだけでこれが実現できる点は、クラウド実行ならではのメリットです。

よくある質問

Q. PropertiesServiceに保存した値は、コード(.gsファイル)を編集しても消える?

→ 消えません。コードとプロパティの値は別々に保存されているため、関数を書き換えたり新しい関数を追加したりしても、既存のプロパティの値はそのまま残ります。トリガー連鎖の記事の実装も、複数回の実行・コード修正をまたいで値が保持されることを前提に設計しています。

Q. スプレッドシートをコピーした場合、DocumentPropertiesの値も一緒にコピーされる?

→ 引き継がれません(リセットされます)。コピーして新しく作成されたファイルは、DocumentPropertiesが空の状態(初期状態)からスタートします。これはGASの仕様として、DocumentPropertiesが「ファイル(コンテナ)のID」に直接紐づいているためです。スプレッドシートをコピーすると新しいファイルIDが発行されるため、プロパティのデータは元のファイルから完全に切り離されます。なおScriptPropertiesUserPropertiesも同様にコピー先には引き継がれません(前述の「機密情報を保存する際の注意点」も参照してください)。

Q. CacheServiceとPropertiesService、同じ用途で両方使うとどうなる?

→ 両立できますが、用途に応じて使い分けるのが基本です。ダイアログ方式の記事ではCacheServiceでHIT件数を一時保存していましたが、有効期限のリセット漏れがバグの原因になったこともありました。トリガー連鎖の記事のように長時間・複数回の実行をまたいで確実に値を残したい場合はPropertiesService、短時間だけ保持できれば十分な一時データにはCacheService、という使い分けが安全です。

Q. UserPropertiesは、同じスプレッドシートを別のGoogleアカウントで開いたらどうなる?

→ アカウントごとに独立した値になります(同じキーで保存しても、他のユーザーからは見えません)。ただし本記事では複数アカウントでの実機検証は行っていないため、公式ドキュメントの仕様に基づく説明である点をご了承ください。

まとめ

  • PropertiesServiceはキーと値を永続的に保存できるサービスで、明示的に削除するまで消えない点がCacheService(最長6時間で自動消去)と異なる
  • ScriptProperties(全ユーザー共通)/UserProperties(ユーザーごと)/DocumentProperties(ドキュメント単位・コンテナバインドのみ)の3スコープがある
  • 値1件9KB・ストア全体500KBという容量制限があるため、大量データではなく設定値や進捗状態など小さなデータの保持に使うのが適切
  • 保存できるのは文字列のみ。オブジェクトや配列はJSON.stringify/JSON.parseで変換する
  • VBAのSaveSetting/GetSettingに近いのはUserProperties。「全ユーザー共通」(ScriptProperties)はVBAにない発想で、GASならではの手軽さといえる
  • ScriptPropertiesはAPIキーなどの機密情報の保存先としてもよく使われる。コードに直書きしない点、スプレッドシートをコピーしても値が引き継がれない点がメリットだが、共同編集者からは普通に見えるため「暗号化された安全な保管庫」ではない点には注意

次回予告

次回はテーマを変え、GASが抱える別の制約——ローカルPCや社内サーバー上にあるファイルを直接開けないという点に取り組む予定です。VBAでは【Excel VBA】ファイルを開いてデータを取得する(その1)(その2)で紹介したGetOpenFilenameFileDialogを使えばローカルファイルを直接指定して開けますが、GASにはこれに相当する手段がありません。

その代替アプローチとして、①HTMLフォームでファイルを選択し、いったんGoogleドライブにアップロードして自動変換・中身をコピーしたあと一時ファイルを削除する方式と、②ブラウザ側でJavaScriptライブラリを使いファイルをその場でパースしてデータだけをGAS側に送る方式の2通りをそれぞれ実装・検証し、その後2方式を比較する記事を予定しています。まずはドライブ経由方式から着手します。

サンプルファイルについて

本記事はPropertiesServiceの基本的な使い方の解説が中心のため、新規のサンプルスプレッドシートは用意していません。上記のコードをコピーしてApps Scriptエディタに貼り付ければそのまま実行できます。実行後は「プロジェクトの設定」の「スクリプト プロパティ」欄から、保存された値をGUIで確認できます。

関連記事

当サイトの記事で使用したVBAなどのサンプルをDLできます

この記事のサンプルはありません!

ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!

よかったらシェアしてね!
  • URLをコピーしました!
目次