PowerAutomateDesktopをExcelVBAと連携

PowerAutomateDesktopとExcelの連携の有効利用について

Excel.RunMacro Instance: ExcelInstance Macro: $'''プロシージャ名;引数1;引数2'''

VBAを実行するアクション

PowerAutomateDesktopはExcelを操作するアクションが複数あります
これらはそのアクション名を見ればおおよそ操作方法については分かるとは思います
Automate自体は処理速度がそれほど早いものでは無いので、VBAで実行できることであればそちらで行う方が圧倒的に早く処理できます

しかし、記事にあるようにAutomateと連携させることで今までVBAだけでは少し難しい処理が可能となります
・ユーザーフォームの操作を自動化
・IE以外のWebブラウザでの処理化

これらの処理はVBA単体で行うことを考えるとかなりハードルの高いものです
ですが、Automateと連携させることで驚くほど簡単に実装出来ます

VBA処理をAutomateから実行

まずAutomateからVBA処理の実行の方法を確認しておきます
操作方法は難しくありませんが、VBA処理の呼び出しで最も最初に注意しておく必要があるのが引数に引き渡せるのが「テキスト型」のみになっている点です
これは処理をすでに作成している場合に引数を設定している場合は要注意です
まあ、あまりオブジェクト等の引き渡しをトリガーになる処理に入れたりは無いとは思いますが…
VBA側で工夫すればテキスト型に限定されていたとしても、だいたい何とかなるとは思いますのでここは仕様と割り切って対応が必要な部分です

Excelのインスタンスを作成するアクション

まずは処理の作成されたExcelブックを開く必要があります
「Excelの起動」アクションから簡単に実行できます

アクションの設定画面

「Excelの起動」は次のドキュメントを開くに設定します
「ドキュメントパス」は絶対パスでファイルを指定します
「読み取り専用として開く」はオンにします
もちろん処理の内容を保存する必要がある場合はオフのままにしておく必要があります
ただ通常のExcelの開く処理と違い、すでに開かれているブックを開こうとした場合に注意のメッセージが表示されずに読み取り専用で起動されます
読み取り専用で開くことを前提としておくことで処理の安定化を図れます

残りの項目は初期設定のままで問題ありません、インスタンスの表示に関しては処理次第で変更しても良いです

プロシージャ名と引数を指定して処理を実行するアクション

処理の実行には「Excelマクロの実行」アクションを利用します

実行する処理

まずこちらが今回実行する処理です
引数に指定された文字列をメッセージ表示する処理です
分かりやすくするために引数を2つ指定しています

アクションの設定画面

アクションの設定画面の1つ目のインスタンスは先ほどExcelを開くアクションで生成された変数を指定します

「マクロ」の設定ですが、「プロシージャ名;引数1;引数2;…」のような形式で全て文字列のまま入力を行います
最初にプロシージャ名を入力しますが、プロシージャ名のみだけの指定となっていますのでモジュールは指定の必要がありません
と、いうより実際にはプロジェクト内全てを参照しているので別のモジュールに同名のプロシージャがあった場合は下記画像のエラーが発生するので注意してください

同名プロシージャが存在しているとエラーになる

とはいえ、別のモジュールでVBA上はさほど問題にならないとはいえ同じ名前のプロシージャが存在するというのはちょっと考えモノですね
動けばええやんという考えの自分ですがさすがにそれは是正した方が良いと思います

少し脱線しましたが、プロシージャ名の後に「;」(半角セミコロン)で引数を区切って入力します、複数ある場合も同形式でそのまま入力していきます

ちなみに、Automate側で数値型の変数を指定したとしてもVBAは文字列として受け取っているので問題が無いので、「”」で囲んだりする必要はありません

実行時の状態

実際に実行してみると、ブックが起動してプロシージャが実行されます
メッセージも渡した文字列がしっかり受け取っていることが分かります

ちなみに、このアクションはVBA処理が終了するまでアクションが停止する点は注意が必要です
もし、Automateで複数の処理を連続実行させたい場合はメッセージ表示などの処理は無くしておいた方が良いですね

ブックを閉じるアクション

蛇足ですが、開いたブックを閉じるには「Excelを閉じる」アクションを実行します
設定項目も生成されたExcelインスタンスの変数を指定するだけですね
ここは実際に操作してみると難しい場面ではないと思います

ユーザーフォームの操作を自動化

ユーザーフォームの操作の自動化ですが、この処理はVBAでは実装はめちゃくちゃに難しいと思います
そもそもVBAにはマウス操作すら行うことが出来ませんし、入力にしてもSendKeysメソッドでシビアなタイミング管理で実行する必要があります

そもそもこのユーザーフォームの操作を自動化する場面自体がほぼ無いかもしれません
ただ入力内容が転記レベルの単調なものであったり、フォームの作成を行ったのが自分では無くさらにその処理の全貌があまり定かではない場合が考えられます

とはいえ、基本的にユーザーフォームの操作自体も全てVBAで処理作成されているわけですから上記の様に処理の全貌が分かっていれば何とかなるかもしれませんが
やはりクリックイベントやチェンジイベントなどで連鎖的に処理が行われるのはユーザーフォームでは当たり前に行われる処理です
それらを全て単純にCallステートメントで呼び出すだけで動くとも限りません

と、前置きが長くなりましたが要はVBAではユーザーフォームの操作を行うのが困難ということです
ですが、Automateでは通常のウィンドウ同様にユーザーフォームの各コントロールを操作が可能です

コントロールの追加

まずはユーザーフォームの操作したいコントロールを登録します
Automateのウィンドウ左にある「UI要素」ボタンをクリックして、表示された画面から「UI要素の追加」ボタンをクリックします

追加の画面

追跡セッションという画面が表示されて、ユーザーフォーム上にマウスを移動させると認識するコントロールに赤枠が表示されます
この赤枠の表示された状態でCtrl+左クリックをすることで、追跡セッション画面に登録されます(画像の状態)
登録出来たら完了ボタンをクリックします

コントロールが追加された状態

これでコントロールの登録が出来ました
同じ要領で必要なコントロールを追加してください
この作業自体は後でアクションの追加時点でも可能なので、ここで追加しなくても都度追加しても大丈夫です

数が少ないうちは気になりませんが、UI要素の数が多くなると管理が大変になりますので各要素の右クリックメニューから名前の変更が可能なので多くなりそうなときは活用してください

登録内容

今回は3つのコントロールを登録しました
閉じるボタンについては作成出来るコントロールではありませんが、ウィンドウ操作が可能なためこれも自動化の対象に出来ます

今回の作成する操作
・テキストボックスに「test」と入力する
・クリアボタンをクリックしてテキストボックスの内容を消去
・フォームの閉じるボタンをクリックしてフォームを閉じる
この3つの操作をAutomateで自動操作してみます

使用するアクション

使用するアクションは2つで、テキスト入力とボタンのクリックアクションです

作成したフロー

いずれのアクションも設定自体は全く複雑なものはありません
直感的に設定可能なのでここでは割愛します

1ではテキストボックスに入力する処理を実行
2ではクリアボタンを押しています、これでテキストボックス内容が消去されます
3では閉じるボタンを押しています、これでフォームが閉じられます

実際の動きに関しては静止画では分かりづらかったので動画を作成しました
動きの気になる人は確認してみてください

フォームの自動操作

この処理において注意の必要なのが、Automateの仕様ではウィンドウのUI操作はマウスの操作も含まれるため他の作業を行いながらの処理実行は出来ません
そもそも自動化なのでしょうがないですけど

IE以外のWebブラウザでの処理化

IEの警鐘が鳴らされてから久しいですが、全くアプリの停止はありませんが
やはりIEの表示が行われないサイトであったり、IE未対応のWebシステムの出現もあり可能であればVBAでの情報収集等のWeb操作もIE以外のアプリを使えるようになると良いです

主なアプリと言えば、GoogleChromeかIEの後継であるMicrosoftEdgeなどが代表的なものと思います

しかしこれらの操作をVBAから行うには「Selenium」の導入が必要となります
ただIE操作のコードともプロパティやメソッドに違いがあったりするので
Web上からのコピペでようやくIE操作が出来たのにChromeに移行するのも大変です

そんな時にAutomateが出番となるかもしれません
もちろんVBAで操作するほどの処理速度を実現するのは不可能ですし、VBAで操作するほど細かい操作はまだAutomateは対応できません
ただこの対応に関しては、今後増加していくことは容易に想像できます

さらに、先般訳あってChromeの使用が出来なくなったのでEdgeに振り替えを行う必要があったのですがAutomateはインスタンス関係のアクションを振り替えるだけで終了しました
このメンテナンス上の優位性はすごいと感じた次第です

今回はChromeを操作して、この部品庫サイトの記事一覧のリストをExcelに取得してみたいと思います
なんせこの部品庫サイトは更新いつしたか分からんもんね

処理の流れとしては、Chromeの起動から情報の取得・Excelの起動をしてVBAに情報を引き渡してVBA処理で入力して保存終了・Chromeを終了の流れで処理化してみましょう
ちなみに、今回の記事では細かい作成要領は割愛します

まずは先にVBA処理を作成しましょう
引数にはテキスト型しか指定出来ないことは解説済みです
そして今回Automateから引き渡すテキストデータは記事一覧が改行されたテキストデータです
それを踏まえて以下のような処理を作成しました

作成した処理

今回の処理に関してはテスト処理なので画像で紹介しています
VBA処理の流れは最初に前回入力値の消去を行っています、全てA列に入力しているのでA列の入力データを消去しています
次に入力用のセルを変数に取得しています
この辺の入力処理は色々想定できるのでなんでも良いです、配列で一括入力もしようと思えば出来ますが、今回は変数セルを更新していって入力を行っていく形にしました
さすがに記事数が数万になったりすることは無いですからね、これからの人生全てを捧げても無理でしょうね、それは♪

次に引数のテキストデータを1行ごとに分割して入力するループ処理です
ここに関してはAutomateからどんなデータが引き渡されるかも事前に知っておく必要はありますが、引き渡すデータは改行されて改行コードはCrLfになっています
なのでそれをSpiritで分割して処理します

次はAutomateのフローを作成します

Web操作の開始アクション

前述しましたが、AutomateではいくつかのWebアプリを操作可能です
現状は画像の4つのアプリですね
今回はChromeを利用したいと思います

各アプリの操作前に拡張機能のインストールが必要になります

拡張機能の設定メニュー

メインメニューの「ツール」⇒「ブラウザー拡張機能」⇒任意のWebアプリを選択するとそのアプリで拡張機能のインストール画面に移行しますのでインストールを実行してください
以降はそのまま操作が可能となります

作成したフロー

今回の作成フローはこんな感じです
1はChromeを起動しています
画像のものはテスト用なのですでに起動済みのものを取得していますが処理化であれば新しく起動で良いでしょう

2行目の「Webページ上の要素の詳細を取得します」アクションで記事一覧のリストを取得しています

リスト範囲の取得

UI要素を指定してその範囲のデータを取得しますので、UI要素を追加します
画像の様にsectionタグになっている範囲がそうなのでその辺にマウスを移動させると取得可能です

取得されたデータ

Automate上での取得データは画像のようなものになっています
表示された文字列を単純なテキストデータとして取得していますね
行数値にあるように改行されたテキストデータです

3~5のアクションではこの記事前半で解説しているExcelのマクロ実行を行っています、今回の場合はデータの更新が必要になるので読み取り専用では開いていませんし、閉じるアクションでは保存するようにしています
ただ、見える必要のない処理なのでExcelのインスタンス表示はしていません

この処理ではWebアプリの操作は要素の取得のみで、Excelもインスタンスの表示が必要ない点から、処理はバックグラウンド実行が可能です
他の作業を行いながら処理を実行できるという事ですね

Automateの自動化も工夫次第でバックグラウンド処理にすることが可能なので、より有効活用が出来ると思います

処理の動きを確認出来る動画を作成しましたので動きの気になる人は確認してみてください

部品庫サイトの記事一覧のリストをExcelに取得

動画の方は動きの確認用にフローを少し編集しています
3行目のアクションをExcelの起動ではなくすでに起動済みのExcelを取得するアクションに変更してブックの閉じるアクションは無効化しています

動画の最初と最後でExcelのA列にデータが入力されていることを確認してください

そして最後にとても大切なことを1つ
この記事の例を試すことにより、部品庫サイトに高アクセスでサーバー攻撃しないでね