https://teratail.com/questions/8dej1x4rsfze10
の続きです。
PythonでExcelリボンの操作を行おうと考えましたが、Windowsロック時に操作出来ない問題の解決が難しそうでしたので、
Pythonは諦めて、Excel VBAで解決しようと考えています。
https://www.ka-net.org/ribbon/ri14.html
こちらのコードを参考にして、
以下のようにすることで、「マーケットスピード II」のタブをExcel VBAで選択することに成功しました。
ExcelVBA
1Option Explicit 2 3Private Declare Function AccessibleChildren Lib "oleacc" (ByVal paccContainer As Office.IAccessible, ByVal iChildStart As Long, ByVal cChildren As Long, ByRef rgvarChildren As Any, ByRef pcObtained As Long) As Long 4 5Private Const CHILDID_SELF = 0& 6Private Const NAVDIR_FIRSTCHILD = &H7 7 8'accRole 9Private Const ROLE_SYSTEM_PROPERTYPAGE = &H26 'リボン , タブ , ステータス バー 10Private Const ROLE_SYSTEM_TOOLBAR = &H16 'クイック アクセス ツール バー , グループ 11Private Const ROLE_SYSTEM_PAGETABLIST = &H3C 'リボン タブ 12Private Const ROLE_SYSTEM_PANE = &H10 '下リボン 13Private Const ROLE_SYSTEM_GROUPING = &H14 'コンテキスト タブのヘッダー 14Private Const ROLE_SYSTEM_PAGETAB = &H25 'コンテキスト タブ(書式等) 15Private Const ROLE_SYSTEM_BUTTONDROPDOWNGRID = &H3A 'Microsoft Office ボタン 16Private Const ROLE_SYSTEM_PUSHBUTTON = &H2B 'ボタン 17 18Sub SelRibbonTAB(myTabName As String) 19 Dim myAcc As Office.IAccessible 20 21 On Error GoTo myErr 22 23 Set myAcc = Application.CommandBars("Ribbon") 24 Set myAcc = GetAcc(myAcc, "マーケットスピード II", 37) 25 myAcc.accDoDefaultAction (CHILDID_SELF) 26 Set myAcc = Nothing 27 Exit Sub 28 29myErr: 30 MsgBox "実行時エラー:" & Err.Number & vbCrLf & Err.Description, _ 31 vbCritical, "処理が失敗しました。" 32End Sub 33 34Private Function GetAcc(myAcc As Office.IAccessible, myAccName As String, myAccRole As Long) As Office.IAccessible 35 Dim ReturnAcc As Office.IAccessible 36 Dim ChildAcc As Office.IAccessible 37 Dim List() As Variant 38 Dim Count As Long 39 Dim i As Long 40 41 If (myAcc.accState(CHILDID_SELF) <> 32769) And _ 42 (myAcc.accName(CHILDID_SELF) = myAccName) And _ 43 (myAcc.accRole(CHILDID_SELF) = myAccRole) Then 44 Set ReturnAcc = myAcc 45 Else 46 Count = myAcc.accChildCount 47 48 If Count > 0& Then 49 ReDim List(Count - 1&) 50 If AccessibleChildren(myAcc, 0&, ByVal Count, List(0), Count) = 0& Then 51 For i = LBound(List) To UBound(List) 52 If TypeOf List(i) Is Office.IAccessible Then 53 Set ChildAcc = List(i) 54 Set ReturnAcc = GetAcc(ChildAcc, myAccName, myAccRole) 55 If Not ReturnAcc Is Nothing Then Exit For 56 End If 57 Next 58 End If 59 End If 60 61 End If 62 63 Set GetAcc = ReturnAcc 64End Function
GetAcc関数内の「myAcc.accName(CHILDID_SELF)」をMsgBoxで出力してみたところ、
マーケットスピードタブ内の接続ボタン「未接続」ボタンも取れる事が分かったため、
以下のように書き換えれば未接続ボタンをクリックさせる事ができるのではないかと考えたのですが、
「実行時エラー:91 オブジェクト変数またはWithブロック変数が設定されていません。」
と出てしまいます。
※myAcc.accRole(CHILDID_SELF)は43(ROLE_SYSTEM_PUSHBUTTON)であることが分かっています。
ExcelVBA
1Option Explicit 2 3Private Declare Function AccessibleChildren Lib "oleacc" (ByVal paccContainer As Office.IAccessible, ByVal iChildStart As Long, ByVal cChildren As Long, ByRef rgvarChildren As Any, ByRef pcObtained As Long) As Long 4 5Private Const CHILDID_SELF = 0& 6Private Const NAVDIR_FIRSTCHILD = &H7 7 8'accRole 9Private Const ROLE_SYSTEM_PROPERTYPAGE = &H26 'リボン , タブ , ステータス バー 10Private Const ROLE_SYSTEM_TOOLBAR = &H16 'クイック アクセス ツール バー , グループ 11Private Const ROLE_SYSTEM_PAGETABLIST = &H3C 'リボン タブ 12Private Const ROLE_SYSTEM_PANE = &H10 '下リボン 13Private Const ROLE_SYSTEM_GROUPING = &H14 'コンテキスト タブのヘッダー 14Private Const ROLE_SYSTEM_PAGETAB = &H25 'コンテキスト タブ(書式等) 15Private Const ROLE_SYSTEM_BUTTONDROPDOWNGRID = &H3A 'Microsoft Office ボタン 16Private Const ROLE_SYSTEM_PUSHBUTTON = &H2B 'ボタン 17 18Sub SelRibbonTAB(myTabName As String) 19 Dim myAcc As Office.IAccessible 20 21 On Error GoTo myErr 22 23 Set myAcc = Application.CommandBars("Ribbon") 24 Set myAcc = GetAcc(myAcc, "未接続", 43) 25 myAcc.accDoDefaultAction (CHILDID_SELF) 26 Set myAcc = Nothing 27 Exit Sub 28 29myErr: 30 MsgBox "実行時エラー:" & Err.Number & vbCrLf & Err.Description, _ 31 vbCritical, "処理が失敗しました。" 32End Sub 33 34Private Function GetAcc(myAcc As Office.IAccessible, myAccName As String, myAccRole As Long) As Office.IAccessible 35 Dim ReturnAcc As Office.IAccessible 36 Dim ChildAcc As Office.IAccessible 37 Dim List() As Variant 38 Dim Count As Long 39 Dim i As Long 40 41 If (myAcc.accState(CHILDID_SELF) <> 32769) And _ 42 (myAcc.accName(CHILDID_SELF) = myAccName) And _ 43 (myAcc.accRole(CHILDID_SELF) = myAccRole) Then 44 Set ReturnAcc = myAcc 45 Else 46 Count = myAcc.accChildCount 47 48 If Count > 0& Then 49 ReDim List(Count - 1&) 50 If AccessibleChildren(myAcc, 0&, ByVal Count, List(0), Count) = 0& Then 51 For i = LBound(List) To UBound(List) 52 If TypeOf List(i) Is Office.IAccessible Then 53 Set ChildAcc = List(i) 54 Set ReturnAcc = GetAcc(ChildAcc, myAccName, myAccRole) 55 If Not ReturnAcc Is Nothing Then Exit For 56 End If 57 Next 58 End If 59 End If 60 61 End If 62 63 Set GetAcc = ReturnAcc 64End Function
どのようにすれば「未接続」ボタンをクリックさせることが出来るでしょうか。
あなたの回答
tips
プレビュー