アメグラ2号のブログ

1980年代後半の古き良きビデオゲームのほか、オッサンの個人的備忘録

VBA クラスモジュール

この前pythonのクラスを扱ってみて、やはりVBAもクラスをもう一回やっておきたいと思ったので。以前読んだ書籍は難しくてよく分からなかったんだよね。

クラスを理解するために最低限のものを作ってみる。

◆取得するデータ

f:id:game-allergy:20210622111114j:plain

よくありがちなエクセルの表。このようなデータ群を扱うためにクラスが最適だそうで。

◆クラスモジュール「Record」

Public ID As String
Public Name As String
Public Age As Long
Public Property Get Self() As Object
    Set Self = Me
End Property

◆標準モジュール

Enum column
    ID = 1
    Name = 2
    Age = 3
End Enum

Private Sub UseRecordColumn()
   
    '==============================
    ' 表データの取得
    '==============================
    Dim TableRange As Range
    Dim TableValue As Variant
    
    ' 表データ取得
    With ThisWorkbook.Worksheets("Sheet1").Range("A2").CurrentRegion
        Set TableRange = .Resize(.Rows.Count - 1).Offset(1)
    End With
    
    '==============================
    ' 表データを配列へ格納
    '==============================
    TableValue = TableRange.Value
    
    '==============================
    ' コレクションに入れる
    '==============================
    ' Columnsコレクション作成
    Dim Columns As New Collection
    
    ' レコードにデータを入れる×●個 →【行×列】データ
    Dim i As Long
    For i = LBound(TableValue) To UBound(TableValue)
        With New Record
            .ID = TableValue(i, 1)
            .Name = TableValue(i, 2)
            .Age = TableValue(i, 3)
            Columns.Add .Self
        End With
    Next

Stop

    Debug.Print "出力テスト1---------------------------"
    Debug.Print Columns.Count
    Debug.Print Columns.Item(1).ID, Columns.Item(1).Name, Columns.Item(1).Age

    Debug.Print "出力テスト2---------------------------"
    Dim data As Record
    For Each data In Columns
        Debug.Print data.ID, data.Name, data.Age
    Next
    
    Debug.Print "出力テスト3---------------------------"
    For Each data In Columns
        If data.Age > 20 Then
            Debug.Print data.ID, data.Name, data.Age
        End If
    Next

    Debug.Print "出力テスト4---------------------------"
    For Each data In Columns
        If data.ID Like "X1-*" Then
            Debug.Print data.ID, data.Name, data.Age
        End If
    Next

End Sub


◆実行結果

f:id:game-allergy:20210622112655j:plain


どなたかのサイトを参考にしてみたら非常にわかりやすかった。

列挙型enumと、コレクションを組み合わせるとこんなにスッキリするのか。

可読性が格段に良くなるっていうのも納得。

配列に入れたデータを加工、抽出する際って、書いているうちに「これなんだっけ?」とか、よくなるんだよね。
出力テスト3は分かりやすい例だと思う。「Ageに関して条件付きで抽出したい」というのが一目でわかる。

まぁpropertyプロシージャを使わないのでなんだかな~と思うかもしれないけど…実際にはこれで事足りそう。