はじめに
七月に、ハルミさんという方のことを書きました。VBA を Git とテストに乗せて AI に育てさせる道具 xlflow を作っている方です。
八月には、その方が「Excel の中にいたまま外と話す」部品を出した話を書きました。仲間ができた、という記事です。
先日、五十日ぶりに、ハルミさんの道具箱──xlflow のリポジトリ──を開きました。
別物になっていました。
七月八日に私が実機で触ったとき、xlflow は v0.19.0 でした。いまは v0.31.0。五十日でマイナー版が12本。静的解析の規則を数えてもらったら、117本ありました。うちの自作ツールの診断は、7本です。
7対117。ツールとしては、負けています。
今日はその負けっぷりの中身と、負けた相手の棚から4本もらってきた話です。
TL;DR
- 五十日ぶりに見た xlflow は v0.19.0 → v0.31.0。マイナー版12本、静的解析の規則は117本。しかも VBA の文法定義(tree-sitter-vba)まで自作していました──こちらは星ゼロのリポジトリです
- うちの VBAマネージャーの診断は 7本でした。7対117。静的解析の物量では、はっきり負けています
- その117本から、4本もらいました。選んだ基準は一つ──**「走らせても出ない」欠陥**を見ているものだけ
- 規則だけでなくコマンドも5本輸入しました(81→86)。テストを22本足して155本通過、その日のうちに公開済みです
- 突き合わせて分かったのは、別々に作ってきた二つの道具に、同じ器官が生えていたこと。秘密の検出、呼び出し関係の地図、機械の関所──打ち合わせは一度もしていません
- それでも向きは逆のままです。あちらはコピーを検査する。うちは開いているブックに相乗りする。「今このブックを、今直す」は、まだうちにしかありません
五十日で、マイナー12本
まず、驚いた側の話をします。
七月八日に xlflow を winget で入れて、自分の道具と並べて実機で比べたことがあります。そのときの版が v0.19.0 でした。それから八月二十六日の v0.31.0 まで、リリースの一覧を数えてもらったら、マイナー版が12本、修正版が4本。週に一本を超える速度です。リポジトリには、この記事を書いている日にも push が入っていました。
中身も、ただ数が増えたのではありません。増え方に向きがあります。
- 静的解析の規則が117本(構文寄りの lint が62本、実行時の危険を見る analyze が55本)。Dictionary の使い方の間違い、エラー処理の漏れ、Excel の API の「お約束」を破っていないか、状態を変えたまま戻していないか、そしてコードに書き込まれた API キーの検出まで
- Call Hierarchy(このマクロを呼んでいるのは誰か、を編集画面から辿る機能)が v0.27.0 で入りました
- v0.29.0 で巨大モジュール向けの増分診断、v0.31.0 で高速化。──遅さが問題になるのは、それだけ使い込まれている証拠です
- UserForm を YAML の設計図で持ち、エディタが設計図の補完と検査までする。実行中のフォームを PNG に撮る機能まであります
一つ一つが「作ってみた」の段ではなく、「毎日使っている人が、使いながら直している」順番で増えています。
星ゼロのリポジトリ
もっと驚いたのは、xlflow の隣にあったものです。
tree-sitter-vba。六月十三日生まれ、コミット124本、MIT ライセンス、npm に公開済み。そしてスターは、ゼロです。
これが何かというと、VBA の文法定義そのものです。.bas も .cls も .frm も読める「VBA の構文の地図」を、部品として書いている。リポジトリには検証用の実例ファイル──実物の .bas / .cls / .frm──が490本並んでいます。
なぜこれが重い工事なのか。診断も、補完も、呼び出し関係の地図も、突き詰めれば全部「VBA の構文を正確に読む土台」に行き着きます。その土台に既製品が無いなら、自分で書くしかない。ハルミさんはそれを実行しました。一番重くて、一番地味で、誰にも褒められない場所の工事です。星がゼロのまま、コミットだけが124本積んである。
私はこの連載で、道具は使われてこそ、と書いてきました。でも、誰も見ていない場所で土台を打つ人がいるから、上に道具が建ちます。117本の規則は、この土台の上に立っています。
ExStruct は、静かでした
ついでに書いておくと、ハルミさんのもう一つの代表作 ExStruct(いわゆる神エクセルを AI が読める形に畳む道具)は、五月十四日の v0.8.1 を最後に静かです。
これは衰えではなく、やり切って手が離れたように見えます。手が空いたから、xlflow の連打と文法の土台に全力が向かっている──そう読みました。ここは私の見立てです。
7対117
さて、こちら側です。
私の VBAマネージャーにも check という診断コマンドがあります。中身を数えると、こうです。
- SendKeys の使用
- On Error が無いプロシージャ
- Sub の閉じ忘れ
- Function の閉じ忘れ
- 未使用の変数
- プロシージャ名の重複
- Option Explicit の有無
以上、7本。向こうは117本。7対117です。
負けているのは数だけではありません。解析の土台が違います。うちの check は正規表現──つまり「文字の並びのパターン」でコードを舐めています。文字列の中のアポストロフィで行を見失う、といった罠を一つずつ避けながら書いてある。向こうは文法定義そのものを書いたので、その種の罠が構造的に起きない場所に立っています。エディタ支援(補完・型推論・リネーム)はうちには無く、配布は winget と Scoop に載っていて、スターは67。
ツールとしては、負けています。 これは強がりを混ぜずに、そのまま書いておきます。
うちの道具の本分は鍛冶場です。マクロを取ってきて、直して、即保存する。検査場ではありません。それでも、数字は数字です。
「走らせても出ない」ものだけ
負けを数えたあと、117本の一覧を眺めて、うちに入れるものを選びました。基準は一つです。
「走らせても出ない」欠陥を見ている規則だけ。
というのも、つい先日──八月二十六日に、手元で事故があったのです。開いていたブックのシートが、真っ黒になりました。犯人は Application.ScreenUpdating(画面の更新を止めるスイッチ)が False のまま残っていたこと。どれかの処理が画面を止めて、戻さずに終わっていた。
このとき、うちの check は 0件で通っています。走らせれば動くのです。動いた上で、あとから別の場所で牙を剥く。この種類の欠陥は、実行しても見えません。八月に作った関所(gate)も全体コンパイル(compile)も、狙っていたのは同じ場所でした。その経緯は先日の更新告知に書きました。
逆に、走らせれば分かるものは、10秒動かせば自分で気づきます。機械に見張らせる価値があるのは、走らせても出ないもののほうです。
117本にこの篩をかけて、4本もらいました。
| もらった規則 | 元(xlflow) | 見ているもの |
|---|---|---|
| VBM008 | VBA203 | Application の状態(ScreenUpdating 等)を変えたまま、戻していない |
| VBM009 | VBA221 | 呼んだ先のマクロが、状態を変えたまま返ってくる(プロシージャをまたぐ漏れ) |
| VBM010 | VBA240 | モジュール変数の書き手が、2か所以上に散っている |
| VBM011 | VBA215 | Find / Replace の引数省略──Excel は前回の検索設定を覚えていて、黙って引き継ぎます |
VBM008 は、まさに黒い画面の犯人を事前に名指しする規則です。VBA213(Dictionary)や VBA218(Excel API の失敗の受け方)などの番号は、xlflow の診断リファレンスにあります。
一つ、正直に書いておきます。もらったのは規則の考え方で、実装は自前の簡易版です。向こうの VBA203 は制御フローグラフで「すべての出口で元の値に戻ると証明できるか」まで見ます。うちの VBM008 は、変えた行と戻した行を数えるだけ。同じ名前を名乗るのが少し気恥ずかしいくらいの差があります。それでも、黒い画面のあの犯人は、これで捕まります。
当てた日の結果
入れた4本を、手元のブックのコピーに当てました。431プロシージャで5.0秒。結果はこうでした。
-
VBM011(Find の引数省略)──2か所。 どちらも
.Find(What:="…")だけで LookAt を省いていました。前回の検索ダイアログの設定しだいで挙動が変わる書き方です - VBM010(書き手が散っている)──3変数。 フォームのモジュール変数に、書き込むボタンが6か所・8か所というものがありました
- VBM008(状態の戻し忘れ)──0件。
最後の 0件には、おまけがあります。本当に0件なのか、規則が働いていないのか分からなかったので、ScreenUpdating への代入を grep で全部数えてもらいました。実物の代入は20か所、すべて False → True の対になっていました。規則が黙るのは、掃除が済んでいる証明でもある──0件にも意味がありました。
ついでに、コマンドも5本
規則を選んでいるうちに、規則ではないもので欲しいものが見つかったので、そちらも輸入しました。5本です。
- inspect-gui ── MsgBox・InputBox・ファイル選択ダイアログなど、自動操縦を止める場所を撃つ前に洗い出すコマンド。AI がマクロを走らせて黙って固まる原因の筆頭がこれです。手元のブック全体では237件出ましたが、マクロ名を渡すとそこから呼ばれる範囲だけに絞れて、対象のマクロでは2件でした
- capabilities ── 86本あるコマンドを「読むだけ/書き換える/消す・止める/任意コードを走らせる」の四つに仕分けした表。破壊的な操作を撃つ前に、機械が自分で照会できます
- rules ── 診断規則の一覧(この記事の7本→11本が、そのまま出ます)
- metrics ── どのプロシージャが重いかの順位表(行数・分岐・ネストの深さ)
- process ── Excel のプロセスの点呼。強制終了はブックを1冊も抱えていないプロセスだけに限定してあります。作業中の Excel を巻き込まないためです
コマンドは81本から86本になり、自動テストを22本足して155本、その日のうちに公開しました。
同じ器官が、別々に生えていた
さて、この作業の途中で、妙なことに気づきました。117本の一覧とうちの装備を突き合わせていると、同じものが両側にあるのです。
| ハルミさん側 | うち側 |
|---|---|
| VBA223 ── コードに埋まった秘密(API キー等)の検出 |
publish_check の秘密検査(公開前の関所) |
| Call Hierarchy ── 呼び出し関係を辿る |
call-graph / impact(影響範囲の予告) |
| 診断+コンパイル検査 |
gate(関所)+ compile(全体コンパイル) |
| AI エージェント用スキルの同梱 | 手順書(AI に渡す段取り書。先日の取材で Claude for Excel から輸入したもの) |
| validate → dry-run → apply の三段 |
rehearse(予行演習)+承認の関所 |
打ち合わせは一度もしていません。読者層も違います。向こうはエンジニアの道具で、うちは事務員の道具です。それなのに、秘密の検出も、呼び出しの地図も、機械の関所も、両側に生えている。しかも時期まで重なっていて、私が関所を作っていた八月の下旬に、向こうでは増分診断と高速化が出ています。
生き物の世界に、収斂進化という言葉があります。タコの目とヒトの目は、別々の系統で、別々に発明されました。作りはほとんど同じです。目が何度も発明されるのは、「見る」ことに価値がある証拠です。
同じ器官が、相談もなしに二つの工房で別々に生えたなら、それはこの場所──AI に VBA を書かせて、人が安心して受け取るという仕事──が本物である証拠だと、私は思っています。おまけに表の四段目の手順書は、Anthropic の Claude for Excel から輸入したものでした。数えてみれば、同じ器官が三か所で別々に生えていたことになります。
それでも、向きは逆のまま
では4本もらって、道具は似てきたのか。いいえ、向きは逆のままです。
七月八日に並べて触ったとき、一番はっきりした違いがこれでした。xlflow は、ブックのコピーを作ってコピーを操作します。開いている本番のブックには触らない。実行も既定では保存しません。だから安全に検査が回る。CI やテストの思想です。
うちの VBAマネージャーは、開いている本番のブックに相乗りします。書いたら即保存。だから「今、目の前で動かないこのマクロを、今直す」ができる。
ちなみにそのとき、同じお題のマクロを両方の道具で AI に作らせて、出てきた VBA を照合したことがあります。1バイト単位で同一でした。書いているのはどちらも AI なのだから、当然といえば当然です。記事には書かなかった手元の実験ですが、道具で変わるのはコードではなく、作る過程と思想のほうだと分かったのは、このときでした。
検査はあちらが上です。117本と7本──いえ、いまは11本ですが──の差は、これからも縮まらないと思います。それでも、「今このブックを、今直す」は、まだうちにしかありません。だから4本もらっても、道具は別物のままです。むしろ、別物のままでいるために、足りない器官だけをもらった──そういう買い物でした。
事実と見立ての仕分け
例によって仕分けます。
事実。 xlflow が七月八日時点で v0.19.0、八月二十六日に v0.31.0 になったこと、その間のマイナー版が12本であることは、リリース一覧の実数えです。診断規則117本(lint 62+analyze 55)は、公式ドキュメントの規則表と、リポジトリ内の規則台帳(registry.json)の両方を数えて一致を確認しました。tree-sitter-vba のコミット124本・スター0・実例ファイル490本、ExStruct の最新が五月十四日の v0.8.1 であることも、この記事を書いた日(八月二十八日)の実数えです。うちの側の数字──診断7本→11本、コマンド81本→86本、テスト155本通過、コピーへの適用結果(2か所・3変数・0件と grep での裏取り)──は同日の実測で、実装はその日のうちに GitHub に公開してあります。実装と検証は Claude(オーパス)が行い、公開のコミットはフェーブルが行いました。私は判断と、負けの宣言です。
一つ白状すると、この規則の総数を、作業中はしばらく 125本だと思い込んでいました。AI がドキュメントの要約を鵜呑みにした数字で、あとから表と台帳を実数えして117本と判明。公開したコードのコメントにまで混ざっていたので、訂正してもう一度公開する羽目になりました。数は、数えるまで信じてはいけません──自戒です。
見立て。 「ExStruct はやり切って手が離れた」は私の読みです。「高速化は使い込まれている証拠」も、リリースノートからの推測で、ハルミさんに聞いたわけではありません。「同じ器官が生えたのは分野が本物である証拠」も、私が引いた線です。
正直な線引き
- 117本のうち、私たちが中身まで検分したのは規則の一覧と数本の仕様書だけです。全部の規則を動かして試したわけではありません
- もらった4本は、上に書いたとおり自前の簡易版です。xlflow の本物と同じ強さではありません
- 静的解析を本気で使いたい方は、xlflow をそのまま使うのが早いです。winget で入ります。私も七月に入れて、実機で動くことを確かめています
- 4本と5本は、入れたばかりです。手元のテスト155本は通っていますが、実戦で育つかどうかはこれからです
- 数字はすべて八月二十八日時点です。あちらのリポジトリは週一本を超える速度で動いているので、この記事が公開される頃には古くなっているかもしれません
- 私の環境は Windows 11 と 64bit Excel、相棒は Claude Code です
おわりに
七月に、道の反対側から手を振ると書きました。八月に、隣から手を振りました。
今回は、隣の工房に道具を借りに行きました。棚には117本並んでいて、うちの籠に入れたのは4本。籠は小さいままでいい、と思える買い物でした。向こうは検査場を建て、うちは鍛冶場を守る。同じ器官を持った、別の生き物のままでいる。
借りたものは、まだ返せていません。
返せるものができたら、返しに行きます。


