20240301エクセルVBA オブジェクト指向備忘録クラス ドメインオブジェクト全部を標準モジュールに
<前書き>
エクセルVBAオブジェクト指向、初心者です。
VBA自体は、以前から使用していました。
オブジェクト指向というものがあることは、知っていましたが、ネットなどを見てもよく分からず、挫折した過去あり。
エクセルVBAで、オブジェクト指向を必要とすることもなかったので、諦めていましたが、
youtubeで、「ひとりごとワンダーランド」様のエクセルVBAでのクラスに関する動画を見させていただき、少しだけやる気になっています。感謝。
(まだ、動画は最後まで見ていません。汗)
不都合なら削除いたしますのでよろしくお願いいたします。(動画内容全部は公開していません。気になったところを自分なりに書いています。)
<以上前書き>
「ひとりごとワンダーランド」様のyoutube動画では、オブジェクトの中でも大事なものを「ドメインオブジェクト」と呼んでいます。
(youtube「クラスモジュール」13)
売上データ
売上データリスト
集計結果
集計結果リスト
そこでは、上記が「ドメインオブジェクト」。
「ひとりごとワンダーランド」様は、動画の中で、「標準モジュールは、「使う側」に徹し、クラスに「作る処理」を任せればいいということで下記のように作成しています。
(標準モジュールのみ載せました。コード少し違っているかも。)
====================================
Option Explicit
Sub 処理開始2()
''----------------------------
''シート読み込み
''----------------------------
Dim v売上シート As 売上シート
Set v売上シート = New 売上シート
Dim v生データ As Variant
v生データ = v売上シート.読み込み("売上")
' シートの読み込みが終わったら、v売上シートを解放
Set v売上シート = Nothing
''----------------------------
''売上データリスト作成
''----------------------------
Dim v売上オブジェクト生成 As 売上オブジェクト生成
Set v売上オブジェクト生成 = New 売上オブジェクト生成
Dim v売上データリスト As 売上データリスト
Set v売上データリスト = v売上オブジェクト生成.リスト生成(v生データ)
' リストの生成が終わったら、v売上オブジェクト生成とv生データを解放
Set v売上オブジェクト生成 = Nothing
Erase v生データ
''集計処理開始
Dim v集計結果オブジェクト生成 As 集計結果オブジェクト生成
Set v集計結果オブジェクト生成 = New 集計結果オブジェクト生成
Dim v集計 As 集計
Set v集計 = New 集計
''----------------------------
''集計処理、集計結果データリスト作成
''----------------------------
Dim v集計結果リスト As 集計結果リスト
Set v集計結果リスト = v集計結果オブジェクト生成.リスト作成(v売上データリスト, v集計)
' 集計結果リストの作成が終わったら、v集計結果オブジェクト生成、v集計、v売上データリストを解放
Set v集計結果オブジェクト生成 = Nothing
Set v集計 = Nothing
Set v売上データリスト = Nothing
''----------------------------
''集計シート出力
''----------------------------
Dim v集計シート As 集計シート
Set v集計シート = New 集計シート
Call v集計シート.表示("集計", v集計結果リスト)
Stop
' 集計シートの出力が終わったら、v集計シートとv集計結果リストを解放
Set v集計シート = Nothing
Set v集計結果リスト = Nothing
End Sub
=================================
「ひとりごとワンダーランド」様の言うように、上記コードでは、色んな作業は、クラスに任せているようです。
(シンプル。)
ただ、初心者の自分には、「ドメインオブジェクトが全部標準モジュールで見れたらなあ」と思いました。
(上記コードには、売上データ、集計結果が見えません。)(まあ「○○リスト」があればいいのですが・・・)
で、自分で書き直してみました。正しいかは分かりません。(少し変なメモ入っています。)
++++++++++++++++++++++++++++++
Option Explicit
Sub 処理開始4自分で修正()
''----------------------------
''シート読み込み
''----------------------------
'//////////////////これクラスいるのか???
Dim v売上シート As 売上シート
Set v売上シート = New 売上シート
Dim v生データ As Variant
v生データ = v売上シート.読み込み("売上")
Set v売上シート = Nothing
''----------------------------
''売上データ(ドメインオブジェクト)
''----------------------------
Dim v売上データリスト As 売上データリスト
Set v売上データリスト = New 売上データリスト
Dim vRowCount As Long
For vRowCount = LBound(v生データ) To UBound(v生データ)
Dim v売上データ As 売上データ
Set v売上データ = New 売上データ
v売上データ.名前 = v生データ(vRowCount, 1)
v売上データ.日付 = v生データ(vRowCount, 2)
v売上データ.売上金額 = v生データ(vRowCount, 3)
' v売上データリスト.Add v売上データ 'v売上データリスト使っている
v売上データリスト.追加 v売上データ
Next vRowCount
'Set v売上オブジェクト生成 = Nothing '標準モジュールにはないので不要
Erase v生データ
Dim v集計結果リスト As 集計結果リスト
Set v集計結果リスト = New 集計結果リスト
Dim v集計 As 集計
Set v集計 = New 集計
' Dim v名前別合算Dict As Dictionary
Dim v名前別合算Dict As Object 'ここも直した
Set v名前別合算Dict = v集計.名前別合算Dict(v売上データリスト) '直し
Dim v売上データ名前 As Variant
For Each v売上データ名前 In v名前別合算Dict
Dim v集計結果 As 集計結果 '集計結果は出るが、ぐるぐる回り消えていく
Set v集計結果 = New 集計結果
v集計結果.名前 = v売上データ名前
v集計結果.売上金額 = v名前別合算Dict(v売上データ名前)
Call v集計結果リスト.追加(v集計結果)
Next v売上データ名前
' v集計結果リストはOK
'Set v集計結果オブジェクト生成 = Nothing '標準モジュールにはないので不要
Set v集計 = Nothing
Set v売上データリスト = Nothing
''----------------------------
''集計シート出力
''----------------------------
Dim v集計シート As 集計シート
Set v集計シート = New 集計シート
Call v集計シート.表示("集計", v集計結果リスト)
Set v集計シート = Nothing
Set v集計結果リスト = Nothing
Stop
End Sub
+++++++++++++++++++++++++++++++++
かなりくどくなりました。汗。
「ひとりごとワンダーランド」様が何回も言っているように、人によって作り方は千差万別・・・と思えばいいのか・・・。汗汗
(以下、ドメインオブジェクトを標準モジュールに書くにあたっての途中メモ。
Set v名前別合算Dict = v集計Dict_追加.名前別合算Dict(v売上データリスト)
の部分が、ややこしくて(クラスを二重に使っている)どうすればいいのか考えたメモで、下記はまとまっていません。)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''集計結果をクラスでなく、親(標準モジュール)に書くには?
'
' Dim v集計Dict_追加 As 集計Dict_追加
' Set v集計Dict_追加 = New 集計Dict_追加
'
' Dim v名前別合算Dict As Object '単なるオブジェクト
'
' Set v名前別合算Dict = v集計Dict_追加.名前別合算Dict(v売上データリスト) 'v売上データリストがcollectionだと型が一致しない
'
'' v名前別合算Dictが出来た・・・。どこのクラスから呼ばれているか?集計クラス
'
''考え・・・上記だが、クラス「集計」の中に、「名前別合算」と「名前別合算Dict」メソッドがある。
''集計結果を親に書きたいなら、「名前別合算」だけをここに書いて、「名前別合算Dict」はクラスでいいのでは?
''書き直し
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'集計のメソッドに「集計結果」があるので、標準モジュールに置く
'v集計結果リストにデータ取れている
'考え 元の標準モジュールは、
'①集計結果オブジェクト生成のメソッドリスト作成を書いて、
'その中に②集計のメソッド名前別合算を呼び、
'その③集計のプライベートのメソッドで名前別合算Dictを使っている。
'集計結果があるのは②なので、②を標準モジュールに記載。
'③はクラスに置いたままにする。
'(①は後で考える・・・)
******************************************
乾燥:
昔作ったものを自分でリファクタリングするのは、もっと勉強が必要です。
「ひとりごとワンダーランド」様に感謝いたします。