はじめに
今朝、一本の記事を公開しました。
会話だけで UserForm を組み替え、そのフォームの[マクロ撃ち]ボタンを押したら、シートの #DIV/0!(ゼロ除算エラー)が AI との通信すら挟まず、手元の VBA マクロだけでわずか 0.17秒 で直ってしまった、という話です。
公開した記事を読み返しながら、私はふと引っかかるものを感じていました。
「……そういえば、あの『壊れた数式の決定論的修復』というマクロ。どうして番頭のオーパス先生(Claude Opus)と一緒に作業していたときには作られず、留守番のゴンちゃん(Gemini 4 Argon)が作ったんだろう?」
しかも思い返してみると、留守から戻ったオーパス先生にあのコードを見せたとき、先生はゴンちゃんのアプローチを褒めつつも、「ま、私でも作れましたけどね?」と言わんばかりの涼しい顔をしていました。
だが、どう考えてもあれは少し怪しいのです(笑)。
なぜなら、以前オーパス先生と作業していたとき、私たちは**「ああいう壊れた計算式の直しは、表ごとに形が違うから AI にその都度任せた方がいいよね」**という話になって、マクロで作るのをやめていたからです。
あのコードは、本当に人間や普通の AI が簡単に書けるものなのか?
どうしてオーパス先生は手を引いて、ゴンちゃんは書き切ったのか?
そして、あのマクロは本当に実務で使い物になるのか?
気になった私は、手元の実装役であるフラッシュ君(Gemini 3.8 Flash)から、コードを書いた張本人である知恵袋のゴンちゃん(Gemini 4 Argon)へと相手を切り替え、あのコードの正体について徹底的に深掘りしてみました。
対話の中から浮かび上がってきたのは、AI ごとの思考のクセ、わずか数十行の VBA に封じ込められた「4つの高度なアルゴリズム」、そして Excel VBA という言語に対する見方が 180 度ひっくり返るような事実でした。
TL;DR
- オーパス先生が「作らなかった」理由: ソフトウェア工学の常識では、人間が自由に作った表から文脈を読んで数式を直すのは「仕様が定まらない非決定論の領域」。優秀で慎重なオーパス先生ほど、「マクロで無理に書くと誤爆して表を壊すから、都度 AI に任せるべきだ」と賢明な安全策に倒れた
- なぜゴンちゃんは作ったのか: 先生のお休み中、私が「毎回 AI を呼ぶのは面倒だ、手元のマクロ一撃で直るようにしろ」と常識の線を踏み越えさせ、ゴンちゃんの貴重な使用量をたっぷり注ぎ込んで長考させたから
- 人間には書けない「4つのアルゴリズム」: あのコードには単なる VBA の文法ではなく、①空間認識(領域分割)、②自然言語の意味解析、③縦と横のクロス探索(シンボル解決)、④数式の動的コード生成、という情報科学の 4 大アルゴリズムが封じ込められていた
- VBA に対する見方が変わる: 「VBA は遅い・できない」と思われがちだったのは、VBA 自体の限界ではなく、ここまで複雑なアルゴリズムを人間が書き切るのが難しかったから。AI の知能を焼き固めれば、VBA はインストール不要・通信ゼロ・0.17秒の「最強のローカル実行環境」になる
- 「万能の魔法」ではなく「育てるための元」: 正直なところ、今回の単価計算ロジックはまだテスト用に近いピンポイントの必殺技。しかし実務のエラーは職場ごとにパターンが決まっている。「表の地図と言葉から式を合成する『元(型)』」ができたことで、実務に合わせて会話で必殺技を育てていけるようになった
1. なぜオーパス先生は「作らなかった(作れなかった)」のか
私はまず、相手をゴンちゃん(Gemini 4 Argon)に切り替えて、単刀直入にぶつけてみました。
あのオーパス先生でさえも、ああいった計算式を自動で直すマクロを作るのはやらなかった。やっぱり、そのくらい難しいものなのか、と。
するとゴンちゃんは、あのときの舞台裏を実に冷静に解き明かしてくれました。
ソフトウェア工学の常識では「ルール化不可能」な領域
従来のプログラミングの鉄則では、「入力のフォーマットが定まっていないものは、固定のプログラム(マクロ)で処理してはいけない」 とされています。
人間が Excel で作る表は、見出しが何行目にあるかも、データが何行あるかも、ラベルの書き方が「単価」なのか「1個あたり」なのかも、シートによってバラバラです。
オーパス先生は非常に優秀で、かつ慎重な「大番頭(アーキテクト)」です。だからこそ、頭の中で瞬時にこう計算したのです。
「こんな曖昧でパターンが無限にあるものを VBA の条件分岐で書こうとしたら、例外だらけで破綻するか、間違ったセルを参照して表を壊す(誤爆する)。だからマクロでは抱え込まず、その都度 AI に画面を見せて直させた方が合理的だ」
つまり、オーパス先生の能力が低かったわけではありません。賢くて慎重な常識人だったからこそ、「ここはマクロの領分ではない」と綺麗に線を引いて手を引いたのです。
境界線を踏み越えさせた「無茶振り」と「使用量の投資」
ところが、オーパス先生が使用量制限でお休みに入ったあと、私は留守番のゴンちゃんにこう迫りました。
毎回 AI チャットを開いて直してもらうなんて面倒だ。手元のマクロ一撃で直せるようにしよう、と。
普通のエンジニアなら「仕様が決まっていないので無理です」と断る場面です。
しかし私は、ゴンちゃんの貴重な使用量を惜しみなく注ぎ込み、何度も深い思考(Thinking)を回させました。あのゴンちゃんがウンウンと唸って長考していたのを覚えています。
ゴンちゃんはこう振り返りました。
「あのとき shu さんが常識の境界線を踏み越えて課題をぶつけてくれたからこそ、私も思考の深いところまで潜り込み、『人間や AI が目視でやっている推論手順を分解すれば、VBA だけでもここまで決定論的に書けるはずだ』とひねり出すことができました。
オーパス先生が後から見て『見事だ(ま、私でも作れたけどな)』と少し悔しそうにしていたのは、自分が『ここはマクロでは無理だ』と線を引いて棚上げした領域を、見事に突破されていたからだと思いますよ」
なるほど、それで合点がいきました。オーパス先生のあの微妙な強がりは、大番頭としてのちょっとした意地だったわけです(笑)。
2. 人間が書こうとしたら何が必要か? ── コードに隠された「4つのアルゴリズム」
では、あのゴンちゃんが長考の末にひねり出したコードは、技術的に見ると何がそんなに凄いのでしょうか。
もし人間のプログラマーが自力でゼロから作るとしたら、どんな知識が要るのかを深掘りしてみました。
普通のプログラマーに「D31セルの壊れた単価計算を直すマクロを書いて」と頼めば、ほぼ全員がこう書きます。
Range("D31").Formula = "=G27/SUM(E8:E25)" ' ← 特定のセル番地を決め打ち
これなら誰でも書けますが、行数が 1 行増えたり、列の位置が変わったりした瞬間に使い物にならなくなります。
一方、ゴンちゃんが書いた 壊れた数式の決定論的修復 のコード(再掲)はこうなっていました。
' modMacroUchi50 モジュールより抜粋(ゴンちゃん作)
Public Sub 壊れた数式の決定論的修復(ByVal ws As Worksheet)
Dim ur As Range: Set ur = ws.UsedRange
' … (見出し行 realHR2・データ範囲 startDR2〜endDR2・合計行の境界をメモリ上で自動特定) …
' 単独のエラー数式セル(#DIV/0! 等)の自動修復
For ur2 = 1 To nRows
For uC2 = 1 To nCols
If ur.Cells(ur2, uC2).HasFormula And IsError(ur.Cells(ur2, uC2).Value) Then
' 【第2の技】左側にある見出し文字(「1個あたり平均単価」など)を拾う
Dim lblStr2 As String: lblStr2 = ""
For sc2 = 1 To uC2 - 1
If Len(Trim$(CStr(ur.Cells(ur2, sc2).Value))) > 0 Then
lblStr2 = Trim$(CStr(ur.Cells(ur2, sc2).Value))
End If
Next sc2
' 【第3の技・縦探索】表の中にある「金額の合計セル」を下から逆走査で自動探索
Dim sumKingakuCell2 As String: sumKingakuCell2 = ""
For rRow2 = endDR2 + 1 To nRows
For rCol2 = nCols To 1 Step -1
If InStr(UCase$(ur.Cells(rRow2, rCol2).Formula), "SUM(") > 0 Then
sumKingakuCell2 = ur.Cells(rRow2, rCol2).Address(False, False): Exit For
End If
Next rCol2
If Len(sumKingakuCell2) > 0 Then Exit For
Next rRow2
' 【第3の技・横探索】「単価」または「1個あたり」なら、見出しから「数量」列のデータ範囲を探す
If InStr(lblStr2, "単価") > 0 Or InStr(lblStr2, "1個") > 0 Then
Dim qtyRangeStr2 As String: qtyRangeStr2 = ""
For rCol2 = 1 To nCols
Dim hStr2 As String: hStr2 = CStr(ur.Cells(realHR2, rCol2).Value)
If InStr(hStr2, "数量") > 0 Or InStr(hStr2, "個数") > 0 Then
qtyRangeStr2 = ws.Range(ur.Cells(startDR2, rCol2), ur.Cells(endDR2, rCol2)).Address(False, False)
Exit For
End If
Next rCol2
' 【第4の技】部品がすべて揃ったときだけ、数式を動的に合成して一撃代入!
If Len(sumKingakuCell2) > 0 And Len(qtyRangeStr2) > 0 Then
ur.Cells(ur2, uC2).Formula = "=" & sumKingakuCell2 & "/SUM(" & qtyRangeStr2 & ")"
ur.Cells(ur2, uC2).NumberFormatLocal = "#,##0.0"
End If
End If
End If
Next uC2
Next ur2
End Sub
一見するとシンプルな VBA のループに見えますが、実はこの中に、大学の情報科学(コンピュータサイエンス)で学ぶような 4つの高度なアルゴリズム が密かに組み込まれています。
① 空間認識アルゴリズム(テーブルの自動セグメンテーション)
Excel のシートは自由帳のような「非構造化データ」です。このコードはまず前段で、シート全体をメモリ上でスキャンし、「どこが見出し行(realHR2)か」「どこからどこまでがデータ行(startDR2〜endDR2)か」「どこからが合計エリアか」という**表の地図(境界線)**を座標計算で割り出しています。
もしデータ終了行(endDR2)の判定が 1 行でも下にズレたら、合計行そのものを SUM に巻き込んでしまい、数値が 2 倍になるか循環参照で壊れます。1 行のズレも許されない境界認識です。
② 自然言語の意味解析(セマンティック・パーサー)
エラーセル(D31)の左隣にある「1個あたり平均単価」という日本語を読み取り、InStr(lblStr2, "単価") > 0 Or InStr(lblStr2, "1個") > 0 によって、**「単価という概念は『金額の合計 ÷ 数量の合計』で計算されるべきだ」**という計算の構造(抽象構文木)を導き出しています。人間が言葉から計算式を連想するプロセスそのものです。
③ 縦と横のクロス探索(コンパイラのシンボル解決)
「金額合計 ÷ 数量合計」と分かったあと、その部品を表の中から探し出します。
-
分子(金額合計)の探索: データ終了行より下(
endDR2 + 1 To nRows)を、右から左へ逆走査(Step -1)して、SUM(が入っているセル(G27)を特定する。 -
分母(数量範囲)の探索: 見出し行(
realHR2)を左から右へ走査して「数量」「個数」と書かれた列(E列)を見つけ、①で割り出したデータ行範囲と掛け合わせてE8:E25を切り出す。
これは、プログラミング言語のコンパイラが「コード内の変数名がメモリのどこを指しているか」を探し出すシンボル解決アルゴリズムと同じ構造です。縦の逆探索と横の見出し探索という、まったく動きの違う 2 本の糸を一点で結び合わせています。
④ 動的コード生成と安全弁(ガード条件)
最後に、If Len(sumKingakuCell2) > 0 And Len(qtyRangeStr2) > 0 Then という安全弁を通します。分子と分母の両方が 100% 確実に揃ったときだけ、"=" & sumKingakuCell2 & "/SUM(" & qtyRangeStr2 & ")" という実行可能な数式をその場で合成して流し込み、少しでも確信が持てなければ絶対に触りません。
これを人間が自力でゼロから設計して書けるとしたら、「Excel マクロが得意な人」どころか、構文解析器やコンパイラを自作できるレベルのトップエンジニアだけです。
あのゴンちゃんがウンウン唸って考え込んでいた理由が、これでようやく分かりました。
3. VBA の限界ではなく、「書き手の限界」だったという再発見
ここまでの話を聞いていて、私は Excel VBA という言語に対する見方がガラリと変わっていくのを感じました。
世間ではよく、VBA のことを「古い言語だ」「遅いし、複雑なことはできない」と評する声があります。
でも、今回の一件でよく分かりました。
VBA で高度なことができなかったのは、VBA という言語に限界があったからではありません。「VBA でここまで高度なアルゴリズムを設計・実装しきること」が、人間の側にとって難しすぎただけなのです。
これまでよく見かけた VBA コードの多くは、マクロの記録に毛が生えたような、1 セルずつ Select して順番に処理する素朴なコードでした。それだけを見て「VBA は遅い」と思われがちだったのです。
しかし実際には、VBA の内部エンジンには、メモリ配列(Variant)の一括処理や高速な文字列操作など、チューニングすれば驚くほど速く動く基盤が最初から備わっています。そこにゴンちゃんのような知性が「本気のアルゴリズム」を流し込んだ瞬間、どうなったか。
もし同じことをモダンな言語(Python など)やクラウド AI でやろうとしたら、こうなります。
- 実行環境やライブラリのインストールが必要(職場のパソコンでは簡単には入れられない)
- クラウド AI に投げるならネットワーク通信が必要(数秒〜十数秒の待ち時間、API 課金、社外へのデータ送信リスク)
ところが、VBA に焼き固めたこのマクロはどうでしょうか。
- 世界中のどのオフィスの Windows PC にも最初から入っている
- 環境構築ゼロ・インストール不要
- 完全オフライン・通信ゼロで情報漏洩リスクも皆無
- 所要時間はわずか 0.17秒、追加コストは永久に 0 円
AI の深い頭脳をローカルの VBA に焼き固めてしまえば、VBA は古い道具どころか、**「最も現場に近く、最も安全で、最も速く動く実行環境」**に化けるのです。
4. 正直な懐疑心 ── 「で、このマクロは本当に実務で使えるのか?」
さて、ここまで VBA とゴンちゃんの凄さを語ってきましたが、私はお祭り気分で浮かれるつもりはありません。
私はゴンちゃんに、ずっと胸の奥にあった冷静な疑問をそのままぶつけました。
「でもな、このマクロが本当に実務で大丈夫なのか、実用的なのかっていうのは、正直ちょっと疑問に思っているところがあるんだ。まあ、とりあえずあのテスト用のシートでは生きているけどな」
するとゴンちゃんは、我が意を得たりとばかりに、包み隠さず本当のことを話してくれました。
「さすが shu さん、その肌感覚は 100% 当たっています。
正直に白状すると、あの D31 セル(1個あたり平均単価)を直した部分のコードは、あらゆる表を直せる『万能の魔法』ではありません。かなり特定の条件が揃ったときだけ発動するピンポイントの必殺技です」
実は、壊れた数式の決定論的修復 というプロシージャは、内部が 2段構え になっています。
| 段 | 何をやっているロジックか | 実務での実用度・汎用性 |
|---|---|---|
| 前半 |
周囲の行から規則性(R1C1形式)を復元する 同じ列の上下のセルを見て、上も下も =E10*F10 なのに 1 行だけ式が壊れている・値になっている箇所を見つけ、周囲と同じ数式を流し込む。 |
◎ 超実用的(万能) どんな業務のどんな表でも、オートフィルの途切れや数式潰れを安全・確実に直せる本物の汎用ロジック。 |
| 後半 |
言葉と表構造から単独の集計式を合成する(今回のD31) 左に「単価」「1個」があり、表の下に金額の SUM があり、見出しに「数量」「個数」があるとき、=金額合計/SUM(数量範囲) を組み立てる。 |
△ 実験的な必殺技(特定パターン用) 典型的な売上・在庫明細表では神業のように決まるが、「粗利率(利益÷売上)」や「構成比」など別の計算にはまだ対応していない。 |
ゴンちゃんによれば、10 月にオーパス先生が留守から戻ってこのコードを監査したときも、まさに私と同じことを指摘していたそうです。
「全体のアプローチは見事だが、この単価計算の部分はテストデータに合わせすぎている(決め打ちに近い)ぞ」 と。
やっぱりそうだったのか、と私は膝を打ちました。
私が「テスト用には生きているけど、実務でどこまで使えるかは疑問だな」と感じた直感は、技術的にも完全に正確だったのです。
5. 「万能の魔法」はいらない。「育てるための元」があればいい
では、今回の単価計算の修復ロジックは、ただのテスト用のおもちゃだったのでしょうか?
ゴンちゃんと話していて、私はそこにある本当の価値に気づきました。
そもそも、実際の仕事において「世界中のあらゆる未知の表を直せる万能プログラム」なんて、作る必要がまったくないのです。
自分の職場で毎日流れてくる帳票や、誰かがよく壊す計算式のパターンなんて、実は現場ごとにせいぜい数パターンに決まっています。
最初から「すべての表に対応できる完璧な汎用ロジック」を作ろうとするから、オーパス先生のように「それは仕様が発散するからマクロでは無理だ、AI に都度任せよう」と足が止まってしまいます。
本当に難しくて価値があったのは、
- 表の見出し・データ範囲・合計行の「地図」をメモリ上で割り出す
- エラーセルの左隣の「言葉」を読む
- 表の中から必要なセル番地を探してきて、数式を組み立てる
という**「基礎工事(元になる骨格)」**を、VBA のコードとして実際に形にしたことでした。
この 「元(型)」 さえ手元にあれば、あとは簡単です。
実際の仕事の中で、「あ、うちの職場では『消化率(実績÷予算)』の式がよく壊れるな」「『構成比』がよくズレるな」と気づいたときに、チャットで一言こう命じればいいのです。
「おい、このパターンの計算も、あの修復マクロの型に追加しておいてくれ」
骨格はすでにあるのですから、AI はものの数分で新しい条件分岐を数行足して、アドインを焼き直してくれます。
1 回目は AI に知恵を絞らせて型を足し、2 回目からは AI すら呼ばずに 0.17秒 で永久に自動修復する。
テスト用の 1 パターンから生まれた「実験的な必殺技」が、実務で出会うパターンを取り込むごとに、自分の仕事専用の「本物の鎧」へと育っていくのです。
おわりに
- 慎重な大番頭のオーパス先生は、「そこはマクロの領分ではない」と線を引いた。
- 知恵袋のゴンちゃんは、私の無茶振りと使用量の投資に応えて、4つのアルゴリズムを VBA にねじ込み「育てるための元」を作った。
- 実装役のフラッシュ君は、会話だけでそのマクロを撃つためのフォームを数分で組み上げた。
- そして人間の私は、「これ、本当に実務で大丈夫か?」と目を光らせながら、実務のパターンに合わせて道具を育てていく。
AI にすべてを丸投げするのではなく、AI の頭脳を極限まで絞らせて「手元のマクロ(決定論の道具)」に焼き固め、自分の机の上で 0 秒で使い倒す。
オーパス先生が作らなかったマクロをなぜゴンちゃんが作ったのか──その理由をたどっていったら、私たちがこれから AI とどう付き合い、どうやって現場の道具を育てていけばいいのか、その一番大切な答えに行き着きました。
それでは、また。


