【问题标题】:How do I create and pass string array to a sub in Excel VBA?如何在 Excel VBA 中创建字符串数组并将其传递给子对象?
【发布时间】:2014-12-31 01:23:26
【问题描述】:

VBA 数组对我来说是新的,似乎有多种方法可以创建字符串数组。

通过用户范围的计数,我知道数组中需要多少项(所以也许我不需要动态数组??)。我无法将数组传递给另一个子例程。

思考过程如下:

  1. 遍历用户名列表
  2. 为每个人创建一个工作表
  3. 在我迭代时将每个用户名保存在一个数组中
  4. 在另一个子例程中,选择我创建的所有工作表并保存为 PDF

下面是我的代码。我收到运行时错误 9 - 下标超出范围(指数组对象)

感谢您的帮助!谢谢!

Sub CreateAllDashboards(StartDate As Date, EndDate As Date)
'Used to iterate through the list of users and call the Sub to create Dashboards

Dim UserNameRangeStart As Range
Set UserNameRangeStart = Range("UserName")
Dim SheetNames() As String

'Cyle through users
For i = 1 To GetUserNameRange().CounT
    'Some code
    ReDim Preserve SheetNames(i)
    SheetNames(i) = UserNameRangeStart.Offset(i, 0).Value
Next i

Call CreatePDF(EndDate, SheetNames) 'Also tried SheetNames()

End Sub

Sub CreatePDF(FileDate As Date, ByRef SheetNames As Variant)

Dim FilePath As String, FileName As String

FilePath = Application.ActiveWorkbook.Path
FileName = "Production Dashboards - " & Format(FileDate, "mmddyy") & ".pdf"


ThisWorkbook.Sheets(SheetNames).Select

ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, FileName:= _
    FileName, Quality:=xlQualityStandard, IncludeDocProperties:=True, _
     IgnorePrintAreas:=False, OpenAfterPublish:=True

End Sub

【问题讨论】:

    标签: arrays vba excel


    【解决方案1】:

    数组参数没有问题,它被正确传递给方法CreatePDF(...)。参数类型可以改为SheetNames() As String,但SheetNames As Variant也可以。

    然后Run-time error 9 - Subscript out of range 在此处引发ThisWorkbook.Sheets(SheetNames).Select,因为数组SheetNames 包含无效的工作表名称,这是第一项。此项为空字符串,空字符串作为工作表名称无效。

    For Next 循环中,索引以值1 开头,但数组以0 开头。所以数组SheetNames 的第一项保持不变,最后是一个空字符串。为了解决这个问题,将ReDim 的下限明确设置为1。高温

    (注意:如果省略下限,则使用Option Base,如果未指定Option Base,则使用0。)

    'Cyle through users
    For i = 1 To GetUserNameRange().Count
        'Some code
        ReDim Preserve SheetNames(1 To i)
        SheetNames(i) = UserNameRangeStart.Offset(i, 0).value
    Next i
    

    【讨论】:

    • 谢谢@dee。这就是我需要的!
    • @Barrett Kuethen 我很高兴它有帮助!
    【解决方案2】:

    我会改变这个:
    Sub CreatePDF(FileDate As Date, ByRef SheetNames As Variant)

    致:
    Sub CreatePDF(FileDate As Date, SheetNames() As String)

    但您的问题出在这一行:
    ThisWorkbook.Sheets(SheetNames).Select

    根据 dee 的评论编辑: 您可以在 .Sheets() 中放置一组工作表名称,但没有空行。所以在你的子“CreateAllDashboards”中这样做:

    ReDim Preserve SheetNames(i - 1)
    SheetNames(i - 1) = UserNameRangeStart.Offset(i, 0).Value
    

    您可以阅读 that 关于 VBA 中的数组。

    【讨论】:

    【解决方案3】:

    我使用一个名为 Users 的范围和另一个名为 FileDate 的工作表测试了以下内容。它按照你的要求做。

    Run-time error 9 - Subscript out of range 错误的原因是您必须引用数组元素。 ThisWorkbook.Sheets(SheetNames).Select 会抛出错误,但 ThisWorkbook.Sheets(SheetNames(x)).Select 不会(只要 x 已初始化并且在数组的范围内)

    Sub PopulateArray()
    Dim user As Range
    Dim SheetNames As Variant
    
        ReDim SheetNames(1 To 1) 'Initialise the array
        For Each user In [Users]
            ThisWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
            With Worksheets(Worksheets.Count)
                .Name = user.Value2
                .[A1] = user.Value2 'you can't print a blank sheet!
            End With
            SheetNames(UBound(SheetNames)) = user.Value2
            ReDim Preserve SheetNames(1 To UBound(SheetNames) + 1)
        Next user
        ReDim Preserve SheetNames(1 To UBound(SheetNames) - 1) 'Delete the last element
        Call CreatePDF([FileDate], SheetNames)
    End Sub
    
    Sub CreatePDF(FileDate As Date, ByRef SheetNames As Variant)
    
    Dim FilePath As String, FileName As String
    Dim x As Long
    
        FilePath = Application.ActiveWorkbook.Path & "\" 'Note backslash added to path.
        FileName = "Amtec Production Dashboards - " & Format(FileDate, "mmddyy")
    
        For x = 1 To UBound(SheetNames)
            ThisWorkbook.Sheets(SheetNames(x)).ExportAsFixedFormat Type:=xlTypePDF, FileName:= _
                FileName & SheetNames(x) & ".pdf", Quality:=xlQualityStandard, IncludeDocProperties:=True, _
                 IgnorePrintAreas:=False, OpenAfterPublish:=True
        Next x
    End Sub
    

    上面演示了如何根据请求将数组解析到另一个子,但您也可以相当容易地将 CreatePDF 代码集成到调用子中。

    【讨论】:

    • 我以同样的方式开始我的回答,但@dee 将我指向this 以表明您可以,令人惊讶的是,我必须说,在.Sheets() 中引用一个数组。 Run-time error 9SheetNames 数组中的空行抛出。
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 2019-11-16
    相关资源
    最近更新 更多