【VBA】UIAutomationで業務改善5
EdgeのCombobox操作
alone in my room寒くなってきたね♪手足が冷え冷えのjimです。ども✋
最近、VBAマクロのブラウザ操作の改修(IE⇒Edge)やってて、Combobox(Edge)の操作でハマったので記事にします😥
Comboboxの一覧を表示させることはできるのですが、UIAutomationで一覧の情報を選択できないという。。。
そして、ググると自分の記事がアホみたいに出てくるという。。。
ちなみに、まだUIAutomationで操作できてません。別の方法を紹介します。
とりあえず、前回の記事のようにEdgeの要素を取得(edgeElementのこと)したところから。
以下のようにしてやれば、Comboboxの一覧を表示させることが出来ます。アクティブウィンドウがVBEに切り替わると消えちゃうんですけどね。
Option Explicit Sub combobox() Dim shellObject As Object Dim uiAuto As UIAutomationClient.CUIAutomation Dim edgeElement As IUIAutomationElement Dim comboboxElement As IUIAutomationElement Dim expandPattern As IUIAutomationExpandCollapsePattern Set shellObject = CreateObject("Shell.Application") shellObject.ShellExecute "https://www.youtube.com/" Set uiAuto = New UIAutomationClient.CUIAutomation Set edgeElement = GetEdge(uiAuto) '待機処理は無視でーす '例えばダウンロードの拡張子を選択する場合で _ Comboboxの名前が『* エクスポートファイルの形式』の場合 Set comboboxElement = _ GetElement(uiAuto, edgeElement, UIA_NamePropertyId, _ "* エクスポートファイルの形式", UIA_ComboBoxControlTypeId) Set expandPattern = comboboxElement.GetCurrentPattern(UIA_ExpandCollapsePatternId) expandPattern.Expand End Sub Function GetElement(ByVal uiAuto As UIAutomationClient.CUIAutomation, ByVal edgeElement As IUIAutomationElement, _ ByVal propertyId As Long, ByVal propertyString As String, Optional ByVal propertyType As Long = 0) Dim Cond1 As IUIAutomationCondition Dim Cond2 As IUIAutomationCondition Set Cond1 = uiAuto.CreatePropertyCondition(propertyId, propertyString) Set Cond2 = uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, propertyType) Set Cond1 = uiAuto.CreateAndCondition(Cond1, Cond2) Set GetElement = edgeElement.FindFirst(TreeScope_Subtree, Cond1) End Function Function GetEdge(ByVal uiAuto As UIAutomationClient.CUIAutomation) Dim allElement As IUIAutomationElement Dim condControls As UIAutomationClient.IUIAutomationCondition Dim arryControls As UIAutomationClient.IUIAutomationElementArray Dim i As Long Set allElement = uiAuto.GetRootElement Set condControls = uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_WindowControlTypeId) Set arryControls = allElement.FindAll(TreeScope_Subtree, condControls) For i = 0 To arryControls.Length - 1 If LCase(arryControls.GetElement(i).CurrentName) Like "*- microsoft? edge" And _ arryControls.GetElement(i).CurrentClassName = "Chrome_WidgetWin_1" Then Set GetEdge = arryControls.GetElement(i) Exit For End If Next End Function
一覧は表示されます。
でも、できないのよ。これから先の操作が。。
Edgeじゃなければ出来るぽいんだけど。。。
PostMessage
仕方ないからキー操作。しばらくはコレだね。
一度、Comboboxの一覧を開けば、一覧が閉じてもキー操作が利くみたいなのね。Comboboxがアクティブになるので、比較的扱いやすいかなって思ってます。UIAutomationで要素取得しながら制御文で何とかなりそう。
一応、『expandPattern.Expand』でウィンドウが最前面にくるのでSendkeysでもいけるかもしれないけど、なるだけ確実に操作したいのでEdgeのハンドルにキーを送信。
↓まず、Edgeのハンドルを取得します。
Sub combobox2() Dim myNum As Long myNum = edgeElement.GetCurrentPropertyValue(UIA_NativeWindowHandlePropertyId) End Sub
↓そして、Edgeのハンドルに上キーを送ります。
Declare Function PostMessage Lib "user32" Alias "PostMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Sub combobox3() Dim myNum As Long myNum = edgeElement.GetCurrentPropertyValue(UIA_NativeWindowHandlePropertyId) PostMessage myNum, &H100, 38, 0 End Sub
キーを押すってのが『&H100』です。KEYDOWNみたいな感じで定数にしておいた方が読みやすいと思います。←やれよ
ちなみに、これだけだと押した状態がキープされた気がする。UPも作った方がいいかも。。
上キーが『38』です。キーコードですね。これも定数にした方がいいかも。←やれよ
ウーン!ってすると。。。
Option Explicit Declare Function PostMessage Lib "user32" Alias "PostMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Sub combobox() Dim shellObject As Object Dim uiAuto As UIAutomationClient.CUIAutomation Dim edgeElement As IUIAutomationElement Dim comboboxElement As IUIAutomationElement Dim expandPattern As IUIAutomationExpandCollapsePattern Dim myNum As Long Set shellObject = CreateObject("Shell.Application") shellObject.ShellExecute "https://www.youtube.com/" Set uiAuto = New UIAutomationClient.CUIAutomation Set edgeElement = GetEdge(uiAuto) '待機処理は無視でーす '例えばダウンロードの拡張子を選択する場合で _ Comboboxの名前が『* エクスポートファイルの形式』の場合 Set comboboxElement = _ GetElement(uiAuto, edgeElement, UIA_NamePropertyId, _ "* エクスポートファイルの形式", UIA_ComboBoxControlTypeId) Set expandPattern = comboboxElement.GetCurrentPattern(UIA_ExpandCollapsePatternId) expandPattern.Expand myNum = edgeElement.GetCurrentPropertyValue(UIA_NativeWindowHandlePropertyId) PostMessage myNum, &H100, 38, 0 PostMessage myNum, &H100, 13, 0 End Sub Function GetElement(ByVal uiAuto As UIAutomationClient.CUIAutomation, ByVal edgeElement As IUIAutomationElement, _ ByVal propertyId As Long, ByVal propertyString As String, Optional ByVal propertyType As Long = 0) Dim Cond1 As IUIAutomationCondition Dim Cond2 As IUIAutomationCondition Set Cond1 = uiAuto.CreatePropertyCondition(propertyId, propertyString) Set Cond2 = uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, propertyType) Set Cond1 = uiAuto.CreateAndCondition(Cond1, Cond2) Set GetElement = edgeElement.FindFirst(TreeScope_Subtree, Cond1) End Function Function GetEdge(ByVal uiAuto As UIAutomationClient.CUIAutomation) Dim allElement As IUIAutomationElement Dim condControls As UIAutomationClient.IUIAutomationCondition Dim arryControls As UIAutomationClient.IUIAutomationElementArray Dim i As Long Set allElement = uiAuto.GetRootElement Set condControls = uiAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_WindowControlTypeId) Set arryControls = allElement.FindAll(TreeScope_Subtree, condControls) For i = 0 To arryControls.Length - 1 If LCase(arryControls.GetElement(i).CurrentName) Like "*- microsoft? edge" And _ arryControls.GetElement(i).CurrentClassName = "Chrome_WidgetWin_1" Then Set GetEdge = arryControls.GetElement(i) Exit For End If Next End Function
あ、『13』はエンターね。
キーコードはググれば出てくると思います。
一応、自分でも簡単に調べる事ができるので、この記事で紹介しておきます。
キーコード
UserFormのボタンに『KeyDown』というイベントがあります。
このイベントはボタンがアクティブの時、押下されたキーコードを取得できるものです。(API使う方法もある)
ユーザーフォームを挿入してコマンドボタンを置き、ユーザーフォームに以下のコードを書いてみましょう。
Private Sub CommandButton1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) Debug.Print KeyCode End Subゆ
ユーザーフォームを開いて上キーを叩くと、イミディエイトウィンドウに38が表示されるはずです。
つまりは、、、そゆこと。
ExcelのワークシートにActiveXのコマンドボタン置いても同じことができると思います。
はい。そゆ感じで、UIAutomationで全て操作できてないっていう😅
これから色々と大変かも。。。
疲れるぅ~😣
ってことで、またねぇ✋
まとめ
関連記事
ハンドルからメッセージの取得⇒
ディスカッション
コメント一覧
まだ、コメントがありません