# vb6 array index question



## cj_white (Oct 28, 2001)

Can you use a variable as an array index when trying to loop through an array?

ie.
f = 0
l = 1
Do Until IsEmpty(arrContacts) = True
lstContacts.AddItem arrContacts(l) & ", " & arrContacts(f)
f = f + 9
l = l + 9
Loop
End If

I am assuming you can not since I keep getting subscript out of range errors, but I can't figure out another way to loop through this. Thanks in advance


----------



## OBP (Mar 8, 2005)

Why are you using 
f = f + 9
l = l + 9
what is the significance of the +9


----------



## cj_white (Oct 28, 2001)

I am trying to get the first and last name out of a text file and they occur at 0 and 1 in the array and then 9 indices later, so the next 2 I would need is 9 and 10. Here is the rest of the code so it will make more sense.

Public Sub Get_Contacts()
Dim fso As New FileSystemObject
Dim ts As TextStream

'set text stream to correct file and permissions
Set ts = fspenTextFile("c:\contactinfo.txt", ForReading, True)

'split file by pipe character (|) and insert each into array
If IsEmpty(ts) = True Then
lstContacts.AddItem "No Contacts"
Else
Do While Not ts.AtEndOfStream
arrContacts = Split(ts.ReadAll, "|")
Loop

I am working on an address book. When a contact is added it sends the info to a text file. I am trying to get the first and last names to appear in a list box to be selected.

Here is the text file

*Bob*| *Smith*| 1226 Somewhere| Knoxville | Tennessee | 37923 | 555-5555 | 555-5555 | [email protected]
|*John* | *Doe*| 1227 Somewhere| Knoxville | Tennessee | 37923 | 555-5555 | 555-5555 | [email protected]

So all I need to do is be able to loop through the array and pick out index 0 and 1 and then every 9th index after that until it reaches the end of the array. If there is an easier way to do this besides using a database please let me know. Also if you need to see more code I will post it. Thanks


----------



## asbo (Sep 21, 2001)

Assuming that you control the format of the address book text file, this is what I would do:

First of all, change the format to


> first|last|street|city|state|zip|home|work|e-mail


with a new line seperating entries, or in VB a 'vbCrLf'.

Using that format, I would use the following code:

```
Public Sub getContacts()
    Dim objAddressBookThread, fsoReadAddressBookFile
    Dim aryRawEntries(), aryEntryTemp(), strOutput As String

    'Create our FSO Scripting Object
    Set objAddressBookThread = CreateObject("Scripting.FileSystemObject")
    
    'Open our file up for FSO access
    Set fsoReadAddressBookFile = objAddressBookThread.OpenTextFile("c:\contactinfo.txt", ForReading, True)

    'Split by linefeeds to seperate each entry
    aryRawEntries = Split(fsoReadAddressBookFile.ReadAll, vbCrLf)

    'Close up the FSO
    fsoReadAddressBookFile.Close
    
    'Loop through the array to seperate
    For i = LBound(aryRawEntries) To UBound(aryRawEntries)
        'Temporary split an entry
        aryEntryTemp = Split(aryRawEntries(i), "|")
        
        strOutput = strOutput & aryEntryTemp(0) & " " & aryEntryTemp(1) & vbCrLf
        strOutput = strOutput & aryEntryTemp(2) & vbCrLf
        strOutput = strOutput & aryEntryTemp(3) & ", " & aryEntryTemp(4) & vbCrLf
        strOutput = strOutput & aryEntryTemp(4) & vbCrLf & vbCrLf
        strOutput = strOutput & aryEntryTemp(5) & vbCrLf
        strOutput = strOutput & aryEntryTemp(6) & vbCrLf
        strOutput = strOutput & aryEntryTemp(7) & vbCrLf
        strOutput = strOutput & aryEntryTemp(8) & vbCrLf
        If i <> UBound(aryRawEntries) Then strOutput = strOutput & "------------------------------------------------" & vbCrLf
    Next
    
    'Whatever else you want
End Sub
```
You'll have to forgive if there are any syntax errors, I didn't get a chance to run it through the IDE.

If you set up "c:\contactinfo.txt" like this:


> Bob|Smith|1226 Somewhere|Knoxville|Tennessee|37923|555-5555|555-5555|[email protected]
> John|Doe|1227 Somewhere|Knoxville|Tennessee|37923|555-5555|555-5555|[email protected]


Then strOutput will end up returning:


> Bob Smith
> 1226 Somewhere
> Knoxville, Tennessee
> 37923
> ...


I think this does what you're asking for. Obviously you can change all the formatting to your desire in the For Loop, but that was just an example of what you can do with it.


----------



## cj_white (Oct 28, 2001)

Thanks, that does answer one problem I will be facing when I get to retrieving all the info, but the problem I am having now is that I need just the first and last name for my list box. So if I do it the way you have it I will need to show index (0) and (1) and then every index number after that to show only first and last names in the list. 

(0) John
(1) Smith
(2) Email
(3) Phone
(4) something else
(5) John
(6) Doe
(7) Email
(8) Phone

So for the above I would need to show indices 0, 1, 5, 6. That is why in my original code I was trying to loop through every 9th index to get only first and last names. I thought I had it figured out but apparently you can't use variables for an array index. I have attached a pic of what I am trying to do. With that you can see in my code that I have hard coded the indices of the array I need into the program. I just want to be able to do this dynamicly. I sure hope this makes sense. Thanks for all the help


----------



## asbo (Sep 21, 2001)

The only problem with doing it with your "by-9" method is that it honestly makes less programmatical sense; in this day and age memory is by no means a barrier and the result of my code just seems like it'd be a heck a lot easier to manipulate in the grand scheme of things. And beside, who doesn't love For loops? 

Because of the limitations VB has in array flexibility, the best way I could see to do this would be to globally declare the master array (aryRawEntries) so that after you parse your data you don't have to repeat the process in order to view that information. So basically:

```
Option Base 0
Dim aryRawEntries() As String
------------------------------------------------
Private Sub getContacts()
    Dim objAddressBookThread, fsoReadAddressBookFile
    Dim aryEntryTemp() As String

    Set objAddressBookThread = CreateObject("Scripting.FileSystemObject")
    Set fsoReadAddressBookFile = objAddressBookThread.OpenTextFile("c:\contactinfo.txt", ForReading, True)

    aryRawEntries = Split(fsoReadAddressBookFile.ReadAll, vbCrLf)

    fsoReadAddressBookFile.Close

    For i = LBound(aryRawEntries) To UBound(aryRawEntries)
        aryEntryTemp = Split(aryRawEntries(i), "|"

        'Add each Last, First entry and make sure that its index in the list is the same as in the array
        lstContacts.AddItem aryEntryTemp(1) & ", " aryEntryTemp(0)
    Next
End Sub
------------------------------------------------
Private Sub lstContacts_Click()
    Dim aryEntryTemp() As String

    aryEntryTemp = Split(aryRawEntries(lstContacts.ListIndex), "|")
    
    txtFirst = aryEntryTemp(0)
    txtLast = aryEntryTemp(1)
    txtAddress = aryEntryTemp(2)
    txtCity = aryEntryTemp(3)
    cmbState = aryEntryTemp(4) 'May want/need to add verification here to make sure it's an actual state
    txtZip = aryEntryTemp(5)
    txtHome = aryEntryTemp(6)
    txtCell = aryEntryTemp(7)
    txtEmail = aryEntryTemp(8)
End Sub
```
How's that work for you?


----------



## cj_white (Oct 28, 2001)

The way I have my code written, I have the contents of the entire text file in an array for later use, but for this instance I just need certain things out of it. I copied your code into my project and the temp array kept overwritting itself with the next value in the master array, until it had no value. I am just learning VB so you must forgive me if I am missing the obvious. Here is my entire code for my main menu page.


```
'***************************************************************
'*SubRoutine to Get the first and last names for the contact list box
'***************************************************************


Public Sub Get_Contacts()
   Dim fso As New FileSystemObject
   Dim ts As TextStream
   
   'set text stream to correct file and permissions
   Set ts = fso.OpenTextFile("c:\contactinfo.txt", ForReading, True)
   
   'split file by pipe character (|) and insert each into array
   If IsEmpty(ts) = True Then
        'lstContacts.AddItem "No Contacts"
   Else
        Do While Not ts.AtEndOfStream
            arrContacts = Split(ts.ReadAll, "|")
        Loop
   '**********************************************************
        'lstContacts.AddItem arrContacts(1) & ", " & arrContacts(0)
        'lstContacts.AddItem arrContacts(10) & ", " & arrContacts(9)
        f = 0
        l = 1
        Do Until IsEmpty(arrContacts) = True
            lstContacts.AddItem arrContacts(l) & ", " & arrContacts(f)
            f = f + 9
            l = l + 9
        Loop
    End If
End Sub
'***************************************************************
'*SubRoutine to add new contact to text file
'***************************************************************
Public Sub AddInfo()
    Dim fso As New FileSystemObject
    Dim ts As TextStream
    Dim strInfo As String

'set the textstream to the appropriate file with the appropriate rights
Set ts = fso.OpenTextFile("c:\contactinfo.txt", ForAppending, True)

'place info into variable to be written to the file
strInfo = "|" & txtFname & " | " & txtLname & " | " & txtAddress & " | " & txtCity & " | " & cboState & " | " & txtZip & " | " & txtHPhone & " | " & txtCPhone & " | " & txtEmail

'write info into file
ts.WriteLine strInfo
'close file
ts.Close
'Display who has been entered
MsgBox txtFname & " " & txtLname & " has been added!"
End Sub
'***************************************************************
Private Sub cmdAddContact_Click()
'call routine that adds info to text file
Call AddInfo

'clear text boxes after data has been sent
Dim ctrl As Control

For Each ctrl In frmMainMenu
    If TypeOf ctrl Is TextBox Then
        ctrl.Text = ""
    End If
Next
End Sub
'**************************************************************
'Subroutine to delete contact
'NOT WRITTEN YET
'*************************************************************
Private Sub cmdDelete_Click()
Beep
MsgBox "Are You Sure You Would Like to Delete This Contact?", vbYesNo
End Sub
'**************************************************************
Private Sub cmdEdit_Click()
frmUpdateContact.Show modal
End Sub
'**************************************************************
Private Sub Form_Load()
'call routine to get first and last names for contact list
Call Get_Contacts
'add states to drop down menu
    frmMainMenu.cboState.AddItem "Alabama"
    frmMainMenu.cboState.AddItem "Alaska"
    frmMainMenu.cboState.AddItem "Arizona"
    frmMainMenu.cboState.AddItem "Arkansas"
    frmMainMenu.cboState.AddItem "California"
    frmMainMenu.cboState.AddItem "Colorado"
    frmMainMenu.cboState.AddItem "Connecticut"
    frmMainMenu.cboState.AddItem "Delaware"
    frmMainMenu.cboState.AddItem "Florida"
    frmMainMenu.cboState.AddItem "Georgia"
    frmMainMenu.cboState.AddItem "Hawaii"
    frmMainMenu.cboState.AddItem "Idaho"
    frmMainMenu.cboState.AddItem "Illinois"
    frmMainMenu.cboState.AddItem "Indiana"
    frmMainMenu.cboState.AddItem "Iowa"
    frmMainMenu.cboState.AddItem "Kansas"
    frmMainMenu.cboState.AddItem "Kentucky"
    frmMainMenu.cboState.AddItem "Louisiana"
    frmMainMenu.cboState.AddItem "Maine"
    frmMainMenu.cboState.AddItem "Maryland"
    frmMainMenu.cboState.AddItem "Massachusetts"
    frmMainMenu.cboState.AddItem "Michgan"
    frmMainMenu.cboState.AddItem "Minnesota"
    frmMainMenu.cboState.AddItem "Mississippi"
    frmMainMenu.cboState.AddItem "Missouri"
    frmMainMenu.cboState.AddItem "Montana"
    frmMainMenu.cboState.AddItem "Nebraska"
    frmMainMenu.cboState.AddItem "Nevada"
    frmMainMenu.cboState.AddItem "New Hampshire"
    frmMainMenu.cboState.AddItem "New Jersey"
    frmMainMenu.cboState.AddItem "New Mexico"
    frmMainMenu.cboState.AddItem "New York"
    frmMainMenu.cboState.AddItem "North Carolina"
    frmMainMenu.cboState.AddItem "North Dakota"
    frmMainMenu.cboState.AddItem "Ohio"
    frmMainMenu.cboState.AddItem "Oklahoma"
    frmMainMenu.cboState.AddItem "Oregon"
    frmMainMenu.cboState.AddItem "Pennsylvania"
    frmMainMenu.cboState.AddItem "Rhode Island"
    frmMainMenu.cboState.AddItem "South Carolina"
    frmMainMenu.cboState.AddItem "South Dakota"
    frmMainMenu.cboState.AddItem "Tennessee"
    frmMainMenu.cboState.AddItem "Texas"
    frmMainMenu.cboState.AddItem "Utah"
    frmMainMenu.cboState.AddItem "Vermont"
    frmMainMenu.cboState.AddItem "Virginia"
    frmMainMenu.cboState.AddItem "Washington"
    frmMainMenu.cboState.AddItem "West Virginia"
    frmMainMenu.cboState.AddItem "Wisconsion"
    frmMainMenu.cboState.AddItem "Wyoming"
'Display Time and Date you logged on
lblWelcome.Caption = "Welcome " & frmLogin.txtUser.Text & "! " & vbNewLine & "Logged in " & Now()
End Sub

'***************************************************************
Private Sub mnuExit_Click()
Unload Me
End Sub
```
If this was PHP and I was retrieving this from a database I would have no problem. Thanks again for your post, I'm sorry if I'm being a pain here I just really want to understand this for my class.


----------



## asbo (Sep 21, 2001)

cj_white said:


> I copied your code into my project and the temp array kept overwritting itself with the next value in the master array, until it had no value.


Okay, we're talking about which iteration of my code, the second or the first?

Second, the temp array is just that -- temporary storage of the split entry from the master array so that the program can take what information it needs. Through each iteration of the For loop, you can take what you need from each raw entry. If you only want it from one specific entry, then figure out the index of it, and run it through the temporary parser. Now that I think about it, I would actually structured the code a whole different way, but I lack the motivation and IDE to do it. I hope you don't mind 

Let me know if you have any other questions.


----------



## cj_white (Oct 28, 2001)

Well I finally got the results I am looking for. This is the code I used for it.


```
Public Sub Get_Contacts()
   Dim fso As New FileSystemObject
   Dim ts As TextStream
   
   'set text stream to correct file and permissions
   Set ts = fso.OpenTextFile("c:\contactinfo.txt", ForReading, True)
   
   'split file by pipe character (|) and insert each into array

        Do While Not ts.AtEndOfStream
            arrContacts = Split(ts.ReadAll, vbCrLf)
        Loop
   '**********************************************************
        If IsEmpty(arrContacts) = True Then
            lstContacts.AddItem "No Contacts"
        Else
            Dim f As Integer
            Dim l As Integer
        
            f = 0
            l = 1
            Do Until f And l > UBound(arrContacts)
                lstContacts.AddItem arrContacts(l) & ", " & arrContacts(f)
                f = f + 11
                l = l + 11
            Loop
        End If
End Sub
```
I'm not sure if it is very sensible or good programming at all, but I got it. I appreciate all the help you gave me asbo.


----------



## asbo (Sep 21, 2001)

I could -probably- rip that apart if I wanted to  It's good to see that you formulated a method on your own -- it's the only true way to learn. From there it's just figuring out what you did wrong in the first place and improving your technique.


----------

