问题
I'm working on a macro that uses the UIAutomationClient client to expand the SAP Analysis ribbon tab from Excel and click one of the buttons available there. This macro is then executed from a Form Control Button.
Here's the code:
'global object to hold the translations
Dim translations As Object
Public Enum oConditions
eUIA_NamePropertyId
eUIA_AutomationIdPropertyId
eUIA_ClassNamePropertyId
eUIA_LocalizedControlTypePropertyId
End Enum
'element name translations for English
Function getEnglishTranslations() As Object
Set Words = CreateObject("Scripting.Dictionary")
'element, element name
Words.Add "Analysis", "Analysis"
Words.Add "Lower Ribbon", "Lower Ribbon"
Words.Add "Design Panel Group", "Design Panel"
Words.Add "Design Panel Menu", "Design Panel"
Words.Add "Display Button", "Display"
Set getEnglishTranslations = Words
End Function
'element name translations for German
Function getGermanTranslations() As Object
Set Words = CreateObject("Scripting.Dictionary")
'element, element name
Words.Add "Analysis", "Analysis"
Words.Add "Lower Ribbon", "Unteres Menüband"
Words.Add "Design Panel Group", "Designbereich"
Words.Add "Design Panel Menu", "Designbereich"
Words.Add "Display Button", "Anzeigen"
Set getGermanTranslations = Words
End Function
Function translate(element As String) As String
translate = translations(element)
End Function
Sub toggleDisplay()
Application.ScreenUpdating = False
Dim oAutomation As New CUIAutomation 'the UI Automation Object
Dim walker As IUIAutomationTreeWalker
Set walker = oAutomation.ControlViewWalker
Dim element As IUIAutomationElement
'references for elements in the UI tree
Dim root As IUIAutomationElement
Dim xl As IUIAutomationElement
Dim analysisTab As IUIAutomationElement
Dim xlrib As IUIAutomationElement
Dim dpanel As IUIAutomationElement
Dim display As IUIAutomationElement
'pattern objects which allow the execution of different UI elements'
functionality
Dim oTogglePattern As IUIAutomationTogglePattern
Dim expcolPattern As IUIAutomationExpandCollapsePattern
Dim selPattern As IUIAutomationSelectionItemPattern
'multi-clause condition references to locate the UI elements in the UI
tree.
Dim analysisCond As IUIAutomationCondition
Dim displayCond As IUIAutomationCondition
Dim disPanelCond As IUIAutomationCondition
'stores the language code for the current active language
Dim languageCode As Integer
'get the active application language
languageCode = _
Application.International(XlApplicationInternational.xlCountryCode)
'choose the language dictionary based on the active language
If languageCode = 49 Then
Set translations = getGermanTranslations
Else
Set translations = getEnglishTranslations
End If
'get a reference to the UI element tree
Set root = oAutomation.GetRootElement
'locate the Excel window
Set xl = root.FindFirst(TreeScope_Descendants, PropCondition(oAutomation,
eUIA_NamePropertyId, _
"test wb for hidden ribbon - new (delete me).xlsm - Excel"))
'click the Analysis tab
Set analysisCond = _
oAutomation.CreateAndCondition(PropCondition(oAutomation,
eUIA_NamePropertyId, translate("Analysis")), _
PropCondition(oAutomation, eUIA_ClassNamePropertyId, "NetUIRibbonTab"))
Set analysisTab = xl.FindFirst(TreeScope_Descendants, analysisCond)
Set selPattern = _
analysisTab.GetCurrentPattern(UIA_SelectionItemPatternId)
selPattern.Select
'locate the Design Panel Group
Set xlrib = xl.FindFirst(TreeScope_Descendants,
PropCondition(oAutomation, eUIA_NamePropertyId, translate("Lower
Ribbon")))
Set dpanel = xlrib.FindFirst(TreeScope_Descendants,
PropCondition(oAutomation, eUIA_NamePropertyId, translate("Design Panel
Group")))
'try locating the Display button
Set displayCond = _
oAutomation.CreateAndCondition(PropCondition(oAutomation,
eUIA_NamePropertyId, translate("Display Button")), _
PropCondition(oAutomation, eUIA_ClassNamePropertyId,
"NetUIRibbonButton"))
Set display = dpanel.FindFirst(TreeScope_Descendants, displayCond)
'true when the window is shrunk to a point where the display button
'is part of the dropdown menu under Design Panel
If display Is Nothing Then
'expand the Design Panel dropdown first
Set disPanelCond = _
oAutomation.CreateAndCondition(PropCondition(oAutomation,
eUIA_NamePropertyId, translate("Design Panel Menu")), _
PropCondition(oAutomation, eUIA_ClassNamePropertyId, "NetUIAnchor"))
Set dpanel = dpanel.FindFirst(TreeScope_Descendants, disPanelCond)
Set expcolPattern = _
dpanel.GetCurrentPattern(UIA_ExpandCollapsePatternId)
expcolPattern.Expand
'attempt to locate the Display button again
Set display = dpanel.FindFirst(TreeScope_Descendants, displayCond)
End If
'Click the Display button programmatically (FINALLY!!!)
Set oTogglePattern = display.GetCurrentPattern(UIA_TogglePatternId)
oTogglePattern.Toggle
Application.ScreenUpdating = True
End Sub
'generate a Condition object with the string to be matched against the
selected property
Function PropCondition(UiAutomation As CUIAutomation, Prop As oConditions,
Requirement As String) As IUIAutomationCondition
Select Case Prop
Case 0
Set PropCondition = _
UiAutomation.CreatePropertyCondition(UIA_NamePropertyId,
Requirement)
Case 1
Set PropCondition = _
UiAutomation.CreatePropertyCondition(UIA_AutomationIdPropertyId,
Requirement)
Case 2
Set PropCondition = _
UiAutomation.CreatePropertyCondition(UIA_ClassNamePropertyId,
Requirement)
Case 3
Set PropCondition = _
UiAutomation.CreatePropertyCondition(UIA_ClassNamePropertyId,
Requirement)
End Select
End Function
I have this strange issue that I cannot find the origin for, but I'm able to reproduce it consistently. Every time I click on the button without having the VBA editor opened, I get run time error 91.
This is the line on which the error occurs - analysisTab refers to Nothing which means it wasn't set for some reason.
I would appreciate it if you can help me spot the cause of this annoying problem.
来源:https://stackoverflow.com/questions/57711269/vba-macro-error-91-without-vba-editor-on-no-error-when-its-open