2016-10-11 10 views
0

Excelで配列の計算をしようとしていますが、1次元の範囲の数を逆にする必要があります私は、スプレッドシートに反転を作成するのではなく、そのための関数を記述したいと思います。Excel VBA関数:範囲を渡し、配列に変換し、逆変換し、配列を返す方法

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

2次元配列を逆にすることもできますが、それは些細なことです。私の質問は、関数が確実に(1、N)の範囲で動作するようにすることです。

ありがとうございます!

+1

'i = x.rows.Count'と' i = x.Columns.Count'の両方が無意味に見えます。 'i'の値は決して使用されません。それは何をすべきか?おそらく、あなたが初期化しようとしていたのは、 '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

もう一度、私は行/ colsする必要がありますときに私は設定時に私のエラーを参照していただきありがとうございます。非常に恥ずかしい –

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次元配列に関数を拡張する時間を節約します。 –

+0

なぜ私は分かりませんが、渡された範囲の長さが1の場合はあなたや私のどちらの仕事もありません。これは簡単なケースですが、同じ値を返すべきではありませんか? –

+0

前述したように、私のコードは範囲の有効性を検証しません。範囲が1つのセルだけの場合、 'source.Value'は配列を返しません。エラー13「型の不一致」が発生します。範囲が連続していない場合はコードが失敗し、その他の場合はコードが失敗する可能性があります。 –

関連する問題