0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

十年越しの「ExcelでRPA」が、AIと二時間で動いた話

0
Last updated at Posted at 2026-08-04

はじめに

ファイル一覧のブックを作っていた頃から、ずっと考えていたことがあります。

Excel から、他のソフトを動かせないか。

やりたいことは単純です。Excel に並べたデータを、別のソフトの入力欄に流し込みたい。世の中ではそれを RPA と呼んで、専用のソフトを買って、ロボットに画面を操作させています。買わずに、Excel の中からできないのか──そう思いながら、十年近く手を出せずにいました。

先日、AI と別の作業をしている流れで、ふとその話になりました。そこから二時間ほどで、動くところまで行きました。

しかも、何も買っていません。何も入れていません。使ったのは Windows に最初から入っているものだけです。

前回は、API キーを挿すつもりで蔵から出したブックが、鍵ごと要らなくなった話を書きました。

今回も「入れずに済ませる」話です。前回は鍵でしたが、今回は道具そのものでした。

TL;DR

  • **Windows には UI Automation という仕組みが最初から入っています。**画面の部品を、座標ではなく名前で掴んで、押したり文字を入れたり読んだりできます
  • これは RPA 製品が中で使っているものと同じです。つまりRPA の心臓部は、最初から手元にあったということになります
  • ただし VBA から CreateObject では呼べません。ProgID が登録されていないのが理由で、レジストリを見て確かめました
  • **PowerShell を一枚挟むと通ります。**PowerShell も Windows 標準なので、インストールは結局ゼロです
  • 実測1:Excel のマクロから電卓を名指しで操作して、7+3=10 を押させ、表示を読み戻すまで1.4秒
  • 実測2:ブラウザの入力欄に文字を入れ、ボタンを押し、画面に出た結果を読み戻すところまで成功
  • ブラウザには落とし穴がありました。**普通に開いた窓では、ページの中身が一切見えません。**起動時にオプションを1つ足す必要があります
  • 部品はどれも既に公開されています。私がやったのは、繋いで、Excel から撃てる形にしただけです

「Excel で RPA」は、だいたい盲打ちだった

先に、これまで何ができなかったのかを書きます。

「Excel VBA で RPA」を調べると、記事も動画もそれなりに出てきます。ただ中身を見ると、たいていは SendKeys です。目的のウィンドウを前に出して、キーボードの文字を送り込む。

これを私は盲打ちと呼んでいます。目をつぶって、そこにあるはずの場所を叩いているからです。

盲打ちには弱点があります。ウィンドウが前に出ていなければ、文字はよそへ飛びます。相手がまだ読み込み中なら、空振りします。入力欄を移るのに Tab を何回押すかは、相手の画面の作り次第です。うまくいくかどうかが、そのときの画面の機嫌に左右される。

ブラウザが相手なら、かつては別の道がありました。Internet Explorer です。CreateObject("InternetExplorer.Application") の一行でブラウザが手に入り、ページの中身を直接触れました。あれは本当によくできていました。

その IE が、2022年6月に終わりました。

乗り換え先として案内されているのは Selenium Basic です。ただこれはインストールが要ります。しかも本体の更新は数年止まっています。

つまり「入れずにブラウザを操る道」は、この四年ほど空席のままでした。

Windows は、RPA の心臓部を最初から積んでいる

ここからが本題です。

Windows には UI Automation という仕組みが入っています。もともとは、目の見えない方が画面読み上げソフトを使うための土台です。画面の部品に名前と種類を持たせて、外から取り出せるようにしてある。

そしてRPA 製品は、これを自社の画面で包んで売っています。 部品を名前で掴んで、押して、読む──製品がやっていることの中核は、この仕組みです。

つまり、心臓部は最初から全員の PC に載っていた。

盲打ちとの違いは決定的です。

盲打ち(SendKeys) 名指し(UI Automation)
何を指定するか 前面のウィンドウ+キーの列 部品の名前
ウィンドウを動かしたら 位置は関係ないが前面である必要 関係ない
相手が読み込み中だと 空振りする その部品が現れるまで待てる
解像度が変わったら 影響なし 影響なし
相手の画面が変わったら Tab の回数から作り直し 名前が同じなら動く

座標を殴るのではなく、名前を呼ぶ。呼べば返事がある。 これが今回の話の芯です。

一つ目の壁 ── VBA から直接は呼べない

さっそく VBA から呼ぼうとしました。私のやり方では、外部の部品は必ず CreateObject で呼びます。参照設定に頼ると、配ったブックが相手の環境で動かなくなるからです。

書いたのはこれだけのはずでした。

Set uia = CreateObject("UIAutomationClient.CUIAutomation")

動きません。段階を記録する診断マクロを入れて撃ったら、一段目で落ちていました。

念のため、クラスの識別番号を直接指定する裏道も試しました。これも駄目。

そこでレジストリを見に行きました。答えはそこにありました。

{ff48dba4-60ef-4201-aa87-54103eef594e}
  ProgID = []                                    ← 空
  DLL    = C:\Windows\System32\uiautomationcore.dll
  Threading = Both

部品は登録されていて、本体の DLL もある。ただし名前(ProgID)が付いていません。

CreateObject は名前でしか呼べない関数です。名前がない部品は、この入口からは呼べない。参照設定を使えば別ですが、それでは配れるブックになりません。

紹介されている記事はいくつかありますが、私が見た範囲では参照設定を有効にする前提のものでした。なぜ CreateObject では駄目なのかを書いたものは見つけられませんでした。ここは実物で確かめるしかなかったところです。

PowerShell を一枚挟む

塞がっているのは VBA からの直通路だけです。別の通り道を探せばいい。

PowerShell なら、この仕組みを最初から扱えます。しかも PowerShell は Windows 標準です。追加で入れるものはありません。

Add-Type -AssemblyName UIAutomationClient
Add-Type -AssemblyName UIAutomationTypes
$root = [System.Windows.Automation.AutomationElement]::RootElement

撃ってみたら、一発で画面の窓が全部並びました。

[Chrome_WidgetWin_1] Claude
[XLMAIN] 秀 - コピー (2).xlsm - Excel
[Progman] Program Manager

通りました。

あとは Excel との繋ぎ方です。これは考える必要がありませんでした。同じ形を既に持っていたからです。

前に、Excel のフォームから AI を呼ぶ道具を作ったときに、こういう手順を組んでいます。

  1. VBA が渡したい内容をファイルに書き出す
  2. 外のプログラムを、画面を出さずに起動する
  3. VBA は DoEvents で回りながら、結果のファイルが出てくるのを待つ
  4. 出てきたら読み取る

**この四手が、そのまま使えます。**呼ぶ相手が AI から PowerShell に変わるだけです。

実験その1 ── 電卓を名指しで押す

最初の相手は電卓にしました。

やらせることは、7 を押して、+ を押して、3 を押して、= を押して、表示された答えを読み戻す。RPA が仕事でやっていることの、縮小版です。

VBA 側はこういう作りです。要点だけ抜きます。

Sub 電卓を操縦する()

    ' (1)PowerShell のスクリプトを組み立てて、UTF-8 で書き出す
    ps = ps & "Add-Type -AssemblyName UIAutomationClient" & vbCrLf
    ps = ps & "..." & vbCrLf

    Set st = CreateObject("ADODB.Stream")
    st.Charset = "UTF-8"
    st.WriteText ps
    st.SaveToFile psPath, 2

    ' (2)画面を出さずに起動する。待たずに戻る
    Set sh = CreateObject("WScript.Shell")
    sh.Run "powershell -NoProfile -ExecutionPolicy Bypass " & _
           "-WindowStyle Hidden -File """ & psPath & """", 0, False

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

    ' (4)読み取る
    ' (ADODB.Stream で UTF-8 として読む)

End Sub

CreateObject しか使っていません。参照設定はゼロです。

PowerShell 側は、押すボタンの名前を並べて順に叩くだけです。

foreach ($id in @('clearButton','num7Button','plusButton','num3Button','equalButton')) {
    $b = $w.FindFirst($TS::Descendants, (名前が $id という条件))
    $b.GetCurrentPattern([System.Windows.Automation.InvokePattern]::Pattern).Invoke()
}

plusButton と書けば、+ のボタンが押される。座標は一つも書いていません。

窓の探し方も工夫しました。「電卓」という表示名で探すのではなく、中に num7Button を持っている窓を電卓と判定しています。表示名が変わっても見つかります。

走らせました。

電卓操縦 1.4秒 → 表示は 10 です

**1.4秒。**押させて、読み戻すまでです。電卓は目の前で実際に動きます。

実験その2 ── ブラウザの入力欄に文字を入れる

本命はこちらです。今どきの業務用の画面はブラウザで動くものが多いので、ここが通らないと使い道が半分になります。

自分で試験用のページを作りました。入力欄を2つと、ボタンを1つ置いただけの、十数行の紙芝居です。ボタンを押すと、入れた文字をそのまま画面に表示します。

ブラウザで開いて、さっきと同じやり方で中を覗きました。

Edit要素 = 2 個
  name=[アドレスと検索バー]
  name=[]

**ページの中身が出てきません。**ブラウザ自身のアドレスバーは取れているのに、私が置いた入力欄が見えない。ボタンの方も、取れるのは「最小化」「戻る」「お気に入り」といったブラウザの部品ばかりです。

二つ目の壁 ── ブラウザは、黙っていると中身を見せない

調べてわかりました。**今のブラウザは、読み上げソフトのような相手が来たと判断するまで、ページの中身を外に公開しません。**常に公開していると重くなるので、必要になってから作る仕組みになっています。

外から起こすには、起動するときにオプションを1つ足します。

--force-renderer-accessibility

これを付けて、専用の設定で窓を1つ立て直しました。同じように覗きます。

Edit要素 = 4 個
  name=[アドレスと検索バー]
  name=[件名]  autoId=[...]
  name=[番号]  autoId=[...]
  name=[]

出てきました。

しかも嬉しい発見がありました。**HTML の id が、そのまま掴むための名前になっています。**ページの作り手が入力欄に付けた名前を、そのまま指定できるということです。

あとは入れて、押して、読むだけでした。

# 入力欄に文字を入れる
$k.GetCurrentPattern([System.Windows.Automation.ValuePattern]::Pattern).SetValue("(サンプルの文字列)")
# ボタンを押す
$t.GetCurrentPattern([System.Windows.Automation.InvokePattern]::Pattern).Invoke()

結果です。

入力欄の中身  = [(サンプルの文字列)]
画面の表示    = 登録しました: (サンプルの文字列)

入力・実行・読み戻し。三つとも通りました。

なお、このオプションの話は RPA 製品の公式ドキュメントに書いてあります。ブラウザの版によっては効き方が変わった時期もあったようで、そのあたりの経緯まで公開されていました。業界では常識の部類です。知らずに撃つと「ブラウザは無理でした」で終わるところでした。

何が変わったか

十年思っていたことが、なぜ今日できたのか。整理します。

**仕組みは、ずっと前からありました。**UI Automation は新しいものではありません。私が知らなかっただけです。

**塞がっていたのは、入口でした。**VBA から直接呼べないという一点で、VBA しか書かない人間は入口の前で止まります。私も止まっていました。

**開いたのは、迂回路を思いついたことでした。**そしてその迂回路は、AI を呼ぶために去年から使っていた四手と、まったく同じ形をしていました。**新しく覚えたものは、実は何もありません。**持っていた部品の向きを変えただけです。

そう考えると、AI とやって早かった理由もはっきりしています。「レジストリを見て名前が付いていないことを確かめる」「別の通り道を探す」「ブラウザが中身を隠している理由を調べる」──ひとつずつは大した話ではありませんが、知らない土地では、どれも半日ずつ溶ける類です。それが続けて片付いたので、二時間で着きました。

事実と見立ての仕分け

例によって仕分けます。

事実:UI Automation のクラスがレジストリに登録されていて、ProgID が空であること(実物確認)。CreateObject および識別番号の直接指定の両方が失敗すること(実測)。PowerShell 経由では成功すること(実測)。Excel のマクロから電卓を操作し、結果を読み戻すまで1.4秒だったこと(Timer 計測・公開前に再確認します)。ブラウザでオプションなしでは入力欄が取れず、--force-renderer-accessibility を付けると取れること(同一ページで前後比較)。HTML の id が掴むための名前として出てくること(実測)。IE のサポートが2022年6月に終了していること。Selenium Basic の利用にインストールが必要であること。

見立て:ブラウザが中身を隠しているのは負荷を避けるためだ、という説明(公開されている解説に基づく理解であって、私が中を読んだわけではありません)。「業界では常識の部類」も、公開ドキュメントに載っていることからの推測です。「二時間で着いた」の内訳も、体感であって計測ではありません。

正直な線引き

  • **部品はどれも既に公開されています。**VBA から UI Automation を使う記事も、PowerShell から使う記事も、ブラウザのオプションの話も、探せば出てきます。私がやったのは、繋いで、Excel から撃てる形にしたことだけです。新発見ではありません
  • 確かめたのは Windows 11・PowerShell 5.1 の環境だけです。他の版は試していません
  • 相手にしたのは電卓と、自作の試験ページです。実際の業務用のソフトで通るかどうかは、その画面の作り次第です。部品に名前が振っていなければ、掴めません
  • ブラウザは専用の起動条件で立てた窓が要ります。普段使っている窓をそのまま使う形にはなっていません
  • 繰り返しの処理や、途中で止まったときの立て直しは、まだ何も作っていません。RPA 製品が金を取っている部分は、そこにあります。一件の転記が通っただけで、業務が回るわけではありません
  • PowerShell の実行が制限されている環境では、この方法は動きません
  • 今回のマクロは実験用で、公開の予定は今のところありません。道具類は公開リポジトリにあります

追記 ── 先行記事がありました(2026-08-05)

公開したあとで調べ直したところ、同じ道を先に歩いている記事がいくつも見つかりました。順に挙げます。

本文に「新発見ではありません」と書きましたが、そのとおりでした。しかも二年以上前から公開されていたわけです。

書き足したいのは、ここからです。

私は、これらに一度も届きませんでした。 十年ほど「Excel で RPA ができないか」と思っていて、探し方を知らなかった。部品も、解説も、支援ツールまで公開されていたのにです。

道具が「ある」ことと、必要な人に「届く」ことは別だ──今回いちばんはっきりわかったのは、たぶんそこです。私が今回たどり着けたのも、腕が上がったからではなく、AI に思いつきを片端から試させられたからでした。

そのうえで、この記事に残る分を正直に書きます。CreateObject が通らない理由(ProgID が空である、という実物の確認)と、VBA しか書かない人間がどこで止まっていたか、という経路の記録です。技術としては先行記事の射程の中にあります。

先を歩かれた方々に、敬意を表します。

おわりに

十年やりたかったことの入口が、Windows のフォルダの中に、ずっと置いてありました。

買うものだと思っていたものが、既に載っていた。呼び方を知らなかっただけでした。今回わかったのは新しい技術ではなくて、手元にあるものの名前です。

名前さえわかれば、呼べば返事があります。

それでは、また。

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?