🧰

シート変更をAIに追従させる ─ xlsm_devkit 新機能と「脱Excel」再考

に公開

この記事で伝えること

前回の記事 では xlsm_devkit の基本機能を紹介しました。VBAモジュールとシートマップを外部ファイルに書き出し、VS Code などのAIチャットに渡すことで、マクロ付きExcelをモダンな開発体験で作れる、というツールです。

今回は「実際に使ってみてわかったこと」と、それを受けて追加した機能 ── InsertDeleteMoveランチャー多言語化(27言語) ── を紹介します。


第1章 使ってみてわかったこと

8000セルのアルゴリズムをAIが読み解いた

xlsm_devkit を既存の業務用 Excel ファイルに適用して VS Code で解析した時の体験が非常に印象的でした。

この Excel ファイルは、高度な業務知識を駆使して効率と精度を向上させるための数々の処理を行います。例えば、業務システムの Web UI で Ctrl+A, Ctrl+C を押してからこの Excel のシートで「貼り付け」ボタンを押すと、それを即座に解析し、業務システムでの操作に不備があれば指摘します。不備がなければその Excel ファイルを保存しておいて次の業務を進めています。後で別のシステムから出力された結果をその Excel ファイルの別のシートに貼り付けると、両者を照合して不整合があれば指摘します。これらの処理は、多数のシートに合計 8000 ほどのセルを使って配置された多段階の複雑な数式の連鎖で実装されています。ビジネスロジックがコードではなく数式で実装された Excel らしい構成です。そのアルゴリズムは、業務システムの Web UI の変化に合わせて改変されてきました。ただ、この Excel の作りは、以前に作成者以外の人が読み解こうとして挫折してしまいました。

ところが、xlsm_devkit でシートマップとVBAコードをエクスポートして VS Code 等の IDE に読み込み、サイドパネルの AIチャットにこのマクロ付きExcelについて質問してみたところ、VS Code の CLAUDE CODE拡張機能 (Sonnet 4.6)・同CODEX拡張機能 (GPT-5.5)・Google Antigravity (Gemini 3.1 Pro) のいずれもが的確にこのアルゴリズムを読み解き、配置・背景色・値・入力規則・数式・マクロコードの全てが合わさって全体としてどう機能しているかを分かりやすく説明し、質問にも的確に答えてくれたのです。全体像の解析や質問への回答にかかった時間は1問あたり CLAUDE CODE・CODEX・Antigravity それぞれ10分・1分・1分程度でした。

以前に書いた記事「ExcelとAIの共存戦略――DAG×UIが理解できない現在のAIと「脱エクセル」の落とし穴」の中で、複雑なスプレッドシートの全体構造をAIが理解することは現時点では困難だが、中期的にはブレイクスルーが起きる可能性が高いと書きましたが、その予測は案外あっさり突破されてしまいました。

巷では「エクセルは属人的」として「脱エクセル」ツールへの移行に誘導する言説が流布されていますが、 AI が複雑な Excel ファイルを読み解いて誰もに理解できるように解説してくれ、質問にも的確に回答してくれるわけですから、その言説が前提としている Excel の 属人性 は、 作った人 にしか理解できないという意味でも、プログラムや AI ではなく 人間 にしか扱えないという意味でも崩れてしまったわけです。

私自身はそのような「脱エクセル」の言説を真に受けていません。確かに Excel は大量の事例の膨大なデータの集積・検索・抽出といった用途には向いていません。しかし Excel は多くの環境で利用できる極めて高機能なアプリケーションであり、しかも多くの人が使い慣れていますので、固有の業務に即した実用的なツールが効率よく作成できる基盤としても優秀に機能します。なので、例えば業務場面毎に雛形ファイルを Excel で作成しておいてそれをコピーして事例毎に配置するという運用であれば、定型業務の Excel 運用の継続も十分に選択肢の一つであると考えています[1]。今回の体験はその考えをさらに強めるものでした。

xlsm_devkit 自体を xlsm_devkit で開発した

もうひとつは、今回追加した InsertDelete・Move・ランチャー・多言語化の開発体験についてです。

これらのオプション機能は xlsm_devkit 自身を使って開発しましたが、 xlsm_devkit の機能が大いに役立ちました。VBA モジュールとフォームを src/ にエクスポートし、VS Code のサイドパネルでチャットして相談したり agent として動作させたりして VBA のコードを書きましたが、その体験は実にスムーズであり、 Python での開発と大差ない印象でした。

xlsm_devkit というツールは PowerPointの翻訳を効率化するためのPowerPoint⇔YAML変換用Excelアプリというツールの開発から生まれ、そうやって生まれた xlsm_devkit を使ってそのオプション機能が開発され、オプション機能によって xlsm_devkit 本体の機能がさらに強化されるといった具合に、複数のツールが相互に機能を充実させあいながら育ってきました。これもとても興味深いことだと思います。

残った課題:シート側の変更へのコードの追従

Excel ファイルを長年運用すると、シート上に配置する項目の追加・削除・配置変更などが生じがちです。シート上で行/列を追加/削除したりセル範囲を移動させたりすると、移動された範囲のアドレス参照がずれますが、シート上の数式はそれに自動で追従してくれます。同様に VBA のコードの例えば Range("E5")Cells(5, 3) といったアドレス参照もずれますが、残念ながらこれらは追従しないので人手で直すしかなく、参照箇所が多いと見落としも起きます。それが面倒なのでついつい新たな項目を無理やり隙間に押し込んだり、項目がなくなっても場所を詰めずに行や列を非表示にしたりといった一時しのぎで済ませてしまいがちです。

VBA のコードでセルをアドレスで参照せずに名前を付けてそれを参照するという方法もありますが、参照したい箇所が 100以上あると今度は名前の管理の方が破綻してしまいます。なので、コード上のアドレスの追従はどうしても解決したい課題でした。

そう思っていたところに、AIがシートとコードの連携を理解する能力の高さを目の当たりにしたので、この課題もAIを使えば解決できると考えて xlsm_devkit のオプション機能として devkit_InsertDeletedevkit_Move を開発することにしました。第2章と第3章ではこれらについて解説します。


第2章 InsertDelete:行・列の変更をAIに伝える

何をする機能か

devkit_InsertDelete は、 VS Code 上の AI を使って Excel シート上での 行/列 の 挿入/削除 に VBA のコードを追従させるオプション機能です。シート名、行/列の開始位置、挿入/削除、行/列の数を指定すると、指定通りに 行/列を挿入/削除し、その変更内容を示した文章と、変更前後のシートマップを作成し、それらに基づいて VBA のコードを更新させるためのプロンプトを生成します。このプロンプトを VS Code などの AI チャットに貼り付けると、 AI の方で影響を受ける VBA のアドレス参照を特定して更新してくれます。修正後のコードを Excel にインポートすれば Excel の VBA のコードが更新されます。

操作フロー

  1. ランチャー(または ShowInsertDeleteForm を直接実行)からフォームを開く
  2. 操作内容を指定する(例:「D列に1列挿入」)
  3. OK を押す ── Excelへの操作実行と前後のシートマップ保存が自動で行われる
  4. 生成されたプロンプトが Instruction ダイアログに表示され、クリップボードにもコピーされる
  5. AI チャットにプロンプトを貼り付けて送信すると、AI によりコード (src/*.bas) が修正される
  6. 修正されたコードを保存し、「インポート」ボタンで Excel に取り込む

InsertDeleteフォームのスクリーンショット

Instructionダイアログのスクリーンショット

生成されるプロンプトの例(D列に1列挿入した場合)

The following operation was performed on Excel sheet "main" (VBA CodeName: Sheet1):

  Inserted 1 column(s) before column D (column number 4).

Please review all .bas files in the src/ folder and update any cell references
in the VBA code that refer to this sheet and have shifted due to this operation.

Sheet map before: @sheet/Sheet1.old.md
Sheet map after:  @sheet/Sheet1.md

Reference formats to check:
- String-form:  Range("C5"), Range("A1:C10"), etc.
- Numeric-form: Columns(N), Cells(R, C), etc.
- Dynamic-form: Range(colLetter & n), Cells(r, colNum + 1), etc.

Please list any references that cannot be updated automatically or require confirmation.

Please respond in Japanese.

@sheet/Sheet1.old.md@sheet/Sheet1.md は、変更前後のシートマップファイルへのパスです。VS Code の GitHub Copilot Chat や Cursor といったAIチャットツールでは、このパスをファイル添付の参照として使えます。AIはコードだけでなく、変更前後のシートの状態を直接見ながら回答を返します。

末尾の「Please respond in Japanese.」はUIの言語設定に応じて変わります。

VS Code による VBA のコード変更

導入に必要なファイル

ファイル 役割
devkit_InsertDelete.bas 機能ロジック
devkit_frmInsertDelete.frm + .frx セットアップダイアログ
devkit_frmInstruction.frm + .frx 結果・インポートダイアログ(Moveと共用)

エントリポイント:ShowInsertDeleteForm


第3章 Move:セル範囲の移動をAIに伝える

InsertDeleteと分けた理由

行・列の挿入削除と、セルの範囲の移動は、VBAへの影響の性質が異なります。

挿入削除は「それ以降のすべてのアドレスがずれる」という系統的な変化です。対してセルの範囲の移動は「特定の範囲だけが別の場所に移る」という局所的な変化です。

また、移動操作の「記録」方法も異なります。 InsertDelete は、どの行・列を何行挿入/削除するかをダイアログで指定するとその通りにマクロの側でシートを操作するという仕様にしました。ですが、セル範囲の移動の場合、移動元と移動先のシートとセル範囲を指定してマクロの側でシートを操作するよりも、ユーザが自分の目でシートを直接確認して範囲を選択し、自分で操作して移動させる方が圧倒的にやりやすいはずです。

ところが、移動の操作をユーザに任せた場合、操作後にその内容を自己申告してもらうことにすると入力が面倒なうえに勘違いや入力ミスが生じてしまいがちです。そこで devkit_Move では、 Excel のマクロ記録機能を使ってユーザーによる移動の操作をマクロに記録してもらい、記録終了後に記録されたコードを解析するという方式を採りました。

操作フロー

  1. ランチャー(または ShowMoveSetupForm を直接実行)からMoveSetupフォームを開き、対象シートを選択する
  2. 「開始」を押すと変更前のシートマップが保存され、MoveWaitダイアログが表示される
  3. Excelの「開発」タブ → 「マクロの記録」で記録を開始する(保存先:作業中のブック)
  4. 切り取り(Ctrl+X)→ 貼り付け(Ctrl+V または Enter) でセルを移動する(ドラッグ&ドロップは不可)
  5. 「記録終了」で停止し、ダイアログの「停止」ボタンを押す
  6. 移動後のシートマップが保存され、AIプロンプトがInstructionダイアログに表示され、クリップボードにもコピーされる
  7. コピーしてAIチャットに貼り付け、修正後にインポートする

MoveSetupフォームのスクリーンショット

MoveWaitダイアログのスクリーンショット

実装の裏側:マクロ動作中にマクロを記録する綱渡り

この設計には、触れておく価値のある技術的な事情があります。

MoveWaitダイアログはモードレスで表示されます。ユーザーがExcel本体を操作できるように、ダイアログを出したままVBAの実行を「待機」状態にする必要があるためです。そしてユーザーは、このVBAが動いている状態のままExcelのマクロ記録を開始します。

ここで問題が起きます。VBAの実行中にマクロ記録を開始すると、VBAランタイムがリセットされます。 つまり、それまで変数に保持していた状態(「どのシートを対象にするか」「変更前のスナップショットをどこに保存したか」といった情報)がすべて消えてしまいます。

これを回避するために、devkit_Move は操作の途中状態をWindowsレジストリに保存しています。VBAランタイムがリセットされてもレジストリは残るため、記録終了後に状態を読み戻して処理を続けることができるからです。

リセット後もユーザーが押すための「停止」ボタンを載せたモードレスダイアログは残っているので、「停止」ボタンのクリックイベントから改めてレジストリ経由で状態を復元し、後続の処理につなげます。

VS Code 等で変更されたコードは「インポート」ボタンで読み込まれます。ただ、 xlsm_devkit 本体と devkit_Move のコードは除外されます。コールスタック上にある状態でインポートするとVBAランタイムがリセットされ、Excelがクラッシュするからです。

Excel VBAの制約をレジストリで迂回しながらモードレスダイアログとマクロ記録機能を共存させるといういささか綱渡りな設計ですが、ユーザーには「手順通りに操作するだけ」という体験が提供できています。

できれば利便性の向上のためにマクロ記録の開始と終了や記録されたマクロの消去まで xlsm_devkit の Move オプションの中で対応したかったのですが、実際に試してみるとうまく動作しなかったり記録されたマクロが不正確に削除されたりしたので、利便性よりも確実性を優先してマクロの記録と削除についての操作はユーザーに任せることにしました。

生成されるプロンプトの例(B7:C8をB8:C9に移動した場合)

The following cell range move was performed on Excel sheet "main" (VBA CodeName: Sheet1):

  Cut B7:C8, pasted to B8 on the same sheet.

Please review all .bas files in the src/ folder and update any VBA references
that target the source range B7:C8 on this sheet to point to B8.

Sheet map before: @sheet/Sheet1.old.md
Sheet map after:  @sheet/Sheet1.md

Reference formats to check:
- String-form:  Range("B7:C8"), Range("B7"), etc.
- Numeric-form: Cells(R, C) where R and C correspond to cells within B7:C8
- Dynamic-form: references constructed from the source range coordinates

Note: Formulas inside the moved range that reference cells outside it
      are updated automatically by Excel. Focus on VBA code references only.

Please respond in Japanese.

⚠ Module "Module2" was created by Excel's macro recorder and is not part of your source.
  VS Code: delete src\Module2.bas -- do not commit this recorded macro file.
  VBE: after this dialog closes (Import or Close), open VBE (Alt+F11) and delete the "Module2" module.

記録に使ったマクロモジュール(この例では Module2)が VBA プロジェクトに残るため、プロンプト末尾に削除を促す警告が自動で付きます。これを見て大抵の場合は AI の側で VS Code 上のモジュールを削除してくれますし、Excel COM 経由で Excel 上のモジュールまで削除してくれる場合もあります。

VS Code による VBA のコード変更

導入に必要なファイル

ファイル 役割
devkit_Move.bas 機能ロジック
devkit_frmMoveSetup.frm + .frx セットアップダイアログ
devkit_frmMoveWait.frm + .frx 記録中ダイアログ
devkit_frmInstruction.frm + .frx 結果・インポートダイアログ(InsertDeleteと共用)

エントリポイント:ShowMoveSetupForm


第4章 ランチャーと多言語化

ランチャー:操作の入口を一本化

オプション機能が増えてくると、それぞれのエントリポイントをVBEのマクロ一覧から探して実行するのが面倒になります。devkit_frmLauncher はインポート・エクスポートの全操作と InsertDelete・Move を一箇所にまとめたダイアログです。

xlsm_devkitのランチャー

扱える操作はつぎの通りです。

操作 内容
全モジュール・フォーム・シートマップをエクスポート src/sheet/ にまとめて書き出す
全モジュール・フォーム・シートマップをインポート src/sheet/ からまとめて読み込む
モジュール・フォームのみ エクスポート / インポート シートマップは操作しない
シートマップのみ エクスポート / インポート コードは操作しない
挿入・削除 InsertDeleteモジュールが読み込まれている場合のみ表示
セル移動 Moveモジュールが読み込まれている場合のみ表示
ファイル 役割
devkit_Launch.bas 機能ロジック
devkit_frmLauncher.frm + .frx ランチャーダイアログ

エントリポイント:ShowLauncherForm

多言語化(i18n):27言語対応

各ダイアログに表示されるテキストは、INIベースの言語ファイルでローカライズしています。lang/ フォルダをブックと同じ場所に置くだけで有効になります。

lang/
  ja.ini      ← 日本語
  en.ini      ← English
  zh-CN.ini   ← 简体中文
  zh-TW.ini   ← 繁體中文
  ko.ini      ← 한국어
  de.ini      ← Deutsch
  fr.ini      ← Français
  ar.ini      ← العربية
  ...(全27言語)

使用言語はWindowsのロケール設定から自動検出されます。ランチャー上部の言語セレクターで手動切り替えも可能です。コードから直接指定することもできます。

SetLang "ja"   ' 日本語に固定
SetLang ""     ' システム設定に戻す

i18n関数(T(key)Fmt(template, args…)SetLang())は xlsm_devkit.bas 本体に組み込まれており、追加モジュールは不要です。

誰しも UI を自分のよく知る言語で使いたいのは同じです。各言語のテキストが簡単に用意できるのであれば対応しない理由はないだろうと考えて用意しました。

ただ、 VBA の UserForm は .NET の WinForms アプリなどと違って RTL レイアウト(アラビア語などの様に右から左の順(RTL, Right To Left)に読む言語に合わせた UI 部品の配置変更)の機能を持っていません。それでも大きな違和感なく使えるように、フォームを縦長にし、ボタンを横長にして左右ではなく上下に並べるというレイアウトにしました。


まとめ

今回追加した機能を整理します。

機能 内容 バージョン
InsertDelete 行・列の挿入削除 → AIプロンプト自動生成 v1.3.0
Move セル範囲の移動(マクロ記録方式)→ AIプロンプト自動生成 v1.3.0
ランチャー 全操作を一箇所に集約したダイアログ v1.3.0 → v1.4.0で強化
多言語化(i18n) INIベース・27言語・Windows自動検出 v1.4.0

xlsm_devkit は GitHub で公開しています。

https://github.com/minipoisson/xlsm_devkit


シリーズ

脚注
  1. 現場側の視点については「技術的ヒエラルキーの心理学」「技術的負債という欺瞞」も合わせてご覧ください。 ↩︎

Discussion