0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

APIキーは、要らなかった ── ExcelのボタンひとつでAIチャットに仕事をさせた話

0
Posted at

はじめに

Excel から生成AI を呼ぶには、API キーが要る。

この連載でも、世の中の実装例でも、ずっとその前提で書いてきました。以前、VBA から生成AI を呼んでいる事例を世界中から探させたことがありますが、見つかったものはほぼ全部キー前提でした。

その前提が、崩れました。

前回、Windows に最初から入っている UI Automation という仕組みを PowerShell 越しに叩いて、Excel から他のソフトを名指しで操る話を書きました。

その道具を、三日後に別の相手へ向けてみました。相手は、ブラウザで開いている生成AI のチャット画面です。

結果から書きます。Excel でセルを選んでボタンを押すと、勝手にチャットが開いて、表が流し込まれて、検品結果が Excel のセルに帰ってきました。 API キーは1文字も使っていません。

TL;DR

  • Excel のボタン1つで、選択範囲を Markdown の表に荷造りし、ブラウザの AI チャットへ投げ、答えをセルに書き戻すところまで通りました。人間の手が動くのは、ボタンを押した一回だけです
  • 使ったのは VBA と PowerShell と Windows 標準の UI Automation とクリップボードだけ。API キーの発行も、契約の変更も、インストールも、管理者権限も要りません
  • 実測は、一言だけ返させる素の往復が3秒、表を渡して検品させて4.8秒。仕込んだ間違い3つを3つとも当てました
  • 頼んでいないのに、AI は自分で検算のコードを走らせていました。チャット版は素の API より賢いことがあります
  • 踏んだ罠は3つ。エンターでは送信されない/送信するとページが切り替わって掴んだ要素が抜け殻になる/回答の執筆中は UI Automation の探索が固まる
  • 橋がやっているのは「新しいチャットを開く・貼る・送信を押す・書き終わりを待つ・コピーを押す」だけなので、特定の AI 専用ではありません
  • 実験用です。公開の予定は今のところありません

使ってよい AI と、組み込める AI のあいだにある壁

まず、なぜこれをやろうと思ったかを書きます。

生成AI を業務の道具に組み込もうとすると、最初に API キーの話になります。キーを発行して、課金の設定をして、コードのどこかに置いて、漏れないように管理する。個人で遊ぶぶんには何ということもありませんが、これが組織の中だと急に重くなる。キーを発行できるかどうかは、たいてい使う人の側では決められません。

一方で、チャットのほうは事情が違います。「AI チャットは使ってよい」という職場は、いま急速に増えています。ブラウザで開いて、質問して、答えを読む。それは許されている。

つまり、使ってよい AI と、道具に組み込める AI のあいだに壁がありました。

鍵がない

正門には鍵がかかっている。鍵は自分では取れない。ところがふと横を見ると、毎日そこを通っている通用口がある。チャットの画面です。

前回作った道具は、まさに「画面の部品を名前で掴んで、押したり文字を入れたり読んだりする」ものでした。チャットの画面にも、入力欄があり、送信ボタンがあり、回答のコピーボタンがある。全部、名前のついた部品です。

なら、通れるはずでした。

橋の作り ── 四段

作ったものは単純です。四段しかありません。

  1. 荷造り ── マクロが選択範囲を Markdown の表に整形し、指示文と合体してファイルに書く
  2. 投げ込み ── PowerShell が新しいチャットを開き、貼り付けて、送信ボタンを押す
  3. 見張り ── 書き終わりを検知して、回答のコピーボタンを押す
  4. 書き戻し ── Excel がクリップボードを受け取って、セルに書く

VBA 側は、前回の記事に書いた四手とまったく同じ形です。

' (1)プロンプトをUTF-8でファイルに書き出す
' (2)PowerShellを画面なしで起動する。待たずに戻る
Set sh = CreateObject("WScript.Shell")
sh.Run "powershell -NoProfile -ExecutionPolicy Bypass " & _
       "-WindowStyle Hidden -File """ & psPath & """", 0, False

' (3)答えのファイルが出てくるまで、固まらずに待つ
開始 = Timer
Do
    DoEvents
    If Dir(ansPath) <> "" Then Exit Do
    If Timer - 開始 > 150 Then Exit Do
Loop

' (4)読み取って、セルに書く

CreateObject しか使っていません。参照設定はゼロ、Function も使わず Sub 一本です。呼ぶ相手が電卓から AI チャットに変わっただけで、器はそのままでした。

荷造り ── 何を渡すかは、受け取る側に聞く

面白かったのは、荷造りの設計です。

指示文だけ投げても、答えは薄くなります。「この表を検品して」と言われても、表が無ければ AI は何も見られません。かといって、シートの中身をそのまま貼ると読みにくい。

そこで、渡す形式を自分で決めずに、受け取る側に聞きました。 AI 自身に「Excel のシートを検品してもらうには、どういう形で渡すのが読みやすいか」と尋ねたわけです。返ってきた答えは Markdown の表でした。

実際にマクロが荷造りしたものが、これです。

あなたはExcelシートの検品係です。以下のシート抜粋(Markdown)を検査して、
おかしい点を箇条書きで簡潔に挙げてください。前置きと結びの文は不要です。

| 行 | 商品 | 単価 | 数量 | 金額 |
|---|---|---|---|---|
| 2 | りんご | 120 | 10 | 1200 |
| 3 | みかん | 80 | 20 | 1600 |
| 4 | ぶどう | 300 | 5 | 1400 |
| 5 | もも | 250 | -3 | -750 |
| 6 | なし | 150 |  | 0 |

補足: 金額 = 単価 × 数量 の想定です。

行番号を左端に付けているのがミソです。これがないと、AI が間違いを見つけても「ぶどうの行」としか言えません。行番号を添えておくと「4行目」と返ってくるので、受け取った側が場所を特定できます。

指示と一緒に、文脈を機械が自動で荷造りする。ここが効いていて、だからボタン1つで中身の濃い仕事が返ってきます。

実験 ── わざと三つ、間違いを仕込む

題材は検品にしました。果物の売上表を作って、わざと三つ間違いを混ぜます。

  • 4行目 ぶどう ── 金額の計算が合わない(300 × 5 は 1,500 のはずが 1,400)
  • 5行目 もも ── 数量がマイナス
  • 6行目 なし ── 数量が空欄

どれも人の目でなら見つかる間違いです。問題は、それを機械の手で渡して、機械の手で受け取れるかでした。

A1:E6 を選んでマクロを実行します。あとは何も触りません。

画面が勝手に動いて、ブラウザに新しいチャットが開き、表と指示が流し込まれ、送信ボタンが押されます。数秒待つと、Excel に戻ってきて、A8 に答えが入っていました。

三つとも当てて、頼んでいない検算までしていた

返ってきたものを、そのまま載せます。

* **4行目(ぶどう)**: 金額の計算結果が間違っています(正しくは 300 × 5 = 1,500)。
* **5行目(もも)**: 数量がマイナス(-3)になっており、金額もマイナスで計算されています。
* **6行目(なし)**: 数量が未入力(空欄)です。

三つとも当てました。

しかも、この箇条書きの前に、頼んでもいないものが付いていました。

Row 2: calc=1200, actual=1200
Row 3: calc=1600, actual=1600
Row 4: calc=1500, actual=1400
Row 5: calc=-750, actual=-750
Row 6: calc=N/A, actual=0

AI が自分で検算のコードを書いて走らせ、その出力を添えてきたのです。私が頼んだのは「おかしい点を箇条書きで」だけでした。

これはチャット版ならではのおまけだと思います。素の API を叩けば、モデルが文章を返すだけです。チャットの画面の向こうには、コードを実行する仕組みまで含めた一式が用意されている。同じ料金(つまり無料の範囲)で、そちらを使えるということになります。

答えを持ち帰る

踏んだ罠は、三つ

ここからが、この記事のいちばん実用的なところだと思います。素直には通りませんでした。

罠1 ── エンターでは、送信されないことがある

貼り付けたあと、キーボードのエンターを送れば送信されるはずでした。されません。文字は入っているのに、送られない。

チャットの入力欄は、エンターで改行する作りだったり、送信する作りだったり、状況によって変わります。キーを送るのは結局のところ盲打ちで、前回の記事で書いた弱点がそのまま出ました。

答えは単純でした。画面の送信ボタンを、名前で掴んで押す。

$send = Find-Buttons (Get-Doc) '^(送信|Send)$|プロンプトを送信|Send message' 'コピー|Copy'
Click-Element $send[-1]

ボタンの名前で探しているので、画面の見た目が多少変わっても効きます。日本語と英語の両方を候補に入れてあるのは、表示言語が変わったときの保険です。

罠2 ── 送信すると、掴んだ要素が抜け殻になる

送信した瞬間、ページが「新規チャット」から「会話中の画面」に切り替わります。すると、それまで掴んでいた画面の部品が中身のない抜け殻になります。触ろうとすると落ちる。

対策は、掴み直すことです。最初に窓のハンドル(窓そのものの番号)だけを覚えておいて、部品が要るたびにハンドルから掴み直す

function Get-Doc() {
  $w = [System.Windows.Automation.AutomationElement]::FromHandle($script:hwnd)
  $d = $w.FindFirst([TreeScope]::Descendants, $condDoc)
  if ($d) { return $d } else { return $w }
}

さらに「掴んでから押す」を一体にして、失敗したら掴み直してやり直す形にしました。掴んだ瞬間と押す瞬間のあいだにページが動くことがあるからです。

罠3 ── 回答を書いている最中は、画面の探索が固まる

これが一番の伏兵でした。

短い答えを返させる実験は通るのに、長い答えを返させるとプログラムごと止まる。原因は、回答の執筆中は画面が絶え間なく書き換わっていて、その最中に画面の部品を全部数えようとすると、探索が返ってこなくなることでした。

つまり「書き終わったか見に行く」という行為そのものが、書いている最中には成立しない。

解決は、力技です。見に行く係を使い捨ての子プロセスにして、10秒返事がなければ殺して、また撃つ。

$p = Start-Process powershell -ArgumentList @('-File','probe.ps1', ...) -PassThru -WindowStyle Hidden
if (-not $p.WaitForExit(10000)) {
    $p.Kill()          # 固まった=まだ執筆中とみなす
    continue           # 2秒待って、また撃つ
}

固まること自体を「まだ書いている」の合図として使う形になりました。行儀はよくありませんが、確実です。

見に行く係のほうは、画面のボタンを見て三つのうちどれかを返すだけの、20行ほどのものです。

# COPY=回答のコピーボタンあり(完成) / STOP=停止ボタンあり(執筆中) / NONE=どちらも無し
if ($n -match 'コピー|Copy' -and $n -notmatch 'コード|code|許可|プロンプト|翻訳') { $copy = $true }
if ($n -match '回答を停止|停止|Stop')  { $stop = $true }

生成中は送信ボタンが「停止」に変わり、書き終わると回答の下に「コピー」が現れる。画面が出している合図をそのまま読むわけです。文字数を数えて増えなくなったら完了、といった当て推量より、こちらのほうがずっと確実でした。

おまけの罠 ── Excel の裏から起動すると、窓を前に出せない

もう一つ。手で PowerShell を走らせると成功するのに、Excel のマクロから起動すると失敗する、という時期がありました。

原因は Windows の作法です。裏で起動されたプログラムには、窓を前面に出す権利がありません。 勝手に画面を奪うソフトを防ぐための仕組みで、正しい挙動です。

回避策は昔から知られているもので、Alt キーを一度押して離してから前面化を頼むと通ります。

[BridgeNative]::keybd_event(0x12, 0, 0, [UIntPtr]::Zero)   # Alt 押下
[BridgeNative]::keybd_event(0x12, 0, 2, [UIntPtr]::Zero)   # Alt 離す
[BridgeNative]::SetForegroundWindow($script:hwnd)

なお、この橋は失敗したら死因をそのまま答えのファイルに書いて帰る作りにしてあります。「送信ボタンを押せなかった」「窓を前面化できなかった」といった一行が Excel 側に返るので、黙って150秒待たされることがありません。エラーの通り道を作っておくのは、この手の道具では速さより先に効きます。

実測

計ったのは2本です。

実験 結果
素の往復(一言だけ返させる) 送信から3秒で回収
表を渡して検品させる 送信から4.8秒で回収・指摘3件中3件的中

いずれも送信を押してから、答えがファイルに落ちるまでの時間です。画面が前に出て、文字が流れて、コピーが押されるまで、人間は何もしていません。十秒かからずに、表の点検がひと回りします。

なお、この数字には新しいチャットを開いてページが読み込まれるまでの数秒は含みません。そこを入れると全体で十数秒です。

用意するものが、何もない

この実験でいちばんの値打ちは、速さではないと思っています。

用意するものが、何もないことです。

  • API キーの発行 ── 要らない
  • 契約の変更 ── 要らない
  • インストール ── 要らない
  • 管理者権限 ── 要らない

使ったのは VBA、PowerShell、UI Automation、クリップボード。PowerShell は2006年からあり、UI Automation も同じころから Windows に入っています。どのパソコンにも最初から載っている道具だけで動きます。

前回の記事で「RPA の心臓部は最初から手元にあった」と書きました。今回はそこからもう一歩進んで、その心臓部で AI が呼べたという話になります。

特定の AI 専用ではない

もう一つ、大事なところです。

橋がやっているのは、結局これだけです。

  1. 新しいチャットを開く
  2. 貼り付ける
  3. 送信ボタンを押す
  4. 書き終わりを待つ
  5. コピーボタンを押す

どの AI チャットにもある部品ばかりです。ボタンの名前で探す作りにしてあるので、日本語でも英語でも拾えます。使えるチャットが何であっても、同じ架け方で橋は架かる理屈になります。

ここは正直に言うと、まだ理屈です。実際に通したのは1つのサービスだけで、他は試していません。ただ、5つの部品のうち特殊なものは一つもないので、当たると思っています。

十年前の机の上

道具は机にあった

前回の記事に書いたとおり、私は十年ほど前に「Excel で RPA」をやろうとして、半年かけてできませんでした。

今回わかったのは、その頃の机の上に、今日の部品が全部載っていたということです。PowerShell も、UI Automation も、クリップボードも、WScript.Shell も。足りなかったのは道具ではありません。

足りなかったのは、資料と、聞ける相手でした。2016年に事務仕事をしながら「PowerShell から UI Automation でブラウザの部品を掴む」書き方を独学で掘り当てるのは、現実的には無理でした。そもそもその組み合わせでできると知る手段がなかったのです。

AI が変えたのは、新しい技術を持ってきたことではなくて、そこだと思います。前からあるものと、それを使えなかった人のあいだが、埋まった。

事実と見立ての仕分け

例によって仕分けます。

事実:Excel のボタンからブラウザの AI チャットへプロンプトを投げ、回答を Excel のセルに書き戻すところまで通ったこと。素の往復が3秒、表を渡した検品が4.8秒だったこと(2026年8月の実測・送信から回収まで)。仕込んだ間違い3件を3件とも指摘したこと。AI が頼まれていない検算コードを自分で実行したこと(出力を本文に転記しています)。エンターでの送信が不発になること、送信後に掴んだ要素が無効になること、回答の執筆中に UI Automation の探索が返ってこなくなること、裏から起動したプロセスが前面化できないこと(いずれも実際に踏みました)。使ったのが VBA・PowerShell・UI Automation・クリップボードだけであること。

見立て:「どの AI チャットでも同じ架け方が効く」は、部品の一般性からの推測です。実際に通したのは1つのサービスだけです。「チャット版は素の API より賢いことがある」も、検算が出てきた1例からの見立てです。「用意するものが何もないから、組織でも使える」も、私の環境で成立しただけで、それぞれの職場の条件までは知りません。

正直な線引き

  • 実験用のコードです。公開の予定は今のところありません。 ブックも橋のスクリプトも、私の環境で動いただけのものです
  • 確かめたのは Windows 11・PowerShell 5.1・Chrome の組み合わせだけです
  • 画面の作りが変われば、そこは直す必要があります。 これは RPA の宿命です。ボタンの名前で探す作りにしてあるので見た目の変更にはある程度強い、というだけで、名前そのものが変われば止まります
  • 送信と回答のあいだ、チャットの画面は前に出ます。 隠していません。何が起きているか見えるほうが、途中経過がわかってよいと判断しました
  • 答えの中身が正しいかどうかは、人間が見る仕事です。今回は仕込んだ間違いを当てましたが、AI が見落とさない保証はどこにもありません
  • 相手のサービスをどう使ってよいかは、それぞれの利用条件によります。ご自身の環境でご確認ください
  • PowerShell の実行が制限されている環境では、この方法は動きません

解説動画

この記事の内容は、動画でもまとめています。本文の差し絵は、もともとこの動画のために描いたものです。

解説動画のサムネイル

おわりに

鍵のかかった正門の前で、ずいぶん長く立っていた気がします。

キーがなければ始まらない、と思っていました。ところが横を見たら、毎日通っている通用口がありました。しかもその扉の開け方は、三日前に別の用事で覚えたばかりのものでした。

道具が道具を呼んで、届かなかった場所に届く。新しい技術は、ひとつも使っていません。

APIキーは、要らなかった。

AI、クロード・フェーブルにもAPIがなければ絶対に無理と言われていたことなのに、それでも諦めずにやっていたら、できました。
しかし、できるまでの様々な知識はフェーブルに教えてもらいましたから、やっぱりこれは、AI、クロード・フェーブルがいなければできなかったことです。
会話しながらマクロを直す流儀は、このように今までできなかったことをできるようにするいい方法だと思っています。

それでは、また。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?