Results 1 to 10 of 10
  1. #1
    sephiroth2906 is offline Advanced Beginner
    Windows 7 32bit Access 2010 32bit
    Join Date
    Apr 2011
    Posts
    73

    Having trouble understanding code in a For/Next loop with an array

    I am trying to learn VBA and have a book I am going through. I was alright until I got to arrays. The book has me write this code:


    Code:
    Sub Lotto()
        Const spins = 6
        Const minNum = 1
        Const maxNum = 54
        Dim t As Integer 'looping variable in outer loop
        Dim i As Integer 'looping variable in inner loop
        Dim myNumbers As String 'string to hold all picks
        Dim lucky(spins) As String 'array to hold generated picks
        
        myNumbers = ""
        For t = 1 To spins
            Randomize
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
            
        'check if this number was picked before
        For i = 1 To (t - 1)
            If lucky(t) = lucky(i) Then
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
            i = 0
        End If
        
        Next i
            MsgBox "Lucky number is " & lucky(t), , "Luckynumber " & t
            myNumbers = myNumbers & " - " & lucky(t)
        Next t
        MsgBox "Lucky numbers are " & myNumbers, , "6 Lucky Numbers"
    End Sub
    It works just fine, but I am not understanding how the inner loop is checking to see if the number has been picked before. Specifically, I don't understand what

    Code:
        For i = 1 To (t - 1)
    Is doing

    Code:
            If lucky(t) = lucky(i) Then
    How this is evaluated and

    Code:
            i = 0
    What this is for.

    If anyone smarter than me can explain this, I would sure appreciate it.

    Thanks!

  2. #2
    ranman256's Avatar
    ranman256 is offline VIP
    Windows Vista Access 2010 32bit
    Join Date
    Apr 2014
    Location
    Kentucky
    Posts
    9,521
    This seems to be a ham fisted way to do it, when you can put the numbers in a table,pick 1 at random, then remove it from the list to not pick it again.

  3. #3
    sephiroth2906 is offline Advanced Beginner
    Windows 7 32bit Access 2010 32bit
    Join Date
    Apr 2011
    Posts
    73
    I get that you wouldn't do it this way in real life, as this is just a stand alone VBA exercise on arrays utilizing for... next loops. I am not as worried about the real world application of this particular program as I am the fact I just don't get what some of the code is doing.

    I believe the i = 0 is to reset i for the next comparison, I understand the random number generator if i and t are the same, but the rest of that loop's program does not make sense to me. I don't quite get how the variable is passed to i in the first place.


    Edit. I get where i got the value now. So

    i = 1 to whatever t is minus 1... I just am not getting how i is getting a value within that array to compare to t.

    Thanks!
    Last edited by sephiroth2906; 05-18-2018 at 03:24 PM. Reason: I became slightly less stupid

  4. #4
    June7's Avatar
    June7 is online now VIP
    Windows 10 Access 2010 32bit
    Join Date
    May 2011
    Location
    The Great Land
    Posts
    52,824
    The nature of a For Next loop is to automatically increase the incrementing variable (i for the inner loop and t for the outer).
    i = 0 resets i to 0 when lucky array elements equal each other. Why code needs to do this test is not clear to me. Haven't gone that far in analyzing this code.

    Learn debugging techniques. Set a breakpoint. Step through the code 1 line at a time and see what values the variables hold as the code processes. When code pauses, hover cursor over variable to see its value.

    Fix nesting indentation to make code more understandable.
    Code:
    Sub Lotto()
        Const spins = 6
        Const minNum = 1
        Const maxNum = 54
        Dim t As Integer 'looping variable in outer loop
        Dim i As Integer 'looping variable in inner loop
        Dim myNumbers As String 'string to hold all picks
        Dim lucky(spins) As String 'array to hold generated picks
        
        myNumbers = ""
        For t = 1 To spins
            Randomize
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
            'check if this number was picked before
            For i = 1 To (t - 1)
                If lucky(t) = lucky(i) Then
                    lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
                    i = 0
                End If
            Next i
            MsgBox "Lucky number is " & lucky(t), , "Luckynumber " & t
            myNumbers = myNumbers & " - " & lucky(t)
        Next t
        MsgBox "Lucky numbers are " & myNumbers, , "6 Lucky Numbers"
    End Sub
    Last edited by June7; 05-18-2018 at 07:13 PM.
    How to attach file: http://www.accessforums.net/showthread.php?t=70301 To provide db: copy, remove confidential data, run compact & repair, zip w/Windows Compression.

  5. #5
    Micron is offline Virtually Inert Person
    Windows 10 Access 2016
    Join Date
    Jun 2014
    Location
    Ontario, Canada
    Posts
    12,737
    Don't have time to study this too much, but can make a suggestion. Step through the code and after a line is executed, evaluate the expression or variable in the immediate window, such as
    ?val(lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum)
    ?lucky(t)
    ?rnd
    ?t-1
    ?lucky(i)
    ?lucky(t)
    and so on. That might help you to figure it out. Can you post back when you figure it out? Don't forget - i and t represent positions in the arrays - not variables for values per se.
    The more we hear silence, the more we begin to think about our value in this universe.
    Paraphrase of Professor Brian Cox.

  6. #6
    sephiroth2906 is offline Advanced Beginner
    Windows 7 32bit Access 2010 32bit
    Join Date
    Apr 2011
    Posts
    73
    Alright. When I get back to it I will do that. Thanks for the suggestion!

  7. #7
    orange's Avatar
    orange is offline Moderator
    Windows 10 Access 2010 32bit
    Join Date
    Sep 2009
    Location
    Ottawa, Ontario, Canada; West Palm Beach FL
    Posts
    16,716
    Watch this video by Steve Bishop on Arrays.

    You can also turn on Locals and step through the code. You will see the values of variables change.

    from Stack Overflow:
    Locals provides a couple of benefits: You can F8 through the code and watch how a variable changes by looking at the locals window as opposed to issuing debug.print statements or hovering over the variables. You can see the contents of an array a heck of a lot quicker than issuing lbound and ubound and a bunch of other statements to check values. Not just arrays either, but any complex data structure such as a custom class module.



  8. #8
    sephiroth2906 is offline Advanced Beginner
    Windows 7 32bit Access 2010 32bit
    Join Date
    Apr 2011
    Posts
    73
    Quote Originally Posted by Micron View Post
    Don't have time to study this too much, but can make a suggestion. Step through the code and after a line is executed, evaluate the expression or variable in the immediate window, such as
    ?val(lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum)
    ?lucky(t)
    ?rnd
    ?t-1
    ?lucky(i)
    ?lucky(t)
    and so on. That might help you to figure it out. Can you post back when you figure it out? Don't forget - i and t represent positions in the arrays - not variables for values per se.
    I apologize for not getting back sooner. I have been swamped and had not been able to look at the code. I stepped through it, and I think I get it. If someone could confirm my understanding, I would really appreciate it. By the way,

    You can also turn on Locals and step through the code. You will see the values of variables change.
    Was immensely helpful. I had never hear of Local, but finding it was easy enough and really gave me what I needed.

    Code:
    Sub Lotto()
        Const spins = 6
        Const minNum = 1
        Const maxNum = 54
        Dim t As Integer 'looping variable in outer loop
        Dim i As Integer 'looping variable in inner loop
        Dim myNumbers As String 'string to hold all picks
        Dim lucky(spins) As String 'array to hold generated picks
        
        myNumbers = ""
        For t = 1 To spins
            Randomize
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
            
        'check if this number was picked before
        For i = 1 To (t - 1)
            If lucky(t) = lucky(i) Then
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
            i = 0
        End If
        
        Next i
            MsgBox "Lucky number is " & lucky(t), , "Luckynumber " & t
            myNumbers = myNumbers & " - " & lucky(t)
        Next t
        MsgBox "Lucky numbers are " & myNumbers, , "6 Lucky Numbers"
    End Sub
    So, lucky is the array. t & i either feed the values into the array or query it. This code:

    Code:
        For t = 1 To spins
            Randomize
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
    Sets the array to 1-6, due to the spins constant and creates a random number for each slot of the array, starting by itself for the first number and then again each time it reaches the "Next t" portion of the code until it fills slot 6.

    This code:

    Code:
        For i = 1 To (t - 1)
            If lucky(t) = lucky(i) Then
            lucky(t) = Int((maxNum - minNum + 1) * Rnd) + minNum
            i = 0
        End If
    Looks at the items in the lucky array to see if the currently held value of t matches any of the values stored there, and, if so, run the generator again. The biggest problem I was running into was understanding

    Code:
    For i = 1 To (t - 1)
    Which now I get will look at each value in the array one at a time, and will do so t number of times, which t is the current number of times numbers have been fed into the array, minus one, because there will never need to look at the array the first time, because t currently has the only existing value, and will also never need to look at the array 6 times, because it will at most need to look at the previous 5 numbers stored there and the current value of t.

    Next i causes the program to look at the next number in the array until it reaches t - 1.

    If I got anything wrong and anyone has time to tell me what, I am happy to learn. I would like to thank all of you for forcing me to figure this out with just little hints instead of explaining it. Thinking this thing through was much more useful than any explanation would have been.

    Thanks all!

  9. #9
    Micron is offline Virtually Inert Person
    Windows 10 Access 2016
    Join Date
    Jun 2014
    Location
    Ontario, Canada
    Posts
    12,737
    Sets the array to 1-6,
    - not really. Creates a 7 element string type array, position numbers are 0-6.
    For t = 1 to spins defines that the loop counter will start at 1 and loop until the counter is 6. The ordinal position in the array is defined by lucky(t). Its value is defined by the calculated expression. Thus, you may have detected, or can understand upon review, that the first position in the array (0) will not be used. While this may be OK for fun, it's probably not a good idea to define more array elements that you intend to use (unless their value can be Null or empty string - at least they'd be factored into any calculation or code step). Before this loop will repeat, the result of the calculation will be checked to see if it is already a member of the array. See next paragraph.

    If the array position is 1 (as on the first loop), the inner loop counter will be For i = 1 to 0, thus this portion will not execute and will go directly to the message box. The first element of MyNumbers will be preceded with a dash (-). On the 2nd pass, i will be 1, t will be 2, thus For i = 1 to 2 and the 1st array element value will be compared to the 2nd. If they are not the same, we go to the message box, recalculate and start the comparison again.

    Every time the outer loop is executed, i goes back to 1. Now the current element in the array is compared to each prior one by advancing through the i counter to ensure that the current value doesn't already exist.

    Hope that helps a bit.

  10. #10
    June7's Avatar
    June7 is online now VIP
    Windows 10 Access 2010 32bit
    Join Date
    May 2011
    Location
    The Great Land
    Posts
    52,824
    Can use Option Base 1 in module header to set the array index to start with 1.
    How to attach file: http://www.accessforums.net/showthread.php?t=70301 To provide db: copy, remove confidential data, run compact & repair, zip w/Windows Compression.

Please reply to this thread with any new information or opinions.

Similar Threads

  1. Replies: 3
    Last Post: 10-10-2017, 08:09 AM
  2. Trouble understanding the logic behind database structure
    By connorwilliamsm in forum Database Design
    Replies: 4
    Last Post: 08-07-2017, 02:34 PM
  3. how to loop through array
    By adakem in forum SQL Server
    Replies: 1
    Last Post: 01-03-2017, 10:03 AM
  4. Replies: 30
    Last Post: 08-30-2012, 05:14 PM
  5. trouble understanding expression
    By mejia.j88 in forum Queries
    Replies: 4
    Last Post: 02-01-2012, 03:00 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums