LoginSignup
4
3

Excel VBA UIAutomation開発支援ツール UIA_Explorer

Last updated at Posted at 2024-05-19

ファイルダウンロード

OneDrive直リンクです。
https://1drv.ms/x/s!AoqQVc8cDlxVg7E1nULo_AMJGYwa5A?e=y2w7AY
※5/26更新(R1)

PCのブラウザからリンクを開いたらWeb版のExcelが起動しますので、ファイル→名前を付けて保存→コピーのダウンロード で保存してください。

何となく触ってみれば使い方は分かるかもしれません。解説記事か動画を作ろうと思います。機会があれば説明会とかも。

動作環境

  • Windows10以降
  • 64bit版のMicrosoft Excel(デスクトップアプリ)
    ※Word,PowerPoint,Accessにも移植できますが、参照設定やらが若干面倒です
  • UIAutomationに頼らざるを得ない環境(他ので済むならそれに越したことは無いです)

機能

ツリー構築による構造調査

  • Do LoopElementFromPointを自動実行しツリーを構築
  • ドラッグ&ドロップでElementFromPointを実行しツリーを構築
  • Do LoopGetFocucedElementを自動実行しツリーを構築
  • ノードをダブルクリックして子要素を表示

エレメントの詳細情報を取得

  • エレメントの位置を枠線によって強調表示
  • エレメントが持つプロパティの一覧表示
  • エレメントが持つコントロールパターンの一覧表示

エレメントに対する処理テスト

  • SetFocusメソッド実行
  • ShowContextMenuメソッド実行
  • クリック処理(左、右、中央)
  • 各種コントロールパターンの動作テスト
  • IAccessiblePatternからAccツリー展開
  • TextPatternなどからTextRangeビューワー展開
  • Internet Explorer_ServerクラスからIHTMLDocumentビューワー展開(試作)

コーディング支援

  • 最初だけNew CUIAutomation宣言コードを挿入
  • FindFirst/FindAllでのエレメントの取得
  • FindFirst/FindAllに使用する検索条件をListViewから設定
  • 検索条件をCreateAndCondition/CreateOrConditionのどちらで合成するかの選択
  • TreeScopeの設定(Treescope_Children/TreeScope_Subtree
  • FindAllで取得した後、GetElement(xx)で更に要素を取得
  • FindAllで取得した後、For Eachで要素を巡回
  • TreeWalker.GetParentElementでのエレメントの取得
  • TreeWalker.GetPreviousSiblingElementでのエレメントの取得
  • TreeWalker.GetNextSiblingElementでのエレメントの取得
  • TreeWalker.GetFirstChildElementでのエレメントの取得
  • TreeWalker.GetLastChildElementでのエレメントの取得
  • これらを1処理として、シナリオリストに登録
  • 登録した一連の処理のコードをクリップボードにコピー
  • 選択したエレメントをトップウィンドウからTreeWalkerで取得するインスタントコードの出力

操作方法

書きかけです。時間がある時に少しずつ書いていきます。

エレメントツリー

image.png
デスクトップ上のUIautomation要素をツリー表示します。ツール起動直後はトップウィンドウが一覧表示されています。ツリーのノードをダブルクリックすることで、対象要素の子要素を展開できます。子要素の取得を繰り返すことで、処理対象の要素の取得経路などを調査することができます。また、各要素の持つプロパティやコントロールパターンについても確認が可能です。

プロパティリスト

image.png
エレメントツリー内で選択した要素が持つ各種プロパティ値を一覧表示しています。これはCUIAutomation.PollForPotentialSupportedPropertiesメソッドによって取得したプロパティIDとプロパティ名を取得 → それをIUIAutomationElement.GetCurrentPropertyValueメソッドの引数に使ってプロパティ値を取得 → リストにそれぞれの値を表示 という流れで実現しています。プロパティの値がIUIautomationElementArrayなんかだと表現がむずしいので、「x個のエレメント」などと表示させる程度に留めています。

コントロールパターンリスト

image.png
プロパティリストと同様、対象のエレメントがサポートしているコントロールパターンの一覧を表示しています。こちらはCUIAutomation.PollForPotentialSupportedPatternsメソッドによって取得しています。

要素の位置の表示/非表示

image.png
この「枠」ボタンがオンの時は、エレメントツリー内で選択中の要素が画面上のどこにあるのかを色のついた枠で表示します。これはCurrentBoundingRectangleプロパティでの座標取得 → user32の関数によって座標位置に透明なウィンドウを作成 → gdi32の関数による枠線描画 という手法で実現しています。

要素位置表示枠のカラー変更

image.png
このボタンを押すと「色の設定」ダイアログが呼び出され、そこで選択した色で枠の色を変更することができます。

エレメントツリーのリセット

image.png
ツリービューの内容を一旦消去し、デスクトップの現在のトップウィンドウを再取得します。

TreeWalkerの変更

image.png
エレメントツリーの構築に使用するIUIautomationTreeWalkerの種類をControlViewWalkerContetntViewWalkerRawViewWalkerから選択します。

エレメントサーチ(カーソル起点、自動実行)

image.png
このトグルスイッチをONにしておくと、ループ処理でGetCursorPosでカーソル座標を連続して取得 → 一定時間カーソル座標に変換がなければElementFromPointでカーソル座標上の要素を取得 → 取得した要素を起点にエレメントツリーを構築 という処理が行われます。Inspectと同じような感じで画面上のエレメントの構成を調査することができます。

エレメントサーチ(フォーカス起点、自動実行)

image.png
エレメントサーチのトグルスイッチに合わせてこちらのトグルスイッチもONにしておくと、ElementFromPointではなくGetFocucedElementによって取得した要素を起点にしてエレメントツリーが構築されるようになります。

エレメントサーチ(カーソル起点、ドラッグ&ドロップ単発)

image.png
このアイコンを取得したい要素までドラッグ&ドロップすることで、カーソル位置でElementFromPointを実行して要素を取得し、エレメントツリーを構築します。

SetFocusメソッド実行

image.png
エレメントツリーで選択中の要素に対してSetFocusメソッドを実行します。実行後にフォーカスを外さないままツリー探索を行うために、エレメントサーチが有効になります。

ShowContextMenuメソッド実行

image.png
エレメントツリーで選択中の要素に対してShowContextMenuメソッドを実行します。実行後にポップアップしたメニューを消さないままツリー探索を行うために、エレメントサーチが有効になります。

マウスクリック実行

image.png
エレメントツリーで選択中の要素に対してマウスのクリック操作を実行します。GetClickablePointまたはCurrentBoundingRectangleで座標を取得 → SetCursorPosでカーソルを移動 → mouse_eventでクリックを実現しています。実行後はそのまま探索を行うために、エレメントサーチが有効になります。

各種コントロールパターンの実行

image.png
このリストに表示されているパターンをダブルクリックすることで、コントロールパターン操作用のフォームを表示します。
image.png
このフォームは、各種コントロールパターンのメソッドの実行や、プロパティ値の確認ができるようになっています。様々なパターンに対応するようにクラスを準備していますが、どう頑張っても実際の場面ではサポートしている要素が無いパターンもありました。

IAccessibleのツリーを探索するためのACC_Explorer

image.png
コントロールパターンの1つであるLegacyIAccessiblePatternのメソッドにGetIAccessibleがあります。言葉の通りですが、これはIUIautomationElementIAccessibleオブジェクトに変換する機能で、ここからIAcessibleとしてツリー探索を続行できるようにしてみました。
image.png
ダブルクリックで子要素を取得したり、選択中の要素の基本的なアクションが行えるだけでコーディング支援機能などもありませんので、オマケ程度の機能と思ってください。

続きは時間がある時に追記します。

その他

オマケのつもりで最後に追加したコーディング支援機能でしたが、「そういえばこんな処理もよく書くよね」と思いながら機能を拡張させた結果、想定外に強烈なものになりました。

私と同じく、システムの改修や導入に一切口を出せない立場で苦労している人に届けばと思います。

更新履歴

※5/26更新(R1)

  • 選択中のエレメントをトップウィンドウからのツリー移動のみで全自動で取得するコード生成機能を追加しました。
  • 選択中のエレメントがInternet Explorer_Serverクラスだった場合、IHTMLDocumentを取得してツリーを展開するサンプル機能を追加しました。

※5/25更新(R1)

  • シナリオ登録時にプロパティコンディションも保存し、後から呼び出せるようにしました。
  • コントロールパターンのテスト領域を別ウィンドウで展開するように変更しました。
  • これに伴い、フォームサイズを小さめにしました。

※5/25更新(R2)

  • ドラッグ&ドロップでも座標を取得できるようにしました。試作段階で実装していた機能でエレメントサーチの自動実行が作れたのでそちらに移行したのですが、実際に使ってみたら単発での取得の方が便利な場面もあったので復活させました。
4
3
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
4
3