0

I have been stuck on this problem with no solution found on the web. I have tried to change a few things around to no avail.

My problem is that I can't seem to call a function within a structure in VB. My structure looks as follows:

Private Structure patient
        Public givenName As String
        Public assignedDoctors() As String
        Public doctorCount As Integer
        Public infected As Boolean
        Private pID As Double
        'Simple status subprocedure
        Public Sub ChangeStatus(ByVal status As String)
            Select Case status
                Case "positive"
                    infected = True
                    givenName = "{" & givenName & "}"
                Case "tested"
                    infected = False
                    givenName = $"[{givenName}]"
                Case "negative"
                    infected = False
                    givenName = $"<{givenName}>"
                Case "untested"
                    infected = False
                    givenName = $"*{givenName}"
            End Select
        End Sub

        Public Sub AddDoctor(ByRef doctor As String)
            doctorCount += 1
            ReDim Preserve assignedDoctors(doctorCount)
            assignedDoctors(doctorCount) = doctor
        End Sub

    End Structure

My error occurs on the following line:

Private Sub btnNew_Click(sender As Object, e As EventArgs) Handles btnNew.Click
        Dim rPatient As patient
        rPatient = New patient
        rPatient.givenName = txtPatientName.Text
        rPatient.doctorCount = 1
        rPatient.assignedDoctors(1) = cbDoctor.Text
        Call rPatient.ChangeStatus(status:=cbStatus.Text)
        ArrayFix(rPatient.assignedDoctors, rPatient.givenName, rPatient.infected)
    End Sub

rPatient is an instance of the structure patient. My error occurs on the "Call" line. The error being: "Object reference not set to an instance of an object." I have tried to make the patient structure "shared" but I do not know how the shared parameter works and have attempted to learn it without progress.

If anyone could point me in the right direction it would be very helpful. Thanks.

Marc Levin
  • 26
  • 1
  • 5
  • 1
    `assignedDoctors` is never initialized. – 41686d6564 stands w. Palestine Mar 30 '20 at 15:44
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – 41686d6564 stands w. Palestine Mar 30 '20 at 15:44
  • 2
    That type should be a class rather than a structure. The fields should be properties and the `String` array should almost certainly be a `List(Of String)`. – jmcilhinney Mar 30 '20 at 16:45
  • @AhmedAbdelhameed `assigned doctors` is not causing my error as well as I have already visited that thread it is not helping my cause here. @jmcilhinney I asked for help with this problem, I am doing this for college and as of such am limited to using set structures. I have to use structure not class and I can't use lists. (It's dumb but roll with it). – Marc Levin Mar 30 '20 at 17:16
  • @MarcLevin `assignedDoctors` _is_ what's causing the exception and you _do_ need to initialize it (perhaps using `AddDoctor`). The linked post teaches you how to deal with and avoid the NullReferenceException in general. Trust me, understanding that exception will save you a lot of trouble in the future (check the second answer there for VB). Finally, there are other problems with the code as jmcilhinney indicated but I'm only addressing the problem at hand. – 41686d6564 stands w. Palestine Mar 31 '20 at 04:11
  • @AhmedAbdelhameed Thanks, I followed Mary's answer below but you are correct in what you said. I apologize for my ignorance. – Marc Levin Mar 31 '20 at 15:11

1 Answers1

1

I renamed the controls to match my test application. Just change them back to yours.

Although you haven't used it, pID should probably be an Integer. I added a Case Else to your Select Case. This is usually a good idea.

In the AddDoctor method I moved the increment of doctorCount to after the assignment. .net Arrays are zero based so, the first addition should be index 0.

When you want to add a doctor just call the AddDoctor method on the instance. Don't try to add to the array from the button code let your method do the work. You can add additional doctors with Button2.

Form.Load just fills my combos. I didn't know what ArrayFix was supposed to do so, I used it for a print out of the patient.

Private Structure patient
    Public givenName As String
    Public assignedDoctors() As String
    Public doctorCount As Integer
    Public infected As Boolean
    Private pID As Integer

    Public Sub ChangeStatus(ByVal status As String)
        Select Case status
            Case "positive"
                infected = True
                givenName = $"{givenName}" 'let's be consistent and use the interpolated string
            Case "tested"
                infected = False
                givenName = $"[{givenName}]"
            Case "negative"
                infected = False
                givenName = $"<{givenName}>"
            Case "untested"
                infected = False
                givenName = $"*{givenName}"
            Case Else
                infected = False
                givenName = $"xx{givenName}xx"
        End Select
    End Sub

    Public Sub AddDoctor(doctor As String)
        ReDim Preserve assignedDoctors(doctorCount)
        assignedDoctors(doctorCount) = doctor
        doctorCount += 1
    End Sub
End Structure

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim Docs() As String = {"Dr. Mathew", "Dr. Mark", "Dr. Luke", "Dr. John"}
    ComboBox1.Items.AddRange(Docs)
    Dim Stats() As String = {"positive", "tested", "negative", "untested"}
    ComboBox2.Items.AddRange(Stats)
End Sub

Private rPatient As patient

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Add patient
    rPatient = New patient
    rPatient.givenName = TextBox2.Text
    rPatient.AddDoctor(ComboBox1.Text)
    rPatient.ChangeStatus(ComboBox2.Text) 'Status
    ArrayFix(rPatient)
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'Add Another Doctor
    rPatient.AddDoctor(ComboBox1.Text)
    ArrayFix(rPatient)
End Sub

Private Sub ArrayFix(p As patient)
    Debug.Print($"Patient Name - {p.givenName}, Infected: {p.infected} ")
    Debug.Print($"{vbTab}Patient's Doctors")
    For Each MD In p.assignedDoctors
        Debug.Print($"{vbTab}{vbTab}{MD}")
    Next
End Sub
Mary
  • 14,926
  • 3
  • 18
  • 27