【VBA】UIAutomationで業務改善3

目次

RPAなんて不要

どうも。「やめろよ。やめろよ。」と言っても台風の時に河川覗く人と、ハロウィンパーティでウィルス集団感染する人の脳内は似てる。と思ってるjimです😉

今回の記事で、いよいよ『UIAutomation』を使うわけだけど、ザックリな説明です😣

こゆのとか、他のAPIと組み合わせて使えば、RPAを黙らせることが出来る、、、

に違いないと思ってます。

結局、プログラミングを使った業務改善って、発想の問題なんだよね。

RPA使ったところで、組み立てる人のサービス精神が乏しければ、いいものも作れないわけで。。。

『どんな手を使ってでも成し遂げよう!』っていう、気持ちよ!

気持ち気持ち😄

 

エレメント取得

今回は、電卓を使って説明します🖥

業務改善1で紹介した『UIAutomationSpy』でエレメントを取得します。

【VBA】UIAutomationで業務改善1

電卓とUIAutomationSpyを開いて、UIAutomationSpyのStartを押すとエレメントの取得が始まります。

ちなみに、Stopで止めないとカーソル部分のエレメントを取得し続けます。

↓UIAutomationSpyの内容(ControlTypeId、Class、Nameの順)

Get-UiaWindow -Class 'ApplicationFrameWindow' -Name '電卓' | `
Get-UiaWindow -Class 'Windows.UI.Core.CoreWindow' -Name '電卓' | `
Get-UiaGroup -Class 'LandmarkTarget' | `
Get-UiaGroup -AutomationId 'NumberPad' -Class 'NamedContainerAutomationPeer' -Name '数字パッド' | `
Get-UiaButton -AutomationId 'num1Button' -Class 'Button' -Name '1'

こんな感じの入れ子になってます。

今回、最初のウィンドウはハンドルから取得して、2行目から順にエレメントを取得し、最終的に『1』のエレメントを取得します。

取得の仕方は、ハンドル操作に似ていて、NameかId(Class)を指定して取得します。

多分、分からないと思うので、実際にコードを記述します😓

 

UIAutomationで電卓の操作

とりあえず、参照設定から、、

『UIAutomationClient』にチェック入れます。

それから、親のハンドルを取得するために『FindWindowA』のAPIを定義します。(今回は親だけで大丈夫)

定義の仕方は↓

【VBA】UIAutomationで業務改善2

親ハンドルを取得するコードを記述します。

Option Explicit
Private Declare Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Sub dentaku()
Dim Hwnd As Long
    Hwnd = FindWindowA(vbNullString, "電卓")
End Sub

次に、電卓ウィンドウを取得。

Dim uiAuto As CUIAutomation
Dim elmDentaku As IUIAutomationElement
Dim iCnd As IUIAutomationCondition
    Set uiAuto = New CUIAutomation
    Set elmDentaku = uiAuto.ElementFromHandle(ByVal Hwnd)

んで、下が『UIAutomationSpy』で取得した2行目の処理。

    Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "電卓")
    Set elmDentaku = elmDentaku.FindFirst(TreeScope_Subtree, iCnd)

Nameで取得の場合⇒(UIA_NamePropertyId,"Name")

Classで取得の場合⇒(UIA_ClassNamePropertyId,"Class")

2行目と同じ処理を繰り返して、最終的に『1』を取得します。

そして、取得したエレメントに送信もできると。。。

Dim InvokePattern As IUIAutomationInvokePattern
    Set InvokePattern = elmDentaku.GetCurrentPattern(UIA_InvokePatternId)
    InvokePattern.Invoke

因みに、キャプション名の取得も出来るし、文字列も送信できます。

Dim iValuePattern As IUIAutomationValuePattern
    Set iValuePattern = エレメント.GetCurrentPattern(UIA_ValuePatternId)
    '文字列送信
    iValuePattern.SetValue 文字列
    'キャプション名
    Debug.Print iValuePattern.CurrentValue

 

最後に

『1+1=』のコードを記述してみました👍

これなら、分かりやすいんじゃないかな?

Option Explicit
Private Declare Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Sub dentaku()
Dim Hwnd As Long
    Hwnd = FindWindowA(vbNullString, "電卓")
    Call potipoti(Hwnd, "1")
    Call potipoti(Hwnd, "+")
    Call potipoti(Hwnd, "1")
    Call potipoti(Hwnd, "=")
End Sub
Private Sub potipoti(ByVal Hwnd As Long, P As String)
Dim uiAuto As CUIAutomation
Dim elmDentaku As IUIAutomationElement
Dim iCnd As IUIAutomationCondition
Dim InvokePattern As IUIAutomationInvokePattern
    Set uiAuto = New CUIAutomation
    Set elmDentaku = uiAuto.ElementFromHandle(ByVal Hwnd)
    Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "電卓")
    Set elmDentaku = elmDentaku.FindFirst(TreeScope_Subtree, iCnd)
    Set iCnd = uiAuto.CreatePropertyCondition(UIA_ClassNamePropertyId, "LandmarkTarget")
    Set elmDentaku = elmDentaku.FindFirst(TreeScope_Subtree, iCnd)
    Select Case StrConv(P, vbNarrow)
        Case "+"
            P = "プラス"
            Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "標準演算子")
        Case "-"
            P = "マイナス"
            Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "標準演算子")
        Case "/"
            P = "除算"
            Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "標準演算子")
        Case "*"
            P = "乗算"
            Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "標準演算子")
        Case "="
            P = "等号"
            Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "標準演算子")
        Case Else
        P = StrConv(P, vbNarrow)
        Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, "数字パッド")
    End Select
    Set elmDentaku = elmDentaku.FindFirst(TreeScope_Subtree, iCnd)
    Set iCnd = uiAuto.CreatePropertyCondition(UIA_NamePropertyId, P)
    Set elmDentaku = elmDentaku.FindFirst(TreeScope_Subtree, iCnd)
    Set InvokePattern = elmDentaku.GetCurrentPattern(UIA_InvokePatternId)
    InvokePattern.Invoke
End Sub

ってことで、全部で3記事にもなってしまったけれど、「APIを使えばoffice以外のことも色々出来ちゃうよ。」って話、、、

長いか😅

 

あ〜い、とぅいまてぇ〜ん🖐

 

next:【VBA】UIAutomationで業務改善4