Reading from a text file into a structure and posting to list boxes I am trying to stay ahead of my Year 12 Software class. Starting to work with records and arrays. I have answered the question, but the solution feels very clunky. I am hoping someone has suggestions/links for completing this task in a more efficient way.
The task: read in lines from a text file and into a structure, and then loop through that, populating four list boxes if an animal hasn't been vaccinated.
Imports System.IO
Public Class Form1
    'Set up the variables - customer record, total pets not vaccinated, total records in the file, and a streamreader for the file.
    Structure PetsRecord
        Dim custName As String
        Dim address As String
        Dim petType As String
        Dim vacced As String
    End Structure
    Dim totNotVac As Integer
    Dim totalRecCount As Integer
    Dim PetFile As IO.StreamReader

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub btnLoad_Click(sender As Object, e As EventArgs) Handles btnLoad.Click

        'set an array of records to store each record as it comes in. Limitation: you need to know how many records in the file. Set the array at 15 to allow for adding more in later.
        Dim PetArray(15) As PetsRecord
        'variables that let me read in a line and split it into sections.
        Dim lineoftext As String
        Dim i As Integer
        Dim arytextfile() As String
        'tell them what text file to read
        PetFile = New IO.StreamReader(&quot;patients.txt&quot;)
        totNotVac = 0

        Try
            totalRecCount = 0
            ' read each line in and split the lines into fields for the records. Then assign the fields from the array. Finally, reset the array and loop.
            Do Until PetFile.Peek = -1
                'read in a line of text 
                lineoftext = PetFile.ReadLine()
                'split that line into bits separated by commas. these will go into the array.
                arytextfile = lineoftext.Split(&quot;,&quot;)
                'dunno whether this is the best way to do it, but stick the array bits into the record, and then clear the array to start again.
                PetArray(totalRecCount).custName = arytextfile(0)
                PetArray(totalRecCount).address = arytextfile(1)
                PetArray(totalRecCount).petType = arytextfile(2)
                PetArray(totalRecCount).vacced = arytextfile(3)

                totalRecCount += 1
                Array.Clear(arytextfile, 0, arytextfile.Length)
            Loop

            For i = 0 To PetArray.GetUpperBound(0)

                If PetArray(i).vacced = &quot;No&quot; Then
                    lstVaccinated.Items.Add(PetArray(i).vacced)
                    lstCustomer.Items.Add(PetArray(i).custName)
                    lstAddress.Items.Add(PetArray(i).address)
                    lstPetType.Items.Add(PetArray(i).petType)

                    totNotVac += 1
                    lblVacTotal.Text = &quot;The total number of unvaccinated animals is &quot; &amp; CStr(totNotVac)
                End If

            Next
        Catch ex As Exception
            MsgBox(&quot;Something went wrong with the file&quot;)
        End Try
        PetFile.Close()

    End Sub

    Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
        Close()

    End Sub
End Class

And one line from the patient.txt file:
    Richard Gere,16 Sunset Blvd,Gerbil,No
Opinion: there is no benefit to building an array like this. I agree it is a clunky use of arrays which I think is unnecessary (and old-school). For instance you don't even need to know in advance how many records, nor do you need to dimension the array to a predetermined size. There are more flexible data types available than arrays for the job.
When adding items to controls like a ListView or ListBox using .Items.Add you can use BeginUpdate at the beginning of your loop and EndUpdate at the end as you are populating the items from a loop.
The aim is to make the UI more responsive - if you have a large file and you're adding lots of items, the interface may freeze while the loop is running.
Although I would probably bind the list to a datatable instead, or another structure. Just append items to the datatable and let the control update itself.
So here is a refactored example: I have converted your structure to a class and I use List Of instead of an array (note the addition of a binding source). For this to work I need to use properties to expose class members (so I think), which is why I am using a class instead of a structure, but there should be a way to retain a structure if you wish.
There are several ways of reading a file, in this example I am using StreamReader. Note the use of a context manager (the Using block), which means I don't have to worry about closing the file, including in case of an exception. This happens automatically past the End Using statement.
In your code PetFile.Close() will not be executed if an exception occurs. Your procedure will exit after MsgBox. But what you can do is move PetFile.Close() to a Finally section within your Try-Catch block. But if you're attempting to close a file that isn't even open, this will raise an exception within the exception. The best solution is not to bother with it and use the context manager.
Note that each line in the file has to contain at least 4 comma-separated fields or the code will crash. So it is advisable to verify for each line that fields.Count = 4 and skip lines that don't match this criterion.
Here I am populating only one listbox, you can figure out the rest easily hopefully.
Imports System.IO

Public Class Form1

    Public Class PetsRecord
        Private m_CustomerName As String
        Private m_CustomerAddress As String
        Private m_PetType As String
        Private m_Vaccinated As String

        Public Property CustomerName() As String
            Get
                Return Me.m_CustomerName
            End Get
            Set(ByVal value As String)
                Me.m_CustomerName = value
            End Set
        End Property

        Public Property CustomerAddress() As String
            Get
                Return Me.m_CustomerAddress
            End Get
            Set(ByVal value As String)
                Me.m_CustomerAddress = value
            End Set
        End Property

        Public Property PetType() As String
            Get
                Return Me.m_PetType
            End Get
            Set(ByVal value As String)
                Me.m_PetType = value
            End Set
        End Property

        Public Property Vaccinated() As String
            Get
                Return Me.m_Vaccinated
            End Get
            Set(ByVal value As String)
                Me.m_Vaccinated = value
            End Set
        End Property
    End Class 'Structure

    Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click
        Dim PetArray As New List(Of PetsRecord)
        Dim bs As New BindingSource()
        Dim PetFile As String = &quot;C:\Users\test\Documents\pets.txt&quot;

        Using r As StreamReader = New StreamReader(PetFile)
            Dim line As String
            line = r.ReadLine
            Do While (Not line Is Nothing)

                ' split the line into fields
                Dim fields As New List(Of String)(line.Split(&quot;,&quot;c))
                If fields.Count &lt; 4 Then
                    Console.WriteLine(&quot;Skipping line (contains less than 4 fields): &quot; &amp; line)
                Else
                    ' flag this line
                    If fields(3) = &quot;No&quot; Then
                        Dim pet As New PetsRecord
                        pet.CustomerName = fields(0)
                        pet.CustomerAddress = fields(1)
                        pet.PetType = fields(2)
                        pet.Vaccinated = fields(3)
                        PetArray.Add(pet)
                    End If
                End If

                line = r.ReadLine
            Loop
        End Using

        ' bind the listbox to PetArray
        bs.DataSource = PetArray
        Me.lstCustomer.DisplayMember = &quot;CustomerName&quot;
        Me.lstCustomer.DataSource = bs

    End Sub
End Class