VBA(Visual Basic for Applications)では、
複数の関連するデータを一つの単位として扱いたいときに「構造体(User-Defined Type)」を使います。
構造体を活用すると、異なるデータ型の情報をひとまとめにでき、コードの可読性や管理のしやすさが向上します。
この記事では、VBAの構造体の基本的な使い方を、
図やサンプルコードを用いりながら、できるだけわかりやすく解説いたします。
-著者情報-
名前:Utatane
VBA(マクロ)歴:3年
エクセル使用歴:15年以上
ひとこと:初心者だった当時に戻った気持ちになって解説いたします
VBA(マクロ)の構造体とは?
構造体とは、異なるデータ型の変数を1つのデータ単位としてまとめる仕組みです。
なにやらピンとこないですね…。
下図のような表をイメージしていただくとわかりやすいかと思います。

文字列・整数・少数などが含まれていますね。
一覧表みたいなイメージでしょうか。
これらをひとまとまりに管理できるのが構造体です。
例えばこれらを「utatane」というひとつのオブジェクト(変数)で管理することができます。
便利ですよね。
では、構造体の作り方を見ていきましょう。
構造体の作り方
ひとまず全コードをお見せします。
少し長いですが、後ほど1つ1つ解説いたします。
Type プロフィール
Name As String
Age As Integer
Height As Double
End Type
Sub 年齢確認()
Dim tanaka As プロフィール
tanaka.Name = "田中"
tanaka.Age = 30
tanaka.Height = 175.5
Debug.Print tanaka.Name & "さんの年齢は" & tanaka.Age & "歳です。"
End Sub
構造体の宣言
まずは構造体を宣言します。
Type プロフィール
Name As String
Age As Integer
Height As Double
End Type
構造体は、「Type」~「End Type」までが宣言となります。
「Type」を書いたら、構造体の名前を書きます。
今回は「プロフィール」としました。
忘れないうちに「End Type」も書いておきましょう。
Type プロフィール
End Type
では2行目にそれぞれの列名(タイトル名)を宣言していきます。
今回は「Name」「Age」「Height」とします。
変数の宣言と同じです。
Name As String
Age As Integer
Height As Double
これでデータ上は下図のようになりました。

次に各データを追加していきましょう。
【注意点】
構造体の宣言はプロシージャの外に書いてください。
下記のようにプロシージャ内に書いてしまうと、エラーが発生して動きません。
Sub 失敗例()
Type プロフィール
Name As String
Age As Integer
Height As Double
End Type
Dim tanaka As プロフィール
tanaka.Name = "田中"
tanaka.Age = 30
tanaka.Height = 175.5
Debug.Print tanaka.Name & "さんの年齢は" & tanaka.Age & "歳です。"
End Sub

データの追加
田中さんなど、メンバーの追加は下記のように行います。
Sub 年齢確認()
Dim tanaka As プロフィール
tanaka.Name = "田中"
tanaka.Age = 30
tanaka.Height = 175.5
End Sub
まずはプロシージャを作成しましょう。
マクロを作り始める時と同じです。
Sub 年齢確認()
End Sub
では8行目に田中さんのデータを追加していきます。
まずは構造体のメンバーであることを宣言します。
【 Dim メンバー名 As 構造体名 】
Dim tanaka As プロフィール
これで、「tanaka」が「プロフィール(構造体)」の要素であることが宣言できました。
あとは各データを追加するだけです。
tanaka.Name = "田中"
tanaka.Age = 30
tanaka.Height = 175.5
メンバー名(tanaka)の後ろに「.」を書いたら、列名(Name)を書きます。
そして「=(イコール)」を書いたら、代入したい値(田中)を記述して完了です。
「Age」や「Height」も同様に記述します。
これでデータ上は下図のようになりました。

田中さんだけではなく、山田さんも追加したい場合は、下記コードのように記述します。
Sub 年齢確認()
Dim tanaka As プロフィール
tanaka.Name = "田中"
tanaka.Age = 30
tanaka.Height = 175.5
Dim yamada As プロフィール
yamada.Name = "山田"
yamada.Age = 28
yamada.Height = 163.1
End Sub
データ上は下記のようになります。

データの一部を出力
Debug.Print tanaka.Name & "さんの年齢は" & tanaka.Age & "歳です。"
作成した構造体を確認するため、上記コードにてデータの一部を出力しています。
今回は、「Debug.Print」を用いて「イミディエイトウィンドウ」に出力しました。

「Debug.Print」の使い方や表示方法については、下記記事をご参考ください。
ここまで、構造体の作り方を解説いたしました。
次に、作成した構造体の活用例を紹介いたします。
構造体の活用例
構造体の活用例を2つ紹介いたします。
作成した構造体をエクセルに出力
前項で作成した構造体を、エクセルに出力するVBAコードです。
Type プロフィール
Name As String
Age As Integer
Height As Double
End Type
Sub 構造体をエクセルに出力()
Dim ws As Worksheet
Dim member(1 To 3) As プロフィール
Dim i As Integer
' ワークシートを取得
Set ws = ThisWorkbook.Sheets(1)
' 構造体配列にデータを設定
member(1).Name = "田中": member(1).Age = 30: member(1).Height = 175.5
member(2).Name = "山田": member(2).Age = 28: member(2).Height = 163.1
member(3).Name = "佐藤": member(3).Age = 35: member(3).Height = 181.8
' タイトルを書き込み
ws.Range("A1").Value = "Name"
ws.Range("B1").Value = "Age"
ws.Range("C1").Value = "Height"
' 構造体のデータをExcelに書き込む
For i = 1 To 3
ws.Cells(i + 1, 1).Value = member(i).Name
ws.Cells(i + 1, 2).Value = member(i).Age
ws.Cells(i + 1, 3).Value = member(i).Height
Next i
End Sub
構造体のメンバーについて、
前項では「tanaka」「yamada」としましたが、これではループ処理ができません。
メンバーを配列にして、member(1)→member(2)→member(3)と繰り返しできるようにしています。
あとはエクセルの1行目にタイトルである「Name」「Age」「Height」を書き込み、
2行目以降にメンバーを順番に書き込むよう、For文でループさせています。

▼関連記事
エクセルデータから構造体を作成
今度は逆に、エクセルデータを読み込んで構造体を作成するVBAコードです。
Type プロフィール
Name As String
Age As Integer
Height As Double
End Type
Sub エクセルデータから構造体を作成()
Dim ws As Worksheet
Dim member() As プロフィール
Dim lastRow As Integer
Dim i As Integer
' ワークシートを取得
Set ws = ThisWorkbook.Sheets(1)
' データがある最終行を取得
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 読み込んだデータの行数に応じて配列の要素数を決定
ReDim member(1 To lastRow - 1)
' データを構造体の配列に格納
For i = 2 To lastRow
member(i - 1).Name = ws.Cells(i, 1).Value
member(i - 1).Age = ws.Cells(i, 2).Value
member(i - 1).Height = ws.Cells(i, 3).Value
Next i
' 確認用メッセージ
Dim msg As String
For i = 1 To UBound(member)
msg = msg & "名前: " & member(i).Name & vbCrLf & _
"年齢: " & member(i).Age & vbCrLf & _
"慎重: " & member(i).Height & vbCrLf & vbCrLf
Next i
MsgBox msg, vbInformation, "Excelデータの読み込み結果"
End Sub
表があるワークシートを取得し、表の最終行を割り出します。
あとは1行目から最終行までを構造体として取り込んで完了です。
作成した構造体は「メッセージボックス」で表示させて確認しています。
▼関連記事
最後に
VBAの構造体について解説いたしました。
当ブログでは、VBAマクロやPythonなど、時間を生み出すプログラミング術を公開しております。
この記事がわかりやすいと感じた方は、他の記事も読んでいってください。
最後までお読みいただき、ありがとうございました。がんばってください!