我正在尝试创建一个数组,其中包含工作簿中包含“模板”一词的所有工作表名称。我认为最简单的方法是首先创建一个集合,然后将其转换为数组,但我遇到了麻烦。现在我得到的错误是
collectionToArray (col)
线。我收到了
参数不可选错误
相当困难,任何帮助都非常感激。谢谢!
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
答案 0 :(得分:7)
一切都在那里,你只是没有使用函数作为一个函数。您需要将结果存储在某些内容中,例如&#39; NewArray&#39; ..?
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
答案 1 :(得分:6)
collectionToArray (col)
请注意函数名称和参数列表之间的空格?这就是VBE告诉你的事情:
我将接受该论点,将其评估为值,然后将其ByVal
传递给您正在调用的过程,即使该过程的签名为ByRef
,明确与否。
这种“无关的括号”习惯不可避免地会让你在某个时刻碰到奇怪的“对象必需”运行时错误:失去它。
Function
过度使用IMO:Variant
可以很好地包装数组,因此我会更改其签名以返回Variant
而不是Variant()
Integer
是一个16位有符号整数类型(在某些其他语言中为short
),使用Long
代替(32位有符号整数)可能更好一点,即int
在其他一些语言中) - 这样当你需要处理超过32,767个值时,你就会避免遇到“溢出”问题(如果涉及到工作表,这种情况尤其常见)。
Public col As New Collection
这会使col
成为自动实例化的对象变量,并且它可能会产生令人惊讶的副作用。请考虑以下代码:
Dim c As New Collection
c.Add 42
Set c = Nothing
c.Add 42
Debug.Print c.Count
您希望此代码能做什么?如果你认为“错误91,因为对象引用是Nothing
”,你就会被自动实例化所困扰。最好避免它,并将声明和作业保持为单独的指令。
除此之外,CLR's answer还有您的解决方案:Function
应该返回一个值,调用代码应该使用该值。
result = MyFunction(args)
你会注意到VBE清除了你可能想要在MyFunction
和(args)
之间添加的任何空格:这是VBE告诉你的:
我将接受该论点,将其传递给MyFunction
,并将函数的返回值分配给result
。
答案 2 :(得分:3)
这是我的collectionToArray功能:
Public Function CollectionToArray(myCol As Collection) As Variant
Dim result As Variant
Dim cnt As Long
ReDim result(myCol.Count)
For cnt = 0 To myCol.Count - 1
result(cnt) = myCol(cnt + 1)
Next cnt
CollectionToArray = result
End Function
它比您正在使用的更好,因为如果集合为空,它不会给出错误。 为了避免在您的案例中出现空集合的错误,您可以考虑添加如下检查:
If col.Count > 0 Then k = CollectionToArray(col)