在VBA中从函数返回数组

25
我想写一个函数来返回一个整数数组,以便我可以对它们进行索引,但是我不知道VBA的语法。以下是伪代码:
function getStats() as integer
    dim returnVal(4) as integer
    returnVal(0)=c2percent14
    returnVal(1)=c3percent14
    returnVal(2)=c4percent14
    returnVal(3)=c5percent14
    getStats=returnVal
end function

msgbox getStats(3)

这些值都应该是整数,然后我可以通过索引返回数组中我想要的统计数据。
如何从函数中返回一个数组?
3个回答

52

将函数类型设置为数组:

function getStats() as Integer()    
    dim returnVal(0 to 3) as integer

    returnVal(0) = c2percent14
    returnVal(1) = c3percent14
    returnVal(2) = c4percent14
    returnVal(3) = c5percent14

    getStats = returnVal
end function

Sub mysub()
   Dim myArray() As Integer

   myArray = getStats()

   msgbox myArray(3)
end sub 

6
这两个答案的应用都可靠吗?还是其中一个更受推荐/它们有不同的属性,导致在某些使用情况下,一个可能更具优势或劣势? - hansa
1
这段代码原本无法正常工作。在我发布答案后的10天内,该代码已根据我的答案中可行的代码进行了修改。 - SendETHToThisAddress

10
Function getStats() As Variant
    getstats = Array(c2percent14, c3percent14, c4percent14, c5percent14)
End Function

Sub mysub()
    Dim myArray() As Variant
    myArray = getStats()
    msgbox myArray(3)
End Sub 

getStats现在是类型为“Variant”的数组。该方法的缺点在于,您不再具有静态类型,因为Variant可以是任何东西。


12
这个解释不正确。根据编码,getStats是一个不需要参数且返回变量的函数,该变量可能是数组,也可能是整数、字符串等。 - Tom the Toolman

8

我会在这里添加一个答案,因为我很高兴地说,在经历了几个小时的挫败和错误信息后,我终于知道如何返回数组了!下面是从函数中返回数组的方法:

Sub mysub()
    Dim i As Integer, s As String
    Dim myArray() As Integer 'if you declare a size here you will get "Compile error, can't assign to array"
    myArray = getStats()

    s = "Array values returned:" & vbCrLf
    For i = 0 To UBound(myArray)
        s = (s & myArray(i) & " ")
    Next
    MsgBox s
End Sub

Function getStats() As Integer() 'The return type must be EXACTLY the same as the type declared in the calling sub.
    Dim returnVal(2) As Integer 'if you DON'T declare a size here you will get "Run-time error '9': Subscript out of range"

    returnVal(0) = 0
    returnVal(1) = 1
    returnVal(2) = 2
    'returnVal(3) = 3 This will throw an error. Remember that an array declared (2) will hold 3 values, 0-2.
    getStats = returnVal
End Function

输出:

在此输入图片描述

我在这里添加的注释非常重要。虽然VBA通常很宽松,但这个特定的事情非常挑剔。以下条件是函数、赋值和返回值所必需的:

  • 调用子程序中声明的数组必须是未声明长度的。
  • 返回数组的函数必须完全相同的类型。即使你在子程序中将数组声明为Variant类型,而函数返回整数类型的数组也不行。
  • 在函数中必须使用临时数组。你不能像在一般函数中那样将值分配给函数名称(getStats)。只有在分配了所有值到临时数组后才能将临时数组分配给函数名称。任何试图将getStats重新定义为数组的尝试都会导致错误。
  • 临时数组必须声明长度。在VBA中,在声明长度之前不能将值分配给数组索引。

1
任何尝试将getStats重新定义为数组都会引发错误 - 实际上并不是这样。确实,您无法从getStats内部分配getStats(2) = 1,但这仅因为编译器将其与递归调用getStats混淆(即使参数不匹配)。但是,您可以执行Redim getStats(2),然后可以将getStats传递给某个接受整数数组的其他函数。因此,变量名称有效,只是无法直接访问其元素。 - GSerg
“temp” 数组必须在声明时指定长度,但不一定是一个 固定 数组(其长度无法更改)。因此,您可以声明 Dim returnVal() As Integer,只需在分配元素之前使用 ReDim returnVal(2) 即可。 - GSerg
请记住,声明为(2)的数组将容纳3个值,从0到2。默认的数组下限由Option Base控制,可以是0或1,因此(2)数组可能包含两个或三个元素。出于这个原因,我总是更喜欢显式地列出边界,例如Dim returnVal(0 To 2)Dim returnVal(11 To 42) - GSerg
@GSerg 在你的第一条评论中,这就是我的意思,你不能像布尔值或字符串返回函数那样直接为函数名赋值。在你的第二条评论中,是的,这就是我的意思,你必须在某个时候声明长度,所以最好在变量声明时就声明它,对吧? - SendETHToThisAddress
2
你必须在某个时刻声明长度,所以最好在变量声明时就这样做了,对吧?副作用是不同的,这可能重要也可能不重要。Dim returnVal(2) 创建一个无法调整大小的数组。如果您需要在函数中稍后调整它,则无法这样做。Dim returnVal():ReDim returnVal(2) 创建一个可以调整大小的数组。在返回数组之后,这并不重要,因为然后它可以被重新调整大小。 - GSerg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接