views:

101

answers:

1

The following code is called everytime the form is opened. It works great until the 5th opening and then misses deleting one of the controls. Anyone know why this is?

 For Each cb In Forms(frmName).Controls
     If cb.ControlType = acCheckBox Then
         If Left(cb.Name, 3) = "clr" Then
            DeleteControl frmName, cb.Name
         End If
     ElseIf cb.ControlType = acLabel Then
         If Left(cb.Name, 3) = "clr" Then
            DeleteControl frmName, cb.Name
        End If
     End If
 Next
+2  A: 

When you delete an item from a collection in Access the next item moves into that items spot. Thus when it comes to deleting items from a collection you must start at the end of the collection and go backward.

So replace the

For Each cb In Forms(frmName).Controls

line with

For counter = Forms(frmName).Controls.Count - 1 To 0 Step -1
set cb = Forms(frmName).Controls.Item(counter)

My next question though is what is your overall objective? It's unusual to be manipulating controls in design view programmatically.

Tony Toews
It is a common problem with collections in VBA, the collections loses the order when deleting by name or from 1 to count, the method suggested by Tony Toews is the usual solution.
Remou
Robert Harvey, your solution works but you didn't understand the nature of collections in Access and how they work when deleting items. So yes, I'm cheeky.
Tony Toews
It is also common in VB and VB.Net to use Step-1
Remou
Robert Harvey - I'm sure all the other languages and platforms have edge cases too. This assumes of course this behavior is an edge case. Also I don't believe MS has ever changed this behaviour in Access. I'd have to load up Access 2.0 to check of course.
Tony Toews
Cheeky or not Toney Toews is right. The code was not failing randomly, it would fail at a set number of form loads depending how many controls were being deleted. For example, if the form had 8 controls it would fail on the 5th load, if it had 16 it would fail on the 29th. EVERY TIME. Thanks for the help!
Eric D. Johnson
@Eric, My solution didn't work because you didn't implement it the way I described. But I'm crying uncle. It is true that looping backwards is the correct and best solution.
Robert Harvey
@Robert Harvey, Tony and others: since the post in question has apparently been deleted, perhaps the comments should be deleted as well?
David-W-Fenton
In my opinion the posting should've been retained along with the comments so others would know what not to do.
Tony Toews