エクセルVBAクラス備忘録 メイン文の使い方

20240421 エクセルVBAクラス備忘録 メイン文の使い方

 

<前書き>
エクセルVBAオブジェクト指向、初心者です。
VBA自体は、以前から使用していました。
オブジェクト指向というものがあることは、知っていましたが、ネットなどを見てもよく分からず、挫折した過去あり。
<以上前書き>

(素人なので間違っているかもしれません。汗。)


今回、メイン処理について、思ったことのメモです。
大事な気がするので、きちんと書きたかったのですが、まとめる時間がなく(能力もなく)、なんとなくのイメージです。

何回か前の備忘録で、「メイン文に「全部のドメインオブジェクト(重要なクラスのインスタンス)」が見えないのは、分かりにくいのでは?」
といった主旨のことを書いて、メイン文に、ドメインオブジェクトを記載した回があります。

 

その後、考えたのですが、
メインから、クラスを呼んで、さらにそこから、他のクラスを呼ぶことはある。
・・・その場合、そうするのか?
とか悩みます。(まあ、自分が分かりやすかったらいいだけですが。)

 

で、【自分なりのルール】を考える。
今現在のスキルで考えていることやコードを書く上で、当たり前のことですが、メモ。


●クラスを使う場合、なるべくメイン文で、クラスをインスタンス化する
(一度インスタンス化したデータをメイン文内で追えるようにしておく)
●そのインスタンス化したデータを利用して、他の処理につなげる場合は、functionでメイン文にデータを持ってくる。
(よく利用するデータは深いところで処理しない(処理してもfunctionでメインに戻す))
●そのインスタンス化したデータを利用しない場合(一度切りの処理・中間処理など)、メインに戻さないでよい。
(クラスメソッドでインスタンス化して、そこで終了)(インスタンスが消える処理すればなお良い)

 

<以下実例>(例と言いながら、かなりややこしいです。)


エクセルシートは、前回同様、下記の通りです。



コードは、youtube「ひとりごとワンダーランド」様を参考に書いています。(←すごく感謝)
(不都合があれば削除いたします。)

 

////////////////////////////////////                                
メイン文                                
Sub 処理開始()                                
    ''シート読み込み                                
    Dim v売上シート As 売上シートk                                
    Set v売上シート = New 売上シートk                                
                                
    Dim v元データ As Variant                            ・・・①    
    v元データ = v売上シート.読み込み("売上")    '売上はシート名 functionで戻し    ・・・②
                                    
    ''売上データリスト作成                                
    Dim v売上オブジェクト生成 As 売上オブジェクト生成k                                
    Set v売上オブジェクト生成 = New 売上オブジェクト生成k                                
                                    
    Dim v売上データリスト As 売上データリストk                                
    Set v売上データリスト = v売上オブジェクト生成.リスト生成(v元データ)   ・・・③④
End Sub                                
                                
/////////////////////////////////////////////////////                                
'クラス「売上データ」                                
Private m名前 As String                                
Private m日付 As Date                                
Private m売上金額 As Long                                
                                
Public Property Let 名前(p名前 As String)                                
    m名前 = p名前                                
End Property                                
Property Get 名前() As String                                
    名前 = m名前                                
End Property                                
                                
Public Property Let 日付(p日付 As Date)                                
    m日付 = p日付                                
End Property                                
Property Get 日付() As Date                                
    日付 = m日付                                
End Property                                
                                
Public Property Let 売上金額(p売上金額 As Long)                                
    m売上金額 = p売上金額                                
End Property                                
Property Get 売上金額() As Long                                
    売上金額 = m売上金額                                
End Property                                
                                
/////////////////////////////////////////////////////                                
クラス「売上シート」                                
Public Function 読み込み(pシート名) As Variant                                
                                
    With ThisWorkbook.Worksheets(pシート名)                                
            Dim hani As Range                                
                                            
            Set hani = .Range("A2").CurrentRegion                                
            Set hani = hani.Offset(1).Resize(hani.Rows.Count - 1)                                
            読み込み = hani '標題除く 2次元配列                                
    End With                                
                                
End Function                                
                                
/////////////////////////////////////////////////////                                
'クラス「売上オブジェクト生成」                                
Public Function リスト生成(v元データ As Variant) As 売上データリストk    '←オブジェクトを返す                                
                                
    Dim v売上データリスト As 売上データリストk      '←返したいデータオブジェクト                                
    Set v売上データリスト = New 売上データリストk                                
                                
    Dim vRowCount As Long                                
    For vRowCount = LBound(v元データ) To UBound(v元データ)                                
        Dim v売上データ As 売上データk                                
        Set v売上データ = New 売上データk                                
                                        
        v売上データ.名前 = v元データ(vRowCount, 2)  '順番変えた                                
        v売上データ.日付 = v元データ(vRowCount, 1)                                
        v売上データ.売上金額 = v元データ(vRowCount, 3)                                
                                
        Call v売上データリスト.追加(v売上データ)                                
    Next vRowCount                                
                                    
    Set リスト生成 = v売上データリスト                                
                                    
End Function                                
                                
/////////////////////////////////////////////////////                                
'クラス「売上データリスト」                                
Private m売上データリスト As Collection    'private化。publicでなくProperty Get 取得で取り出し。                                
           'letはないけどgetは作る。変数名Itemsとかでなくprivate変数(m売上データリスト)でcollection                                
                                
Public Property Get 取得() As Collection                                
    Set 取得 = m売上データリスト                                
End Property                                
                                
Public Sub 追加(p売上データ As 売上データk)                                
    If m売上データリスト Is Nothing Then                                
        Set m売上データリスト = New Collection                                
    End If                                
    m売上データリスト.Add p売上データ                                  
                                    
End Sub                                
                                
                                
解説メモ                                
①v元データという命名は気に入っています。名前からして重要そうでない。また、クラス名にも類似のものがない。                                
(variantで受けるので、多分配列ということが分かる。)                                
                                
②クラス「売上シート」の読み込むメソッド(function)で、値(配列)を読み込みに入れて、さらに、メイン文のv元データに戻している。                                
(この使い方で、メイン文に、v元データオブジェクトをメインに戻している。データを続けて使うため。)                                
                                
③④        Set v売上データリスト = v売上オブジェクト生成.リスト生成(v元データ)                               
ここでは最終的に、v元データ(配列)を売上データリスト(collectionオブジェクト)に、入れることをしている。                                
                                
まず、    v売上オブジェクト生成.リスト生成(v元データ) の箇所について、
クラス「売上オブジェクト生成」では、リスト生成メソッド    (function)がある。    
そこで、配列v元データのデータ(1行分)をクラスv売上データ(1item)に入れている。                                
(クラスv売上データのプロパティ(日付・名前・売上金額))                                
上記処理のために、このクラス内で、クラス「v売上データ」をNewしているが、この「売上データ」オブジェクトは メイン文には表れない。メインに戻す必要はない。                    
                                
続けて、このクラスでは、最終的に欲しい「売上データリスト」オブジェクトをNewするが、                                
    Set v売上データリスト = New 売上データリストk                                
として「売上データ」クラスを使って、v売上データリストをNewしている。
                                
で、この「売上データリスト」クラスは、collectionとして、設定されている。                                
そしてこの「売上データリスト」クラスには、追加メソッドを持っているので、                                
クラス「売上データリスト」の追加メソッドを使って、v売上データ(1item)を、                                
売上データリストにcollectionしていく。                                
                                
で、上記で、できたものをfunctionで、メイン文のv売上データリストに戻して完了。                                
    Set v売上データリスト = v売上オブジェクト生成.リスト生成(v元データ)                                   


その他
クラスの命名については、もっと分かりやすくならないだろうか・・・(課題)

今回使用したクラスは、
・売上シート
・売上データ
売上データリスト
・売上王ジェクト生成
と4つあるが、
売上データが、入れ物(プロパティの塊)で、売上データリストが、出すもの(collection)。
残りの売上シートは、配列用の範囲で、売上王ジェクト生成はfunction。
v元データは、ワークシート上にしかない。

各クラスがそんな機能・働きなのか分かりやすければ、もっといいかも。