手術シフトの執刀・助手の振り分けを、GASで自作してみた話

はじめに:手術シフトは「誰かの善意」で成立している
医局で手術のシフト表を組んだことがある人なら、この感覚はわかってもらえると思う。
- 誰がどの手術に入るか、毎週カレンダーとにらめっこで決める
- 助手の「領域ごとの偏り」は、感覚で調整している
- 「前回もあの先生が助手だった気がする」は、誰かの記憶に依存している
- 決まったシフトは、Slackやメールで飛び交って、どこかのスプレッドシートに手書きで残る
どれも数十分の仕事に見えるけれど、毎週繰り返すと、シフト作成者の脳内リソースをかなり持っていく。しかも、後から「3か月分の手術件数と担当者を統計したい」となったとき、必要なデータが散らばっていて集計に数時間かかる。
今回、この一連の流れを Google Apps Script(以下 GAS)で組み直せるシステムを作ってみた。狙いは、「シフト作成者の脳内で動いていた処理を、カレンダーとスプレッドシートの上に載せ替える」こと。まだ実運用には入っていないが、設計と試験運用の段階で見えてきたことを共有したい。
---
GASで組もうと思ったきっかけ
正直に書いておくと、勤務先で Google Workspace は数年前から使っていたものの、GAS について自分は理解が不十分だった。スプレッドシートにちょっとした関数を書く程度の認識で、「カレンダーと連携して独立したアプリケーションを作る」粒度のことができるとは、あまり想像できていなかった。
きっかけは、まじんさん(@Majin_AppSheet)のX投稿だった。GAS と Google Workspace の組み合わせで、ここまで実務的な業務改善ツールが自分の手で組めるのか、という視点を頂いた。着想源として明記しておく。感謝を込めて。
そこから調べ直してみると、GAS は「スプレッドシートの拡張マクロ」という位置づけで捉えていた自分の認識がだいぶ狭かったことに気づいた。カレンダー API、WebApp として公開する HtmlService、Advanced Services の Freebusy クエリなど、医療現場の業務改善アプリを組む道具として十分に揃っている。しかも院内の Workspace 内で閉じて動かせるので、外部クラウドへのデータ送信が発生しない。これは医療現場で業務改善アプリを組むうえで、かなり大きな利点だと思う。
---
何を作ったか
Google Workspace で完結する、手術の執刀医・助手の自動割り当てシステム。
- スプレッドシート1つ+ GAS スクリプト一式
- WebApp UI(スプレッドシートから開けるブラウザ画面)でマスター編集・プレビュー・確定
- 外部サービスは使わない(Firebase も Vercel も使わない)
シンプルに言うと、手術用カレンダーに「空の手術枠」を作っておけば、医局の他のメンバーのカレンダー予定を読んで、執刀と助手を自動で埋めてくれる。コードは書いているが、個人で保守できる粒度に収めた(ファイル数は .gs と .html 合わせて18個程度)。
---
これで何が変わりそうか(想定される改善)
まだ現場に導入したばかりで、実運用での効果検証はこれからになる。ただ、設計の段階で「ここが変わることを狙っている」という点は明確にしてある。現時点で想定している改善を、3つに分けて書いておく。
1. シフトを組む時間を「考える時間」に寄せられるはず
これまでは「誰が空いているか」を調べる時間と、「誰を当てるか」を考える時間が混ざっていた。システムを通すと、空いている人・領域が合う人・直近の負担が軽い人が先に絞られるので、最後の人間判断だけに集中できる設計にした。どのくらい時短になるかは、実際に数週間運用してみないと分からない。
2. 助手の偏りが「可視化」される
これまで属人的な感覚で「最近◯◯先生が助手続いているな」と気づいていたものを、過去データに基づくスコアで自動計算する形に移した。感覚で捉えていた偏りが、数値として見えるようになるはず。自分で気づけていたつもりの偏りが、実際にはどれだけ見落とされていたかは、運用してから振り返る予定。
3. 過去データが副産物として自動で貯まる
確定した手術は全て、スプレッドシートの PastHistory シートに自動で追記される設計になっている。特別に「集計しよう」と意識しなくても、運用を続ければ構造化された執刀歴・助手歴が手元に残る。これは後述するが、後で臨床研究や教育評価の集計をしたい場面で効いてくると思っている。逆に言うと、今まではこのデータを「意識的に集計しない限り残らなかった」わけで、ここが自動化されるのは構造的に大きい変化になると想定している。
---
技術的な要点
GAS で作るメリット
GAS を選んだのは、医療現場で小さく業務改善アプリを作るときの相性がいいと思っているから。
- 医局の Google Workspace 内で完結する(外部にデータを出さない)
- サーバー運用もクラウド契約も要らない(Googleアカウントがあればゼロ円で動く)
- スプレッドシートと Google カレンダーに標準で繋がる
- WebApp として公開すれば、医局のメンバーがブラウザで使える
特に、患者個人情報を扱わない「シフト管理」「日程調整」「マスター台帳」レベルの業務改善なら、GAS の守備範囲で十分収まる。院内のセキュリティ部門と相談するときも、外部クラウドにデータを置かない点は説明しやすい。
カレンダー連携の仕組み
ここが今回の肝。
- 手術用カレンダー:医局で共有する1つのカレンダー。「空の手術枠」を作っておく。タイトルは
耳 鼓室形成術のような形式で、作成者のメールアドレスも同時に取れる。 - 各医師の個人カレンダー:Workspace 内の Free/Busy 共有で、予定が入っている時間帯だけ取得する。予定の中身は見ない(守秘の観点でも楽)。
Advanced Calendar Service の Freebusy.query() を使うと、医師全員の「忙しい時間帯」を1つのAPIでまとめて取れる。これで「手術枠に対して、誰と誰が空いているか」が即座に判定できる。
過去の手術履歴を参照して自動調整
助手の割り当てロジックは、次のようなスコア式を使っている。
score = (過去の同領域助手カウント + 今週の同領域助手カウント) × 2
+ 今週の総担当時間(時間単位)
スコアが小さい助手から優先的に割り当てる。ポイントは、「過去に同じ領域の助手にたくさん入っている人は、今週は他の領域に回る」というロジックが、データだけで自動で効くこと。
作成者優先のルールも入れた。手術枠を作った本人が執刀可能で空いていれば、その人を最優先で執刀に当てる。「この手術は自分がやるつもり」という意図は、カレンダーの作成者情報に自然に現れるので、それをそのまま読み取る形にした。
履歴が統計しやすい形で残る
確定した手術は、スプレッドシートの PastHistory に次のカラムで追記される。
| 確定日時 | 手術日 | 領域 | 正式術式名 | 執刀 | 助手 | 部屋 | イベントID | 割当ID |
|---|
この時点で、構造化データとしてピボットテーブルや BigQuery に取り込める形になっている。例えば「この半年で自分が入った手術の領域分布は?」「若手の助手経験は領域ごとに何件?」といった問いに、その場で答えが出せる。
臨床研究で「過去1年間の執刀データをください」と言われたとき、Excelと格闘しなくていい。これは地味だけど、後から効く。
---
AI エージェントに渡すと有効だったプロンプト例
このシステムは Claude Code(AI コーディングエージェント)に実装を手伝ってもらった。非エンジニアでも同じようなシステムを作りたい人向けに、実際に使って効いたプロンプトの型を共有しておく。
1. 要件定義フェーズ(最初にこれを入れる)
現在の業務フロー:
- 手術のシフトは毎週◯曜日にスプレッドシートで手作業で作成
- 助手の領域の偏りが問題になっている
- 過去の手術履歴は属人的でデータ化されていない
やりたいこと:
- Google Workspace内で完結する割り当てシステムを作りたい
- 外部クラウドにはデータを出したくない(院内ルール)
- 非エンジニアが保守できる粒度にしたい
制約:
- Googleカレンダー(手術用+各医師の個人)を連携
- 助手は過去データを参照して偏りを平滑化
- 最終判断は人間が行う(AIの判定はあくまで提案)
この要件をGASで実装する場合の、ファイル構成案と主要データモデルを
先に提示してほしい。コードはまだ書かなくていい。
ポイント:いきなり「コード書いて」と言わない。要件 → ファイル構成 → データモデル → コードの順で、骨格から詰める。
2. データモデル設計フェーズ
このシステムで扱うデータを、スプレッドシートのシートとして設計したい。
マスターデータ(医師・術式・領域)と、トランザクションデータ(手術履歴・
スナップショット・ログ)を分けて、各シートのカラム定義を日本語で
出してほしい。将来の統計解析を考慮して、正規化しすぎず
フラットな構造を優先する。
ポイント:「将来の統計解析を考慮」と明示すると、集計しやすい形で設計してくれる。
3. 割り当てロジック設計フェーズ
助手の割り当てロジックで、以下の観点を考慮したスコア式を提案してほしい:
- 過去の同領域助手経験(偏りを避ける)
- 今週の既割当時間(総負荷の平滑化)
- 領域適合(専門でない領域には入れない)
- 作成者優先(カレンダー作成者が執刀可能なら優先)
スコアが小さい人を優先する形で、重み付けの根拠と、
破綻しうるエッジケースも併記してほしい。
ポイント:「エッジケースも併記」と頼むと、破綻パターンを先に潰せる。
4. 実装フェーズ
上記で決めた仕様で、AssignmentEngine.gs を実装してほしい。
コメントは日本語。関数は小さく分ける。
ロジックの要所に「なぜこの判定を入れたか」のコメントを残す。
ポイント:「なぜこの判定を入れたか」のコメントを頼むのが重要。後で自分が読み返すときに、意図が残っていると保守しやすい。
5. UI フェーズ(WebApp)
このシステムの操作UIを、GASのWebApp機能で作りたい。
タブ構成は:プレビュー・医師マスター・術式マスター・領域マスター・履歴・設定。
プレビュー画面は1週間を視覚的にグリッド表示し、
未割当は赤、割当済は緑で表示。
執刀と助手はドロップダウンで手動上書き可能にする。
ポイント:UI はスクリーンショットやスケッチを添えるとさらに精度が上がる。ない場合は、視覚要素(色分けのルール、クリック時の挙動)を言葉で細かく書くと良い。
6. デバッグフェーズ
WebAppを開いたら「構文エラー: Unexpected token '<' 行:1 ファイル:WebApp.gs」
と出た。原因と対処法を教えてほしい。コード全体は変更せず、
どこを見ればいいかだけ指示して。
ポイント:エラーメッセージは省略せずに原文のまま貼る。「どこを見ればいい」と範囲を制限すると、AIが推測で余計な書き換えをしない。
---
限界と、人間が引き受ける部分
便利になった部分を書いたので、引き受けが必要な部分も書いておく。
- AIの自動割り当ては「提案」であって、最終判断は人間
- 症例の難度、若手の教育機会、特定の指導医との組み合わせなど、数値化されていない判断軸はまだ多い。プレビュー画面で必ず目視確認する運用にしている。
- 施設固有のルールはシステムが知らない
- 「この術式はこの指導医の同席必須」「この曜日は研修医の勉強会と重なる」などは、マスターに載せ切れていない前提で運用している。
- 個人情報のスコープ
- 今回扱っているのは「医師の予定と手術枠」であって、患者情報ではない。この線は絶対に超えないように、データ設計の段階でカラムから除外している。
- データが蓄積されるほど、バイアスも蓄積されうる
- 「過去に助手に入っていないから、次は◯◯先生」という自動調整は、構造的な偏りを温存する可能性もある。定期的に、人の目で分布を確認する必要があると思っている。
---
まとめ
GASとGoogleカレンダーだけで、手術シフトの割り当てに使っていた時間の一部を、仕組みに移せる原型は作れた。これが画期的な発明かというと、現時点での実用的な答えの一つ、くらいの位置づけが妥当だと思っている。実際に現場で回してみて、どれだけ時短になるか・どれだけ判断の質が変わるかは、これから数週間〜数か月かけて検証していく予定。
ただ、「非エンジニアの医療従事者が、自分の現場の不便を、自分で組んだ道具で直す」という選択肢が現実的に取れるようになってきているのは、実感として面白い。AIコーディングエージェントに要件を渡せば、週末の空き時間で原型が立ち上がる粒度にはなっている。
ある程度機能が固まり、みなさんの希望があるようならGithubで公開も考える。なにかあればXで連絡ください。
Xに参考動画あげてます。https://x.com/2YuM1Cwg1K92898/status/2044272945204474065
---
参考:環境と所要時間
- 使用AI:Claude Code(Opus 4.6)gemini3.1 pro
- 実装言語:Google Apps Script(JavaScript ベース)
- UI:GAS の HtmlService(Bootstrap も React も使わない素のHTML/CSS/JS)
- 所要時間:設計対話から初回デプロイまで半日程度
- 運用コスト:Google Workspace 利用料内で完結(追加課金ゼロ)
議論のタイムライン
読み込み中...