クラスに楽にデータを入れたい
レコードイメージのクラスを良く使う。そのクラスの中にその固有の処理をカプセル化していけばいいのだ。しかし、外部との連携は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からのパースにも使えるのでデシリアライズがはかどる~