Excel VBA函数:如何传递范围,转换为数组,反向和返回数组

时间:2016-10-11 04:03:05

标签: arrays excel vba excel-vba

我正在尝试在Excel中进行一些数学运算,这需要我多次反转一些1维范围,所以我想为它编写一个函数,而不是在电子表格中创建反转。 / p>

我在VBA中编写了reverse()函数,但它返回#VALUE!电子表格中的错误。无论数组大小如何,也无论是输入相同大小的数组函数还是使用SUM()等汇总函数封装都会发生这种情况。我验证了反转逻辑作为Sub工作。这让我相信问题在于传递/返回范围/数组,但我不明白错误。

Function reverse(x As Range) As Variant()
' Array formula that reverses a one-dimensional array (1 row, x columns)
    Dim oldArray() As Variant, newArray() As Variant
    Dim rows As Long: i = x.rows.Count
    Dim cols  As Long: i = x.Columns.Count
    ReDim oldArray(1 To rows, 1 To cols), newArray(1 To rows, 1 To cols)

    oldArray = x.Value
    newArray = oldArray

    For i = 1 To cols / 2 Step 1
        newArray(1, i) = oldArray(1, cols - i + 1)
        newArray(1, cols - i + 1) = oldArray(1, i)
    Next

    reverse = newArray
End Function

请记住,我可以将其扩展为反向二维数组,但这是微不足道的部分。我的问题是试图确保函数在(1,N)范围内工作。

谢谢!

3 个答案:

答案 0 :(得分:2)

查找以下代码....

Function reverse(x As Range) As Variant()
' Array formula that reverses a one-dimensional array (1 row, x columns)
    Dim oldArray() As Variant, newArray() As Variant
    Dim rows As Long
    rows = x.rows.Count
    Dim cols  As Long
    cols = x.Columns.Count
    ReDim oldArray(1 To rows, 1 To cols), newArray(1 To rows, 1 To cols)

    oldArray = x.Value
    newArray = oldArray

    For i = 1 To cols / 2 Step 1
        newArray(1, i) = oldArray(1, cols - i + 1)
        newArray(1, cols - i + 1) = oldArray(1, i)
    Next
reverse = newArray
End Function

答案 1 :(得分:1)

以下代码更通用,它使用可选参数来确定是否应反转行,列或两者(或无)。默认情况下,它会反转列。

Function ReverseRange(Source As Range, Optional ReverseRows As Boolean = False, Optional ReverseColumns As Boolean = True) As Variant()
    Dim SourceArray() As Variant
    Dim DestArray() As Variant
    SourceArray = Source.value

    Dim nRows As Long, nColumns As Long
    nRows = UBound(SourceArray, 1)
    nColumns = UBound(SourceArray, 2)
    ReDim DestArray(1 To nRows, 1 To nColumns)

    Dim r As Long, r2 As Long, c As Long, c2 As Long
    For r = 1 To nRows
        r2 = IIf(ReverseRows, nRows - r + 1, r)
        For c = 1 To nColumns
            c2 = IIf(ReverseColumns, nColumns - c + 1, c)
            DestArray(r2, c2) = SourceArray(r, c)
        Next c
    Next r
    ReverseRange = DestArray
End Function

请注意,没有关于范围有效性的验证。

答案 2 :(得分:0)

无论行数如何,这都将反转范围中的列。

Function reverse(Source As Range) As Variant()
    Dim Data, RevData
    Dim x As Long, y As Long, y1 As Long

    Data = Source.Value

    ReDim RevData(1 to UBound(Data, 1),1 to UBound(Data, 2))

    For x = 1 To UBound(Data, 1)
        y1 = UBound(Data, 2)
        For y = 1 To UBound(Data, 2)
            RevData(x, y1) = Data(x, y)
            y1 = y1 - 1
        Next
    Next
    reverse = RevData
End Function