Solved

List of (myClass) troubles

Posted on 2014-12-29
12
35 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 69

Accepted Solution

by:
Qlemo earned 168 total points
ID: 40523306
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
ID: 40523364
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 75

Expert Comment

by:käµfm³d 👽
ID: 40523477
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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:randys106
ID: 40523547
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 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 166 total points
ID: 40523551
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
 
LVL 3

Expert Comment

by:Nico
ID: 40523612
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 33

Expert Comment

by:it_saige
ID: 40523869
*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 33

Expert Comment

by:it_saige
ID: 40524599
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
ID: 40525571
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 33

Expert Comment

by:it_saige
ID: 41696853
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

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 …
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

830 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