I hope complete code is below.
Q1: Why do the 2 Debug writes produce different values?
The first Debug Write performs correctly but the second shows each object in the array has the same values as the last object created in the For Each loop.
Q2: Is there a better way to handle a collection of objects other than an array?
Test Values at the end.
Thanks for any help.
Code:
Public Class Form1
Public facilities() As Facility
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileToImport As String = GetFileName("Select Facility Import File")
Dim facility As New Facility
Dim counter As Integer = 0
Dim words() As String
Dim i As Integer
'Sample line format: FacID<TAB>FacSingleChar<TAB>ParentFacID
Try
If File.Exists(FileToImport) Then
For Each line As String In File.ReadLines(FileToImport)
words = line.Split(vbTab)
With facility
.FacilityID = words(0)
.FacilitySingleCharID = words(1)
.ParentFacilityID = words(2)
End With
ReDim Preserve facilities(counter)
facilities(counter) = facility
Debug.WriteLine("First Print: " & facilities(i).FacilityID & vbTab & facilities(i).ParentFacilityID & facilities(i).FacilitySingleCharID)
counter = counter + 1
Next line
For i = 1 To facilities.GetUpperBound(0)
Debug.WriteLine("Second Print: " & facilities(i).FacilityID & vbTab & facilities(i).ParentFacilityID & facilities(i).FacilitySingleCharID)
Next
End If
Catch ex As Exception
MsgBox(ex.Message & vbTab & ex.ToString)
End Try
End Sub
Private Function GetFileName(ByVal DialogTitle As String, Optional ByVal FileFilter As String = "All Files (*.*)|*.*") As String
Dim oDlg As New OpenFileDialog()
Dim FileName As String = ""
Try
With oDlg
.Title = DialogTitle
.Filter = FileFilter
.ShowDialog()
FileName = .FileName
End With
Return FileName
Catch ex As Exception
Return ""
End Try
End Function
End Class
Public Class Facility
Private m_FacilityID As String = Space(4)
Private m_ParentFacilityID As String = Space(4)
Private m_FacilitySingleCharID As String = Space(1)
Public Property FacilityID As String
Get
Return m_FacilityID
End Get
Set(ByVal value As String)
m_FacilityID = value.PadRight(4)
End Set
End Property
Public Property ParentFacilityID As String
Get
Return m_ParentFacilityID
End Get
Set(ByVal value As String)
m_ParentFacilityID = value.PadRight(4)
End Set
End Property
Public Property FacilitySingleCharID As String
Get
Return m_FacilitySingleCharID
End Get
Set(ByVal value As String)
If Len(value) = 1 Then
m_FacilitySingleCharID = value
Else
m_FacilitySingleCharID = "?"
End If
End Set
End Property
End Class
Test Data for Import File:
Import File should have 3 tab delimited columns:
(There should not be blank between entries, that was the only way to make them readable here)
APC A NCT
BAB B NCT
BABG C NCT
CCR D NCT
There are a couple of issues at work here.
The most straightforward one is that on your second print loop, your For..Next loop index variable i
has 1
as the start value where it should be 0.
The second is a little more complicated.
You create a new facilities object and each pass through the loop, you assign new values to the object and assign the object to the newly created last element in the array.
The problem is to do with how objects work and how they are used
Each time through the loop, you just assign new values to the same object and store that object in every element of the array. However what the code is doing in the background is not storing a new object each time with all the new values, it's storing a reference to the same object in each element and changing the values on each pass through the loop. That's why all your values in the array are the same.
What you need to do is move the line
Dim facility As New Facility
into the loop so that a new object is created on each pass through the loop
Like this
For Each line As String In File.ReadLines(FileToImport)
Dim facility As New Facility
words = line.Split(vbTab.ToCharArray)
With facility
.FacilityID = words(0)
.FacilitySingleCharID = words(1)
.ParentFacilityID = words(2)
End With
ReDim Preserve facilities(counter)
facilities(counter) = facility
Debug.WriteLine("First Print: " & facilities(counter).FacilityID & vbTab & facilities(counter).ParentFacilityID & facilities(counter).FacilitySingleCharID)
counter = counter + 1
Next line
Initially objects can be confusing, but have a look at reference types and value types and variable scope.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.