[[20250301140702]] 『クラスモジュール、コレクションの中身をセルに一』(ヘンリー) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) |

| 全文検索 | 過去ログ ]

 

『クラスモジュール、コレクションの中身をセルに一括代入』(ヘンリー)

クラスモジュールを勉強中のものです。
クラスやコレクションに対する理解不足だと思い、
色々調べましたが、なかなか思った通りにできないので、
ご質問させてください。

やりたい事は以下の通りです
clsDataは、1行(1レコード)分の情報を1つのクラスオブジェクトとします。
これを、clsCollでコレクションオブジェクトにします。
(「コレクションオブジェクト」が正しい言い方なのかはまだよくわかっていません)
このコレクションを、セルに一括代入したいのです。

コレクションにAddをすることと、件数を取得するCountはできたのですが、
clsCollの中身を、例えばB2セル以降に代入したいと考えています。

イメージ的には、

    Dim varValue As Variant

    varValue = Range("A1:C5").Value
    Range("E1:G5").Value = varValue
の「Range("A1:C5").Value」部分を「clsColl」にしたいのです。
(variant型の配列であれば、セルに一括代入できるので)

clsCollに以下のコード
Public Function GetData() As Variant

    GetData = mColl
End Function
を追加し、標準モジュールに
    Dim varValue As Variant
    varValue = cColl.GetData
としてみたのですが、引数の数が一致しません。
というエラーが出てしまいます。

どなたかご享受して頂けないでしょうか。
よろしくお願いいたします。


クラスモジュール名:clsData
Option Explicit

Private mID As String
Private mName As String

Public Property Let ID(pID As String)

    mID = pID
End Property
Public Property Get ID() As String
    ID = mID
End Property

Public Property Let Name(pName As String)

    mName = pName
End Property
Public Property Get Name() As String
    Name = mName
End Property


クラスモジュール名:clsColl
Option Explicit
Private mColl As Collection

Private Sub Class_Initialize()

    Set mColl = New Collection
End Sub

Public Sub Add(pData As clsData)

    mColl.Add pData
End Sub

Public Function Count() As Long

    Count = mColl.Count
End Function


標準モジュール名:modTest
Option Explicit

Sub Test()

    Dim cData As clsData
    Dim cColl As clsColl

    Set cData = New clsData
    Set cColl = New clsColl

    cData.ID = "001"
    cData.Name = "あああ"
    Call cColl.Add(cData)

    cData.ID = "002"
    cData.Name = "いいい"
    Call cColl.Add(cData)

    Debug.Print cColl.Count

End Sub

< 使用 Excel:Microsoft365、使用 OS:Windows11 >


 コレクションは配列ではないですから、そのまま代入できません。
 ループ処理で一つずつデータを取り出して配列に格納するしかないと思います。


 クラスモジュール clsColl

 Public Function GetData() As Variant()
    Dim aryData(), i As Long
    ReDim aryData(1 To mColl.Count, 1 To 2)
    For i = 1 To mColl.Count
        With mColl(i)
            aryData(i, 1) = .ID
            aryData(i, 2) = .Name
        End With
    Next
    GetData = aryData
 End Function


 標準モジュール modTest

 Option Explicit
 Sub Test()

    Dim cData As clsData
    Dim cColl As clsColl

    Set cColl = New clsColl

    Set cData = New clsData
    cData.ID = "001"
    cData.Name = "あああ"
    Call cColl.Add(cData)

    '↓clsDataを新規生成しないと同じものに上書きすることになります。
    Set cData = New clsData 
    cData.ID = "002"
    cData.Name = "いいい"
    Call cColl.Add(cData)

    Debug.Print cColl.Count

    Dim varValue As Variant
    varValue = cColl.GetData
    Range("E1").Resize(UBound(varValue, 1), UBound(varValue, 2)).Value = varValue
 End Sub

(hatena) 2025/03/01(土) 14:45:16


 ちなみに、私なら、現状のAddメソッドではなく下記のようなメソッドを追加するかな。


 クラスモジュール clsColl

 Public Sub AddData(pID As String, pName As String)
    Dim pData As clsData
    Set pData = New clsData
    pData.ID = pID
    pData.Name = pName
    mColl.Add pData
 End Sub


 標準モジュール modTest

 Option Explicit
 Sub Test()

    Dim cColl As clsColl
    Set cColl = New clsColl

    cColl.AddData "001", "あああ"
    cColl.AddData "002", "いいい"

    Debug.Print cColl.Count

    Dim varValue As Variant
    varValue = cColl.GetData
    Range("E1").Resize(UBound(varValue, 1), UBound(varValue, 2)).Value = varValue
 End Sub

 コレクションへのデータ追加が1行で書けるようになります。

(hatena) 2025/03/01(土) 15:06:33


>'↓clsDataを新規生成しないと同じものに上書きすることになります。
ありがとうございます。ローカルウインドで「いいい」になっていた理由が分かりました。

>Public Sub AddData(pID As String, pName As String)
>cColl.AddData "001", "あああ"
>cColl.AddData "002", "いいい"
1行で書ける書き方のアドバイスありがとうございます。
今回のはテストで、実務の物は、プロパティが10個以上あるので、
clsDataを引数にすると思いますが、大変参考になりました。
今後はこの書き方を使う事があると思います。

>ループ処理で一つずつデータを取り出して配列に格納するしかないと思います。
ありがとうございます。一つずつデータを取り出して配列にすればよいのですね。

hatena様、丁寧なご回答いただき、本当にありがとうございます。
おかげさまで、Testプログラムでできましたので、
実務の方に反映できると思います。

(ヘンリー) 2025/03/01(土) 16:36:40


 > 今回のはテストで、実務の物は、プロパティが10個以上あるので、
 > clsDataを引数にすると思いますが、大変参考になりました。

 引数ではなくプロパティで代入したいということなら、下記のような書き方もあります。

 クラスモジュール clsColl

 Public Function AddData() As clsData
    Dim pData As clsData
    Set pData = New clsData
    mColl.Add pData
    Set AddData = pData
 End Function

 標準モジュール modTest

 Sub Test()

    Dim cColl As clsColl
    Set cColl = New clsColl

    With cColl.AddData
        .ID = "001"
        .Name = "あああ"
    End With
    With cColl.AddData
        .ID = "002"
        .Name = "いいい"
    End With

    Debug.Print cColl.Count

    Dim varValue As Variant
    varValue = cColl.GetData
    Range("E1").Resize(UBound(varValue, 1), UBound(varValue, 2)).Value = varValue
 End Sub

 まあ、この辺は好みの問題なのでお好きなようにすればいいでしょう。

(hatena) 2025/03/01(土) 18:24:48


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.