ユーザー定義型は、C言語でいう構造体のような仕組みです。
一般的な変数には、1つの値しか格納できません。配列には複数の値を同時に格納できますが、それは同じ型の値です。名前(文字列型)と年齢(長整数型)のように、異なる型の値をセットにして格納するには、配列ではなくユーザー定義型が便利です。ユーザー定義型は、次のようにして使います。
Type ○○ 要素1 As 型 要素2 As 型 End Type Sub Sample() Dim 変数名 As ○○ 変数名.要素1 = 値 変数名.要素2 = 値 End Sub
ユーザー定義型の定義は、宣言セクションでします。宣言セクションとは、モジュールの一番上に記述したプロシージャの、さらに上の部分です。変数の宣言を強制するオプションを設定したとき、モジュールに挿入されるOption Explicitや、APIの宣言やパブリック変数の宣言などをするのと同じ場所です。
ユーザー定義型として定義した型を変数として使うには、そのほかの型宣言と同じように「Dim 変数名 As ○○」と指定します。As まで入力すると、ユーザー定義型として定義した型名がリストに表示されます。
Type Personal Name As String Age As Long End Type Sub Sample56() Dim Member As Personal Member.Name = "tanaka" Member.Age = 38 End Sub
ちょっと複雑になりますが、ユーザー定義型で定義する要素の型に、別のユーザー定義型を指定することも可能です。
Type Personal Name As String Age As Long End Type Type Area Tokyo As Personal Yokohama As Personal End Type Sub Sample57() Dim Member As Area Member.Tokyo.Name = "suzuki" Member.Yokohama.Age = 28 End Sub
複数の値をセットにして管理するとはいえ、その数が少ないときは一般的な変数でも代用できます。上記の例は、次のように書いても大きな違いはありません。
Sub Sample58() Dim UserName As String, UserAge As Long UserName = "tanaka" UserAge = 38 End Sub
ユーザー定義型が活躍するのは、そうしたセットのデータを大量に管理する場合でしょう。そんなときは、ユーザー定義型の配列を使います。たとえば、次のようなCSVデータがあったとします。
ワークシート上に入力されているデータなら、何も変数に格納しなくたって、セルを検索すれば事が足ります。セルに入力されているということは、変数に格納されているようなものですから。そうではなく、CSVデータのように外部ファイルとしてデータが存在する場合は、一度変数に格納しておくと後々の処理が楽になります。ここでは、UserFormと組み合わせた例をお見せします。ちょっと長いですけど、実用的なマクロとなると、どうしてもこれくらいになっちゃいますね。がんばって読んでください。
Private Type Personal Name As String Age As Long Area As String Sex As String End Type Dim Member() As Personal Private Sub ListBox1_Change() Dim i As Long For i = 0 To UBound(Member) If Member(i).Name = ListBox1.Value Then Label1.Caption = Member(i).Age Label2.Caption = Member(i).Area If Member(i).Sex = "男性" Then OptionButton1.Value = True Else OptionButton2.Value = True End If Exit Sub End If Next i End Sub Private Sub UserForm_Initialize() Dim buf As String, i As Long Const Data As String = "C:\Work\Member.csv" If Dir(Data) = "" Then Exit Sub Open Data For Input As #1 Do Until EOF(1) Line Input #1, buf ReDim Preserve Member(i) Member(i).Name = Split(buf, ",")(0) Member(i).Age = Split(buf, ",")(1) Member(i).Area = Split(buf, ",")(2) Member(i).Sex = Split(buf, ",")(3) i = i + 1 Loop Close #1 For i = 0 To UBound(Member) ListBox1.AddItem Member(i).Name Next i ListBox1.ListIndex = 0 End Sub