Solved For Loop Not Initialized (1 Viewer)

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
Is there another explanation for the error "For Loop Not Initialized" other than :
  • You jumped into the middle of a For...Next loop. Remove the jump into the loop. Placing labels inside a For...Next loop isn't recommended.
Every solution I have been able to find is that you have jumped into the loop with a GoTo or something. I am not doing that. I have two for loops in a module. Both iterate through their own array. The first one looks like this

For Each frmName In mainForms

'some code that works fine

Next frmName


the next for loop looks like this

For Each frmName in OpenForms

DoCmd.Close acForm, frmName

Next frmName

I tested it up to the second for look and it works great, and for some reason when it gets to the second loop I get the error "For Loop Not Initialized". I thought perhaps it was because I used the same iterator "frmName", but even if I change the variable to something else, I still get the same error. When I looked up the error, the only solution is in relation to jumping into the loop, but I assure you I am not doing that. The loop is inside an if statement that evaluated the result of a yes/no message box. I can add the entire code if necessary, but the rest of it works fine.
 

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 23:22
Joined
Oct 29, 2018
Messages
21,489
Hi. Welcome to AWF!

You could start with showing us what's in "some code that works fine."
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 01:22
Joined
Feb 28, 2001
Messages
27,217
Is there another explanation for the error "For Loop Not Initialized"

Yes, sometimes.

The error of "xxxx not initialized" CAN be caused by a prior "xxxx not terminated" situation. USUALLY this involves failing to properly close an "IF/THEN/END IF" block inside a loop such that it looks like the loop's end declaration is inside a different IF-block level than its initialization. The error you get is basically (pun mildly intended) due to whichever condition the compiler recognizes first.

If you recall, you can't jump into an IF-block either, because BASIC (not VBA but the overarching language specification itself) treats IF-blocks as little isolated microcosms for which you can get out any of several ways but the only way in is through the IF statement. It turns out that if you open a FOR loop (or any other flavor loop) you have ANOTHER constrained circumstance. Again, you can leave any time you want but you can only enter through the initializer for that loop.

You might notice that we often present code that is indented in a certain pattern. The VBA editor supports that by remembering the level of indentation. That indentation is done as a visual reminder of what level of block depth we are in. We INdent the start of an IF or LOOP block and OUTdent the end of it. When we do that and recognize that an end and beginning don't align, we know we have a missed termination or an extra termination. Or something else that has confused the block structure.
 

sonic8

AWF VIP
Local time
Today, 08:22
Joined
Oct 27, 2015
Messages
998
For Each frmName in OpenForms

DoCmd.Close acForm, frmName

Next frmName
This cannot work! - Ok, it depends on what "OpenForms" is exactly, but if is a real time collection of open forms, it should be obvious that this loop design is flawed.
You are looping through "OpenForms" and in the loop you are closing forms and thus removing a form from the "OpenForms" collection. Once this happens the iteration through "OpenForms" cannot work anymore because the original "OpenForms" collection, on which you started the iteration, does not exist anymore. Now there is a new "OpenForms" collection, which is the original minus the form that was closed.

Solution:
Use a counter driven loop. Count downwards from the number of elements in the collection to close the form.
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
This cannot work! - Ok, it depends on what "OpenForms" is exactly, but if is a real time collection of open forms, it should be obvious that this loop design is flawed.
You are looping through "OpenForms" and in the loop you are closing forms and thus removing a form from the "OpenForms" collection. Once this happens the iteration through "OpenForms" cannot work anymore because the original "OpenForms" collection, on which you started the iteration, does not exist anymore. Now there is a new "OpenForms" collection, which is the original minus the form that was closed.

Solution:
Use a counter driven loop. Count downwards from the number of elements in the collection to close the form.
openForms is just an array of strings. I am not removing anything from the array.
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
I didn't want to post my whole code because I didn't want to deal with people yelling about something that has nothing to do with my question, (which was literally the second response to my question). Even if I replace my code in the first loop with a Message box with a test message I have the same problem. all the first loop does is create the array. I have repeatedly tested that and there are no issues with it.
 

sonic8

AWF VIP
Local time
Today, 08:22
Joined
Oct 27, 2015
Messages
998
I didn't want to post my whole code because I didn't want to deal with people yelling about something that has nothing to do with my question,
To avoid that, create the most minimal sample that reproduces the problem and then post that sample code.
Incidentally, when you do the above, in 90% of the cases you will stumble upon the root cause of the problem. ;-)
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
Yes, sometimes.

The error of "xxxx not initialized" CAN be caused by a prior "xxxx not terminated" situation. USUALLY this involves failing to properly close an "IF/THEN/END IF" block inside a loop such that it looks like the loop's end declaration is inside a different IF-block level than its initialization. The error you get is basically (pun mildly intended) due to whichever condition the compiler recognizes first.

If you recall, you can't jump into an IF-block either, because BASIC (not VBA but the overarching language specification itself) treats IF-blocks as little isolated microcosms for which you can get out any of several ways but the only way in is through the IF statement. It turns out that if you open a FOR loop (or any other flavor loop) you have ANOTHER constrained circumstance. Again, you can leave any time you want but you can only enter through the initializer for that loop.

You might notice that we often present code that is indented in a certain pattern. The VBA editor supports that by remembering the level of indentation. That indentation is done as a visual reminder of what level of block depth we are in. We INdent the start of an IF or LOOP block and OUTdent the end of it. When we do that and recognize that an end and beginning don't align, we know we have a missed termination or an extra termination. Or something else that has confused the block structure.
That is actually a helpful suggestion thanks. I have already verified that all my previous loops are properly closed and do what I expect them to do. I verified the indentation as well. If I completely remove the second For Loop everything works perfectly.
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
To avoid that, create the most minimal sample that reproduces the problem and then post that sample code.
Incidentally, when you do the above, in 90% of the cases you will stumble upon the root cause of the problem. ;-)
That is exactly what I did.
 

cheekybuddha

AWF VIP
Local time
Today, 07:22
Joined
Jul 21, 2014
Messages
2,288
Try resetting your looping variable between loops:
Code:
For Each frmName In mainForms
  'some code that works fine
Next frmName

frmName = Null

For Each frmName in OpenForms
  DoCmd.Close acForm, frmName
Next frmName
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
Where is this code run from?
The code is called from a form with no source that I use as the "Main Menu" that just has a lot of buttons on it to navigate to different forms. The Module is public so that it can be called by any button that is used to open one of the main forms. The problem that I am having, which is why I am writing this code, is that my 4 main forms are pretty complex so when they open more than 2 of the main 4 forms, it is too much for Access to process so I need to prevent users from doing that so when the button is clicked all loaded form names are checked against an array. If the form matches one of those name the name as a string is added to another array. This produces a message box that tells the user that they must close some of these before opening another form. they can either say "Yes close all forms and open the new one" or "Cancel" and manually close the forms before opening the new form.

The likelihood of this happening is extremely low, but I need to protect against it anyway. Mostly I am the only one that would open more than two of them at the same time. The users would likely never do it unless they were poking around. 2 forms a piece correspond to the two halves of our department and users never work on something in the other half of the department, but if they happen to have their secondary form open, which will be rarely used anyway, and then want to look up something from the other half of the department, it will crash Access.
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
Try resetting your looping variable between loops:
Code:
For Each frmName In mainForms
  'some code that works fine
Next frmName

frmName = Null

For Each frmName in OpenForms
  DoCmd.Close acForm, frmName
Next frmName
I tried that and I even used a completely different variable for the second loop and I still get the error
 

cheekybuddha

AWF VIP
Local time
Today, 07:22
Joined
Jul 21, 2014
Messages
2,288
OK, so debug a step at a time.

First, check you're getting the form names you expect:
Code:
' ...
For Each frmName in OpenForms
  ' DoCmd.Close acForm, frmName
  Debug.Print frmName
Next frmName
 

Ummyeah

New member
Local time
Today, 00:22
Joined
Jun 16, 2022
Messages
15
OK, so debug a step at a time.

First, check you're getting the form names you expect:
Code:
' ...
For Each frmName in OpenForms
  ' DoCmd.Close acForm, frmName
  Debug.Print frmName
Next frmName
yeah I did that. If I take the DoCmd.Close line out of the for loop and add a message box or some test code I get the same error. If I completely remove the second for loop and instead print the arrays, it works fine and the arrays print exactly as expected. Additionally, that is the entirety of the second for loop. It is just supposed to close the forms with the form name being whatever is in the array.
 

cheekybuddha

AWF VIP
Local time
Today, 07:22
Joined
Jul 21, 2014
Messages
2,288
The problem likely resides in the code you haven't shown us. Your code you posted should work as it is.

I created a test:
Code:
Function CloseForms() As Boolean

  Dim OpenForms(2) As Variant, frmName As Variant, i As Integer
 
  For Each frmName In CurrentProject.AllForms
    If frmName.IsLoaded Then
      OpenForms(i) = frmName.Name
      i = i + 1
    End If
  Next frmName
  For Each frmName In OpenForms
    Debug.Print frmName
    DoCmd.Close acForm, frmName
  Next frmName
  CloseForms = Err = 0
 
End Function

In the Immediate Window:
Code:
?CloseForms
Form11
Form10
Form1
True

No error.
 

Users who are viewing this thread

Top Bottom