レコードイメージのクラスへのコピー

クラスに楽にデータを入れたい

レコードイメージのクラスを良く使う。そのクラスの中にその固有の処理をカプセル化していけばいいのだ。しかし、外部との連携はDictionary等に比べると面倒な感じ。

Person クラス

Option Explicit

Public Name As String
Public Age As Long
Public Address As String

以下のようなテーブルを Person クラスに設定することを考えます。

ふつうに追加するとこんな感じ

Sub TableToPersonClass()
    
    'Person Class にコピー
    Dim col2 As Collection
    Set col2 = New Collection
    
    Dim c As Person
    Dim LO As ListObject
    Set LO = ActiveSheet.ListObjects(1)
    
    Dim i As Long
    Dim j As Long
    
    For i = 1 To LO.DataBodyRange.Rows.Count
            
        Set c = New Person
        'ベタに書くしかない
        c.Name = LO.DataBodyRange.Cells(i, 1).Value
        c.Age = LO.DataBodyRange.Cells(i, 2).Value
        c.Address = LO.DataBodyRange.Cells(i, 3).Value
    
        col2.Add c
    
    Next
    
    For Each c In col2
        Debug.Print c.Name
        Debug.Print c.Age
        Debug.Print c.Address
    Next
    
End Sub

列が増えればその分記入も増えて大変。このへんいつもめんどうだとおもっていました。

CallByNameの出番

今頃気が付きましたが、CallByName を使用すればシームレスに値のコピーが可能です。テーブルの列名を合わせておけば項目名を意識せずに処理可能です。

Sub TableToPersonClass()
    
    'Person Class にコピー
    Dim col2 As Collection
    Set col2 = New Collection
    
    Dim c As Person
    Dim LO As ListObject
    Set LO = ActiveSheet.ListObjects(1)
    
    Dim i As Long
    Dim j As Long
    
    For i = 1 To LO.DataBodyRange.Rows.Count
            
        Set c = New Person
        
        For j = 1 To LO.HeaderRowRange.Columns.Count
        
            'Person Class
            CallByName c, LO.HeaderRowRange(, j).Value, VbLet, LO.DataBodyRange.Cells(i, j).Value
        
        Next
    
        col2.Add c
    
    Next
    
    For Each c In col2
        Debug.Print c.Name
        Debug.Print c.Age
        Debug.Print c.Address
    Next
    
End Sub

Dictionaryからのシャローコピーにも使える。

Sub DictionaryToPerson()

    Dim dic As Scripting.Dictionary
    
    Set dic = New Scripting.Dictionary
    
    dic.Add "Name", "watanabe"
    dic.Add "Age", 48
    dic.Add "Address", "千葉県"
    
    Dim v As Variant
    Dim c As Person
    
    Set c = New Person
    
    For Each v In dic.Keys
        CallByName c, v, VbLet, dic.Item(v)
    Next

    Debug.Print c.Name
    Debug.Print c.Age
    Debug.Print c.Address

End Sub

JSONからのパースにも使えるのでデシリアライズがはかどる~

ABOUTこの記事をかいた人

はてなブックマークで驚愕の1600越えを記録した伝説が今明らかに! エクセル方眼紙 四天王の1人(ほぼ最弱)窓の杜大賞2014 大賞受賞! Excelを便利にする250以上の機能を体系化したアドインはこちらです。