TL;DR
- Excel VBA は IDE が古く外部から触りにくいので、Claude Code のような AI コーディングツールと相性が悪い……はずだった
- Python(
win32com)で VBE をプロシージャ単位で読み書きする CLI を作り、Claude Code から VBA を直接編集できるようにした -
.basファイルの CP932 罠(Claude が UTF-8 で書いて文字化けさせる事故)を、Claude Code の Skills 機能 にルールとして焼き込んで完全に封じた - 結果、「
F_Calendarの前へボタンを左に5px寄せて」みたいな会話だけで VBA が直る環境ができた
ターゲット:Excel VBA で社内ツールを作っていて、AI で開発を爆速化したい人。
ツールキットは GitHub に公開しています:
https://github.com/shu1551/shu-vba-manager
動機:VBA は AI と組み合わせづらい
私は 秀.xlsm という Excel アドイン(標準モジュール shu001 にマクロを足すだけで、フォームのメニューに自動で並ぶフレームワーク)を個人で育てています。
ところが VBA 開発は AI 支援を入れにくい。理由は3つ:
-
VBE(VBA エディタ)が外部編集しにくい
.xlsmの中に閉じていて、ファイルとして Git に乗せにくい -
.basエクスポートは CP932(Shift-JIS)固定
AI のエディタは UTF-8 前提なので、日本語識別子・コメントを片っ端から文字化けさせる -
VBE は Attribute 行(ショートカットキー定義等)を勝手に書き換える
AddFromStringで流し込むと壊れるケースがある
要するに、Claude Code に .bas を Edit させると 一発でモジュールが破壊される。
これを解決したら、VBA × AI コーディングはむちゃくちゃ強くなるはず、と思ってやってみました。
アーキテクチャ
┌─────────────────────────────┐
│ Claude Code(CLI / 会話) │
└──────────────┬──────────────┘
│ 会話で指示
▼
┌─────────────────────────────┐
│ shu-addin-manager Skill │ ← ルール集(CP932厳守、手順、コマンド一覧)
└──────────────┬──────────────┘
│ 規定の手順で呼ぶ
▼
┌─────────────────────────────┐
│ vba_manager.py │ ← Python CLI
│ form_builder.py │
└──────────────┬──────────────┘
│ win32com.client
▼
┌─────────────────────────────┐
│ Excel + VBE(秀.xlsm) │
└─────────────────────────────┘
ポイントは Skills 層 を挟んだこと。後述しますが、これがないと毎回事故ります。
1. vba_manager.py:プロシージャ単位で読み書きする CLI
VBA を「ファイル単位」じゃなく「Sub 単位」で扱える CLI を Python で作りました。Claude が 1個の Sub だけ取り出して修正して戻す、という小さな単位で動けるのが肝。
# マクロ一覧
py vba_manager.py list
# プロシージャを取り出す → _last_proc.vba(UTF-8)に保存
py vba_manager.py get カレンダー表示
# Claude は _last_proc.vba を Read → Edit → 保存
# 編集後の _last_proc.vba でプロシージャを置換(バックアップ自動取得)
py vba_manager.py replace-procedure
中身は win32com.client で Excel.Application をつかみ、VBProject.VBComponents(...).CodeModule を Lines() / DeleteLines() / InsertLines() で操作するだけ。シンプルですが、「アクティブな Excel ブックを自動検出」「同名プロシージャ複数ある時はモジュール指定」「自動バックアップ」 あたりを地味に作り込むと、Claude からほぼ事故らず使えるようになります。
def get_workbook(target_file_arg=None):
if not target_file_arg:
xl = win32com.client.GetActiveObject("Excel.Application")
wb = xl.ActiveWorkbook
print(f"対象ブック: {wb.Name} (アクティブブック自動検出)")
return xl, wb
# ...
get の出力先を _last_proc.vba という固定ファイル名にしておくのもコツ。Claude が 「直前に取得した Sub」をファイル名を覚えずに編集できる。replace-procedure 側も引数なしで同じファイルを読みに行く。
2. CP932 の罠と、Skill によるルールの永続化
ここが今回の記事で一番伝えたい話です。
何度も繰り返す事故
.bas を Claude に Edit で直接修正させると、保存時に UTF-8 になる。これを VBE にインポートすると、
Sub ƒJƒŒƒ"ƒ_[•\ަ()
みたいに日本語識別子もコメントも全部死にます。モジュール名まで化けるので最悪。
最初は CLAUDE.md(プロジェクト指示)に「.bas に Edit/Write 使うな」と書いていました。でも事故りました。 何度も。理由は単純で、CLAUDE.md は会話の冒頭に1回だけ流れる「お願い」レベルの強度しかなく、Claude は熱中するとうっかり破ります。
Skills 機能でルールを「ツール側」に持たせる
Claude Code の Skills は、特定のキーワード(「秀」「マクロ」「shu001」など)に反応して自動的にロードされるルール集です。CLAUDE.md より強い、かつ呼び出しタイミングが明示的。
~/.claude/skills/shu-addin-manager/SKILL.md にこう書いておきます:
---
name: shu-addin-manager
description: |
秀.xlsm のマクロ追加・修正・管理を行うスキル。
このスキルは以下のときに必ず使うこと:
- ユーザーが「秀」「アドイン」「shu001」に言及したとき
- 「マクロを追加して」「マクロを修正して」などVBAアドイン関連の作業
---
## 絶対に守るべきルール
⚠ .bas ファイルに Edit ツール・Write ツールを絶対に使うな ⚠
Claude の Edit / Write ツールは UTF-8 で書き込むため、
CP932 の .bas ファイルが破壊される。
.bas ファイルを修正するときは必ず以下のいずれかを使うこと:
1. Python で CP932 のまま読み書き
2. _last_proc.vba 経由で replace-procedure
これを入れてから事故が ゼロ になりました。
ポイントは「ルールを Claude のメモリに置く」のではなく、「ツール(Skill)を呼ぶこと自体を強制し、その Skill の中にルールが書いてある」 という構造にしたこと。CLAUDE.md と Skills は似ているようで、強度と呼び出しタイミングが違う。これは VBA に限らず、AI コーディング全般で効くパターンだと思います。
3. form_builder.py:UserForm も Python から組み立てる
VBA で一番だるいのが UserForm のデザイン作業です。GUI でちまちまボタン置いていくやつ。
これも win32com で Designer.Controls.Add を叩けば全部 Python から作れます。
from form_builder import FormBuilder, add_btn, add_lbl, add_txt, add_lst
with FormBuilder.connect() as fb: # アクティブブックに接続
frm = fb.get_or_create("F_Calendar", caption="カレンダー", width=300, height=240)
f = fb.clear_controls(frm)
add_lbl(f, "lblYM", "2026年5月", 10, 10, 100, 18)
add_btn(f, "btnPrev", "<", 120, 10, 30, 20)
add_btn(f, "btnNext", ">", 160, 10, 30, 20)
add_lst(f, "ListBox1", 10, 40, 280, 180)
fb.inject_vba(frm, "_calendar_code.vba") # イベントコードを注入
fb.save()
Claude にこう頼むだけで上のスクリプトを書いてくれます:
「F_Calendar フォームに前月/次月ボタンを付けて、日付一覧の ListBox を貼って」
人間がやると30分かかるレイアウト調整が、会話 → 実行 → 微調整 → 完成、で5分です。
4. 実際の開発フロー
会話だけで shu001.bas の「カレンダー表示」マクロを直すケース:
私: 「カレンダー表示が祝日を赤くしてないので直して」
Claude:
1. py vba_manager.py list # 一覧確認
2. py vba_manager.py get カレンダー表示 # _last_proc.vba に保存
3. Read _last_proc.vba # 中身を確認
4. Edit _last_proc.vba # 祝日判定を追加
5. py vba_manager.py replace-procedure # 適用(バックアップ自動)
→ 「適用しました。Excel で動作確認してください」
ポイント:
- Claude は
.xlsmに直接触らない。常に Excel 上の VBE 経由で操作するので、開いたまま編集できる - バックアップは
vba_manager.py側で自動取得。Skill 側で「失敗したら巻き戻し方」も教えてある - マクロ名は日本語のまま(
カレンダー表示)でいい。CP932 まわりを Skill が全部面倒見てくれる
5. やってみてわかったこと
効果
- VBA の編集時間がざっくり 1/5 になりました
- 特に UserForm の作り直しが激変。手で置くより速い
- 「ボタンのキャプションに状態を表示する」みたいな UX 改善が、思いついた瞬間に試せるようになった
落とし穴
-
win32comは Excel が応答待ちだと固まる。モーダルフォームが開いていたら閉じてから操作する必要がある -
replace-module(モジュール全体置換)は VBComponents の末尾に移動する副作用がある。マクロ表示順が変わるので、関連モジュールもまとめて差し替える必要あり - Attribute 行(ショートカットキー定義)は
AddFromStringだと欠落することがあるので、必ず Remove + Import 方式で
これらは全部 Skill の中に「落とし穴集」として書いてあります。運用知見を Skill に書き溜めると、未来の自分(と Claude)が同じミスをしなくなる。
まとめ
- Excel VBA × Claude Code は、Python の
win32comを間に挟む だけで一気に現実的になる -
.basを直接編集させず、プロシージャ単位 + 固定ファイル名 で受け渡すのが事故らないコツ - CLAUDE.md より Claude Code Skills にルールを書く方が遥かに強い。「ツールを呼ぶこと自体を強制する」構造がポイント
- UserForm すら Python から組めるので、VBA で一番だるい部分が消える
社内に「Excel VBA で作られた野良ツール」が積み上がっている方は、この構成試す価値あると思います。同じような環境を組んでる方いたらコメントで教えてください。
リポジトリ:https://github.com/shu1551/shu-vba-manager
ユーチューブ:
https://www.youtube.com/@%E3%81%97%E3%82%85%E3%81%86-v2w
動作環境:Windows 11, Excel 365, Python 3.11, pywin32, Claude Code