# Thread: [RESOLVED] Don't understand For...Next loop

1. ## [RESOLVED] Don't understand For...Next loop

Code:
```  '
'
For n = 1 To UBound(SquaresAroundTarget)
If AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n) Then
MakeAlive SqNo
Exit Function
End If
Next n
'
'```
When the loop begins it goes through the code one time and then exits the loop but it should go through the loop nine time.

There are nine square numbers in the array. There is the target square number which occupies element 5 and the other elements contain the square numbers that surround the target square.

I know that only element nine contains a square number that is alive and all the other squares are dead so it should have gone through the loop and when it got to element nine it should fall into the clause and make the target square alive but it didn't

Can anyone see what I'm doing wrong

2. ## Re: Don't understand For...Next loop

Debug your code. Set a breakpoint on the line with the "MakeAlive" command and then see what the values of n, SquaresAroundTarget(n), and AliveByteArray(SquaresAroundTarget(n)) are.

If the If statement is evaluating to True earlier than you expect it would, then the most likely reason is that the array elements you are referencing either don't contain the values you expect them to contain, or the array elements you are referencing aren't the array elements you are intending on referencing.

3. ## Re: Don't understand For...Next loop

I already did all that checking before I posted. All the arrays are correct. It never goes to the line with "MakeAlive" because it will only hit that line when it reaches the 9th time through the loop but it exists on the first time and n has a value of 2

4. ## Re: Don't understand For...Next loop

What kind of result is the function AliveByteArray returning?
you pass your Array-Element to this function and compare the result to your element, which evaluates to true, otherwise it wouldn't enter the if-clause.
at a guess: You have an OERN before the loop active, ActiveByteArray returns a boolean and you ccompare that boolean to an number, error is raised, the OERN invokes the next line

5. ## Re: Don't understand For...Next loop

Just a shot in the dark, but I'm going to guess that your Exit Function statement is what's terminating it.

That loop is going to run until it goes through to UBound(SquaresAroundTarget), or until something makes it terminate. There are a couple of things I can think of that would make it terminate:

1) Something within the loop terminates it, such as Exit Function (discussed first), or Exit For (which isn't currently in the loop).

2) Or, the other thing I could think of is that n has global or module level scope, and that some other procedure is tampering with this n. For instance, it's clear that MakeAlive is another procedure. Is that possibly tampering with n? Or, it's possible that AliveByteArray is a procedure. Is that one tampering with n?

3) The only other thing would be some kind of memory corruption, which I seriously doubt.

Good Luck,
Elroy

6. ## Re: Don't understand For...Next loop

Originally Posted by Code Dummy
I already did all that checking before I posted. All the arrays are correct. It never goes to the line with "MakeAlive" because it will only hit that line when it reaches the 9th time through the loop but it exists on the first time and n has a value of 2
There are only way that I can see the n=2 after the loop finishes is if UBound of SquaresAroundTarget equals 1.

7. ## Re: Don't understand For...Next loop

Originally Posted by MarkT
There are only way that I can see the n=2 after the loop finishes is if UBound of SquaresAroundTarget equals 1.

Hi Mark,

There are actually several ways that could happen. Here's a rather trivial way it could happen:

Code:
```
Option Explicit

Dim n As Long

For n = 1 To 9

n = 2
Exit For

Next

Debug.Print n

End Sub

```

Take Care,
Elroy

8. ## Re: Don't understand For...Next loop

Yes, but in this case he says it never makes it inside the if statement and there is no other exit condition in his loop. In the code OP supplied, I see no other options.

9. ## Re: Don't understand For...Next loop

If AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n) Then

What are you comparing here?
Boolean = Number
Number = Number
Boolean = Boolean

Boolean = Boolean seems unlikely as you are using SquaresAroundTarget(n) as an index to an array (based on the name, although it could be a function).
If AliveByteArray is an array of booleans then it doesn't make much since to compare it to a number.

You should have at least given us the declaration for AliveByteArray, the contents of that array, and the contents of the SquaresAroundTarget array if you want us to debug the issue. We can't tell what the error might be in this case since we don't have the data.

If you put a breakpoint on the If statement, and then type in the immediate window
? AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n)

Does it say True or False?
When it says True, then print each side of the =
? AliveByteArray(SquaresAroundTarget(n))

? SquaresAroundTarget(n)

What are the two values that it is comparing?

10. ## Re: Don't understand For...Next loop

Yes, for the code in the OP, I'd have to agree.

If we're never getting to any code inside the If block, and n=2 immediately after the Next, then UBound(SquaresAroundTarget) must equal 1.

11. ## Re: Don't understand For...Next loop

Originally Posted by Code Dummy
I already did all that checking before I posted. All the arrays are correct. It never goes to the line with "MakeAlive" because it will only hit that line when it reaches the 9th time through the loop but it exists on the first time and n has a value of 2
Also, perhaps break on the For line before you start the loop and just step through it so you see how it progresses.
When you get the break print out the result of UBound(SquaresAroundTarget) to make sure it should be looping.
In the Immediate window,
? UBound(SquaresAroundTarget)

These problems should be easily resolvable by stepping through the code using the debugger capability one line at a time and checking the values and logic of what it is doing compared to what you expect it to be doing.

p.s I see Elroy and I came to the same point around the same time...

12. ## Re: Don't understand For...Next loop

Originally Posted by Code Dummy
Code:
```  '
'
For n = 1 To UBound(SquaresAroundTarget)
If AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n) Then
MakeAlive SqNo
Exit Function
End If
Next n
'
'```
When the loop begins it goes through the code one time and then exits the loop but it should go through the loop nine time.

There are nine square numbers in the array. There is the target square number which occupies element 5 and the other elements contain the square numbers that surround the target square.

I know that only element nine contains a square number that is alive and all the other squares are dead so it should have gone through the loop and when it got to element nine it should fall into the clause and make the target square alive but it didn't

Can anyone see what I'm doing wrong
Add this before the "If" line:

Debug.Print n, AliveByteArray(SquaresAroundTarget(n)), SquaresAroundTarget(n)

That's how we do it.

Questions:

1 - What's the data type of these two arrays?
2 - Do you have an error handler in this routine or any of its callers?
3 - Do you have any "On Error Resume Next" anywhere in your project?

13. ## Re: Don't understand For...Next loop

@qvb6
If AliveByteArray (Byte?) is in fact an Array, then SquaresAroundTarget must be Integer-Type, otherwise it wouldn't compile.
If it's a function (and that's my guess) then the important information is: What's the Type of the Result?
See my Post #4

14. ## Re: Don't understand For...Next loop

Perhaps if it is an array, and the contents are merely a flag indicating live or dead, then you shouldn't be comparing to your index, but comparing to your flag value.
Code:
` If AliveByteArray(SquaresAroundTarget(n)) = 1 Then 'if the square is alive`
Also, you're not updating SqNo in your loop, so that doesn't make a lot of sense to me either.
Perhaps you mean to refer to the index you found?
Code:
`MakeAlive SquaresAroundTarget(n)`

16. ## Re: Don't understand For...Next loop

Code:
```Dim ByteArray() As Byte
Dim AliveByteArray() As Integer

Dim SquaresAroundTarget(1 To 9) As Integer
'
'
'
Randomize

ReDim ByteArray(1 To 3780)
ReDim AliveByteArray(1 To 3780)
'
'
End Sub

Private Sub CheckForLoneliness(SqNo As Integer)
'
' Rule 1 If a living cell has no living cells around it then it will die from loneliness
'
' SquaresAroundTarget(n) is zero if that square contains no living cell (never occupied)
'
' If any square around the target square is alive then make target square alive
'
GetSquaresAroundTarget SqNo

For n = 1 To UBound(SquaresAroundTarget)
If n <> 5 Then ' Don't check element 5 as it is the target square
If SquaresAroundTarget(n) <= 3780 Then
If AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n) Then
MakeAlive SqNo
Exit Sub
End If
End If
End If
Next n

'Here if no living squares found around target square(SqNo)
'
'
End Sub

Private Sub GetSquaresAroundTarget(SqNo As Integer)
SquaresAroundTarget(1) = SqNo - 45 - 1
SquaresAroundTarget(2) = SqNo - 45
SquaresAroundTarget(3) = SqNo - 45 + 1
SquaresAroundTarget(4) = SqNo - 1
SquaresAroundTarget(6) = SqNo + 1
SquaresAroundTarget(7) = SqNo + 45 - 1
SquaresAroundTarget(8) = SqNo + 45
SquaresAroundTarget(9) = SqNo + 45 + 1
End Sub

Shape1(SqNo).FillColor = vbBlack
Shape1(SqNo).BorderColor = vbBlack
End Sub

Private Sub MakeAlive(SqNo)
Shape1(SqNo).FillColor = vbGreen
Shape1(SqNo).BorderColor = vbGreen
AliveByteArray(SqNo) = SqNo
End Sub```
OK, I included all the relevant code and variables. It still does the same thing

UBound(SquaresAroundTarget) is 9. I check it every time I try to debug this code

I put a break point at the line For n = 1 To UBound(SquaresAroundTarget)
then I single step through the code. It hits each If statement and each End If statement and it never hits the inner clause. After it hits the last End If it hits the Next n line, adds 1 to n and then it falls through to the MakeDead SqNo.

17. ## Re: Don't understand For...Next loop

Based on your other thread, this sounds like it is similar to Conway's Game of Life, which I have some experience with.

I see something that may be an issue with your code. I'm not sure, though, because I'm not completely following your nested If logic, and it seems like you've posted only some of your code.

With Conway's Game of Life, everything is evaluated on a generation level. Meaning, you take a snapshot of the living cells from Generation 1 and use that snapshot to determine the living cells in Generation 2, and repeat. Presumably, that is the same process as with this game.

Looking at this from the standpoint of data, lets look at the below grid:

C01 C02 C03 C04
C05 C06 C07 C08
C09 C10 C11 C12
Ok, so say we're evaluating if C06 is going to be alive or not in the next generation. We look at C01, C02, C03, C05, C07, C09, C10, and C11 and count the living cells and note if C06 is currently alive or dead and then follow Conway's rules to determine if C06 is going to be alive or dead. Now, lets assume that C06 was dead in Generation1 but will be alive in Generation2. We can't just mark C06 as alive in our "Status" array and move on. Because then when we move on to evaluating C07, now C06 is marked as alive - but it wasn't alive in Generation1, and we need to use C06's Generation1 status when evaluating C07.

Maybe you are already addressing this in your code. I see you have an alive and a dead array, maybe that's what those are for, not sure.

The way I worked around it in my code was somewhat convoluted due to the large size of the arrays I was using, but given small enough arrays like the size you are using, you would want a second array that stores the next generation.

So, you evaluate each cell based on the value in the "current" generation array. When you determine if that cell will be alive or dead, you store that data in the "next" generation array, leaving the value in the "current" generation array alone. At the end of evaluation of all cells, you update the screen based on the "next" generation array, then you copy the contents of the "next" generation array into the "current" generation array. And repeat.

Good luck.

18. ## Re: Don't understand For...Next loop

I still don't see what the contents of the AliveByteArray is.
For instance,
' SquaresAroundTarget(n) is zero if that square contains no living cell (never occupied)

Does that comment make sense to you?
SquaresAroundTarget(n) should never be 0, because it is an array of nine integers that point to other elements in your array.
It is an array of indexes into your arrays.

Let's pick 100 as the target cell.
So, your code populates the SquaresAroundTarget array with the following values.
Code:
```1: 54
2: 55
3: 56
4: 99
5: 0
6: 101
7: 144
8: 145
9: 146```
I would have expected 100 at index 5, but since that is your target cell and you ignore it, it being 0 shouldn't matter.

Now this is the question I've been wanting to get answered for quite a while now.
What does AliveByteArray contain?

In your loop, n is = 1 the first time through, so lets check the values of the If statement for that value of n.
Code:
```       If AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n) Then
'is
If AliveByteArray(SquaresAroundTarget(1)) = SquaresAroundTarget(1) Then
'is
If AliveByteArray(54) = 54 Then```
You say that the 9th cell should be alive and meet the condition, so that would be
If AliveByteArray(146) = 146.

Can you see my confusion here? Are you saying that if a cell is alive, it should contain an integer that is its index.
So, AliveByteArray(2000) should contain 2000 if it is alive, but 0 if it is dead.
And AliveByteArray(3000) should contain 3000 if it is alive, but 0 if it is dead and so forth.

I was thinking that AliveByteArray might contain something like 0 if it was dead and 1 if it was alive.
So, you would want:
Code:
`If AliveByteArray(54) = 1 Then`
rather than
Code:
`If AliveByteArray(54) = 54`

19. ## Re: Don't understand For...Next loop

.....which returns us to my question in post #4
Is AliveByteArray a Function which returns a boolean......

20. ## Re: Don't understand For...Next loop

Which is answered in Post #16

Dim AliveByteArray() As Integer

21. ## Re: Don't understand For...Next loop

OK, first, ignore the fact that I named it AliveByteArray. When I first started this project I was going to use a byte array but later changed my mind and made it an integer array but for some reason I didn't change the name of the array but it really makes no difference what the array name is. It contains the square numbers of all squares that are alive. So, AliveByteArray(54) = 54 if square 54 is alive otherwise that position will be 0

If you look at the code you will see in sub GetSquaresAroundTarget that I load elements 1, 2, 3, 4, 6, 7, 8, 9 with the numbers of the squares that surround the target square so element 5 is the target square so I didn't load it with any number and kept it at 0 and I ignore it anyway in the code.

As far as SquaresAroundTarget(n) is zero if that square contains no living cell (never occupied). I think I made that comment when I was thinking about putting a border array around the grid array which those squares would contain zeros but I never did that and just didn't give any further thought to the comment. That was in case the target square was a border square and therefore some of the squares around it don't exist. I have since corrected that situation.

In any event these matters don't really have anything to do with the issue of why the For...Next loop doesn't work. As long as Ubound is 9 then it should loop 9 times through the loop and when it get to the 9th time it should fall into the inner clause but it doesn't

22. ## Re: Don't understand For...Next loop

What is the smallest value of SqNo you are passing to CheckForLoneliness?

23. ## Re: Don't understand For...Next loop

Originally Posted by Code Dummy
...
In any event these matters don't really have anything to do with the issue of why the For...Next loop doesn't work. As long as Ubound is 9 then it should loop 9 times through the loop and when it get to the 9th time it should fall into the inner clause but it doesn't
Which is why you need to check what the values are on the two sides of the If statement.

You didn't give us a testcase, so I can't test what you're testing.
But when I step through it it loops 9 times.
If I set

AliveByteArray(146) = 146

and then pass 100 to the CheckForLonliness function, it loops nine times, and on the ninth iteration (n = 9), The if condition is True and it calls the MakeAlive function.

So, if AliveByteArray(x) = x, then it works. If that is your design, then it works. The only reason it wouldn't work is you are not setting AliveByteArray(x) to x. That is why I said (post #9) when you get to that point (the ninth iteration where you expect it to work), print out the values in the Immediate window to see what they are. (you can use ? as a short hand for Print in the Immediate window, an old MSBasic holdover)
Code:
```? AliveByteArray(SquaresAroundTarget(n))
146
? SquaresAroundTarget(n)
146
? AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n)
True```

24. ## Re: Don't understand For...Next loop

Well I don't use the Print but I do hover the mouse over everything as I go through the loop and I do have the correct values in the arrays I expect. I say again as long as the Ubound in For n = 1 To UBound(SquaresAroundTarget) is 9 and it is 9 it should loop 9 times but it quits on the first time. Also I can comment out the inner clause and it doesn't change anything because it never gets there in the first place.

Code:
```1 here--> For n = 1 To UBound(SquaresAroundTarget)
2 here-->   If n <> 5 Then ' Don't check element 5 as it is the target square
3 here-->     If SquaresAroundTarget(n) <= 3780 Then
4 here-->       If AliveByteArray(SquaresAroundTarget(n)) = SquaresAroundTarget(n) Then
not here->        MakeAlive SqNo
not here->        Exit Sub
5 here-->       End If
6 here-->     End If
7 here-->   End If
8 here--> Next n
9 here-->  '```
Target square or SqNo = 1415

1) Ubound = 9
2) n = 1
3) SquaresAroundTarget(1) = 1369
4) AliveByteArray(SquaresAroundTarget(1)) = 0

AliveByteArray(1461) = 1461 all other elements are 0

SquaresAroundTarget:

Code:
``` ' +--------+--------+--------+
' |1) 1369 |4) 1414 |7) 1459 |
' +--------+--------+--------+
' |2) 1370 |5) 0    |8) 1460 |
' +--------+--------+--------+
' |3) 1371 |6) 1416 |9) 1461 |
' +--------+--------+--------+```

25. ## Re: Don't understand For...Next loop

Well, it shouldn't be that hard to humor me. The code works for me.
When you break, just copy the following three lines and paste them in the Immediate Window.
Then put your text cursor on each line in turn and hit return. You don't have to be at the end of the line, hitting return anywhere in the line will execute it.
See what the three values you get back are.
Code:
```? AliveByteArray(SquaresAroundTarget(9))
? SquaresAroundTarget(9)
? AliveByteArray(SquaresAroundTarget(9)) = SquaresAroundTarget(9)```
p.s. And if it really just hits the Next, and then leaves the loop, copy the Ubound part of your for loop and print that out as well.
Code:
`? UBound(SquaresAroundTarget)`
If it is 9, then it seems like there must be something goofed up in your IDE environment. Perhaps you need to get out of the IDE, reopen the project, try building an exe and see if that works or not.

26. ## Re: Don't understand For...Next loop

For the sake of testing, what happens if you comment out everything inside the for loop and trace it through to see how many times it loops?

Where/how is n defined?

Do you have any error handling code set up?

27. ## Re: Don't understand For...Next loop

A few minor observations, I noticed the SquaresAroundTarget array has a lower bound of 1. Why? Also since in vb6 it's possible to use any integer value as a lower bound I prefer not to hardcode the lower bound when initializing an iterator variable. I recommend that you always use the LBound function instead.

28. ## Re: Don't understand For...Next loop

Originally Posted by Peter Swinkels
A few minor observations, I noticed the SquaresAroundTarget array has a lower bound of 1. Why?
This is an interesting question.

Zero based numbering systems seem to mirror concepts from math (http://www.cs.utexas.edu/users/EWD/t...xx/EWD831.html)

And 1 based systems seem to come from counting things in the real world. For example, if you have a dozen eggs, the first egg is number 1, not number 0 and the last egg is 12 not 11.

But then you have things like Mathmatica and Matlab that use 1 based arrays (perhaps due to matrix notation?)

vb6 mixes and matches, even within objects

To loop through records in a recordset:
For i = 1 to rs.recordcount

To loop through fields in a recordset:
for i = 0 to rs.fields.count -1

I have no preference for either, as long as it is consistent.

29. ## Re: Don't understand For...Next loop

Close.
You use 0-based Loops, if you want to use the loop-variable addressing an item of a collection (because those are zero-based)
Your sample with Recordsets is wrong (or better said: it doesn't matter, since you don't use the loop-variable addressing a recordset.
You can loop through all your Recordsets without using a loop-variable once.
Code:
```RS.MoveFirst
Do
Debug.Print RS.Fields(0)
RS.MoveNext
Until RS.EOF```
Addressing the Fields in a Recordset is the way you've shown: Debug.Print RS.Fields(i)

30. ## Re: Don't understand For...Next loop

Originally Posted by Zvoni
Close.
You use 0-based Loops, if you want to use the loop-variable addressing an item of a collection (because those are zero-based)
It depends on the collection. ADO collections are zero based. As are Access colections. Other office programs are not. Third party controls are a nice mixture.

and your code does not work (eof is for recordsets, not fields)

Code:
```Do While (i < rs.fields.Count - 1)
Debug.Print rs.fields(i)
i = i + 1
Loop```

31. ## Re: Don't understand For...Next loop

Originally Posted by DllHell
and your code does not work (eof is for recordsets, not fields)
Errrr....you did see, that i'm moving my Recordset with MoveNext forward? and that i'm checking RS.EOF (not Fields).
I've been doing it that way for years. Never used a loop-variable fo it

#### Posting Permissions

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

Featured