構造体って使っていますか?構造体とは、配列と同じようにデータをひとかたまりで扱うことができて便利です。
配列は同じ型のデータをひとかたまりで扱うことができますが、構造体は型の違うデータもひとかたまりで扱うことができます。構造体というとC言語がよく知られていますが、VBAでも構造体を扱うことができます。
この記事では、構造体について
といった基本的な内容から
など応用的な内容についても解説していきます。
今回は構造体について、使い方をわかりやすく解説します!
構造体とは
構造体とは、複数以上のデータをまとめて1つのかたまりにしたものです。まとめられたデータはフィールド(メンバ変数)と呼ばれ、型の違う変数をフィールドとすることができます。
構造体はオブジェクトを生成して使用します。オブジェクトからフィールドを呼び出し、値を代入して使用します。
なお、同じように複数のデータをまとめて1つのかたまりにしたものに配列があります。配列の場合は同じ型のデータしか1つのかたまりにできません。構造体は型の違うデータも1つのかたまりにできます。
構造体の使い方
構造体の使い方について宣言の方法、初期化の方法を順に説明していきます。
構造体の宣言
構造体を宣言する方法について説明します。
構造体はTypeステートメントを使ってユーザー定義型を宣言します。下記のように記述します。
Type 構造体名 フィールド名1 As 型名 フィールド名2 As 型名 ・・・ End Type
構造体名というデータ型として定義されます。
例えば以下のような記述になります。
Type personalInfo name As String sex As String age As Integer add As String job As String End Type
この例ではpersonalInfo型の構造体(ユーザー定義型)を宣言しています。
構造体の初期化
それでは構造体のオブジェクトを定義し、初期化する方法について説明します。
以下のようにオブジェクトを生成します。
Dim オブジェクト名 As 構造体名
オブジェクトを定義したら、次のように記述してフィールドにアクセスします。
オブジェクト名.フィールド名
それではサンプルコードで確認しましょう。
'構造体の宣言 Type personalInfo name As String sex As String age As Integer add As String job As String End Type Sub macro1() 'オブジェクトの定義 Dim tanaka As personalInfo 'フィールドの初期化 tanaka.name = "T.Tanaka" tanaka.sex = "male" tanaka.age = 30 tanaka.add = "Tokyo" tanaka.job = "teacher" MsgBox tanaka.name & "は" & tanaka.age & "歳で、" & _ tanaka.add & "で" & tanaka.job & "をしています" End Sub
実行結果:
※「パブリック ユーザー定義型は定義できません」といったエラーが出る場合、Typeの宣言を標準モジュールで行うようにしましょう。
このサンプルコードでは、Typeステートメントを使ってpersonalInfo型の構造体を宣言しています。そして、Dimステートメントを使ってオブジェクトtanakaを作成しています。
オブジェクトtanakaからそれぞれのフィールドを呼び出して値を代入して、初期化しています。なお、Typeステートメントを使った構造体型の宣言はオブジェクトを作成するSubプロシージャの外に記述します。
構造体を引数に指定する
構造体をFunctionプロシージャの引数に指定すると引数の数を削減できて便利です。
構造体のオブジェクトをFunctionプロシージャの引数で渡すには、ByRefステートメントを使って参照型で渡す必要があります。サンプルコードで確認しましょう。
'構造体の宣言 Type personalInfo name As String sex As String age As Integer add As String job As String End Type Sub macro2() 'オブジェクトの定義 Dim tanaka As personalInfo 'フィールドの初期化 tanaka.name = "T.Tanaka" tanaka.sex = "male" tanaka.age = 30 tanaka.add = "Tokyo" tanaka.job = "teacher" msg tanaka End Sub Function msg(ByRef p As personalInfo) MsgBox p.name & "は" & p.age & "歳で、" & _ p.add & "で" & p.job & "をしています" End Function
実行結果:
このサンプルコードでは、Functionプロシージャを使ってMsgBoxを表示するmsg関数を定義しています。
引数に構造体(ユーザー定義型)personalInfoを指定していますが、ByRefステートメントを使って参照型で渡すようにしています。構造体を引数に指定することで、変数を4つを引数に指定するよりも簡潔に関数を宣言することができています。
なお、Functionプロシージャの使い方や引数の参照渡しについては、こちらで詳しく解説しています。ぜひ参考にしてください。
配列の要素に構造体を指定する
構造体を配列の要素に指定することが可能です。
配列の要素に構造体を指定することで、さらにデータをひとかたまりで扱うことができて便利になります。サンプルコードで確認しましょう。
Sub macro() 'オブジェクトの定義 Dim persons(3) As personalInfo 'フィールドの初期化 persons(0).name = "T.Tanaka" persons(0).sex = "male" persons(0).age = 30 persons(0).add = "Tokyo" persons(0).job = "teacher" persons(1).name = "H.Yamada" persons(1).sex = "female" persons(1).age = 40 persons(1).add = "Osaka" persons(1).job = "doctor" persons(2).name = "I.Suzuki" persons(2).sex = "male" persons(2).age = 20 persons(2).add = "Nagoya" persons(2).job = "student" Dim i As Integer For i = LBound(persons) To UBound(persons) - 1 msg persons(i) Next i End Sub Function msg(ByRef p As personalInfo) MsgBox p.name & "は" & p.age & "歳で、" & _ p.add & "で" & p.job & "をしています" End Function
実行結果:
配列の使い方については、こちらでまとめています。
ぜひ参考にしてください。
構造体をコピーする方法
構造体のオブジェクトをコピーするには、別のオブジェクトに「=」記号を使って格納することでコピーすることができます。
サンプルコードで確認しましょう。
'構造体の宣言 Type personalInfo name As String sex As String age As Integer add As String job As String End Type Sub macro3() 'オブジェクトの定義 Dim tanaka As personalInfo 'フィールドの初期化 tanaka.name = "T.Tanaka" tanaka.sex = "male" tanaka.age = 30 tanaka.add = "Tokyo" tanaka.job = "teacher" Dim tanaka2 As personalInfo tanaka2 = tanaka 'コピー msg tanaka2 End Sub Function msg(ByRef p As personalInfo) MsgBox p.name & "は" & p.age & "歳で、" & _ p.add & "で" & p.job & "をしています" End Function
実行結果:
構造体のフィールドで定数を定義する
構造体のフィールドでConstステートメントを使って定数を定義しようとするとエラーが発生します。
フィールドに定数を定義する代替手段として、定数列挙型で初期化する方法についてご紹介します。列挙型はEnumステートメントを使って宣言します。列挙型の変数には定数を指定することができます。
ただし、列挙型の変数には長整数型の値しか指定できません。構造体のフィールドで長整数型の値を指定する場合は、次のように記述します。
'構造体の宣言 Type personalInfo name As String sex As String age As Integer add As String job As String End Type '列挙型の宣言、定義 Enum myEnum age = 30 End Enum Sub macro4() 'オブジェクトの定義 Dim tanaka As personalInfo 'フィールドの初期化 tanaka.name = "T.Tanaka" tanaka.sex = "male" tanaka.age = myEnum.age '定数を指定 tanaka.add = "Tokyo" tanaka.job = "teacher" msg tanaka End Sub Function msg(ByRef p As personalInfo) MsgBox p.name & "は" & p.age & "歳で、" & _ p.add & "で" & p.job & "をしています" End Function
実行結果:
このサンプルコードでは、Enumステートメントを使って列挙型myEnumを宣言し、変数ageを定数で定義しています。
personalInfo型のオブジェクトtanakaのフィールドageを呼び出し、myEnumの定数ageを格納しています。
まとめ
ここでは、構造体の使い方について説明しました。構造体を使うと複数のデータをひとまとまりに扱うことができて便利です。
使いこなすことができるように、この記事を何度も参考にして下さいね!