■ 配列や構造体を一気に複写(コピー)しよう!
配列については初級編でも少しふれましたが、今回はより詳しく解説したいと思います。
特に配列の中身を他の配列に一度で一気にコピーする方法は、おぼえておくと大変便利ですので、ぜひここで理解しておいてください。
■ 配列の種類
配列には静的配列と動的配列の2種類があります。
・静的配列
配列の宣言時に配列のサイズを定義します。
Dim MyStr(1) As String
Dim MyStr(0 To 1) As String
これは、一般的によく使われる静的配列の定義です。上と下では同じ静的配列を定義しています。
どちらも、MyStr(0),MyStr(1)の2つの文字列型変数の領域をメモリ上に確保します。
ちなみにDim MyStr(1 To 2) … としてやれば、配列の要素番号の開始値は1になります。
また、モジュールの宣言部で
Option Base 1
を宣言した場合、明示的に要素番号の開始値を0に指定しない限り、開始値はデフォルトで1になります。
・動的配列
配列の宣言時にはサイズを指定しません。ReDimステートメントで配列のサイズを再定義します。
Dim MyStr() As String
Dim MyNum() As Long
ReDim MyStr(MyNum)
条件などによって要素数が変化する配列は、ReDimステートメントを使用して配列の要素数を増減させます。
このとき配列自体が初期化されるため、格納していた値は無効になります。
そこでPreserve キーワードを使用すると、有効要素番号に格納されていた値を変更後も保持することができます。
ReDim Preserve MyStr(MyNum+1)
要素番号、開始値〜MyNum までに格納されていた配列の値は、変更後も保持されます。
※ 多次元配列の場合、Preserveキーワードを使用して要素数を変更できるのは最終次元に限られます。
ReDim MyStr(1, 1) を
ReDim Preserve MyStr(1, 2) にすることはできますが、
ReDim Preserve MyStr(2, 1) にしようとすると、エラーになります。
■ 配列の複写(コピー)
配列をコピーする場合、ループさせて配列の要素毎に複写するやり方は一般的ですが、複写先の配列を動的配列にすることでループを使用しなくても一回で一気にコピーすることが可能です。
Public Sub test()
Dim MyStr1() As String
Dim MyStr2() As String
ReDim MyStr1(1)
MyStr1(0) = "aaa"
MyStr1(1) = "bbb"
MyStr2 = MyStr1
MyStr1(0) = "ccc"
Debug.Print MyStr1(0) & ":" & MyStr2(0)
End Sub
MyStr1は静的配列であっても構いません。複写先の配列MyStr2が動的配列でさえあればOKです。
MyStr2 = MyStr1
の部分で配列を一気に複写しています。
その後、MyStr1(0)の内容を書き換えました。イミディエイトウィンドウに出力される値は、"ccc:aaa" です。
ここで気をつけてほしいのは、配列を複写するときは、あくまで「値渡し」をしているということです。
「参照渡し」はしていないので注意が必要です。
VB.netユーザーならば、配列のコピーは参照渡しが基本だと思われるでしょうが、VBA(VB6)では値渡しになります。
複写後、MyStr1(0)の値を書き換えてもMyStr2(0)に反映されなかったのは、参照渡しでなく値渡しをしていたからですね。
また、Variant変数を使っても、同じように一回で配列の全体コピーが可能です。
Public Sub test()
Dim MyStr1 As Variant
Dim MyStr2 As Variant
MyStr1 = Array("aaa", "bbb")
MyStr2 = MyStr1
Debug.Print MyStr1(0) & ":" & MyStr2(0)
End Sub
Variant変数への配列の格納はArray関数を使用して行います。
この方法で複写を行っても値渡しでコピーが行われます。
さらに構造体(ユーザー定義型)も、同じ方法を使って中身を一度にコピーすることが可能です。
Public Type MyType
type1 As String
type2 As String
End Type
Public Sub test()
Dim MyType1 As MyType
Dim MyType2 As MyType
MyType1.type1 = "aaa"
MyType1.type2 = "bbb"
MyType2 = MyType1
Debug.Print MyType1.type1 & ":" & MyType2.type1
End Sub
構造体の中身がいっぺんにコピーされましたね。この場合も値渡しです。
構造体(ユーザー定義型)が配列の場合でも同様に複写が可能です。
■ 配列の初期化
配列の初期化には、Erase ステートメントを使用した初期化が大変便利です。
Erase MyStr
配列、MyStr の中身が一気に初期化されます。
・静的配列の場合は、全ての要素を初期化します。
・動的配列の場合は、割り当てたメモリ領域を解放します。
・Variant配列の場合は、Empty値に初期化されます。
なお、配列をもたない構造体(ユーザー定義型)の初期化には使用できません。
(配列をもつ構造体の場合、静的なら値の初期化を、動的ならメモリの解放を行います)
以上、
配列はプログラミングをする上で、とても重要な概念です。中級者、上級者になるほど、配列の使い方が目に見えて上手になります。
ぜひ配列をマスターし、あなたのプログラミングテクニックをさらにステップアップしてください。
※VBAの扱える配列の最大次元数は60次元ですが、3次元以上の配列は極端にメモリ領域を使用します。
慎重に扱う必要がありますので注意してください。
|
|
|