Dale Maunder Dale Maunder - 2 months ago 6
Vb.net Question

Visual Basic - ReDim Preserve - Object reference not set to an instance of an object

I'm very new to programming and trying to write a program where it reads data about real estate properties from a txt file and has the option of adding another property on a new line under the rest of the properties in the txt file.

This is the sub handling the ReDim of the array at the moment:

Private Sub ExitSetTexts()

Dim propertyId As String = arrListings(UBound(arrListings)).propertyId

ReDim Preserve arrListings(UBound(arrListings) + 1)
arrListings(UBound(arrListings)).address = txtAddress.Text
arrListings(UBound(arrListings)).city = txtCity.Text
arrListings(UBound(arrListings)).state = txtState.Text
arrListings(UBound(arrListings)).postcode = txtPostcode.Text

If rbHouse.Checked = True Then
arrListings(UBound(arrListings)).type = "H"
ElseIf rbUnit.Checked = True Then
arrListings(UBound(arrListings)).type = "U"
ElseIf rbAcreage.Checked = True Then
arrListings(UBound(arrListings)).type = "A"

End If

arrListings(UBound(arrListings)).bedrooms = txtBedrooms.Text
arrListings(UBound(arrListings)).salePrice = txtSalePrice.Text


propertyId = CInt(propertyId.Trim.Remove(0, 1))
propertyId = CInt(propertyId) + 1
propertyId = CInt(propertyId).ToString("D4")
propertyId = " P" + propertyId
arrListings(UBound(arrListings)).propertyId = propertyId


End Sub


When I run the program, enter all the details and then click on the button that runs this code, it throws a NullReferenceException saying "Additional information: Object reference not set to an instance of an object" and highlights this line:

arrListings(UBound(arrListings)).address = txtAddress.Text


I presume the ReDim is not working as intended because if I change it to (UBound(arrListings) - 1) then it will rewrite the new information ontop of the last line perfectly fine, but I cannot get it to write it on a new line.

Any guidance would be greatly appreciated,

Thanks.

Edit:

Forgot to add the part where I declare the array. I feel the way I've done this is rather dodgy but it was the first way I thought of and it seems to work.

In modMain is this;

Private listings() As Listing


Further in the Module is this function;

Public Function getListings() As Listing()

Return listings
End Function


At the top of frmListings I've declared a second array;

Private arrListings() As Listing


frmListings then calls this function on frmListings_Load like this;

arrListings = getListings()


Then at the end when you close the form is calls a second sub which replaces the data in the original array with the altered data in the second array.

Like this;

setListings(arrListings)

Public Sub setListings(ByVal arrListings())
listings = arrListings
End Sub


It's very messy but I couldn't work out how to use the array in the module from the form so I just did it like that.

Answer

When you resize the array, the new elements are Nothing by default so you need to set them to something before you use them:

ReDim Preserve arrListings(arrListings.Length)
arrListings(UBound(arrListings)) = New Listing
arrListings(UBound(arrListings)).address = txtAddress.Text
...

or

Private Sub ExitSetTexts()

    Dim list = New Listing
    list.address = txtAddress.Text
    ...
    list.propertyId = propertyId

    ReDim Preserve arrListings(arrListings.Length)
    arrListings(UBound(arrListings)) = list

End Sub

A better answer would be to use Private arrListings As New List(Of Listing), but that would need a lot of changes in your code, so easier to leave it as array.