如何将具有范围、单个单元格和/或直接输入的 ParamArray 转换为数组?

use*_*829 2 excel vba

我正在尝试构建一个 UDF,它将接受 ParamArray,该 ParamArray 将接受一个单元格、一系列单元格和/或直接值。然后我需要循环遍历 ParamArray 以获取传递的所有值,但是当我尝试 ReDim 数组时,它会卡住并且循环结束。我这样做是完全错误的吗?因为这看起来工作量太大了。

Function myudf(first As Variant, ParamArray args() As Variant)
    Dim i, j As Long
    Dim argsarray() As Variant
    ReDim argsarray(0, 0)

    For i = 0 To UBound(args)
        If Not IsObject(args(i)) Then
            ReDim Preserve argsarray(0 To UBound(argsarray) + 1)
            argsarray(i) = args(i) ' Handle explicitly passed arguments, e.g. "1,goonie,etc")

        ElseIf IsArray(args(i).Value2) Then
            For j = 1 To UBound(args(i).Value2)
                ReDim Preserve argsarray(0 To UBound(argsarray) + 1)
                argsarray(UBound(argsarray) + 1) = args(j).Value2 ' Handle a range of cells, e.g. A1:A3
            Next j
        Else
            ReDim Preserve argsarray(0 To UBound(argsarray) + 1)
            argsarray(i) = args(i).Value2 ' Handle individual cells, e.g. A1)
        End If
    Next i

    myudf = Join(argsarray, ",")

End Function
Run Code Online (Sandbox Code Playgroud)

Dmi*_*liv 5

你有一个二维数组ReDim argsarray(0, 0)

正如MSDN的后续报道:

如果使用Preserve,则只能调整数组最后一个维度的大小。对于每个其他维度,您必须指定现有数组的边界。

所以,这行不通ReDim Preserve argsarray(0 To UBound(argsarray) + 1),但这个行得通ReDim Preserve argsarray(0, 0 To UBound(argsarray) + 1)

顺便说一句,Preserve这是非常昂贵的操作。我建议您检查代码并ReDim argsarray在计算所有单元格后使用 single

试试这个:

Function myudf(first As Variant, ParamArray args() As Variant)
    Dim i As Long, cnt As Long
    Dim argsarray() As Variant

    Dim c, rng

    For Each rng In args
        If IsObject(rng) Then
            cnt = cnt + rng.Cells.Count
        ElseIf IsArray(rng) Then
            cnt = cnt + UBound(rng)
        Else
            cnt = cnt + 1
        End If
    Next

    ReDim argsarray(1 To cnt)

    i = 1
    For Each rng In args
        If IsObject(rng) Or IsArray(rng) Then
            For Each c In rng
                argsarray(i) = c
                i = i + 1
            Next
        Else
            argsarray(i) = rng
            i = i + 1
        End If
    Next

    myudf = Join(argsarray, ",")
End Function
Run Code Online (Sandbox Code Playgroud)

如果 UDF 的目的只是连接值,您也可以使用这个:

Function myudf2(first As Variant, ParamArray args() As Variant)       
    Dim c, rng

    For Each rng In args
        If IsObject(rng) Or IsArray(rng) Then
            For Each c In rng
                myudf2 = myudf2 & c & ","
            Next
        Else
            myudf2 = myudf2 & rng & ","
        End If
    Next

    myudf2 = Left(myudf2, Len(myudf2) - 1)
End Function
Run Code Online (Sandbox Code Playgroud)