Dynamic Arrays in VB.NET

Hello There,

I have created two arrays(Names() and Phones(), pretty self explanatory...). I want to be able to save on the fly, the content of textboxes into these arrays. I do not know how many elements will my arrays contain as it depends on the user's input.
Then I want to be able to look up a value from one array to the other i.e knowing a name I want to find the corresponding phone number and vice versa.

The first problem I am encountering is this: How can I check that the content of textboxes is actually stored in the arrays?
I have tried to have a couple of listboxes in there but I am not convinced 100% that it displays the content of the arrays...(see my code below) because I want to display the arrays content like this: [One array that is]
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Position As Long
        Dim Names() As String

        ReDim Preserve Names(UBound(Names))
        For Position = LBound(Names) To UBound(Names)
            MsgBox(Name(Position))
        Next Position
    End Sub
and this doesn't work. It's giving me an "ArgumentNullException was unhandled. Values cannot be null. Parameter name: Argument 'Array' is Nothing"
I don't understand the meaning of this error. Could you please explain?

And second, how do I go about implementing the look up? I am thinking of sorting the elements in the array first(that's why I am trying to see the content of the arrays) , am I in the right track?
Any suggestions or guidance would be much appreciated.

Here is a fragment of code that I have so far:
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        
        Dim Names() As String ' array to hold names
        Dim Phones() As String  ' array to hold phone numbers
        Dim Dimensioned As Boolean  ' to help check whether the array has been dimensioned
        Dim strName As String  ' to temporarily hold names
        Dim strPhone As String  ' to temporarily hold phone numbers
        

        Dimensioned = False   'means the array has not been dimensioned

        Do
            ' get data from textboxes
            strName = txtFullName.Text
            strPhone = txtPhone.Text
            If strName <> "" Then
                If Dimensioned = True Then
                    ReDim Preserve Names(0 To UBound(Names) + 1)
                    ReDim Preserve Phones(0 To UBound(Phones) + 1)
                Else
                    ReDim Names(0 To 0)
                    ReDim Phones(0 To 0)
                    Dimensioned = True
                End If
                Names(UBound(Names)) = strName
                Phones(UBound(Phones)) = strPhone
                ListBox1.Items.Add(Names(UBound(Names)))
                ListBox2.Items.Add(Phones(UBound(Phones)))
                txtFullName.Text = ""
                txtPhone.Text = ""
                txtFullName.Focus()
            End If

        Loop Until strName = ""

    End Sub

Open in new window

SmanyxAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jorge PaulinoIT Pro/DeveloperCommented:
Don't use Arrays, use list from generics class
Dim list As New List(Of String)
0
Wayne Taylor (webtubbs)Commented:
You'll find everything much easier if you replace your arrays with ArrayLists or Generic lists.

http://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx
http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

Wayne
0
SmanyxAuthor Commented:
Thanks experts for your prompt reply and references provided but using arrays is a requirement. I need to have both arrays and look up the name from one array and get the corresponding phone number in the other array and vice versa.
How to go about that  using arrays? There should be a way, should it be hard or complicated, right?

Smanyx
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

Jorge PaulinoIT Pro/DeveloperCommented:
>> using arrays is a requirement
Not even close. Arrays are not strongly typed, you need to redim all the time and they are slower that way.
Generics offers a best way to do what you want.

PS: Do you think this is a question for 50 points ? :)
0
Wayne Taylor (webtubbs)Commented:
Why do you say it's a requirement? Is it because of some restriction in another class? If so, you can still pass an ArrayList or generic List object as a simple array by using the respective ToArray methods.

Wayne
0
SmanyxAuthor Commented:
Starting with the points attributed to the question, I have to admit that I don't really know how that works, I am not the expert so I may not have a clue as to how hard my question can be. Some times I may think it could be a simple solution but when working with you guys then I may realise how difficult the question actually is.
May be giving point after the first expert comments or when accepting the solution could help, I am not quite sure.
I might want to increase points now but how many point this  question is worth? Honestly, I don't know.
Let me increase that to 250. Hope it is fair.
Do the points allocated to a question influence the way you guys answer them? (Good for me to know for future questions, thanks)

Ok, back to my question. "Using arrays is  a requirement" for this particular exercise. Probably not in the real world situations programming.
I need to develop a program that uses two ARRAYS to provide  a facility for storing and looking up values.

Yes, I need to ReDim the array every time a new name is entered. Because I don't know when the user will stop entering names, I have a loop that continuously enters data and ReDims the array accordingly.
Please, look at my code that I have provided. Is it any good in this regard? As you mentioned, there is a better way to achieve the same thing with ArrayLists and Generic Lists, I am looking forward to be looking into it shortly.
But for now, I need to deal with this problem using arrays.

Am I really off track ? Looking at my code, is there a way to check that the arrays to contain whatever was input in the textboxes?

Thanks.

Smanyx
0
Wayne Taylor (webtubbs)Commented:
Seems a little odd to absolutely require redimensioning arrays, but anyway....

To determine if an array contains a particular item, use the IndexOf method, which returns the position of the item, or -1 if not found...

    If Names.IndexOf(txtFullName.Text) > 0 Then
        'the name already exists
    Else
        'the name does not exist
    End If

It would also be a good idea to read through this -> http://msdn.microsoft.com/en-us/library/system.array.aspx

Wayne
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jorge PaulinoIT Pro/DeveloperCommented:
>> Do the points allocated to a question influence the way you guys answer them?
Yes, it does. Normally 50 points are for rookie question, links or limited users questions. That why I have included the note (sincee you are a Premium account)
Aboute the question ... you can still use arrays, and Wayne already showed you a possible solution, but it's our "responsability" (and me as Microsoft MVP) to lead you on the right direction and syntax. Is not only to show you solution but provide a real suppport that will help you in the future.
That why me an Wayne are insisting on that!
Old arrays are not very used today ... check this small example using a List(Of T):
 

        ' Declare the new list
        Dim names As New List(Of String)

        ' Add itens (no redim)
        names.Add("jorge")
        names.Add("Smanyx")

        ' Add a range of itens
        names.AddRange(New String() {"name A", "name B", "name C"})

        Debug.WriteLine("Total itens: " & names.Count)

        If names.Contains("jorge") Then
            MessageBox.Show("Yes!")
        End If

        names.Clear()

Open in new window

0
PaulHewsCommented:
Smanyx,
I'm guessing that this is for a school project that has certain requirements.

In the code that you wrote, you declared your arrays as local variables.  This means that they are local to the btnSave_Click procedure.  You should declare them at the Form level if you wish to maintain the values between calls to this procedure.  

Scope of Variables
http://www.dreamincode.net/forums/index.php?showtopic=58655

I've provided a tiny sample that shows how to declare a form level array, and call redim to resize it on the fly.  Create a new project with a default form, and add two buttons:  btnAdd and btnShow.  Note that btnShow displays the contents of the array in the debug window.  You can access the debug window from the Debug menu > windows > Immediate or try Ctrl+G.
Public Class Form1
    Dim mFormLevelArray() As String
    Dim Count As Integer = 0
    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        If mFormLevelArray Is Nothing Then
            ReDim mFormLevelArray(0)
        Else
            ReDim Preserve mFormLevelArray(mFormLevelArray.GetUpperBound(0) + 1)
        End If
        Count += 1
        mFormLevelArray(mFormLevelArray.GetUpperBound(0)) = "Hello World " & Count.ToString
    End Sub
    Private Sub btnShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShow.Click
        For i As Integer = 0 To mFormLevelArray.GetUpperBound(0)
            Debug.WriteLine(mFormLevelArray(i))
        Next
    End Sub
End Class

Open in new window

0
SmanyxAuthor Commented:
Thanks for all your input guys, I have managed to check that my arrays were adequately populated.

So far so good. The trouble I am having at the moment is at two levels:
1/ How to check that the name to be added to the array already exists, and give appropriate warning?
2/ How to look up the telephone number on name?
 
to check that the name exists, I am trying this:

For i As Integer = 0 To mFormLevelArray.GetUpperBound(0)

        If strName = mFormLevelArray(i) Then
            MessageBox.Show("This record does exist !")
         End If
         MessageBox.Show("New record")

        Next
I am using a loop here which makes it hard because this checking should happens when the user clicks the btnSave , not on it 's own. I am not sure this is an effective way to go about achieving what I want.

To try looking up the number:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        For i As Integer = 0 To mFormLevelArray.GetUpperBound(0)

            If strName = mFormLevelArray(i) Then
                TheNumber = mFormLevArrayPhone.GetValue(i)
                Label1.Text = TheNumber
            End If


        Next
    End Sub
Obviously, it's not working.

I 'll attach the entire code as I have it now so that you can continue to point me in the right direction.
Thank you.
Public Class Form1
    Dim mFormLevelArray() As String
    Dim count As Integer
    Dim strName As String
    Dim mFormLevArrayPhone() As String
    Dim strPhone As String
    Dim TheNumber As String ' store the phone number to display in textbox


    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        If mFormLevelArray Is Nothing Then
            ReDim mFormLevelArray(0)
        Else
            ReDim Preserve mFormLevelArray(mFormLevelArray.GetUpperBound(0) + 1)
        End If

        If mFormLevArrayPhone Is Nothing Then
            ReDim mFormLevArrayPhone(0)
        Else
            ReDim Preserve mFormLevArrayPhone(mFormLevArrayPhone.GetUpperBound(0) + 1)
        End If
        count += 1
        strName = TextBox1.Text
        strPhone = txtPhone.Text
        TextBox1.Text = ""
        txtPhone.Text = ""
        TextBox1.Focus()
        Dim NameToFind As String
        Dim NameFoundAt As String

        NameToFind = TextBox1.Text
        'NameFoundAt = -1   ' means not found

        'If Not Array.Find(mFormLevelArray, AddressOf) Is Nothing Then
        '    'MessageBox.Show("Found at: " + NameFoundAt.tostring))
        '    'MessageBox.Show(Array.IndexOf(mFormLevelArray, NameFoundAt).ToString)
        'Else
        '    'MessageBox.Show("Not found")
        '    'MessageBox.Show(Array.IndexOf(mFormLevelArray, NameToFind).ToString)
        'End If

        mFormLevelArray(mFormLevelArray.GetUpperBound(0)) = strName
        mFormLevArrayPhone(mFormLevArrayPhone.GetUpperBound(0)) = strPhone

    End Sub

    Private Sub btnShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShow.Click
        For i As Integer = 0 To mFormLevelArray.GetUpperBound(0)
            'Debug.WriteLine(mFormLevelArray(i))
            ListBox1.Items.Add(mFormLevelArray(i) & ControlChars.Tab & _
                               mFormLevArrayPhone(i))
        Next
        'For i As Integer = 0 To mFormLevelArray.GetUpperBound(0)

        '    If strName = mFormLevelArray(i) Then
        '        MessageBox.Show("This record does exist !")
        '    End If
        '    MessageBox.Show("New record")

        'Next
    End Sub

    Private Sub btnCount_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' to get the number of elements contained in the array
        Dim counter As Integer
        counter = mFormLevelArray.Length
        MessageBox.Show("Your array contains " & counter & " elements")
    End Sub

    Private Sub btnDisplayNumber_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        For i As Integer = 0 To mFormLevelArray.GetUpperBound(0)

            If strName = mFormLevelArray(i) Then
                TheNumber = mFormLevArrayPhone.GetValue(i)
                lblPhoneNumber.Text = TheNumber
            End If


        Next
    End Sub
End Class

Open in new window

0
PaulHewsCommented:
1. Wayne already indicated how to tell if an item is contained in the array in http:#a29040792  The IndexOf method is what you need.

2. You have the right basic approach.  The index will be the same for the name and corresponding phone number in the two arrays.  What part of this is not working?
0
SmanyxAuthor Commented:
I am a bit confused. Trying to implement the search:

If mFormLevelArray.IndexOf(TextBox1.Text) > 0 Then
           ' record exist
            MessageBox.Show("Existing record", MessageBoxButtons.OK)
        Else
           ' new record, add it
            mFormLevelArray(mFormLevelArray.GetUpperBound(0)) = strName
            mFormLevArrayPhone(mFormLevArrayPhone.GetUpperBound(0)) = strPhone
        End If

I am getting these erreur messages before compile:

Error      1      Overload resolution failed because no accessible 'IndexOf' accepts this number of arguments.      C:\Documents and Settings\user1\My Documents\Visual Studio 2008\Projects\OnTheFly\Form1.vb      27      12      OnTheFly

Error      2      Overload resolution failed because no accessible 'Show' can be called without a narrowing conversion:
    'Public Shared Function Show(owner As System.Windows.Forms.IWin32Window, text As String) As System.Windows.Forms.DialogResult': Argument matching parameter 'owner' narrows from 'String' to 'System.Windows.Forms.IWin32Window'.
    'Public Shared Function Show(owner As System.Windows.Forms.IWin32Window, text As String) As System.Windows.Forms.DialogResult': Argument matching parameter 'text' narrows from 'System.Windows.Forms.MessageBoxButtons' to 'String'.
    'Public Shared Function Show(text As String, caption As String) As System.Windows.Forms.DialogResult': Argument matching parameter 'caption' narrows from 'System.Windows.Forms.MessageBoxButtons' to 'String'.      C:\Documents and Settings\user1\My Documents\Visual Studio 2008\Projects\OnTheFly\Form1.vb      28      13      OnTheFly

What does all this mean?
0
PaulHewsCommented:
Array.IndexOf is a shared function, which means it doesn't act on a class instance but instead you call it like this:

If Array.IndexOf(mFormLevelArray, NameToFind) > 0 Then

The messagebox can be simplified and made error free:

MessageBox.Show("Existing record")

0
SmanyxAuthor Commented:
Thank you guys! I have finally managed to get my program working with all your guidance and input.
Cheers,

Smanyx
0
PaulHewsCommented:
Glad you got it working... One correction to what I posted above.  It should be:

If Array.IndexOf(mFormLevelArray, NameToFind) > -1

If the item is not found in the array the function returns (lowerbound -1) which in this case would be -1.
0
SmanyxAuthor Commented:
Oh yes, I did figure it out. It took me quite some time though. But it's all good.
Thanks heaps for pointing me in the right direction.
I really do appreciate.

Smanyx
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.