Results 1 to 19 of 19

Thread: [RESOLVED] loop trouble

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    Resolved [RESOLVED] loop trouble

    Why can't the variable "word" remain the value that is assigned to it by
    resp(z) when a loop occurs?

    For a = 1 To 10
    Data1.Recordset.MoveFirst
    Do
    If Data1.Recordset.EOF Then Exit Do
    x = Data1.Recordset.Fields("words")
    Data1.Recordset.MoveNext
    If Data1.Recordset.EOF Then Exit Do
    y = Data1.Recordset.Fields("words")
    If x = word Then ans = ans & " " & y
    Loop
    resp = Split(ans, " ")
    Randomize Timer
    z = Int(Rnd * UBound(resp))
    word = resp(z)
    Label1.Caption = Label1.Caption & " " & word
    Next a

    When next a occurs and it returns to the beginning of the for loop, the value of the variable "word" returms to what it was previously. How do I fix this?

  2. #2
    Banned dglienna's Avatar
    Join Date
    Jun 2004
    Location
    Center of it all
    Posts
    17,901

    Re: loop trouble

    Please explain what you are trying to do. You seem to have something wrong with your logic. That code does more work than is necessary, I think.

  3. #3
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: loop trouble

    It is a logic error, albeit a minor one. You always get the previous word because your array contains it and one other item, however your random number will never actually be high enough to select the other value (as the value from Rnd is always less than 1).

    Try this change:

    z = Int(Rnd * (UBound(resp)+1))


    ps: I agree with David that the method you are using probably isn't the best, whatever it is that you are trying to acheive!

  4. #4
    Hyperactive Member umilmi81's Avatar
    Join Date
    Sep 2005
    Location
    Sterling Heights, Mi.
    Posts
    335

    Re: loop trouble

    LMAO! What in the world are you doing?

    The only advise I can give you is to use
    Data1.Recordset.Fields("words").Value

    instead of Data1.Recordset.Fields("words")

    This will allow whatever crazy thing you're doing to work faster because it doesn't have to box and unbox a recordset into a string.

    (Make sure X and Y are declared strings too. Otherwise it wont help)

  5. #5
    Fanatic Member Comintern's Avatar
    Join Date
    Nov 2004
    Location
    Lincoln, NE
    Posts
    826

    Re: loop trouble

    Check to see what the UBound of resp is when you do this:
    VB Code:
    1. z = Int(Rnd * UBound(resp))
    I suspect this line is the source of the problem. You might just be indexing to the same place in the array each time through. Rnd will return the most recently generated random number if it is passed 0. I believe the correct way to get a random array index is:
    VB Code:
    1. z = Int((UBound(resp) - LBound(resp) + 1) * Rnd + LBound(resp))
    If the LBound is always going to be 0, this reduces to:
    VB Code:
    1. z = Int(Rnd * (UBound(resp)[COLOR=Red] + 1[/COLOR]))
    Finally, you only need to call Randomize once, not every time though the loop.

    EDIT: Ooops, si_the_geek beat me to it. I must just be slow when I'm tired...
    Last edited by Comintern; Oct 27th, 2005 at 11:09 PM. Reason: Oops

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    didnt work

    z = Int(Rnd * (UBound(resp)+1))

    did not work, I don't think its a logic error. here is what the program does:

    It is an NLP program designed to generate raw sentences out of a list of words in a database:

    Public Sub Process()
    'gets input word
    word = Text1.Text
    Text1.Text = ""
    Label1.Caption = ""
    'adds word to a database if user chooses so
    If Check1.Value = 1 Then
    Data1.Recordset.AddNew
    Data1.Recordset.Fields("words") = a
    Data1.Recordset.Update
    End If
    ' this part goes through the database, getting a record and the one immediately after it, until the the variable x (the first record) = word
    For a = 1 To 10
    Data1.Recordset.MoveFirst
    Do
    If Data1.Recordset.EOF Then Exit Do
    x = Data1.Recordset.Fields("words")
    Data1.Recordset.MoveNext
    If Data1.Recordset.EOF Then Exit Do
    y = Data1.Recordset.Fields("words")
    'gathers up all occurances of a word in the database, putting the next record immediately after each occurance into a the variable ans (x is a record, y is the one immediately after it)
    If x = word Then ans = ans & " " & y
    Loop
    'now that the variable ans has all the information it needs stored as words separated by spaces, it splits them into an array "resp"
    resp = Split(ans, " ")
    'randomly chooses one word out of the array to continue the sentence with and use as criteria for the next search
    Randomize Timer
    z = Int(Rnd * (UBound(resp) + 1))
    word = resp(z)
    Label1.Caption = Label1.Caption & " " & word
    Next a
    End Sub

    even if the array was one number off die to the rnd, it is still assigning it to a variable. the odd thing is, the variable "word" seems to undergo a change between 'next a' and 'for a'.

  7. #7
    Hyperactive Member umilmi81's Avatar
    Join Date
    Sep 2005
    Location
    Sterling Heights, Mi.
    Posts
    335

    Re: loop trouble

    I can't see how this line

    VB Code:
    1. If x = word Then ans = ans & " " & y
    will ever evaluate to true assuming both "word" and "ans" are both empty at the begining of the loop.

  8. #8
    Ex-Super Mod RobDog888's Avatar
    Join Date
    Apr 2001
    Location
    LA, Calif. Raiders #1 AKA:Gangsta Yoda™
    Posts
    60,709

    Re: loop trouble

    Post #6 merged from a mis-post as a new thread.
    VB/Office Guru™ (AKA: Gangsta Yoda®)
    I dont answer coding questions via PM. Please post a thread in the appropriate forum.

    Microsoft MVP 2006-2011
    Office Development FAQ (C#, VB.NET, VB 6, VBA)
    Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
    If a post has helped you then Please Rate it!
    Reps & Rating PostsVS.NET on Vista Multiple .NET Framework Versions Office Primary Interop AssembliesVB/Office Guru™ Word SpellChecker™.NETVB/Office Guru™ Word SpellChecker™ VB6VB.NET Attributes Ex.Outlook Global Address ListAPI Viewer utility.NET API Viewer Utility
    System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6

  9. #9
    Hyperactive Member umilmi81's Avatar
    Join Date
    Sep 2005
    Location
    Sterling Heights, Mi.
    Posts
    335

    Re: loop trouble

    I've looked at it again. I'd rewrite this:
    VB Code:
    1. For a = 1 To 10
    2.     Data1.Recordset.MoveFirst
    3.     Do
    4.         If Data1.Recordset.EOF Then Exit Do
    5.         x = Data1.Recordset.Fields("words")
    6.         Data1.Recordset.MoveNext
    7.         If Data1.Recordset.EOF Then Exit Do
    8.         y = Data1.Recordset.Fields("words")
    9.         If x = word Then ans = ans & " " & y
    10.     Loop
    11.     resp = Split(ans, " ")
    12.     Randomize Timer
    13.     z = Int(Rnd * UBound(resp))
    14.     word = resp(z)
    15.     Label1.Caption = Label1.Caption & " " & word
    16. Next a

    to this:

    VB Code:
    1. Dim a As Integer
    2. Dim PrevRecord As String
    3. Dim CurrRecord As String
    4. Dim Word as String
    5. Dim z as Integer
    6. Dim resp() As String
    7.  
    8. Randomize Timer
    9. For a = 1 to 10
    10.     Data1.Recordset.MoveFirst
    11.     Do While Not Data1.RecordSet.EOF
    12.         PrevRecord = CurrRecord
    13.         CurrRecord = Data1.RecordSet.Fields("words").Value     
    14.         Data1.Recordset.MoveNext
    15.         If PrevRecord = word Then
    16.             ans = ans & " " & CurrRecord
    17.         End If
    18.     Loop
    19.     resp = Split(ans," ")
    20.     z = Int(Rnd * UBound(resp))
    21.     word=resp(z)
    22.     Label1.Caption = Label1.Caption & " " & Word
    23. Next a

    But I still can't see how you would ever get anywhere unless "word" or "ans" was already equal to something.

  10. #10
    Fanatic Member Comintern's Avatar
    Join Date
    Nov 2004
    Location
    Lincoln, NE
    Posts
    826

    Re: loop trouble

    OK, this is not related to your loop, but you probably shouldn't rely on position in a dataset to be static. Make the "answer" into a seperate table with a primary key of "word" and then you can just do a simple SQL query to get all of the related answers for a given word.

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    Re: loop trouble

    I tried rephrasing the code, but it was essentially doing the same thing. the variables "word" and "ans" are always equal to something. when the sub is first triggered, the first thing it does is assign the contents of a text box to "word" - the word that starts off the sentence generation sequence.

    Ok, I have tracked down the poit where "word" reverts to its previous value:

    For a = 1 To 10
    Data1.Recordset.MoveFirst
    --------- word = value a
    Do - this is the point where the varaible changes.
    --------- word = value b
    If Data1.Recordset.EOF Then Exit Do
    x = Data1.Recordset.Fields("words")
    Data1.Recordset.MoveNext
    If Data1.Recordset.EOF Then Exit Do
    y = Data1.Recordset.Fields("words")
    If x = word Then ans = ans & " " & y
    Loop
    resp = Split(ans, " ")
    Randomize Timer
    z = Int(Rnd * UBound(resp))
    word = resp(z)
    Label1.Caption = Label1.Caption & " " & word
    Next a

    there is nothing about the command do that can influence the content of a variable, is there? it survives the for loop, but the do loop reverts it.

  12. #12
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: loop trouble

    While my alteration may not have fixed the issue, it was an essential change. For proof, try running this code (even tho it is Rnd*10, the highest value you get will be 9):
    VB Code:
    1. Dim a As Integer, b As Integer, c As Integer
    2.  
    3. a = 10
    4. b = 0
    5. Randomize Timer
    6.  
    7. Dim x As Integer
    8. For x = 1 To 10000
    9.   c = Int(Rnd * [b]10[/b])
    10.   If c < a Then a = c
    11.   If c > b Then b = c
    12. Next x
    13. MsgBox "lowest value: " & a & vbCr _
    14.      & "highest value: " & b

    Another change that you should do, is change the "If x = word" line to have an "Exit Do" aswell, so that you do not read more data than required (this will make it much faster). You also do not need to use If's to check the EOF state, as long as the code is modified a little (this will make it faster too). And another, there is no reason to read the y value every time (again, faster!).

    Here is a version which has these modifications:
    VB Code:
    1. Randomize Timer  'this only needs to be done once, not each time you call Rnd
    2.  
    3. For a = 1 To 10
    4.   Data1.Recordset.MoveFirst
    5.   Do While Not Data1.Recordset.EOF
    6.     x = Data1.Recordset.Fields("words")
    7.     Data1.Recordset.MoveNext
    8.     If x = word Then
    9.       If Not Data1.Recordset.EOF Then
    10.         y = Data1.Recordset.Fields("words")
    11.         ans = ans & " " & y
    12.       End if
    13.       Exit Do
    14.     End If
    15.   Loop
    16.   resp = Split(ans, " ")
    17.   z = Int(Rnd * (UBound(resp)+1))
    18.   word = resp(z)
    19.   Label1.Caption = Label1.Caption & " " & word
    20. Next a

    I have also thought of a major issue with your logic - you are getting the "next" word from the database, but the picking of a random word that has already been used means that you are likely to be getting the same word again. Try instead setting z to be UBound(resp), and see what results you get then.


    I cannot think why the variable is changing on the Do, I have never seen something like that before, and can think of no reason why it would happen. (but from my above comment, it may be that you are just not debugging properly). The only suggestion I can make is that you could try a different variable name, as "word" may be a name used by one of your references.

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    Re: loop trouble

    I changed the code, -again- and it operated just as it did with any ither variation of the original code. the problem is - the variable is being changed by the "do" command. This is very abnormal

  14. #14
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: loop trouble

    Well it might not have solved the problem , but at least the code is improved for when this has been fixed.

    It is indeed abnormal... Have you tried both of my suggestions in my previous post? (ie: use "z = UBound(resp)", and change "word" to something else)

    If so, can I ask how you are debugging & checking the values? If you aren't doing this already, I would recommend using F8 (or the menu option) to step thru the code, and having a watch for the variable.

  15. #15

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    Re: loop trouble

    I have tried all the suggestions - with "z = UBound(resp)" I got no reaction whatsoever - resp(z) did not calculate. i changed word to wo which changed nothing, and I put a watch on word, and debugged - this is extremely wierd - the watch did not detect the value of word change after the "Do", yet I put a "print word" before and after the do, and saw that the value definitely did change. In fact, the second time i ran the check, I noticed that the watch displayed a different value for word than the print command gave me, a non array variable cannot be more than one value at a time... what the hell is going on here?

  16. #16
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: loop trouble

    this is extremely odd.. could you upload your code files and database? that way we can take a look and hopefully see it happening & fix it

  17. #17

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    Re: loop trouble

    Here are the database, project, form, and workspace files. to operate it, type a single word in the text box and hit space. if the word is not in the database, a subscript out of range error will occur, ignore it, just look in the database for words that will work. Thanks for all your help
    Attached Files Attached Files

  18. #18
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: loop trouble

    I've had a look, and the only major issue I can see is spaces - at the end of data in the database, and as such also in the array when you split (Trim and Mid can be used to correct this). I see the data is different to what I was expecting, so you were right to ignore the "Exit Do".

    Here is an updated version which seems ok, and has a safety net to avoid the error:
    VB Code:
    1. Public Sub Process()
    2. Dim x As String
    3. Dim y As String
    4. Dim word As String
    5. Randomize Timer
    6. word = Trim(Text1.Text)
    7. Text1.Text = ""
    8. Label1.Caption = ""
    9. If Check1.Value = 1 Then
    10.   Data1.Recordset.AddNew
    11.   Data1.Recordset.Fields("words") = Trim(word)
    12.   Data1.Recordset.Update
    13. End If
    14. For a = 1 To 10
    15.   Data1.Recordset.MoveFirst
    16.   Do While Not Data1.Recordset.EOF
    17.     x = Trim(Data1.Recordset.Fields("words"))
    18.     Data1.Recordset.MoveNext
    19.     If x = word Then
    20.       If Not Data1.Recordset.EOF Then
    21.         y = Trim(Data1.Recordset.Fields("words"))
    22.         ans = ans & " " & y
    23.       End If
    24.     End If
    25.   Loop
    26.   resp = Split(Mid(ans, 2), " ")
    27.   If UBound(resp) = -1 Then  'no data
    28.     MsgBox "No data found!"
    29.     Exit For
    30.   End If
    31.   z = Int(Rnd * (UBound(resp) + 1))
    32.   word = resp(z)
    33.   Label1.Caption = Label1.Caption & " " & word
    34. Next a
    35. End Sub

  19. #19

    Thread Starter
    Lively Member
    Join Date
    Jun 2005
    Location
    New Jersey, USA
    Posts
    119

    Re: [RESOLVED] loop trouble

    ha - the error was so simple! the variable ans was gathering up too much data, so things started repeating themselves - the error was not in the variable word at all! all I had to to was add a simple
    VB Code:
    1. ans = ""
    in the beggining of each for loop

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