2016-10-11 87 views
0

我想在Excel中做一些數組運算,這需要我反轉一定數量的一維範圍很多次,所以我想爲它編寫一個函數,而不是在電子表格中創建反轉。我在VBA中寫了一個reverse()函數,但它返回#VALUE!電子表格中的錯誤。無論數組大小如何,也不管是輸入相同大小的數組函數,還是使用SUM()等彙總函數進行封裝。我證實了倒車邏輯可以作爲一個Sub。這導致我相信問題是傳遞/返回範圍/數組,但我不明白什麼是錯的。Excel VBA函數:如何通過範圍,轉換爲數組,反轉,並返回數組

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)範圍內工作。

謝謝!

+1

'i = x.rows.Count'和'i = x.Columns.Count'都顯得毫無意義。這些「我」的價值從未被使用過。那應該做什麼?也許是你想要初始化的變量'rows'和'cols'(而不是'i')。實際上,'rows'和'cols'都不會從其默認值'0'移動。 –

+0

哇!對我而言,這是多麼的疏忽。現在起作用了。謝謝約翰。 –

回答

1

查找下面的代碼....

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 
+0

再次,謝謝我現在看到我的錯誤設置我應該是行/列。非常尷尬 –

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 
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 

請注意,範圍有效性沒有驗證。

+0

謝謝,這並不明顯幫助我捕捉到我的錯誤,但確實節省了將函數擴展到2-dim數組的時間。 –

+0

我不確定爲什麼,但是如果範圍傳遞的長度等於1,那麼您或我的工作都不會工作。這是一個微不足道的情況,但它不應該返回相同的值嗎? –

+0

如上所述,我的代碼不會對範圍有效性進行驗證。如果範圍只有一個單元格,'source.Value'不會返回一個數組,並且您將得到錯誤13「類型不匹配」。如果範圍不是連續的,也可能在其他情況下,代碼也可能失敗。 –

相關問題