Personsクラスの改良
Personsクラスの改良
前回
のPersons
クラスをちょこっとだけ改良する。
Persons
クラスのextractNames
メソッドは、その名のとおりPerson
インスタンスのName
プロパティの値だけを指定したセルを開始位置として転記するものだった。
これを、Person
インスタンスが持つ三つのデータ(Name
、BirthPlace
、BelongsTo
各プロパティの値。)を転記するように改める。
Personsクラスのコードの修正
Persons
クラスのextractNames
メソッドの名前をextractData
とし、中身を次のように書き換える。宣言セクションに列挙体を追加した関係で、クラスモジュール全体を掲載する。
Personsクラス
Option Explicit 'Constants' Private Enum PersonsData psdName = 1 psdBirthPlace psdBelongsto End Enum 'Module Level Variables' Private items_ As New Collection 'Properties' Public Property Get Items() As Collection Set Items = items_ End Property 'Methods' Public Sub addItem(ByVal name__ As String, _ ByVal birthPlace__ As String, _ ByVal belongsTo__ As String) Dim newPerson As New Person Call newPerson.init(name__, birthPlace__, belongsTo__) Call items_.Add(newPerson) End Sub Public Sub removeItem(ByVal indexNumber As Long) Call items_.Remove(indexNumber) End Sub Public Sub extractData(ByVal targetLeftTop As Range) Const DATA_COUNT As Long = 3 Dim i As Long Dim ar() As String ReDim ar(1 To items_.Count, 1 To DATA_COUNT) For i = 1 To items_.Count With items_(i) ar(i, psdName) = .Name ar(i, psdBirthPlace) = .BirthPlace ar(i, psdBelongsto) = .BelongsTo End With Next Dim targetRange As Range Set targetRange = targetLeftTop.Resize(items_.Count, DATA_COUNT) targetRange.Value = ar End Sub
各Person
インスタンスの諸データを2次元配列に格納するFor
ループ内で、2次元目のインデックスを指定するときにreadableになるように、列挙体PersonsData
を定義した。
あと、2次元目の上限値の指定がマジックナンバーになってしまうので、メソッド冒頭で定数(DATA_COUNT
)にしている。
将来、Person
クラスのプロパティが増えたときには、この値を変更すれば良い。
また、Person
クラスのプロパティ数(データの種類)を、他のメソッド等で使用するような事態になったら、この定数をProcedure LevelからModule Levelにしたら良い。
実行
シート上のコマンドボタンに、次のプロシージャを登録して実行してみる。
M01ModuleMainモジュール
Private Sub testPersonClass() Dim i As Long With Sh01Master.NameList For i = 1 To .Rows.Count Call Persons.addItem(.Cells(i, sh01icName).Value, _ .Cells(i, sh01icBirthPlace).Value, _ .Cells(i, sh01icBelongsTo).Value) Next For i = 1 To Persons.Items.Count Call Persons.Items(i).introduceMyself( _ .Cells(i, sh01icEntranceSide).Value, _ .Cells(i, sh01icWrestlerRank).Value) Next End With Call Persons.extractData(Sh02Extracted.StartCell) '……(*)' Sh02Extracted.NameList.Borders.LineStyle = xlContinuous Set Persons = Nothing End Sub
前回から変えたのは(*)のところだけ。変えたっつってもメソッド名の変更に追随しただけですけど。
オブジェクト指向の良いところは、このように呼び出し側を変更する必要がない、というところですね。
このとおり。
おわりに
まあ、同様のことはPerson
オブジェクトの配列でも実現できるんですけど、データの抽出とか転記、といった処理をクラスの中に閉じ込めることができる、というのは結構なメリットかも。
抽出とか転記の処理を書くこと自体は簡単だけれど、毎回毎回となると結構めんどくさいんで。