Solved

List of (myClass) troubles

Posted on 2014-12-29
12
21 Views
Last Modified: 2016-07-10
I have a class called Patients with three properties; Patient.Name as string, Patient.ID as integer, Patient.ExternalID as string.  

The following code works fine.  That is, the listbox loads.
   Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
        Next
    End Sub

Open in new window

r(2) is the Last Name, r(1) is the First Name.

But, I am trying to populate a list consisting of the Patents Class.  

This code does not work:
 Private PatientList As List(Of Patients)
 Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        PatientList = New List(Of Patients)
        Dim aPatient As Patients
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
            aPatient.Name = r(2) & ", " & r(1)
            aPatient.ID = r(0)
            aPatient.ExternalID = r(3)
            PatientList.Add(aPatient)
        Next
    End Sub

Open in new window

There are (at least) three problems:
1) I get an warning telling me that "Variable 'aPatient' is used before it has been assigned a value. A null reference exception could result at runtime."
 2) It does not load the list
3) It only loads the first item in the dataset into the listbox.

What am I doing wrong?
0
Comment
Question by:randys106
12 Comments
 
LVL 68

Accepted Solution

by:
Qlemo earned 168 total points
Comment Utility
You need to create a new Patients object after DIMing it. I can't tell whether you need to do that for each new row, though.
0
 
LVL 1

Assisted Solution

by:GHz
GHz earned 166 total points
Comment Utility
Try this one

Private PatientList As List(Of Patients)
 Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        PatientList = New List(Of Patients)
        
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
            Dim aPatient As New Patients()
            aPatient.Name = r(2) & ", " & r(1)
            aPatient.ID = r(0)
            aPatient.ExternalID = r(3)
            PatientList.Add(aPatient)
        Next
    End Sub

Open in new window

0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
It does not load the list
It does not load the list because as the first warning/error tells you there is a null reference exception occurring on line 8. This is corrected by what the others have mentioned. Make sure you are not using On Error in your code. That old VB6-style of error handling should be abandoned in favor of Try/Catch. Try/Catch is easier to follow/understand and debug.
0
 

Author Comment

by:randys106
Comment Utility
Let's see...
Kaufmed nailed it.  I am an old VB6 guy who is trying to make the transition to .net.  Trying, and mostly failing.  I an not using OnError.  I do not use Try/catch here.  But it would be nice to get an error so I could know something was wrong.
 
Tried what GHz suggested but it did not change anything.  

I'm not sure exactly what I should do based on what Olemo said.
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 166 total points
Comment Utility
Qlemo is saying to do what GHz did in line 8. You have to instantiate a variable before you can make use of it. Whether you do New directly, or capture the return value of some method, a variable has to have some value (i.e. point to something in memory) before you can interact with its members.

But it would be nice to get an error so I could know something was wrong.
Then wrap that code in a Try/Catch, and in the Catch show a MessageBox (or something).
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Expert Comment

by:Nico
Comment Utility
I think most has been answered, but I will try to add something:

I think in VB6, Doing 'Dim thing As MyClass' would create a reference to 'the' MyClass instance.

In .NET, you are only defining a variable to do this. You always have to create a new instance of a class if you want to use it. So in your first post you are only defining the variable but not initializing it to an actual instance.

You can do either:

Dim instance As MyClass = New MyClass()

Or:

Dim instance As New MyClass()

Note: you can omit the () in VB.NET when you are using the default constructor
Note: my personal preference is the form "Dim instance As MyClass = New MyClass()" as it is more explicit (also it looks more like C# which is my preferred language :))

Hope this helps!
0
 
LVL 32

Expert Comment

by:it_saige
Comment Utility
*No Points*

Proof of concept project based on other experts input (Note: My table columns are not the same as yours so the column identifiers are off, same with my table identifier in the dataset):
Public Class Form1
	Private PatientList As List(Of Patient)
	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		PatientList = New List(Of Patient)
		PatientsTableAdapter.Fill(PatientsDataSet.Patients)
		Dim aPatient As Patient
		For Each row In PatientsDataSet.Tables(0).Rows
			ListBox1.Items.Add(String.Format("{0}, {1}", row(3), row(2)))
			aPatient = New Patient() With {.ID = row(0), .ExternalID = row(1), .Name = String.Format("{0}, {1}", row(3), row(2))}
			If Not aPatient Is Nothing Then
				PatientList.Add(aPatient)
			End If
		Next
	End Sub
End Class

Public Class Patient
	Public Property ID() As Integer
	Public Property ExternalID() As String
	Public Property Name() As String
End Class

Open in new window

Produces the following output -Capture.JPGAnd shows the following in the PatientList -Full listFirst PatientLast Patient-saige-
0
 
LVL 32

Expert Comment

by:it_saige
Comment Utility
And if you really want to get fancy, why create a new listbox item for each patient, when you can just use the patient list as the datasource for your listbox control:
Public Class Form1
	Private PatientList As List(Of Patient)
	Private Source As New BindingSource

	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		PatientList = New List(Of Patient)
		PatientsTableAdapter.Fill(PatientsDataSet.Patients)
		Dim aPatient As Patient
		For Each row In PatientsDataSet.Tables(0).Rows
			aPatient = New Patient() With {.ID = row(0), .ExternalID = row(1), .Name = String.Format("{0}, {1}", row(3), row(2))}
			If Not aPatient Is Nothing Then PatientList.Add(aPatient)
		Next
		Source.DataSource = PatientList
		ListBox1.DataSource = Source
	End Sub
End Class

Public Class Patient
	Public Property ID() As Integer
	Public Property ExternalID() As String
	Public Property Name() As String

	Public Overrides Function ToString() As String
		Return Name
	End Function
End Class

Open in new window

Produces the same output as above -Capture.JPGAnd since I overrided the ToString method of the Patient class, now the PatientList shows -Capture.JPG-saige-
0
 
LVL 1

Expert Comment

by:Niladrisekhar Dey
Comment Utility
Try this :
    Private PatientList As List(Of Patients) = Nothing
    Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        PatientList = New List(Of Patients)
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
            PatientList.Add(New Patients With {.Name = r(2).ToString & ", " & r(1).ToString, _
                                               .ID = r(0).ToString, .ExternalID = r(3).ToString})
        Next
    End Sub

Open in new window

0
 
LVL 32

Expert Comment

by:it_saige
Comment Utility
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now