以下は、配列と範囲を一様に処理するために書いたコードです(Accepting a range as an array parameter)。これには、という名前の関数が含まれています。これは、数字のの2Dコレクションで呼び出すことができ、同じ数値を2次元配列の倍数として返す関数です。1次元配列から1次元配列への変換を中止する
Public Function item(ByRef A As Variant, i As Integer, j As Integer) As Double
If TypeName(A) = "Range" Then
item = A.Cells(i, j)
Else
item = A(i, j)
End If
End Function
Public Function rows(ByRef A As Variant) As Integer
If TypeName(A) = "Range" Then
rows = A.rows.Count
Else
rows = UBound(A, 1) - LBound(A, 1) + 1
End If
End Function
Public Function cols(ByRef A As Variant) As Integer
If TypeName(A) = "Range" Then
cols = A.columns.Count
Else
cols = UBound(A, 2) - LBound(A, 2) + 1
End If
End Function
Public Function sanitise(ByRef A As Variant) As Double()
Debug.Print TypeName(A)
If TypeName(A) = "Double()" Then
sanitise = A
Else
Debug.Print rows(A)
Dim B() As Double
ReDim B(1 To rows(A), 1 To cols(A))
Dim i As Integer, j As Integer
For i = 1 To rows(A)
For j = 1 To cols(A)
B(i, j) = item(A, i, j)
Next j
Next i
sanitise = B
End If
End Function
実装は、あなたがそれを期待どおりに動作します:ワークシートの範囲を選択し、A1:B2
を言って、コールはそれに消毒するとあなたは同じことの2つのコピーがあります:
しかし、何が問題になるのですか。sanitise
^2です。
sanitise
を2回コールすると、が呼び出されます()。複数の行:細かい、単一の列:細かい。それがなぜ起こるか
は、私が知っている:最初のsanitise
た後、どのような形状のアレイのExcel忘れが返されました。 (タイプも忘れています:Double()
の代わりに、sanitise
の入力はVariant()
です)
誰もこの問題を回避する方法を知っていますか?
sanitise
を2度続けて使用することはまずありませんが、上記の例は、2次元配列に沿って2つの関数を作成することが難しい理由を示しています。
注:この問題は、sanitise
がワークシートから呼び出されたときにのみ発生します。
アップデートは、私がそれを考え出した:行と同義でワークシートの1Dストレージ、ためので考慮する必要があること
が私の最終バージョン:
Public Function get_2D(ByRef A As Variant) As Double()
'turns various forms of input into a 2D array of Doubles
Dim result() As Double
Dim i As Integer
If TypeOf A Is Range Or dims(A) = 2 Then
ReDim result(1 To rows(A), 1 To cols(A))
Dim j As Integer
For i = 1 To rows(A)
For j = 1 To cols(A)
result(i, j) = item(A, i, j)
Next j
Next i
Else
'1D storage is treated as a row
ReDim result(1 To 1, 1 To rows(A)) 'rows(A) gets length of the first axis
For i = 1 To rows(A)
result(1, i) = A(i)
Next i
End If
sanitise = result
End Function
dims
があります配列の次元数を返す関数:https://support.microsoft.com/en-us/kb/152288
' 'あなたのDebug.Print行(A)の後に'あなたがいることがわかります外側の 'sanitise'が実行されたとき、つまり' cols(A) 'を呼び出している間にクラッシュしたときに何も印刷しません。なぜなら、内部の 'sanitise'は、(1〜1、2〜2)の形の配列を返すからです。なぜなら、渡される前に(1〜2)の形の配列に変換されました外側の '' sanitise''にコードがあり、コードは1次元配列、単なる範囲または2次元配列を扱いません。 – YowE3K
エラーを再現できませんでした。あなたはダウンロードリンクを提供できますか? –