スライドショー

【VBA入門】構造体の使い方(宣言、初期化、引数、コピー、定数)

構造体って使っていますか?構造体とは、配列と同じようにデータをひとかたまりで扱うことができて便利です。

配列は同じ型のデータをひとかたまりで扱うことができますが、構造体は型の違うデータもひとかたまりで扱うことができます。構造体というと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

    実行結果:
    Type01

    ※「パブリック ユーザー定義型は定義できません」といったエラーが出る場合、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

    実行結果:
    Type01

    このサンプルコードでは、Functionプロシージャを使ってMsgBoxを表示するmsg関数を定義しています。

    引数に構造体(ユーザー定義型)personalInfoを指定していますが、ByRefステートメントを使って参照型で渡すようにしています。構造体を引数に指定することで、変数を4つを引数に指定するよりも簡潔に関数を宣言することができています。

    なお、Functionプロシージャの使い方や引数の参照渡しについては、こちらで詳しく解説しています。ぜひ参考にしてください。

    【VBA入門】Functionの使い方(呼び出し、引数、戻り値)
    更新日 : 2019年9月26日

    配列の要素に構造体を指定する

    構造体を配列の要素に指定することが可能です。

    配列の要素に構造体を指定することで、さらにデータをひとかたまりで扱うことができて便利になります。サンプルコードで確認しましょう。

    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

    実行結果:
    Type01
    Type02
    Type03

    配列の使い方については、こちらでまとめています。

    ぜひ参考にしてください。

    【VBA入門】配列総まとめ(初期化、ループ操作、コピー、結合、比較)
    更新日 : 2019年9月26日

    構造体をコピーする方法

    構造体のオブジェクトをコピーするには、別のオブジェクトに「=」記号を使って格納することでコピーすることができます。

    サンプルコードで確認しましょう。

    '構造体の宣言
    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

    実行結果:
    Type01

    構造体のフィールドで定数を定義する

    構造体のフィールドで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

    実行結果:
    Type01

    このサンプルコードでは、Enumステートメントを使って列挙型myEnumを宣言し、変数ageを定数で定義しています。

    personalInfo型のオブジェクトtanakaのフィールドageを呼び出し、myEnumの定数ageを格納しています。

    まとめ

    ここでは、構造体の使い方について説明しました。構造体を使うと複数のデータをひとまとまりに扱うことができて便利です。

    使いこなすことができるように、この記事を何度も参考にして下さいね!

    LINEで送る
    Pocket

    無料でSEからWebエンジニアへ転職しませんか?



    侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

    • システムエンジニアという職業だけどコードが書けない
    • 事務作業が多くスキルがないため将来が不安
    • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
    という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

    弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

    既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

    まずは無料体験レッスンを予約する

    書いた人

    長野 透

    長野 透

    熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
    お問合せはこちらでも受け付けています。
    [email protected]

    おすすめコンテンツ

    あなたにぴったりなプログラミング学習プランを無料で診断!

    プログラミング学習の効率を劇的に上げる学習メソッドを解説