VBA 遍历形状名称数组

VBA Loop Through Array of Shape Names

我正在尝试遍历形状数组列表,但在遇到函数 ShapeExists 时,我不断收到错误“下标超出范围”。如果我单独执行 ShapeExists 函数,代码运行良好。我做错了什么?

 Sub Workbook_Open() 
    Debug.Print "Begin Workbook_Open sub." 
    Dim ws As Worksheet 
    Dim wsCount As Integer 
    Dim shapeList As Variant 
    Dim element As Variant 
     
    CheckFirstRun = True 
     
    wsCount = Sheets.Count 
    Debug.Print "Number of Sheets: " & wsCount 

    shapeList = Array("exportData", "InitializeData")

        Debug.Print "Making sure the Initilize and Export buttons are hidden." 
        For i = 1 To wsCount 
            For Each element In shapeList 
                Debug.Print "Working to hide shape " & element 
                If ShapeExists(element) = True Then 
                    Debug.Print element & " exists. Working to hide." 
                    HideShapes (element) 
                End If 
            Next element 
            'Sheets(i).Shapes("exportData").Visible = False 
            'Sheets(i).Shapes("InitializeData").Visible = False 
        Next i  
    Debug.Print "End Workbook_Open sub." 
End Sub 
  
Sub HideShapes(shapeName As Variant) 
    Sheets(i).Shapes(shapeName).Visible = False 
End Sub 
  
Function ShapeExists(shapeName As Variant) As Boolean 
    Dim sh As Shape 
    For Each sh In Sheets(i).Shapes 
        If sh.Name = shapeName Then ShapeExists = True 
        Debug.Print ShapeExists 
    Next sh 
End Function

请注意,虽然您可以添加一个全局变量 i,但它通常被认为是不好的做法,最好更改您的子例程以添加一个参数,以便您可以传入 sheet 数字以及形状名称:

Sub HideShapes(wsNumber As Long, shapeName As Variant) 
    ThisWorkBook.WorkSheets(wsNumber).Shapes(shapeName).Visible = False 
End Sub

然后这样调用:

HideShapes i, element 'no parentheses!

另请注意,最好始终明确说明要影响哪个工作簿(即使在 ThisWorkbook 代码模块中并非绝对必要)

同样 SheetsWorksheets - 第一个还包括图表 sheets(如果存在)。

这里有一个稍微不同的方法:

Sub Workbook_Open()
    Dim ws As Worksheet, wb As Worksheet
    Dim shapeList As Variant
    Dim element As Variant
     
    Debug.Print "Begin Workbook_Open sub."
    'CheckFirstRun = True
    shapeList = Array("exportData", "InitializeData")
    
    For Each ws In ThisWorkbook.Worksheets 'easier loop
        For Each element In shapeList
            On Error Resume Next  'ignore error if no matching shape
            ws.Shapes(element).Visible = False
            On Error GoTo 0       'stop ignoring errors
        Next element
    Next ws
    Debug.Print "End Workbook_Open sub."
End Sub