VB6の配列とは?宣言・要素数・動的配列の使い方
VB6の既存システムを改修していると、配列を使った処理が出てくることがあります。
配列は、複数の値を1つの変数名でまとめて扱うための仕組みです。
たとえば、CSVファイルから読み込んだ複数行のデータ、帳票出力用の明細、画面上の入力値、コード表のような固定値などを一時的に保持するときに使われます。
VB6の配列は、基本的な考え方はシンプルですが、実際の既存コードでは注意が必要です。
固定配列なのか、動的配列なのか。
添字は0から始まるのか、1から始まるのか。
ReDimでサイズ変更しているのか。
ReDim Preserveで値を保持しているのか。
LBoundやUBoundで範囲を確認しているのか。
Variant型に配列が入っていないか。
このあたりを確認しないまま修正すると、「インデックスが有効範囲にありません」「配列が初期化されていません」「想定より1件多い・少ない」といった不具合につながることがあります。
この記事では、VB6の配列の基本、宣言方法、要素数の考え方、動的配列の使い方、既存システムを改修するときの注意点を解説します。
VB6の配列とは
VB6の配列とは、複数の値を1つの変数名で管理するための仕組みです。
通常の変数は、1つの変数に1つの値を入れます。
Dim name As String
name = "田中"
一方、配列では、同じ変数名の中に複数の値を持たせることができます。
Dim names(2) As String
names(0) = "田中"
names(1) = "佐藤"
names(2) = "鈴木"
この場合、names という配列に3つの文字列を格納しています。
配列の各値は「要素」と呼ばれます。
要素を取り出すときは、かっこの中に番号を指定します。この番号を「添字」と呼びます。
MsgBox names(0)
上記の場合は、田中 が表示されます。
VB6の業務システムでは、配列は次のような場面でよく使われます。
CSVの行データを分解する。
複数の明細行を一時的に保持する。
帳票出力用のデータを並べる。
固定のコード値をまとめて持つ。
検索結果や集計結果を一時的に保持する。
同じ処理を複数件に対して繰り返す。
単純な変数だけでは扱いにくい複数データを、まとめて処理したいときに配列を使います。
VB6で配列を使う基本構文
VB6で配列を宣言する基本形は、次の通りです。
Dim 配列名(上限) As 型
たとえば、文字列の配列を作る場合は次のように書きます。
Dim arrName(2) As String
この書き方では、arrName(0)、arrName(1)、arrName(2) を使えます。
注意したいのは、Dim arrName(2) と書いた場合、要素数が2個ではなく、通常は0から2までの3個になる点です。
arrName(0) = "大阪"
arrName(1) = "東京"
arrName(2) = "名古屋"
VB6の配列では、宣言時に指定した数値は「最大添字」として扱われることが多くあります。
そのため、配列の件数を考えるときは、宣言の数字だけを見て判断しない方が安全です。
固定配列の使い方
固定配列とは、宣言時にサイズを決める配列です。
Dim scores(4) As Integer
この場合、通常は scores(0) から scores(4) まで使えます。
つまり、5個の値を格納できます。
scores(0) = 80
scores(1) = 75
scores(2) = 90
scores(3) = 60
scores(4) = 100
固定配列は、件数があらかじめ決まっている場合に使いやすいです。
たとえば、曜日、月、固定の分類コード、一時的な集計枠などです。
Dim monthName(12) As String
monthName(1) = "1月"
monthName(2) = "2月"
monthName(3) = "3月"
ただし、このように1から使っている配列もあれば、0から使っている配列もあります。
既存VB6コードを読むときは、配列が0開始なのか、1開始なのかを必ず確認する必要があります。
配列の要素数の考え方
VB6の配列で間違いやすいのが、要素数の考え方です。
たとえば、次の配列があります。
Dim arr(10) As String
この場合、通常は arr(0) から arr(10) まで使えます。
つまり、実際の要素数は11個です。
「10個の配列を作ったつもり」でも、実際には11個使える状態になっている場合があります。
逆に、明確に1から10までにしたい場合は、次のように下限と上限を指定できます。
Dim arr(1 To 10) As String
この場合は、arr(1) から arr(10) まで使えます。
要素数は10個です。
既存システムでは、次のような書き方が混在していることがあります。
Dim arrA(10) As String
Dim arrB(1 To 10) As String
この2つは同じように見えて、添字の範囲が違います。
そのため、ループ処理で固定値を使うと不具合の原因になります。
LBoundとUBoundの使い方
配列の範囲を安全に確認するには、LBound と UBound を使います。
LBound は配列の最小添字を返します。UBound は配列の最大添字を返します。
Dim arr(1 To 3) As String
Dim i As Integer
arr(1) = "A"
arr(2) = "B"
arr(3) = "C"
For i = LBound(arr) To UBound(arr)
MsgBox arr(i)
Next i
このように書くと、配列の開始位置が0でも1でも対応しやすくなります。
既存コードでは、次のように固定値でループしていることがあります。
For i = 0 To 10
MsgBox arr(i)
Next i
この書き方は、配列の範囲が変わったときにエラーになりやすいです。
改修時に配列のサイズや開始位置を変更する可能性がある場合は、LBound と UBound を使った書き方の方が安全です。
動的配列とは
動的配列とは、実行時にサイズを決められる配列です。
固定配列では、宣言時にサイズを決めます。
Dim arr(10) As String
一方、動的配列では、宣言時にはサイズを指定しません。
Dim arr() As String
この状態では、まだ配列のサイズは確保されていません。
実際に使う前に、ReDim を使ってサイズを指定します。
ReDim arr(5)
これで、通常は arr(0) から arr(5) まで使えるようになります。
動的配列は、件数が事前に分からない処理でよく使われます。
CSVを読み込む。
ファイルの行数を数えてから格納する。
検索結果を一時的に保持する。
帳票明細を一時的に作成する。
条件に一致したデータだけを配列に追加する。
件数が固定でない処理では、動的配列の方が扱いやすい場合があります。
ReDimの使い方
ReDim は、動的配列のサイズを指定するために使います。
Dim arr() As String
ReDim arr(2)
arr(0) = "A"
arr(1) = "B"
arr(2) = "C"
この場合、arr(0) から arr(2) まで使えます。
ただし、ReDim を実行すると、それまで配列に入っていた値は消えます。
Dim arr() As String
ReDim arr(1)
arr(0) = "A"
arr(1) = "B"
ReDim arr(2)
MsgBox arr(0)
この場合、2回目の ReDim によって、最初に入れていた値は消えます。
既存コードで ReDim が複数回出てくる場合は、どのタイミングで値が消えるのかを確認する必要があります。
ReDim Preserveの使い方
配列の中身を残したままサイズを変更したい場合は、ReDim Preserve を使います。
Dim arr() As String
ReDim arr(1)
arr(0) = "A"
arr(1) = "B"
ReDim Preserve arr(2)
arr(2) = "C"
この場合、arr(0) と arr(1) の値を残したまま、arr(2) を追加できます。
Preserve を付けないと、既存の値は消えます。
そのため、既存データを保持したまま配列を拡張したい場合は、ReDim Preserve が必要です。
ただし、ReDim Preserve を大量データの処理で何度も実行すると、処理が重くなることがあります。
たとえば、CSVを1行読むたびに ReDim Preserve を実行するような処理です。
ReDim Preserve arr(count)
arr(count) = lineText
少量データであれば問題にならないこともありますが、大量データでは処理速度に影響する場合があります。
既存システムで処理が遅い場合、ループ内で ReDim Preserve を繰り返していないか確認するとよいです。
多次元配列の使い方
VB6では、多次元配列も使えます。
多次元配列は、行と列のようにデータを持ちたい場合に使われます。
Dim data(2, 3) As String
この場合、2つの添字を指定して値を扱います。
data(0, 0) = "商品A"
data(0, 1) = "10"
data(0, 2) = "1000"
data(1, 0) = "商品B"
data(1, 1) = "5"
data(1, 2) = "2000"
帳票出力用の明細や、表形式のデータを一時的に扱うときに使われることがあります。
ただし、多次元配列は可読性が下がりやすいです。
data(i, 0) が商品名なのか、商品コードなのか、金額なのか、コードだけでは分かりにくくなることがあります。
既存VB6コードを改修するときは、配列のどの列に何が入っているかを確認する必要があります。
コメントがなければ、代入している箇所や帳票出力している箇所から意味を追うことになります。
配列を関数やプロシージャに渡す方法
VB6では、配列を関数やプロシージャに渡して処理することがあります。
Private Sub PrintNames(ByRef names() As String)
Dim i As Integer
For i = LBound(names) To UBound(names)
Debug.Print names(i)
Next i
End Sub
呼び出し側は次のようになります。
Dim arr(2) As String
arr(0) = "田中"
arr(1) = "佐藤"
arr(2) = "鈴木"
Call PrintNames(arr)
配列を渡す場合、呼び出し先で中身が変更される可能性があります。
特に ByRef で渡されている場合は、プロシージャ内で値を変更すると呼び出し元にも影響します。
既存コードでは、配列を渡している先で値を書き換えていることがあります。
そのため、配列を改修するときは、宣言箇所だけでなく、どのプロシージャに渡しているかも確認する必要があります。
Variant型と配列の関係
VB6では、Variant型に配列が入っている場合があります。
たとえば、Split 関数の戻り値は配列として扱われます。
Dim arr As Variant
arr = Split("A,B,C", ",")
MsgBox arr(0)
この場合、arr(0) には A が入ります。
Variant型は柔軟ですが、型が分かりにくくなります。
既存コードで Variant が多用されている場合、その変数に単一の値が入っているのか、配列が入っているのかを確認する必要があります。
VB6からVB.NETやC#へ移行する場合、Variant配列は見直しが必要になることがあります。
移行先では、String配列、Integer配列、List、DataTableなど、用途に応じて明確な型へ整理した方が保守しやすくなります。
Split関数で配列を作る方法
VB6では、文字列を区切り文字で分割して配列にする処理がよく使われます。
Dim arr() As String
arr = Split("001,田中,大阪", ",")
この場合、次のように値を取り出せます。
MsgBox arr(0) '001
MsgBox arr(1) '田中
MsgBox arr(2) '大阪
CSV処理や設定値の分解でよく使われる書き方です。
ただし、実務では注意が必要です。
想定した数の項目がない。
空文字が含まれる。
区切り文字が存在しない。
項目の中にカンマが含まれる。
行によって列数が違う。
たとえば、次のようなコードがあります。
arr = Split(lineText, ",")
customerCode = arr(0)
customerName = arr(1)
address = arr(2)
このコードは、必ず3項目ある前提です。
もし2項目しかない行が入ってきた場合、arr(2) でエラーになります。
そのため、CSVや外部ファイルを扱う場合は、UBound を使って要素数を確認してから参照する方が安全です。
arr = Split(lineText, ",")
If UBound(arr) >= 2 Then
customerCode = arr(0)
customerName = arr(1)
address = arr(2)
End If
既存システムでは、入力データが正常である前提で作られていることがあります。
改修時には、想定外データが入った場合にどこでエラーになるかを確認しておくことが大切です。
配列でよくあるエラー
VB6の配列でよくあるエラーの一つが、「インデックスが有効範囲にありません」です。
これは、配列の範囲外を参照したときに起こります。
Dim arr(2) As String
MsgBox arr(3)
この場合、arr(0) から arr(2) までしか存在しないため、arr(3) を参照するとエラーになります。
また、動的配列を ReDim する前に参照した場合もエラーになります。
Dim arr() As String
MsgBox arr(0)
この配列はまだサイズが確保されていないため、参照できません。
既存コードで配列エラーが出る場合は、次の点を確認します。
配列はReDimされているか。
添字の開始位置は正しいか。
UBoundを超えて参照していないか。
Split後の要素数を確認しているか。
ループ範囲が固定値になっていないか。
ReDimで値が消えていないか。
配列のエラーは、原因箇所とエラー発生箇所が離れていることがあります。
たとえば、配列に値を入れる処理ではなく、後で取り出す処理でエラーになる場合があります。
配列が空かどうかを確認するときの注意点
VB6では、動的配列が空かどうかを単純に判定しにくい場合があります。
特に、次のような未初期化の動的配列に対して UBound を実行するとエラーになります。
Dim arr() As String
MsgBox UBound(arr)
このような場合、エラー処理を使って判定している既存コードもあります。
Private Function IsArrayInitialized(ByRef arr() As String) As Boolean
On Error GoTo ErrHandler
Dim n As Long
n = UBound(arr)
IsArrayInitialized = True
Exit Function
ErrHandler:
IsArrayInitialized = False
End Function
配列の空判定は、プロジェクト内で書き方がばらばらになっていることがあります。
改修時には、どのようなルールで空配列を扱っているかを確認した方が安全です。
特に、CSV読込や検索結果の処理では、0件の場合の扱いが重要です。
0件のときに配列が未初期化のままなのか、ReDim arr(0) されているのかによって、後続処理の書き方が変わります。
配列を使ったループ処理の注意点
配列は、For文と組み合わせて使うことが多くあります。
Dim arr(2) As String
Dim i As Integer
arr(0) = "A"
arr(1) = "B"
arr(2) = "C"
For i = LBound(arr) To UBound(arr)
Debug.Print arr(i)
Next i
この書き方であれば、配列の範囲に合わせて処理できます。
注意したいのは、ループ範囲を固定値で書いている場合です。
For i = 0 To 10
Debug.Print arr(i)
Next i
この場合、配列のサイズが10未満ならエラーになります。
逆に、配列のサイズが11以上ある場合でも、途中までしか処理されません。
既存VB6コードでは、配列サイズとループ範囲が別々に管理されていることがあります。
改修時に配列サイズを変更した場合、ループ範囲も同時に見直す必要があります。
また、ループ中に ReDim している処理にも注意が必要です。
For i = 0 To 10
ReDim arr(i)
arr(i) = CStr(i)
Next i
このようなコードでは、ReDim のたびに配列の値が消えます。
値を保持したい場合は ReDim Preserve が必要ですが、頻繁に使うと処理が重くなる場合があります。
既存VB6コードで配列を読むときのポイント
既存VB6システムを改修するときは、配列の値の流れを追うことが重要です。
まず、配列の宣言場所を確認します。
フォーム内で宣言されているのか。
標準モジュールで宣言されているのか。
プロシージャ内のローカル変数なのか。
Public変数として使われているのか。
次に、固定配列か動的配列かを確認します。
Dim arr(10) As String
このように宣言されていれば固定配列です。
Dim arr() As String
このように宣言されていれば動的配列です。
動的配列の場合は、どこで ReDim されているかを確認します。ReDim Preserve が使われている場合は、どのタイミングで要素が追加されているかも確認します。
また、配列に値を入れている箇所と、配列の値を使っている箇所が離れていることがあります。
特に、フォーム間で配列を共有している場合や、標準モジュールのPublic配列を使っている場合は注意が必要です。
配列を改修するときは、次の順番で確認すると整理しやすいです。
配列の宣言場所を確認する。
固定配列か動的配列か確認する。
添字の開始位置を確認する。
ReDimの場所を確認する。
Preserveの有無を確認する。
値を代入している箇所を確認する。
値を参照している箇所を確認する。
配列を渡しているプロシージャを確認する。
帳票・CSV・DB更新に使われていないか確認する。
配列は一見小さな処理に見えても、帳票出力やデータ更新に関わっていることがあります。
修正前に影響範囲を確認することが大切です。
VB6からVB.NET・C#へ移行するときの配列の注意点
VB6からVB.NETやC#へ移行するときも、配列の扱いには注意が必要です。
VB6では、Variant型、動的配列、ReDim Preserve、Option Base、暗黙の型変換などが使われていることがあります。
これらをそのまま移行しようとすると、移行先で分かりにくいコードになる場合があります。
特に見直したいのは、次のような処理です。
Variant型に配列を入れている。
ReDim Preserveを繰り返している。
配列の添字開始位置が統一されていない。
多次元配列に業務データを詰め込んでいる。
配列の列番号に意味を持たせている。
Public配列を複数画面で共有している。
移行先では、単純な配列ではなく、List、Dictionary、DataTable、クラスなどに置き換えた方が分かりやすい場合があります。
たとえば、商品明細を多次元配列で持っている場合、移行時には商品明細クラスの一覧として持つ方が読みやすくなることがあります。
VB6では次のようなコードになっていることがあります。
data(i, 0) = productCode
data(i, 1) = productName
data(i, 2) = quantity
data(i, 3) = price
この場合、0列目が商品コード、1列目が商品名、2列目が数量、3列目が単価という意味を、コードを読んで理解する必要があります。
移行時には、意味のある項目名で扱える形に見直すと、保守しやすくなります。
配列を使う処理を改修するときの確認ポイント
VB6の既存システムで配列を使う処理を改修する場合は、単にエラー箇所だけを直すのではなく、前後の処理も確認する必要があります。
確認したいポイントは次の通りです。
入力データの件数は最大でどれくらいか。
配列サイズは固定で足りるか。
動的配列の初期化タイミングは正しいか。
ReDimで既存値が消えていないか。
ReDim Preserveを多用していないか。
添字範囲を超えて参照していないか。
0件の場合の動作は問題ないか。
帳票やCSV出力に影響しないか。
DB更新処理に使われていないか。
移行時に型を整理できないか。
たとえば、配列サイズを増やすだけの修正でも、帳票の明細行数、CSV出力項目、ループ処理、集計処理に影響することがあります。
また、配列の中身がどの業務データを表しているか分からないまま修正すると、表面上は動いていても、出力結果が変わってしまうことがあります。
配列を改修するときは、値を入れる処理、値を加工する処理、値を出力する処理の3つを確認することが重要です。
まとめ
VB6の配列は、複数の値をまとめて扱うための基本的な仕組みです。
固定配列では宣言時にサイズを決め、動的配列では ReDim を使って実行時にサイズを決めます。
配列の範囲を確認する場合は、固定値ではなく LBound と UBound を使うと安全です。
また、ReDim を実行すると既存の値は消えます。
値を保持したままサイズを変更したい場合は、ReDim Preserve を使います。ただし、多用すると処理速度に影響する場合があります。
既存VB6システムを改修するときは、配列の宣言場所、添字の範囲、ReDimのタイミング、Preserveの有無、値の流れを確認することが重要です。
特に、CSV、帳票、データベース更新、外部連携に使われている配列は、修正の影響が大きくなることがあります。
VB6からVB.NETやC#へ移行する場合は、Variant配列、多次元配列、Public配列、ReDim Preserveを多用した処理を見直し、保守しやすい形に整理することも検討するとよいでしょう。