Collection Error

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

HI ive just created my first collection. For arguments sake lets say it is a box with many items in it. I fill the box with items. But then when i come to look in the box, i.e. Box.Item(0).ToString it always returns the last item i put in the box, no matter which index i ask it to look in. I realise it must be something daft im doing. Could someone please help me out.

Regards

James

P.S. I didnt put any code with this to keep it tidy, but if that would help then i can post it up.
 
* "=?Utf-8?B?SmFtZXMgUHJvY3Rvcg==?= said:
HI ive just created my first collection. For arguments sake lets say
it is a box with many items in it. I fill the box with items. But then
when i come to look in the box, i.e. Box.Item(0).ToString it always
returns the last item i put in the box, no matter which index i ask it
to look in. I realise it must be something daft im doing. Could someone
please help me out. [...]
P.S. I didnt put any code with this to keep it tidy, but if that would help then i can post it up.

Yes, please post your code...
 
Public Class ClassKi

Inherits System.Collections.CollectionBas

Public Sub AddDrug(ByVal NewDrug As ClassDrug
List.Add(NewDrug
End Su

Public Sub RemoveDrug(ByVal Index As Integer
If Index > Count - 1 Or Index < 0 The
MsgBox("Index Not Valid!"
Els
List.RemoveAt(Index
End I
End Su

Public Property Drug(ByVal Index As Integer) As ClassDru
Ge
Return CType(List.Item(Index), ClassDrug
End Ge
Set(ByVal Value As ClassDrug
List.Item(Index) = Valu
End Se
End Propert

End Clas

Public Class ClassDru

Private Shared c_Name As Strin
Private Shared c_TradeName As Strin
Private Shared c_Strength As Strin
Private Shared c_Volume As Strin
Private Shared c_ID As Lon
Private Shared c_BatchNumber As Strin
Private Shared c_ExpiryDate As Dat

Public Shared Property Name() As Strin
Ge
Return c_Nam
End Ge
Set(ByVal Value As String
MsgBox(Value
c_Name = Valu
End Se
End Propert

Public Shared Property TradeName() As Strin
Ge
Return c_TradeNam
End Ge
Set(ByVal Value As String
c_TradeName = Valu
End Se
End Propert

Public Shared Property Strength() As Strin
Ge
Return c_Strengt
End Ge
Set(ByVal Value As String
c_Strength = Valu
End Se
End Propert

Public Shared Property Volume() As Strin
Ge
Return c_Volum
End Ge
Set(ByVal Value As String
c_Volume = Valu
End Se
End Propert

Public Shared Property ID() As Lon
Ge
Return c_I
End Ge
Set(ByVal Value As Long
c_ID = Valu
End Se
End Propert

Public Shared Property BatchNumber() As Strin
Ge
Return c_BatchNumbe
End Ge
Set(ByVal Value As String
c_BatchNumber = Valu
End Se
End Propert

Public Shared Property ExpiryDate() As Dat
Ge
Return c_ExpiryDat
End Ge
Set(ByVal Value As Date
c_ExpiryDate = Valu
End Se
End Propert

Public Overrides Function ToString() As Strin
Dim TradeName As Strin
If Me.TradeName <> "" The
TradeName = " (" & Trim(Me.TradeName) & ")
Els
TradeName = Nothin
End I
Return Trim(Me.Name) & ", " & Trim(Me.Strength) & ", " & Trim(Me.Volume) & Trim(TradeName
End Functio

End Clas

Sub ReadDru
Dim NewKit As New KitClas
Dim Drug As New DrugClas
Drug.Name = "Drug1
NewKit.Drug.Add(Drug
Drug.Name = "Drug2
NewKit.Drug.Add(Drug
Drug.Name = "Drug3
NewKit.Drug.Add(Drug
MsgBox NewKit.Drug(1).Sho
End Su

As i said if i loop through watching it load the class it seems to be adding the correct data, but then when i loop through to read the class back it always displays the last item added

Thanks for your help

J
 
James Proctor said:
Sub ReadDrug
Dim NewKit As New KitClass
Dim Drug As New DrugClass
Drug.Name = "Drug1"
NewKit.Drug.Add(Drug)
Drug.Name = "Drug2"
NewKit.Drug.Add(Drug)
Drug.Name = "Drug3"
NewKit.Drug.Add(Drug)
MsgBox NewKit.Drug(1).Show
End Sub

As i said if i loop through watching it load the class it seems to be
adding the correct data, but then when i loop through to read the class back
it always displays the last item added.

You create *one* drug, set it's name, add it to the list, change the drug's
name, add the same drug again... In the sample you add the same drug 3
times. Solution:

Dim NewKit As New KitClass
Dim Drug As DrugClass

Drug = New DrugClass
Drug.Name = "Drug1"
NewKit.Drug.Add(Drug)

Drug = New DrugClass
Drug.Name = "Drug2"
NewKit.Drug.Add(Drug)

Drug = New DrugClass
Drug.Name = "Drug3"
NewKit.Drug.Add(Drug)

MsgBox NewKit.Drug(1).Show
 
Thanx, ive tried that, but still when i loop through and read back each item it always displays the last item that i added. I cant understand it. Any more ideas?
 
James Proctor said:
Thanx, ive tried that, but still when i loop through and read back
each item it always displays the last item that i added. I cant
understand it. Any more ideas?

What's your current code?
 
James,
Private Shared c_Name As String
Private Shared c_TradeName As String
Private Shared c_Strength As String
Private Shared c_Volume As String
Private Shared c_ID As Long
Private Shared c_BatchNumber As String
Private Shared c_ExpiryDate As Date

In addition to Armin's comment about creating one Drug *Object*. You are
only storing information for a single *Drug*.

You only use the Shared keyword if that field, property, sub, function
should be shared across all instances of the class. If that field or method
is specific to a single instance of the class you do not use Shared. Seeing
as Name is specific to a Drug it cannot be shared by all Drugs!

Try something like:
Private c_Name As String
Private c_TradeName As String
Private c_Strength As String
Private c_Volume As String
Private c_ID As Long
Private c_BatchNumber As String
Private c_ExpiryDate As Date
Public Property Name() As String

Public Property TradeName() As String

Public Property Strength() As String

Public Property Volume() As String

Public Property ID() As Long

Public Property BatchNumber() As String

Public Property ExpiryDate() As Date

Also you may want to consider a Constructor in the Drug class:

Public Sub New(ByVal name As String)
Me.Name = name
End Sub

Then when you are creating Drugs, you can pass the name of the drug to the
constructor, instead of setting the value after the fact!

Dim Drug As DrugClass
Drug = New DrugClass("Drug1")

If you pass Name to the constructor of Drug, then you have the option of
making Name readonly, meaning once a Drug is created you cannot change its
name. Of course you can pass Name to the constructor & still have it read
write...

Robin A. Reynolds-Haertle's book "OOP with Microsoft Visual Basic .NET and
Microsoft Visual C# .NET - Step by Step" covers creating classes with
constructors and info on Shared fields.

Hope this helps
Jay



James Proctor said:
Public Class ClassKit

Inherits System.Collections.CollectionBase

Public Sub AddDrug(ByVal NewDrug As ClassDrug)
List.Add(NewDrug)
End Sub

Public Sub RemoveDrug(ByVal Index As Integer)
If Index > Count - 1 Or Index < 0 Then
MsgBox("Index Not Valid!")
Else
List.RemoveAt(Index)
End If
End Sub

Public Property Drug(ByVal Index As Integer) As ClassDrug
Get
Return CType(List.Item(Index), ClassDrug)
End Get
Set(ByVal Value As ClassDrug)
List.Item(Index) = Value
End Set
End Property

End Class

Public Class ClassDrug

Private Shared c_Name As String
Private Shared c_TradeName As String
Private Shared c_Strength As String
Private Shared c_Volume As String
Private Shared c_ID As Long
Private Shared c_BatchNumber As String
Private Shared c_ExpiryDate As Date

Public Shared Property Name() As String
Get
Return c_Name
End Get
Set(ByVal Value As String)
MsgBox(Value)
c_Name = Value
End Set
End Property

Public Shared Property TradeName() As String
Get
Return c_TradeName
End Get
Set(ByVal Value As String)
c_TradeName = Value
End Set
End Property

Public Shared Property Strength() As String
Get
Return c_Strength
End Get
Set(ByVal Value As String)
c_Strength = Value
End Set
End Property

Public Shared Property Volume() As String
Get
Return c_Volume
End Get
Set(ByVal Value As String)
c_Volume = Value
End Set
End Property

Public Shared Property ID() As Long
Get
Return c_ID
End Get
Set(ByVal Value As Long)
c_ID = Value
End Set
End Property

Public Shared Property BatchNumber() As String
Get
Return c_BatchNumber
End Get
Set(ByVal Value As String)
c_BatchNumber = Value
End Set
End Property

Public Shared Property ExpiryDate() As Date
Get
Return c_ExpiryDate
End Get
Set(ByVal Value As Date)
c_ExpiryDate = Value
End Set
End Property

Public Overrides Function ToString() As String
Dim TradeName As String
If Me.TradeName <> "" Then
TradeName = " (" & Trim(Me.TradeName) & ")"
Else
TradeName = Nothing
End If
Return Trim(Me.Name) & ", " & Trim(Me.Strength) & ", " &
Trim(Me.Volume) & Trim(TradeName)
End Function

End Class

Sub ReadDrug
Dim NewKit As New KitClass
Dim Drug As New DrugClass
Drug.Name = "Drug1"
NewKit.Drug.Add(Drug)
Drug.Name = "Drug2"
NewKit.Drug.Add(Drug)
Drug.Name = "Drug3"
NewKit.Drug.Add(Drug)
MsgBox NewKit.Drug(1).Show
End Sub

As i said if i loop through watching it load the class it seems to be
adding the correct data, but then when i loop through to read the class back
it always displays the last item added.
 
Jay B. Harlow said:
James,

In addition to Armin's comment about creating one Drug *Object*. You
are only storing information for a single *Drug*.

Aaah! I didn't see it. :-)
 
Back
Top