[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/10/25(Tue) 00:24
投稿者名:はせ
Eメール:
URL :
タイトル:
Collectionで悩んでます
VB6.0 + Win2000です

Collectionを使いこなせなくて悩んでます。
クラス内で宣言されているCollectionにオブジェクトを追加すると
Collection内の全てのオブジェクトが書き換えられてしまいます。

こんな感じです。
Item1、Item2、Item3、一覧はクラスです。

Item1.Name="あああ"
Item2.Name="いいい"
Item3.Name="ううう"

Call 一覧.Add Item1
Call 一覧.Add Item2
Call 一覧.Add Item3


------一覧クラス内
Private ItemList as Collection
Friend Sub Add(Item as clsItem)

ItemList.Add Item

end sub

Item1を追加した時は ItemList.Item(1).Name は ”あああ” なのですが
Item2を追加した時は ItemList.Item(1).Name も Item(2) も ”いいい”になってしまう
Item3を追加した時は ItemList.Item(1).Name も Item(2) も Item(3)も
 全部 Name=”ううう”になってしまうのです。

どこがいけなかったでしょうか?
レコードとか配列を使えば解決しそうなのですが
Collectionをやっつけれるように、ご教授お願いします。

投稿時間:2005/10/25(Tue) 02:29
投稿者名:Renard
Eメール:
URL :
タイトル:
Re: Collectionで悩んでます
> Item1を追加した時は ItemList.Item(1).Name は ”あああ” なのですが
> Item2を追加した時は ItemList.Item(1).Name も Item(2) も ”いいい”になってしまう
> Item3を追加した時は ItemList.Item(1).Name も Item(2) も Item(3)も
>  全部 Name=”ううう”になってしまうのです。

こちらで書いたテストコードではちゃんと期待動作をします。
症状を再現できる最小のコードを、「手書き」ではなく、「コピー&ペースト」で
再投稿してみてはどうですか?

投稿時間:2005/10/25(Tue) 09:02
投稿者名:るしぇ
Eメール:
URL :
タイトル:
参照アドレスが同じなのでは?
現象的にはオブジェクト変数に同じ参照アドレスが入っている
ようですね。Item(1) 〜 Item(3) が参照しているオブジェクト
のメモリ上のアドレスが同じなのでしょう。例えば
   Dim Form1 As FormA
   Dim Form2 As FormA
   Set Form1 = New FormA
   Set Form2 = Form1
   Form1.Show
   Form2.Show '←同じフォームの実体(インスタンス)に命令するので意味がない
みたいな処理になってしまってます。どこかで同じオブジェクト
を使いまわすようなケアレスミスをしているか、Module で宣言
したようなプログラムを通して1意なオブジェクトを使ってしまっ
てるとか…。

投稿時間:2005/10/25(Tue) 09:27
投稿者名:はせ
Eメール:
URL :
タイトル:
Re: 参照アドレスが同じなのでは?
参照アドレスが同じなのでしょうね・・・

オブジェクトの使いまわし・・・
 はい、使いまわしてます・・・。

ケアレスミス・・・
 ケアレスミスでは済まないほど乏しい知識でクラス化に取り組んでます

もう少しクラスを分けるようにしてみます。

投稿時間:2005/10/25(Tue) 09:20
投稿者名:はせ
Eメール:
URL :
タイトル:
Re: Collectionで悩んでます
すいませんほぼオリジナルのソースを貼り付けました。
あれ?Detailクラスを引数にしてDetailクラスに放り込んでいる・・・
問題ありでしょうかね?



−−−−ソース−−−−−
’外部から引数としてResNoとDetail渡してDetailに結果を保存する

Friend Function GetDetailList(RcNo As Long, Detail As C_Detail) As Boolean
Dim tmpItem As New C_MenuItem
'Set tmpItem = New C_MenuItem

Detail.Reset    'Detail内のコレクションをリセットするメソッドの実行

'明細の取得
With tmpItem
Set RS = DbCn.Execute("SELECT * FROM BT36 WHERE BT36F001 = " & RcNo)
If RS.RecordCount > 0 Then

    Do Until RS.EOF
    
        .PSC = RS!BT36F005 & ""

        If IsNull(RS!BT36F006) = False Then .Code = RS!BT36F006
        .Name = RS!BT36F023
        .Group = RS!BT36F026

        Detail.AddList tmpItem
    RS.MoveNext
    Loop
End If
End With
End Function

−−−−以下Detailクラスです。
Private MenuList As Collection   '明細リスト用コレクション

Friend Sub AddList(MenuItem As C_MenuItem)

If MenuList.Count = 0 Then
    MenuList.Add MenuItem
    Else
    MenuList.Add MenuItem, , , 1
End If
'Debug.Print MenuList.Item(1).Name & "   " & MenuList.Item(2).Name
End Sub

投稿時間:2005/10/25(Tue) 11:18
投稿者名:るしぇ
Eメール:
URL :
タイトル:
Re^2: Collectionで悩んでます
[クラスモジュール講座]
hhttp://homepage1.nifty.com/CavalierLab/lab/vb/clsmdl/index.html
まずはクラスとインスタンスについてのイメージを固めて下さい。

細かい事ですが、[VB6.0]において下記のような問題点があります。
hhttp://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+200506/05060038.txt
変数宣言での New は使わないクセを付けておく方が良いです。

で、本題に入りますが、ループの内部でループが繰り返されるごとに
新しい C_MenuItem のインスタンス(実体)を生成して下さい。

    Dim tmpItem As C_MenuItem
    '明細の取得
    Set RS = DbCn.Execute("SELECT * FROM BT36 WHERE BT36F001 = " & RcNo)
    If RS.RecordCount > 0 Then
        Do Until RS.EOF
            Set tmpItem = New C_MenuItem ' ←ここ
            With tmpItem
                .PSC = RS!BT36F005 & ""
                If IsNull(RS!BT36F006) = False Then .Code = RS!BT36F006
                .Name = RS!BT36F023
                .Group = RS!BT36F026
            End With
            Detail.AddList tmpItem
            RS.MoveNext
        Loop
    End If

投稿時間:2005/10/28(Fri) 22:59
投稿者名:はせ
Eメール:
URL :
タイトル:
Re^3: Collectionで悩んでます
Renardさん
るしぇさん

ありがとうございました。
無事?コレクションを解決しました。
ただ?毎回実体化するので、処理速度が遅くなったような・・・。
クラス化ではしかたないことなのでしょうかね?
実体化したクラスの処理結果を配列変数に代入していた時より
処理速度が落ちたのですが・・・。

もうすこし勉強してみます。

ありがとうございました。