サーチ…
配列のコピー
=
演算子を使用して、VBA配列を同じ型の配列にコピーできます。配列は同じ型でなければなりません。さもなければ、コードは "配列に代入できません"というコンパイルエラーをスローします。
Dim source(0 to 2) As Long
Dim destinationLong() As Long
Dim destinationDouble() As Double
destinationLong = source ' copies contents of source into destinationLong
destinationDouble = source ' does not compile
ソース配列は固定または動的にできますが、宛先配列は動的でなければなりません。固定配列にコピーしようとすると、 "Can not assign to array"コンパイルエラーがスローされます。受信配列内の既存データはすべて失われ、その範囲と次元は送信元配列と同じに変更されます。
Dim source() As Long
ReDim source(0 To 2)
Dim fixed(0 To 2) As Long
Dim dynamic() As Long
fixed = source ' does not compile
dynamic = source ' does compile
Dim dynamic2() As Long
ReDim dynamic2(0 to 6, 3 to 99)
dynamic2 = source ' dynamic2 now has dimension (0 to 2)
コピーが作成されると、2つの配列はメモリ内で別々のものになります。つまり、2つの変数は同じ基礎データへの参照ではないため、一方の配列の変更は他方の配列には表示されません。
Dim source(0 To 2) As Long
Dim destination() As Long
source(0) = 3
source(1) = 1
source(2) = 4
destination = source
destination(0) = 2
Debug.Print source(0); source(1); source(2) ' outputs: 3 1 4
Debug.Print destination(0); destination(1); destination(2) ' outputs: 2 1 4
オブジェクトの配列のコピー
オブジェクトの配列では、それらのオブジェクトへの参照がコピーされ、オブジェクト自体はコピーされません。 1つの配列内のオブジェクトに変更が加えられた場合、その変更は他の配列でも変更されているように見えます - 両方とも同じオブジェクトを参照しています。ただし、要素を1つの配列内の別のオブジェクトに設定しても、それを他の配列に設定することはできません。
Dim source(0 To 2) As Range
Dim destination() As Range
Set source(0) = Range("A1"): source(0).Value = 3
Set source(1) = Range("A2"): source(1).Value = 1
Set source(2) = Range("A3"): source(2).Value = 4
destination = source
Set destination(0) = Range("A4") 'reference changed in destination but not source
destination(0).Value = 2 'affects an object only in destination
destination(1).Value = 5 'affects an object in both source and destination
Debug.Print source(0); source(1); source(2) ' outputs 3 5 4
Debug.Print destination(0); destination(1); destination(2) ' outputs 2 5 4
配列を含むバリアント
バリアント変数との間で配列をコピーすることもできます。バリアントからコピーするときは、受信配列と同じ型の配列を含む必要があります。それ以外の場合は、「型の不一致」ランタイムエラーが発生します。
Dim var As Variant
Dim source(0 To 2) As Range
Dim destination() As Range
var = source
destination = var
var = 5
destination = var ' throws runtime error
関数から配列を返す
通常のモジュール(クラスモジュールではない)の関数は、データ型の後に()
を置くことによって配列を返すことができます。
Function arrayOfPiDigits() As Long()
Dim outputArray(0 To 2) As Long
outputArray(0) = 3
outputArray(1) = 1
outputArray(2) = 4
arrayOfPiDigits = outputArray
End Function
関数の結果は、同じ型またはバリアントの動的配列に格納することができます。要素には、第2のブラケットセットを使用して直接アクセスすることもできますが、これは毎回関数を呼び出すため、複数回使用する予定がある場合は結果を新しい配列に格納することをお勧めします
Sub arrayExample()
Dim destination() As Long
Dim var As Variant
destination = arrayOfPiDigits()
var = arrayOfPiDigits
Debug.Print destination(0) ' outputs 3
Debug.Print var(1) ' outputs 1
Debug.Print arrayOfPiDigits()(2) ' outputs 4
End Sub
返されるのは、実際には関数内の配列のコピーであり、参照ではありません。関数が静的配列の内容を返す場合、そのデータは呼び出し側のプロシージャによって変更できません。
出力引数による配列の出力
プロシージャの引数が入力であり、戻り値を介して出力されるのは、通常は良いコーディング方法です。しかし、VBAの制限により、プロシージャがByRef
引数を介してデータを出力する必要がByRef
ます。
固定配列への出力
Sub threePiDigits(ByRef destination() As Long)
destination(0) = 3
destination(1) = 1
destination(2) = 4
End Sub
Sub printPiDigits()
Dim digits(0 To 2) As Long
threePiDigits digits
Debug.Print digits(0); digits(1); digits(2) ' outputs 3 1 4
End Sub
クラスメソッドからの配列の出力
出力引数は、クラスモジュールのメソッド/プロシージャから配列を出力するためにも使用できます
' Class Module 'MathConstants'
Sub threePiDigits(ByRef destination() As Long)
ReDim destination(0 To 2)
destination(0) = 3
destination(1) = 1
destination(2) = 4
End Sub
' Standard Code Module
Sub printPiDigits()
Dim digits() As Long
Dim mathConsts As New MathConstants
mathConsts.threePiDigits digits
Debug.Print digits(0); digits(1); digits(2) ' outputs 3 1 4
End Sub
プロジェクトへの配列の受け渡し
配列変数の名前の後ろに()
置くことによって、配列を手続きに渡すことができます。
Function countElements(ByRef arr() As Double) As Long
countElements = UBound(arr) - LBound(arr) + 1
End Function
配列は参照渡しする必要があります。渡すメカニズムが指定されていない場合、たとえばmyFunction(arr())
場合、VBAはデフォルトでByRef
を引き受けますが、明示的にするのは良いコーディング方法です。たとえば、 myFunction(ByVal arr())
配列を値渡しで渡すと、「配列引数はByRefでなければなりません」コンパイルエラー(VBEオプションでAuto Syntax Check
がチェックされていないと「構文エラー」コンパイルエラー) 。
参照渡しとは、配列への変更が呼び出し手順で保持されることを意味します。
Sub testArrayPassing()
Dim source(0 To 1) As Long
source(0) = 3
source(1) = 1
Debug.Print doubleAndSum(source) ' outputs 8
Debug.Print source(0); source(1) ' outputs 6 2
End Sub
Function doubleAndSum(ByRef arr() As Long)
arr(0) = arr(0) * 2
arr(1) = arr(1) * 2
doubleAndSum = arr(0) + arr(1)
End Function
元の配列を変更しないようにするには、要素を変更しないように関数を記述するように注意してください。
Function doubleAndSum(ByRef arr() As Long)
doubleAndSum = arr(0) * 2 + arr(1) * 2
End Function
あるいは、配列の作業コピーを作成し、そのコピーで作業してください。
Function doubleAndSum(ByRef arr() As Long)
Dim copyOfArr() As Long
copyOfArr = arr
copyOfArr(0) = copyOfArr(0) * 2
copyOfArr(1) = copyOfArr(1) * 2
doubleAndSum = copyOfArr(0) + copyOfArr(1)
End Function