将VBA集合转换为数组

San*_*ean 3 excel vba excel-vba

我正在尝试创建一个数组,其中包含工作簿中包含"模板"一词的所有工作表名称.我认为最简单的方法是首先创建一个集合,然后将其转换为数组,但我遇到了麻烦.现在我得到的错误是在

collectionToArray (col)
Run Code Online (Sandbox Code Playgroud)

线.我收到了

参数不可选错误

相当困难,任何帮助都非常感激.谢谢!!

Public col As New Collection
Public Sub Test()
For Each ws In ThisWorkbook.Worksheets
    If InStr(ws.Name, "Template") <> 0 Then
        col.Add ws.Name
    End If
Next ws

collectionToArray (col)
End Sub

Function collectionToArray(c As Collection) As Variant()
    Dim a() As Variant: ReDim a(0 To c.Count - 1)
    Dim i As Integer
    For i = 1 To c.Count
        a(i - 1) = c.Item(i)
    Next
    collectionToArray = a
End Function
Run Code Online (Sandbox Code Playgroud)

CLR*_*CLR 8

就在那里,你只是没有将函数用作函数.你需要将结果存储在某些内容中,比如'NewArray'..?

Public col As New Collection
Public Sub Test()
For Each ws In ThisWorkbook.Worksheets
    If InStr(ws.Name, "Template") <> 0 Then
        col.Add ws.Name
    End If
Next ws


' Tweaked as per Vityata's comment

If col.Count > 0 Then 
    newarray = collectionToArray(col)
Else
    ' Do something else
End If

End Sub

Function collectionToArray(c As Collection) As Variant()
    Dim a() As Variant: ReDim a(0 To c.Count - 1)
    Dim i As Integer
    For i = 1 To c.Count
        a(i - 1) = c.Item(i)
    Next
    collectionToArray = a
End Function
Run Code Online (Sandbox Code Playgroud)


Mat*_*don 7

collectionToArray (col)
Run Code Online (Sandbox Code Playgroud)

请注意函数名称和参数列表之间的空格?那是VBE告诉你的:

我将接受该参数,将其作为值进行评估,然后将其传递ByVal给您正在调用的过程,即使该过程的签名ByRef明确与否也是如此.

这种"无关的括号"习惯不可避免地会让你在某个时刻碰到奇怪的"对象必需"运行时错误:失去它.

Function是IMO矫枉过正:一个Variant可以完美地包住一个数组,所以我会改变它的签名,以返回Variant代替Variant().

Integer作为一个16位有符号整数类型(即short在其他一些语言中),使用Long替代(32位有符号整数,即int在其他一些语言中)可能是一个更好的主意- 这样你就可以避免遇到"溢出"当您需要处理超过32,767个值时出现问题(如果涉及工作表,则尤为常见).

Public col As New Collection
Run Code Online (Sandbox Code Playgroud)

这使得col一个自动实例化的对象的变量,它有潜在的令人惊讶的副作用.考虑以下代码:

Dim c As New Collection
c.Add 42
Set c = Nothing
c.Add 42
Debug.Print c.Count
Run Code Online (Sandbox Code Playgroud)

你期望这段代码做什么?如果你认为"错误91,因为对象引用是Nothing",你就被自动实例化所困扰了.最好避免它,并将声明和作业保持为单独的指令.

除此之外,CLR的答案有你的解决方案:a Function应该返回一个值,调用代码应该消耗.

result = MyFunction(args)
Run Code Online (Sandbox Code Playgroud)

你会注意到VBE清除你可能想要在这里MyFunction(args)这里添加的任何空格:这是VBE告诉你的:

我将接受该参数,将其传递给MyFunction,并将函数的返回值赋值给result.

  • 这实际上是一个很好的答案,我不得不阅读它两次并使用一些代码来准确理解您在第一部分中的意思。也许你可以考虑添加一个这样的例子 - https://github.com/Vitosh/VBA_personal/blob/master/ByReferenceByValue.vb 以使第一部分更容易理解。 (2认同)