前提・実現したいこと
ExcelVBAでクラスモジュールとCollectionオブジェクトを組み合わせた活用法を模索しています。
実現したいことは画像のデータをSheet1からSheet2へそのまま転記することです。
実行のイメージとしては、表のデータ1行分を1つのオブジェクト(後述のDataクラス)と捉え、
Collection(後述のItemsクラス)へ次々と格納し、Sheet2へFor Each構文を使用して転記をします。
これまではSheet2へ転記を行うコードである、後述の「M_Original」の「ApplayToSheet」プロシージャを
「C_Items」クラスに記述していました。
上述の方法を実務で試した結果、当然のことながら転記がこんなに単純なはずがなく、
また、Items(Collectionオブジェクト)を何度も使用しなければならないため、
「C_Items」クラス内の記述が増え可読性が落ちてしまいました。
そこでItems(Collectionオブジェクト)を標準モジュールへ渡すことができれば
様々な機能の切り離しが可能になり、より可読性の高い構成にできると考え以下の通り再編成してみました。
つきましては以下の構成が最善であるかという観点からアドバイス等いただけたら幸いです。
構成
■標準モジュール
- 「M_Main」モジュール:このプロシージャからマクロを実行します。
M_Main
1Sub 転記マクロ() 2 3 Dim myItems As C_Items: Set myItems = New C_Items 4 Dim items As Collection 5 Set items = myItems.getItems 6 myItems.DataStore 7 Call TenkiData(items) 8 9End Sub
- 「M_Original」モジュール:Collectionに溜め込んだデータの転記を行います。
M_Original
1Public Sub ApplayToSheet(ByVal items As Collection) 2 3 Dim i As Long 4 Dim d As C_Data 5 i = 1 6 For Each d In items 7 With Sheet2 8 .Cells(i, 1) = d.name 9 .Cells(i, 2) = d.age 10 .Cells(i, 3) = d.location 11 i = i + 1 12 End With 13 Next d 14End Sub
■クラスモジュール
- 「C_Data」クラス:表1行分のデータを表すオブジェクトになります。
C_Data
1Public name As String 2Public age As Integer 3Public location As String 4 5Public Sub Initialize(ByVal rng As Range) 6 name = rng(1) 7 age = rng(2) 8 location = rng(3) 9End Sub
- 「C_Items」クラス:items(Collection)へデータの格納などitemsの管理を行います。
C_Items
1Private items As Collection 2 3Private Sub Class_Initialize() 4 Set items = New Collection 5End Sub 6 7Public Property Get getItems() As Collection 8 Set getItems = items 9End Property 10 11Public Sub DataStore() 12 Dim i As Long 13 For i = 1 To 11 14 Dim d As C_Data: Set d = New C_Data 15 With Sheet1 16 d.Initialize .Range(.Cells(i, 1), .Cells(i, 3)) 17 items.Add d 18 End With 19 Next i 20End Sub
※以下修正したコード
■標準モジュール
- M_Mainモジュール
M_Main
1Option Explicit 2 3Sub Tenkisyori() 4 Call TenkiData 5End Sub
- M_Originalモジュール
M_Original
1Option Explicit 2 3Private items As Collection 4 5Public Sub TenkiData() 6 '## Sheet2へデータの転記を実行する 7 Dim i As Long: i = 1 8 Dim d As C_Data 9 10 For Each d In GetPersonCollectionFrom(Sheet1) 11 With Sheet2 12 .Cells(i, 1) = d.name 13 .Cells(i, 2) = d.age 14 .Cells(i, 3) = d.location 15 i = i + 1 16 End With 17 Next d 18 19End Sub 20 21Function GetPersonCollectionFrom(ByRef TargetSheet As Worksheet) As Collection 22 '## Sheet1のデータをCollectionへ順次格納する 23 Set GetPersonCollectionFrom = New Collection 24 Dim i As Long 25 26 For i = 2 To 6 27 Dim personItem As C_Data: Set personItem = New C_Data 28 With personItem 29 .name = TargetSheet.Cells(i, 1) 30 .age = TargetSheet.Cells(i, 2) 31 .location = TargetSheet.Cells(i, 3) 32 End With 33 GetPersonCollectionFrom.Add personItem 34 Next i 35 36End Function
■クラスモジュール
- C_Dataクラス
C_Data
1Option Explicit 2 3Public name As String 4Public age As Integer 5Public location As String

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/01/30 04:04
2022/01/30 10:34
2022/01/30 16:04
2022/01/30 22:32
2022/01/31 12:08