Dale Maunder Dale Maunder - 1 year ago 63
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 Source

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.