Results 1 to 8 of 8

Thread: VB 6 Array Problems

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    3

    VB 6 Array Problems

    Hello,

    I'm new to these boards so if I'm doing anything wrong here please let me know.

    I'm currently trying to produce a word game in VB 6, very much like Word Challenge on Facebook for those familiar. ATM I'm making a test program which loads a dictionary file into a 2D array so (4, 1) is 4 letter word, (5, 1) 5 letter word and so on. Code below

    Code:
    Option Explicit
    
    Dim WordDictionary As String
    Dim DictionaryWord As String
    Dim Words() As String
    Dim Index(3 To 6) As Integer
    Dim WordLength As Integer
    Dim ArrayUpper As Integer
    Dim ArrayLower As Integer
    Dim ArrayRange As Integer
    
    
    Private Sub Form_Load()
    WordDictionary = App.Path & "\WordDictionaryFiles\Dashed.txt"
    End Sub
    
    Private Sub cmdTest_Click()
    Index(3) = 1
    Index(4) = 1
    Index(5) = 1
    Index(6) = 1
    
    Open WordDictionary For Input As #1
        Do While Not EOF(1)
            Line Input #1, DictionaryWord
            WordLength = Len(DictionaryWord)
            ReDim Preserve Words(3 To 6, 1 To Index(WordLength)) As String
            Words(WordLength, Index(WordLength)) = DictionaryWord
            Index(WordLength) = Index(WordLength) + 1
        Loop
    Close #1
    From my tests this should work (setting watches on the different variables as filling in a grid as it loads each cell of the array). However from here I made a test in order to return the 3 to 6 letter words each individually on click of each command button. This seems to work fine for the 3 letter words but 4, 5 and 6 are all presenting issues, printing just one word and a series of blank lines. Code as follows,

    Code:
    Private Sub cmd3Letters_Click()
    ArrayLower = LBound(Words, 2)
    ArrayUpper = UBound(Words, 2)
    
    For ArrayRange = ArrayLower To ArrayUpper
        Form1.Print Words(3, ArrayRange)
    Next ArrayRange
    
    End Sub
    
    Private Sub cmd4Letters_Click()
    
    ArrayLower = LBound(Words, 2)
    ArrayUpper = UBound(Words, 2)
    
    For ArrayRange = ArrayLower To ArrayUpper
        Form1.Print Words(4, ArrayRange)
    Next ArrayRange
    
    End Sub
    
    Private Sub cmd5Letters_Click()
    
    ArrayLower = LBound(Words, 2)
    ArrayUpper = UBound(Words, 2)
    
    For ArrayRange = ArrayLower To ArrayUpper
        Form1.Print Words(5, ArrayRange)
    Next ArrayRange
    
    End Sub
    
    Private Sub cmd6Letters_Click()
    
    ArrayLower = LBound(Words, 2)
    ArrayUpper = UBound(Words, 2)
    
    For ArrayRange = ArrayLower To ArrayUpper
        Form1.Print Words(6, ArrayRange)
    Next ArrayRange
    
    End Sub
    Atm I'm pretty stumped and I've been thinking on this for several days, I have a suspicion that I need to use a variable (jagged) array, but I am not aware of how to do this. I've attatched a zip with the files so you can view the program in it's entirety.

    Can anyone help me out here?

    Thank you in advance,

    Danimono
    Attached Files Attached Files

  2. #2
    PowerPoster Spoo's Avatar
    Join Date
    Nov 2008
    Location
    Right Coast
    Posts
    2,656

    Re: VB 6 Array Problems

    Dani

    I work with arrays, but do not much experience using
    ReDim Preserve -- I typically oversize the array and just
    populate it.

    Nonetheless, the highlighted line from your loop seems
    to be problematic ...
    Code:
    Open WordDictionary For Input As #1
    Do While Not EOF(1)
        Line Input #1, DictionaryWord
        WordLength = Len(DictionaryWord)
        ReDim Preserve Words(3 To 6, 1 To Index(WordLength)) As String
        Words(WordLength, Index(WordLength)) = DictionaryWord
        Index(WordLength) = Index(WordLength) + 1
    Loop
    Close #1
    Perhaps it should just read as
    Code:
            ReDim Preserve Words(WordLength, 1 To Index(WordLength)) As String
    That is, instead of trying to ReDim all of the 1st-D elements, only
    ReDim the 1st-D element that applies.

    I have not tried this, but hopefully it works.

    Spoo

  3. #3
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: VB 6 Array Problems

    Welcome to VBForums

    You can only REDIM PRESERVE the last dimension of an multi-dim array. Any change of the other dimensions will raise a run-time error!
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  4. #4

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    3

    Re: VB 6 Array Problems

    Hmm thanks for the advice, just trying to think it through atm,

    Spoo: "ReDim Preserve Words(WordLength, 1 To Index(WordLength)) As String" I think I remember thinking this through, but I will try to implement it when I have access to the program again tommorow.
    I think I might have dismissed it worrying that this would say preserve the values in 5, 1 to 5 for example, but then clear 3 and 4, _'s values. Am I wrong here.

    And opus: I'm trying to think of this in a visual code sense, can you give a brief example as to how I would have to code this so just the last dimension is Redim preserved or would this clear the other cells in the array?

    In honestly think I should note I am a bit of a VB newbie, mostly self taught in the odd hours I have spare. Some code comes to me kinda naturally where I can logically think things through. But it doesn't seem to be working here.

    I've had variable/jagged arrays mentioned for storing/managing information like this from some and it seems to make sense but I have never attempted, not can I find any basic guide to show how to get started about implementing a one.

    Oh And thank you for the welcome.

    Regards,

    Danimono

  5. #5
    PowerPoster Spoo's Avatar
    Join Date
    Nov 2008
    Location
    Right Coast
    Posts
    2,656

    Re: VB 6 Array Problems

    Dani

    As I mentioned, I don't work much with ReDim Preserve, but
    the more I think about it, I'm inclined to think that my suggestion
    will have little (if any) effect.

    Granted, per Opus's comment, you are properly only trying to
    increase "last dimension", but I am now thinking that the problem
    may lie in your cmdButton subs -- the "print out" subs.

    Have you checked to see if the array itself is properly populated?

    That is, do Words(4,2), Words(4,3) etc contain values? You can
    quickly do this by looking in the Locals Window.

    Spoo

  6. #6

    Thread Starter
    New Member
    Join Date
    Oct 2011
    Posts
    3

    Re: VB 6 Array Problems

    Well I tested to ensure that the words were being loaded into the array correctly by setting a watch to stop the program each time the value of "Words(3, Index(WordLength))", Words(4, Index(WordLength)) and so on changed, I then added the word that is showed on each stop a drawn representation of the array in the relevant cells.

    After doing my drawn representation of the array came out as I had expected, and to confuse me more so, the 3 letter words all print in the exact order that my drawn representation shows that it should... so that must be right... This is why I'm having so much confusion. I'm sorry if I'm overlooking your suggestion of how to check the values, but again I will be looking when I have the opportunity. It is just very much unusual, in my opinion, the way that it's not seeming to work for any other word length but the 3.

    Regards,

    Danimono

  7. #7
    Frenzied Member
    Join Date
    Jun 2006
    Posts
    1,098

    Re: VB 6 Array Problems

    Code:
    Open WordDictionary For Input As #1
        Do While Not EOF(1)
            Line Input #1, DictionaryWord
            WordLength = Len(DictionaryWord)
            ReDim Preserve Words(3 To 6, 1 To Index(WordLength)) As String
            Words(WordLength, Index(WordLength)) = DictionaryWord
            Index(WordLength) = Index(WordLength) + 1
        Loop
    Close #1
    The problem with this code is that the array will sometimes become smaller. If you already have five 4-letter words when you get your third 3-letter word, the array will go from (3 To 6, 1 To 5) down to (3 To 6, 1 To 3). This causes loss of data, and this is why some of your longer words are missing.

    You can easily avoid making the array smaller by testing the upper bound first:
    Code:
    ReDim Words(3 To 6, 1 To 1)
    Open WordDictionary For Input As #1
        Do While Not EOF(1)
            Line Input #1, DictionaryWord
            WordLength = Len(DictionaryWord)
            If Index(WordLength) > UBound(Words, 2) Then
                ReDim Preserve Words(3 To 6, 1 To Index(WordLength))
            End If
            Words(WordLength, Index(WordLength)) = DictionaryWord
            Index(WordLength) = Index(WordLength) + 1
        Loop
    Close #1
    That should solve your immediate problem. There is, however, no need to separate the words by length. You'll be better off will all of the words in a one-dimensional array.

  8. #8
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: VB 6 Array Problems

    Alternatively, if you do want to separate by length you could use a UDT array with a Dynamic Array as a member, rather than a 2D array. Also, 'ReDim Preserve' is fairly slow so minimising the number times you use it is a good idea.

    The code below is an example of using a UDT and 'over dimensioning' the Dynamic Arrays such that they only have to be ReDim Preserve(d) once. The use of Constants for the Minimum and Maximum number of characters in a word gives an opportunity to extend easily. (eg if you want to include 7 letter words, just change the Constant 'MAX' to 7)
    Code:
    Option Explicit
    
    Private Const MIN As Integer = 3    'Minimum number of characters in a word
    Private Const MAX As Integer = 6    'Maximum number of characters in a word
    
    Private Type Words
        Count As Long
        List() As String
    End Type
    
    Private uWords(MIN To MAX) As Words
    
    Private Sub Command1_Click()
    Dim intFile As Integer
    Dim intI As Integer
    Dim lngI As Long
    Dim intLen As Integer
    Dim strData As String
    Dim strRecords() As String
    intFile = FreeFile
    '
    ' Open the data file, read the entire contents
    ' and split into records
    '
    Open "C:\dashed.txt" For Input As intFile
    strData = Input(LOF(intFile), intFile)
    Close intFile
    strRecords = Split(strData, vbNewLine)
    '
    ' 'Over Dimension' each dynamic array in the Words List(s)
    '
    For intI = MIN To MAX
        ReDim uWords(intI).List(UBound(strRecords))
    Next intI
    '
    ' Populate the Words List(s)
    ' Note that any blank lines in the data file are ignored
    ' and any word less than 'MIN' or greater than 'MAX' characters
    ' (after removing leading and / or trailing spaces) is ignored
    '
    For lngI = 0 To UBound(strRecords)
        strRecords(lngI) = Trim$(strRecords(lngI))
        If strRecords(lngI) <> vbNullString Then
            intLen = Len(strRecords(lngI))
            If intLen >= MIN And intLen <= MAX Then
                uWords(intLen).List(uWords(intLen).Count) = strRecords(lngI)
                uWords(intLen).Count = uWords(intLen).Count + 1
            End If
        End If
    Next lngI
    '
    ' ReDim the Words List(s) to the actual number
    ' of elements populated
    '
    For intI = MIN To MAX
        If uWords(intI).Count > 0 Then
            ReDim Preserve uWords(intI).List(uWords(intI).Count - 1)
        End If
    Next intI
    Command2.Enabled = True
    MsgBox "UDT Populated"
    End Sub
    
    Private Sub Command2_Click()
    '
    ' Output the UDT to the Immediate Window
    '
    Dim intI As Integer
    Dim lngJ As Long
    For intI = MIN To MAX
        Debug.Print CStr(intI) & " Letter Words:(" & CStr(uWords(intI).Count) & ")"
        If uWords(intI).Count > 0 Then
            For lngJ = 0 To UBound(uWords(intI).List)
                Debug.Print , uWords(intI).List(lngJ)
            Next lngJ
        End If
        Debug.Print
    Next intI
    End Sub
    
    Private Sub Form_Load()
    Command2.Enabled = False
    End Sub
    Last edited by Doogle; Oct 14th, 2011 at 01:07 AM. Reason: Added Constants

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width