エクセルVBA オブジェクト指向備忘録クラス (コレクションの要素の加算と書き方4パターン)

20240328 エクセルVBAクラス備忘録 

エクセルVBA オブジェクト指向備忘録クラス

 

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

 

今回の疑問
コレクション(collectionオブジェクト)は加算できるのか?
素人ですみません。ディクショナリは、集計できます。
コレクションて、集計でなく、その内容を変えること(加算とか)はできるのか?
(まあ、できるよね)
ということを、オブジェクト指向のコーディングに近づけて考えてみました。

下記に4個のコードを書いています。同じ挙動ですが、オブジェクト指向の度合いが高くなっていきます。
参考HP:「いつも隣にITのお仕事」様(エクセルVBAでクラスモジュールを使っての独自のコレクションを作る方法他の記事)
(感謝いたします。)
(もし、掲載で不都合ありましたら、すぐに削除いたします。)

時間なかったので、部分部分、Bing様に聞いています。
(感謝いたします。)
(もし、掲載で不都合ありましたら、すぐに削除いたします。)

 

コード1
//////////////////////////////////////
' 野菜クラスモジュール(VegetableClass)
Option Explicit

Private m_Type As String
Private m_Quantity As Double
Private m_Amount As Double


Public Property Let vegeType(ByVal p_Type As String)
    m_Type = p_Type
End Property

Public Property Get vegeType() As String
    vegeType = m_Type
End Property


Public Property Let Quantity(ByVal p_Quantity As Double)
    m_Quantity = p_Quantity
End Property

Public Property Get Quantity() As Double
    Quantity = m_Quantity
End Property

 

Public Property Let Amount(ByVal p_Amount As Double)
    m_Amount = p_Amount
End Property

Public Property Get Amount() As Double
    Amount = m_Amount
End Property


/////////////////////////////////

' 親モジュール
Sub Main()
    Dim veggieCollection As Collection
    Set veggieCollection = New Collection

    ' 人参のインスタンスを作成してコレクションに追加
    Dim carrot As New VegetableClass  'インスタンス
    carrot.vegeType = "人参"
    carrot.Quantity = 100
    carrot.Amount = 100
    veggieCollection.Add carrot, carrot.vegeType

    ' 大根のインスタンスを作成してコレクションに追加
    Dim radish As New VegetableClass      'インスタンス
    radish.vegeType = "大根"
    radish.Quantity = 50
    radish.Amount = 500
    veggieCollection.Add radish, radish.vegeType

    ' 人参の本数を10加算
    carrot.Quantity = carrot.Quantity + 10

    ' 人参の金額を50加算
    carrot.Amount = carrot.Amount + 50

    ' 結果を表示
    Debug.Print "人参の本数: " & carrot.Quantity
    Debug.Print "人参の金額: " & carrot.Amount
    
    Stop    'veggieCollectionでItem1、Item2が取れた。
End Sub

 

--------------------------------------------
コード2
//////////////////////////////////////
' 野菜クラスモジュール(VegetableClass)はコード1と変わらず。

/////////////////////////////////////
'野菜のコレクションを独自コレクションに設定(Vegetables)
Public Items As Collection

////////////////////////////////////
' 親モジュール
Sub Main()
    Dim veggieCollection As Vegetables
    Set veggieCollection = New Vegetables
    
    Set veggieCollection.Items = New Collection  'Itemsをインスタンス

    ' 人参のインスタンスを作成してコレクションに追加
    Dim carrot As New VegetableClass  'インスタンス
    carrot.vegeType = "人参"
    carrot.Quantity = 100
    carrot.Amount = 100
    veggieCollection.Items.Add carrot, carrot.vegeType    'Itemsはcollectionなのでadd使える

    ' 大根のインスタンスを作成してコレクションに追加
    Dim radish As New VegetableClass      'インスタンス
    radish.vegeType = "大根"
    radish.Quantity = 50
    radish.Amount = 500
    veggieCollection.Items.Add radish, radish.vegeType

    ' 人参の本数を10加算
    carrot.Quantity = carrot.Quantity + 10

    ' 人参の金額を50加算
    carrot.Amount = carrot.Amount + 50

    ' 結果を表示
    Debug.Print "人参の本数: " & carrot.Quantity
    Debug.Print "人参の金額: " & carrot.Amount
    
    Stop    'veggieCollectionでItem1、Item2が取れた。しかし独自クラスではない。「いつも隣にIT」様の独自コレクションを読んで直す予定
End Sub

 

--------------------------------------------
コード3(コード2とコード3は微妙な差しかないです。)
//////////////////////////////////////
' 野菜クラスモジュール(VegetableClass)はコード1と変わらず。

/////////////////////////////////////
'野菜のコレクションを独自コレクションに設定(Vegetables)
Public Items As Collection

Private Sub Class_Initialize()  ’独自クラスのinitializeで、Itemsをコレクションしてしまう。

    Set Items = New Collection  
End Sub

/////////////////////////////////////
' 親モジュール
Sub Main()
    Dim veggieCollection As Vegetables
    Set veggieCollection = New Vegetables
    
'    Set veggieCollection.Items = New Collection  'Itemsをインスタンス化 class_initializeにする(ここコメントアウト)

    ' 人参のインスタンスを作成してコレクションに追加
    Dim carrot As New VegetableClass  'インスタンス
    carrot.vegeType = "人参"
    carrot.Quantity = 100
    carrot.Amount = 100
    veggieCollection.Items.Add carrot, carrot.vegeType    'Itemsはcollectionなのでadd使える

    ' 大根のインスタンスを作成してコレクションに追加
    Dim radish As New VegetableClass      'インスタンス
    radish.vegeType = "大根"
    radish.Quantity = 50
    radish.Amount = 500
    veggieCollection.Items.Add radish, radish.vegeType

    ' 人参の本数を10加算
    carrot.Quantity = carrot.Quantity + 10

    ' 人参の金額を50加算
    carrot.Amount = carrot.Amount + 50

    ' 結果を表示
    Debug.Print "人参の本数: " & carrot.Quantity
    Debug.Print "人参の金額: " & carrot.Amount
    
    Stop    'veggieCollectionでItem1、Item2が取れた。
End Sub

 

----------------------------------------------------
コード4
//////////////////////////////////////
' 野菜クラスモジュール(VegetableClass)はコード1と変わらず。

//////////////////////////

'野菜のコレクションを独自コレクションに設定(Vegetables)
Public Items As Collection

Private Sub Class_Initialize()
'
    Set Items = New Collection
    
        ' 人参のインスタンスを作成してコレクションに追加
    Dim carrot As New VegetableClass  'インスタンス
    carrot.vegeType = "人参"
    carrot.Quantity = 100
    carrot.Amount = 100
    Items.Add carrot, carrot.vegeType    'Itemsはcollectionなのでadd使える

    ' 大根のインスタンスを作成してコレクションに追加
    Dim radish As New VegetableClass      'インスタンス
    radish.vegeType = "大根"
    radish.Quantity = 50
    radish.Amount = 500
    Items.Add radish, radish.vegeType

    ' 人参の本数を10加算
    carrot.Quantity = carrot.Quantity + 10

    ' 人参の金額を50加算
    carrot.Amount = carrot.Amount + 50

    ' 結果を表示
    Debug.Print "人参の本数: " & carrot.Quantity
    Debug.Print "人参の金額: " & carrot.Amount
    
End Sub

/////////////////////////////////////////
' 親モジュール
Sub Main()
    Dim veggieCollection As Vegetables
    Set veggieCollection = New Vegetables
    

    
    Stop    'veggieCollectionでItem1、Item2が取れた。
End Sub

=======================================
基本的に4つのコードとも同じ動き。
でも、親モジュールでのstopの時のインスタンスの数は4番目が一番少ない。

 

今の自分は、コード1が基本になってしまう。いきなりコード4を書こうとすると、クラスを分割しない書き方にしてしまうかも。

あと、クラスの基本的な使い方かもしれないが、

     ' 人参のインスタンスを作成してコレクションに追加
    Dim carrot As New VegetableClass  'インスタンス
    carrot.vegeType = "人参"
    carrot.Quantity = 100
    carrot.Amount = 100

この書き方で、クラスが複数作成可能なのに納得できる。

上記の小さいクラスをまとめようとcollectionを使ったが、コレクションへのまとめ方もいろいろありうるのか。

 

データとクラス、コレクションやディクショナリは、相性がよい感じですね。

 

次回も似たようなことを練習するつもりです。