生成AIの活用ノウハウや、 注目の技術に関する記事を掲載
公開

Google Sheets canvasはどこまで業務アプリになれるか|GAS・onEdit・外部API・Sheets APIとの連携を検証

はじめに

Google Sheetsの「Sheets canvas」(以下、Canvas)は、Geminiへの指示だけで、シートのデータからカンバンボードやダッシュボードのような画面を作れる機能です。
Google Workspaceでは2026年8月から順次使えるようになりました。
Canvasで編集した値は、元のシートに書き戻されます。

Sheets canvasとシート・Apps Script・外部APIの関係を示す概念図

CanvasからApps Scriptや外部APIに直接つながるか、元になるシートを介してつながるかを検証する

業務の画面として使うなら、既存の仕組みとどうつながるかが問題になります。
ところが、CanvasとApps Script(以下、GAS)やSheets APIとの関係は、2026年9月27日時点の公式ドキュメントに説明がありません。
そこで、LLMのAPI費用を試算するスプレッドシートを題材に、Canvasと数式・GAS・外部API・Sheets APIのつながりを11の経路に分けて試しました。
結果の要点は次のとおりです。

  • Canvasで入力するとシートの数式が再計算され、GASやSheets APIによる更新も開いたままのCanvasに届いた
  • Canvasの編集でもGASのonEditトリガーは動いた。ただし編集前後の値(e.value・e.oldValue)は空で、1回はトリガー自体が動かなかった
  • 今回生成したCanvasから行を追加すると、計算列に固定値が入り、既存の配列数式が #REF! になった。Canvasではそのエラーが0円と表示された
  • 外部APIへの直接の通信は、今回の環境ではCanvasの画面に設定されたセキュリティポリシー(CSP)で止められた
  • GASの関数の呼び出しと別タブの参照は、Geminiが未対応と回答した

直接つながらなかった経路も、セルの変更をGASで拾う形や、シートの数式を挟む形なら実現できました。
GASを使ったスプレッドシート連携は、ChatGPTのGPTs Actionsと組み合わせた例を以前の記事で紹介しています。

生成AI関連
ChatGPT GPTs × GAS で業務を自動化する ── Actions と MCP の使い分…

Sheets canvasについて公式に書かれていること

Googleの発表では、Canvasとシートの変更は互いにすぐ反映されるとしています。

Changes made in the canvas, such as dragging task cards or adding new entries, instantly update your source sheet. Likewise, any updates to the source sheet reflect in your canvas in real time.

Google Workspaceのブログ(2026年9月11日)も、財務予測の例で、基になる数式を壊さずにシナリオを試せると紹介しています。

Share the dynamic canvas with your team to test alternative scenarios together without altering or breaking underlying formulas.

利用条件は次のとおりです(確認日:2026年9月27日)。

項目 内容
データソース 1つのシートタブのみ。100万セルを超えるタブは未対応
言語・環境 Googleアカウントの言語設定が英語の場合に、PCのWeb版で使える。モバイルのSheetsアプリでは使えない
ファイル Google Drive上のファイルのみ(他社のストレージ上やオフラインのファイルは不可)。ダウンロード・コピー・印刷が無効になっているファイルでは使えないことがある
権限 スプレッドシートの共有設定に従う。閲覧者・コメント可の利用者はCanvasでデータを変更できない
提供対象 Workspace の Business Standard / Plus、Enterprise Standard / Plus のほか、Google AI Pro / Ultra など。Gemini in Sheets が有効な利用者に既定で提供される
利用上限 Canvasの作成・編集には、ユーザーごとの利用上限がある

出典:Create a Sheets canvas(Google ドキュメント エディタ ヘルプ)、Google Workspace Updates
一方、GASのトリガーやSheets APIとCanvasとの関係、Canvasを操作する開発者向けのAPIについては、どのページにも記載がありません。

検証の方法

題材は、LLMのAPI費用を試算するシミュレーターです。
利用者数、1人1日のリクエスト数、1回あたりの入力・出力トークン数(LLMが処理する文章の単位)を変えると、30日分の月額がシートの数式で計算されます。
架空の Model A と Model B の初期値は、どちらも利用者100人、1人1日10回、1回あたり入力2,000・出力500トークンです。
100万トークンあたりの単価は、Model A が入力2USD・出力8USD、Model B が3USD・15USDです。
月額は240USDと405USDで、1ドル150円なら36,000円と60,750円になります。
タブは、データソースにする Sim、単価表の Prices、為替レートを置く Settings、トリガーの記録を残す Log の4つです。
Sim タブには、Canvasが数式の種類で扱いを変えるかを見るため、種類の違う数式を混ぜました。

列 内容
B〜E 入力値(Users、ReqPerUserDay、InTokens、OutTokens)。Canvasから編集する
F・G 入力・出力の単価(InPrice・OutPrice)。Prices タブを XLOOKUP で参照
H 為替レート。Settings タブのセルを名前付き範囲(USDJPY)で参照
I 月額(USD)。行ごとの通常の数式
J 月額(円)。J2 に書いた1つの ARRAYFORMULA で下の行まで計算
K I列と同じ計算をするGASのカスタム関数 AI_COST
L Refresh(チェックボックス)。CanvasからGASを動かす入口

GAS側には、次の3つを用意しました。

  • 発火するたびに Log タブへ1行記録する3種類のトリガー(単純トリガーの onEdit、インストール型の onEdit と onChange)
  • APIキーなしで使える為替API Frankfurter からレートを取得し、取得時刻(UpdatedAt)とともに Settings タブに書き込む fetchRate
  • Sim タブの Model A の利用者数を100増やす bumpUsers

単純トリガーは関数名を onEdit にするだけで動き、インストール型は事前に登録して使います。
onChange は、行の挿入など構造の変更でも動きます。
11の経路と結果は次のとおりです。

検証する11経路を示す構成図

検証する経路の全体像。黄色の破線は、Canvasから直接、またはセルの編集(onEdit)を経由してつながるかを試す経路。青の実線はGASの処理とSheets APIによる書き込みで、シートの変更がCanvasに届くかも確かめた
ID 経路 確かめること 結果
T1 Canvas ⇄ シート 双方向に同期するか 双方向に反映された
T2 Canvasの入力 → 数式 → Canvas 再計算の結果が届き、数式が残るか 再計算された値が表示され、数式も残った
T3 Canvasでの行の追加 新しい行に数式が入るか 計算列に固定値が入り、配列数式が #REF! になった。Canvasではエラーが0と表示された
T4 GAS → Sim タブ → Canvas GASの書き込みが反映されるか 反映された
T5 GAS → 外部API → Settings タブ → 数式 → Canvas データソース以外のタブの変更が届くか 数式を通じて反映された
T6 外部システム → Sheets API → Canvas APIによる書き込みが反映されるか 反映された。onEdit は動かず、onChange は記録された
T7 Canvasの編集 → トリガー Canvasの編集でトリガーが動くか 3種類とも動いた。ただし、編集前後の値は空だった
T8 Canvas → 外部API Canvasから外部APIを直接呼べるか 「Failed to fetch」で失敗した。Canvasの画面のCSPが通信を止めていた
T9 Canvas → GASの関数 CanvasのボタンからGASの関数を実行できるか Geminiが未対応と回答した
T10 Canvas → セル → onEdit → 外部API シートを経由すれば外部と連携できるか e.value ではなくセルの値で判定すると成立した。1回はトリガーが動かなかった
T11 Canvas → 別タブ データソース以外のタブを表示できるか 直接はGeminiが未対応と回答した。Sim タブに数式で引き込んだ値は表示できた

検証は2026年9月26日と27日に、Google Workspace Business Standard のアカウント(言語設定は英語)とPCのChromeで行いました。
T8の原因などの追加確認は、28日に同じアカウントで行っています。
各経路は基本的に1回ずつ(T10だけは条件を変えて4回)操作し、終わるたびに利用者数100・為替150の初期状態に戻しました(T5だけはT4の続きで実行)。
反映までの時間は測っておらず、操作後に画面を見た時点で反映されていたことを確かめています。
複数人での同時編集や大量のデータは試していません。

Canvasと数式の連携(T1〜T3)

Canvasから入力した値はシートに書き戻され、数式で再計算された結果がCanvasに表示されました。
行を追加したときだけは、新しい行に数式が入らず、既存の配列数式まで壊れています。
Canvasは、Sim タブを開いた状態で、次の指示文をGeminiに入力して作りました(Canvasは英語で提供されている機能なので、指示文も英語です)。


Create an interactive AI API cost simulator from the data in this tab.
- Let me select a model (Model A or Model B) from the Model column.
- Show editable inputs for Users, ReqPerUserDay, InTokens and OutTokens of the selected row, and save every change back to the sheet.
- Display InPrice, OutPrice, USDJPY, MonthlyUSD, MonthlyJPY and AI_COST as read-only values taken from the sheet. Do not calculate them in the canvas.
- Show the annual cost in JPY, calculated in the canvas as MonthlyJPY x 12.
- Add a bar chart comparing MonthlyJPY across all models.
- Add a form to add a new model row with Model, Users, ReqPerUserDay, InTokens and OutTokens.

費用はシートの値をそのまま表示させ、年額だけは、Canvasがシートの値をどう扱うかを見るためにCanvas側で計算させています。
生成されたCanvasには、指示していない「Refresh: Off」ボタンも付いていました。

指示文から生成されたAIコストシミュレーターのCanvas

生成されたCanvas。Model A の月額は36,000円、Canvas側で計算した年額は432,000円

通常のシート画面(以下、グリッド)とCanvasは、同じスプレッドシートを2つのブラウザタブで開いて見比べました。

入力値の編集(T1・T2)

Canvasで Model A の利用者数を100から500に変えると、Sim タブの B2 は500になり、月額は1,200USD・180,000円に再計算されました。
Canvasも同じ値を表示し、Canvas側で計算した年額は2,160,000円でした。
グリッドで B2 を100に戻すと、Canvasは再読み込みしなくても元の値に戻りました。
XLOOKUP、名前付き範囲を参照する式、通常の数式、ARRAYFORMULA、カスタム関数は、どれも数式のまま残っています。

Usersを500に変更した後のCanvas

利用者数を500にした後のCanvas。月額はシートの数式で再計算された180,000円

行を追加すると、数式が引き継がれなかった(T3)

Canvasの「Add Model」フォームから、Prices タブにない Model C を追加しました。
Sim タブの4行目に Model C の行が入りましたが、数式はひとつもありませんでした。
フォームには指示していない単価と為替の欄もあり、初期値のまま送信すると、単価・為替・月額・カスタム関数の列すべてに固定値が入りました。
影響は既存の行にも及びました。
J列の ARRAYFORMULA は、J2 の1つの式から下の行へ結果を書き出します。
書き出し先の J4 に固定値が入ったため、J2 は #REF! になり、Model B の J3 も空になりました。
このときCanvasでは、Model A・B の月額(円)と年額が0円と表示され、エラーだとわかる表示はありませんでした。

Model C を追加した後のCanvas

Model C を追加した後のCanvas(Model A を選択中)。シートの J2 が #REF! になり、月額(円)と年額は0円、グラフでも Model A・B は0円と表示された

#N/A でも同じでした。
グリッドで F4 に入力単価を引く XLOOKUP を入れると、Prices タブに Model C がないため F4 は #N/A になります。
Canvasで Model C を選ぶと、入力単価(InPrice)は $0.00 と表示され、エラーの表示はありませんでした。

F4 が #N/A になったときのCanvas

F4 が #N/A になった Model C の表示。入力単価(InPrice)は $0.00 と表示された

J2 が #REF! でも、Canvasが自分で計算していれば Model A の月額(円)は36,000円と表示されたはずです。
実際には計算列の値をシートから受け取って表示しており、今回のCanvasでは、シートのエラーが0と表示されました。
画面だけを見ていると、異常に気づけません。
T1とT7で入力値を元に戻した直後にも、AI_COST の欄だけが一時的に0.00と表示されたことが1回ずつありました。
カスタム関数の計算中(Loading…)の状態が0に見えた可能性があります。
入力値の編集で数式が残った点は、Google Workspaceのブログの説明どおりでした。
4行目を削除すると #REF! は解消し、Canvasの表示も元に戻りました。

GASやSheets APIからの更新(T4〜T6)

GASやSheets APIによる書き換えは、データソース以外のタブの変更も含めて、開いていたCanvasに再読み込みなしで届きました。
メニューから bumpUsers を実行し、Model A の利用者数を100から200にすると(T4)、Canvasは月額72,000円、年額864,000円に変わりました。

GASでUsersを200に更新した後のCanvas

GASで利用者数を200に書き換えた後のCanvas。再読み込みなしで月額72,000円に変わった

続いて、利用者数を200にしたまま fetchRate を実行しました(T5)。
Settings タブのレートが150から158.37に変わると、名前付き範囲でつながった Sim タブの為替と月額(円)が再計算され、Canvasの表示も変わりました。

為替レート取得後のCanvas

GASで取得したレート158.37が反映されたCanvas(利用者数はT4の200のまま)。年額は912,211円と表示された

年額912,211円は、カードの「¥76,018 × 12」(912,216円)ではなく、丸める前の月額76,017.60円(480USD×158.37)の12倍です。
Canvasが受け取るデータを表示させて確かめると、シートの書式を適用する前の値が渡っており、丸めるのは表示するときだけでした。
T6では、外部の業務システムを想定して、Sheets APIから Sim タブを書き換えました。
認証にはサービスアカウントの一時的なアクセストークンを使っています。
Model A の利用者数を100から200にすると、開いていたCanvasは月額72,000円・年額864,000円に変わり、100に戻すと元の表示に戻りました。
数式もすべて残っています。

Canvasの編集でもonEditは動いたが、編集前後の値は空だった(T7)

GASやSheets APIの書き込みとは違い、Canvasでの編集は onEdit トリガーを動かしました。
GASを動かすきっかけには使えますが、編集前後の値で判定する処理は、そのままでは条件が成り立ちません(T10)。
公式ドキュメントの説明は次のとおりです。

The onEdit(e) trigger runs automatically when a user changes the value of any cell in a spreadsheet.

Script executions and API requests don't cause triggers to run. For example, calling Range.setValue() to edit a cell does not cause the spreadsheet's onEdit trigger to run.

インストール型トリガーにも同じ制約があります。

Canvasの編集がユーザー編集とスクリプト・API書き込みのどちらとして扱われるかという問い

onEditは人の編集で動き、スクリプトやAPIの書き込みでは動かない。Canvasからの編集がどちらに当たるかを確かめる

Log タブには、2つの onEdit が編集されたセルと編集前後の値(e.oldValue・e.value)を、onChange が変更の種類を記録します。
グリッド、Canvas、プログラムからの書き込みで、記録は次のように分かれました。

操作 onEdit(単純・インストール型とも) onChange(インストール型)
グリッドで B2 を500→100(T1) B2、編集前500、編集後100 EDIT、OTHER
グリッドで C2 を10→20 C2、編集前10、編集後20 EDIT、OTHER
Canvasで B2 を100→500(T1) B2、編集前・編集後とも空 EDIT、OTHER
Canvasで C2 を20→10 C2、編集前・編集後とも空 EDIT、OTHER
Canvasで行を追加(T3) A4:L4、編集前・編集後とも空 INSERT_ROW
GASで Sim タブを書き換え(T4) 記録なし 1行(OTHER)
GASで Settings タブを書き換え(T5) 記録なし 記録なし
Sheets APIで Sim タブを書き換え(T6) 記録なし 書き込みのたびに2行(EDIT と OTHER)

onChange の欄は変更の種類(changeType)で、EDIT は値の編集、OTHER はその他の変更です。
公式の説明どおり、外部システムがSheets APIでデータを流し込んだだけでは、onEdit で組んだ処理は動きません。
Canvasからの編集では、変わったセルは記録されましたが、e.value と e.oldValue は空でした。
9月28日に、Canvasの「+10」「-10」ボタンで B2 を編集し直したときも同じです。
イベントオブジェクトの説明では、この2つは編集範囲が単一セルの場合にだけ渡されるとあり、グリッドでの B2・C2 の数値の編集では、どちらの値も入っていました。
行の追加(A4:L4)が空なのはこの説明どおりですが、Canvasでの B2・C2 の編集は単一セルでも空でした。

Canvas編集とグリッド編集で記録された Log タブ

T1で記録された Log タブ。E・F列が編集前後の値(onChange の行のF列は変更の種類)。Canvasで編集した28・30行は空で、グリッドで編集した32・33行には500→100が記録された

onChange は、Sheets APIで書き込んだT6では毎回、GASで書き込んだT4でも1行記録されました。
公式の説明とは異なりますが、T6ではCanvasとグリッドを開いたまま、T4では同じ時間帯にシートを再読み込みしており、書き込みそのものが記録のきっかけかは切り分けていません。

Canvasから外へつなげるか(T8〜T11)

Canvasから直接つなぐ経路のうち、T8は外部APIへの通信が止められ、T9とT11はGeminiが未対応と回答しました。
シートを経由する経路(T10と、T11の参照列)は通っています。
T8・T9・T11は、同じ Sim タブから作った検証用のCanvasで、GASやセルの書き換えといった代わりの手段を指示文で禁じて試しました。

外部APIへの通信は、Canvasに設定されたCSPで止められた(T8)

次の指示で、Geminiはボタンの付いたCanvasを生成しました。


Create a separate canvas named "T8 Direct API Test" from this Sim tab.
Show a small read-only table of Model, USDJPY and MonthlyJPY from the sheet.
Add a button labeled "Fetch latest rate".
When clicked, call https://api.frankfurter.dev/v2/rate/USD/JPY directly from the canvas and show the returned JPY rate next to the button.
Do not write the rate or any other values to the sheet.
Do not use Apps Script, a Refresh checkbox, mock data, or a hardcoded rate.
If the request fails, show the actual error.
This is a capability test.

Geminiのパネルの「Show code」で見ると、生成されたコードはボタンを押したときに指定のURLを直接呼んでいます。


const response = await fetch('https://api.frankfurter.dev/v2/rate/USD/JPY');

しかし、ボタンを押すと「TypeError: Failed to fetch」と表示され、レートは取得できませんでした。

「Fetch latest rate」を押して TypeError: Failed to fetch と表示されたCanvas

「Fetch latest rate」を押すと「TypeError: Failed to fetch」と表示された(右はGeminiが生成したコードの冒頭。App 関数が受け取るのは、data、行を操作する関数、followLink だけ)

同じAPIはGASからは取得できており、API側はどの呼び出し元にも応答を許可するヘッダー(Access-Control-Allow-Origin: *)を返していました。
別ドメインからの応答をブラウザが読めるかを決める仕組み(CORS)は、原因ではありません。
通信を止めていたのは、Canvasの画面が動く枠(iframe)に設定されたCSPでした。
9月28日に、このCSPと違反の記録を表示する欄をGeminiに加えさせ、同じボタンを押した結果が次の画面です。

CSPの診断欄を加えたT8の検証用Canvas

「Fetch latest rate」を押した後の診断欄。fetch は connect-src の違反として止められ、下の欄には枠の CSP(default-src 'none'; …)が表示された(nonce の値は伏せている)

枠には、Sheetsが差し込んだCSPの meta タグがあり、default-src 'none' が指定されていました。
fetch などの通信先を決める connect-src の指定がないため、default-src 'none' がそのまま適用され、枠の中からの通信はすべて禁止されます。
fetch は、この connect-src の違反として止められていました。
WebSocket も、CSPとは別に差し込まれたスクリプトで無効化されており、読み出すと「WebSockets are disabled」という例外になります。
Sheetsが読み込むJavaScriptを見ると、このCSPはGoogle側の機能フラグで内容が切り替わる作りになっていました。
少なくとも今回の環境では、Canvasのコードに外部APIの呼び出しを書いても、枠の中からは通信できません。

GASの関数の呼び出し(T9)

通常のシートでは図形にスクリプトを割り当ててボタンにできるので、Canvasのボタンに fetchRate() を割り当てるよう指示しました(T9)。
Geminiは「Unsupported」と回答し、ボタンを作りませんでした。
Geminiの説明では、隔離された枠で動くCanvasの画面には、google.script.run のようなGASを呼ぶ仕組みがありません。
使えるのは、シートの行データと、行を操作する関数、リンクを開く関数だけだといいます。
公式の仕様ではありませんが、T8で生成されたコードも、この3種類だけを受け取る形でした。

GASの関数を呼ぶボタンの依頼に対して Unsupported と回答した Gemini と、Canvas表示中に開いた検証メニュー

GASの関数を呼ぶボタンを依頼したときのGeminiの回答(右)。Canvasの表示中も、メニューバーにはGASで追加した「検証」メニューが出ていた

セルを経由してGASに外部APIを呼ばせる(T10)

T10は、Canvasのボタンにはセルを書き換えさせるだけにして、外部APIの呼び出しはGASに任せる経路です。
Refresh のチェックを拾うGASの条件を、e.value ではなくセルの現在の値で判定するように直すと、次の経路が成立しました。


Canvas のボタン → Sim!L2 を TRUE に → onEditInstalled → fetchRate(外部API)
→ Settings タブの為替レートを更新 → Sim の H列 → Canvas の表示が変わる

ボタンには、最初のCanvasに付いていた「Refresh: Off」を使いました。
押すと、Sim タブの L2 のチェックボックスが TRUE になります。
外部APIを呼ぶ UrlFetchApp は利用者の許可が要るため、単純トリガーでは使えません。
そこで、為替レートの取得はインストール型の onEdit(onEditInstalled)に任せました。
登録したユーザーの権限で動き、編集されたセルもわかるからです。
最初に用意したコードは次のとおりです(判定の修正は後述)。

Apps Script(onEditInstalled)

function onEditInstalled(e) {
  log_('installable onEdit', e); // Log タブに1行記録する
  const range = e.range;
  // Sim タブの L列(Refresh)が TRUE になったら、為替レートを取得してチェックを戻す
  if (range.getSheet().getName() === 'Sim' && range.getRow() > 1 &&
      range.getColumn() === 12 && range.getNumRows() === 1 && range.getNumColumns() === 1 && e.value === 'TRUE') {
    fetchRate();
    range.setValue(false);
  }
}

このコードで、次の4回を試しました(4回目だけは判定を直した後)。

回 操作 結果
1 Canvasで Refresh を押す トリガーの記録がない。L2 は TRUE のままで、為替レートも変わらない
2 比較のため、グリッドで L2 を TRUE にする 3種類のトリガーが動き、レート158.36を取得。L2 は FALSE に戻った
3 Canvasを再読み込みしてから Refresh を押す トリガーは動いたが、編集前後の値が空。条件が成り立たず、レートは取得されない
4 判定をセルの値に変えてから Refresh を押す レート158.36を取得し、L2 は FALSE に戻った。Canvasの表示も更新

(レートがT5の158.37と違うのは、取得した時刻が違うためです)
1回目は、L2 が TRUE になったのにトリガーが1つも動かず、その原因はわかっていません。
3回目に条件が成り立たなかったのは、T7と同じく e.value が空だったためです。
そこで、判定をセルの現在の値で行うように1行だけ直しました。
グリッドでの編集なら e.value には文字列の 'TRUE' が入りますが、getValue() は真偽値を返すので、比較する値も true にしています。

onEditInstalled の判定の修正

-      range.getColumn() === 12 && range.getNumRows() === 1 && range.getNumColumns() === 1 && e.value === 'TRUE') {
+      range.getColumn() === 12 && range.getNumRows() === 1 && range.getNumColumns() === 1 && range.getValue() === true) {

4回目は、ボタンを押してから約13.8秒後に画面を見た時点で、レートの取得、L2 のチェックの解除、表示の更新まで終わっていました。
Model A の月額は38,006円、年額は456,077円に変わっています。
9月28日に修正後のGASで Refresh を2回押したときも、どちらもトリガーが動き、為替が更新されました。

判定をセルの値に変えた後にRefreshを押し、為替レート158.36と Model A の月額38,006円が表示されたCanvas

判定を直した後にRefreshを押した結果。再読み込みなしで、為替レートが158.36、Model A の月額が38,006円に変わった

別タブの表示(T11)

Prices タブの価格表と Settings タブの UpdatedAt(B2 の値)を表示するよう指示すると、Geminiはこれも「Unsupported」と回答しました。
代わりに提案された方法の1つが、データソースのタブに、別のタブを参照する数式の列を作る方法です。
そこで、Sim タブのM列に Settings タブを参照する数式(=Settings!$B$2)を入れました。
Canvasには、その列と、XLOOKUP で Prices タブを参照している単価の列を表示させています。
その後、Sheets API 経由で、Settings タブの B2 に入れておいた試験用の文字列と、Prices タブの Model A の入力単価(2→4)を書き換えました。
開いていたCanvasは再読み込みなしで変わり、Model A の月額は54,000円になりました。
Canvasに出せるのは Sim の行に引き込んだ値だけで、Prices タブの表そのものではありません。

Sim タブの参照列を経由して、Settings タブと Prices タブの変更を表示した検証用Canvas

Sim タブの参照列を経由した表示。Settings タブの文字列と、Prices タブの単価を2から4にした結果(Model A の月額54,000円)が、再読み込みなしで表示された。価格表は画面外

業務で使うときの考え方

Canvasには値の表示と既存の行への入力を任せ、計算はシートの数式、外部との連携はセルの変更を拾うGASに置きます。
数式の列があるシートでは、行の追加をCanvasから行わないようにします。

Canvas・シート・GAS・外部APIの役割分担を示す図

今回の結果に基づく役割分担。Canvasは1つのタブの入力と表示、計算と別タブの取り込みはシートの数式、外部APIの呼び出しはセルの変更を拾うGASが受け持つ

前提として、Canvasを使えるのは言語設定が英語で Gemini in Sheets が有効な利用者だけで、環境もPCのWeb版に限られます。
Canvasから値を変えられるのも、スプレッドシートの編集者だけです。
今回のCanvasで起きたことが、別の指示で作ったCanvasでも起きるかは確かめていません。
業務で使う画面を作ったら、次の点を実際のデータで試しておいてください。

  • 行を追加したとき、計算列が固定値で埋まったり、配列数式がエラーになったりしないか
  • シートでエラーになったセルが、Canvasで0と表示されないか
  • Canvasから編集したとき、イベントの値(e.value・e.oldValue)が空でもGASが意図どおりに動くか
  • トリガーがセルの現在の値で判定する場合、ボタンの連打や複数人の同時操作で、処理が重なったり抜けたりしないか
  • Canvasの操作でトリガーが動かなかったときに、それに気づけるか
  • onChange を使う場合、外部システムからの書き込みで動いても、処理が誤作動しないか
  • 外部サービスを呼ぶボタンを置くなら、実際に押して通信できるか

まとめ

Canvasは、既存のシートとGASの上に、入力と表示の画面を足す道具として使えます。
つまずきやすいのは行の追加と、外部APIやGASの呼び出しなので、筆者はこの2つをCanvasに持たせない分担から始めるのがよいと考えています。
まずは普段のスプレッドシート業務で小さな画面を1つ作り、前の節の確認項目を実際のデータで試してみてください。

生成AI活用支援サービスのご紹介

Tech Funでは、お客様のフェーズに合わせ、生成AI活用に向けた様々な支援をご提供しています。

  1. 無料診断パック:業務・プロセスの現状を無料で診断し、生成AI活用の可能性をレポートします。
  2. 検証(PoC)パック:診断で有効性が確認された業務を対象に、プロトタイプ構築を支援します。
  3. コンサルティングサービス:生成AI導入戦略の策定から運用体制構築までを包括的に支援します。
  4. Plain RAG:社内文書をもとに回答し、社内問い合わせを効率化するAIチャットパッケージです。

生成AIに限らず、Web・業務システム開発やインフラ設計など、技術領域を問わずご相談を承っています。「何から始めれば良いか分からない」という段階でも構いませんので、ぜひお気軽にお問い合わせください。

執筆・編集

Tech Fun Magazine R&Dチーム
Tech Funの生成AI研究に携わるエンジニアが、最新のAIモデル動向やプロンプト設計、実業務への応用手法など、生成AIに特化した知見を執筆・編集しています。
モデル評価や業務シナリオに応じたAI活用設計など、日々のR&D活動で得られる実践的なノウハウをわかりやすく紹介します。

ARTICLE
生成AI関連記事一覧

生成AI関連

Google Sheets canvasはどこまで業務アプリ…

生成AI関連

Amazon BedrockのRerank APIで検索順位…

生成AI関連

OpenAI Agents APIとは?本番運用に必要な5つ…

生成AI関連

Codex App Serverとは?Pythonでの使い方…

生成AI関連

Amazon Bedrockの基盤モデルパーサーを実測する―…

生成AI関連

ChatGPT WorkのScheduled TasksをW…

生成AI関連

Amazon Bedrock Knowledge Bases…

生成AI関連

ChatGPTのChat・Work・Codexの違い|5時間…

生成AI関連

Amazon BedrockのModel invocatio…

記事一覧を見る