Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Remove a control from a control array?

Status
Not open for further replies.

gdrenfrew

Programmer
Aug 1, 2002
227
GB
Hi there,

hope someone can help, haven't been able to solve this...

I'm trying to remove a control from a control array, dynamically within the code.

I have a form with 3 controls on it, called CtlLine(0),(1) and (2). How can I remove the second element?

Unload CtlLine(1) removes it from the screen, but my code still trips up when I do some validation as the code thinks there is still an element CtlLine(1) as it still appears in the Me.Controls collection. I can write around this using a "check control exists" function everytime, but this is pretty longwinded.

Is there a way to remove a control completely from control array? Me.Controls.Remove CtlLine(1) doesn't work...

Thanks
 
To test your situation, I did the following. I added a text box and two command buttons to a form, and set the text box's index property to 0. Then I added the following code:
Code:
Option Explicit

Private Sub Command1_Click()
Static cindex As Integer
cindex = cindex + 1
Load Text1(cindex)
Text1(cindex).Top = Text1(cindex - 1).Top + Text1(0).Height
Text1(cindex).Visible = True
End Sub

Private Sub Command2_Click()
Dim i As Integer
Unload Text1(2)
For i = 0 To Text1.Count
    Debug.Print Text1(i).Text
Next
End Sub
I then clicked Command1 several times, and then clicked Command2. As expected, the third text box in the column disappeared, and I got an error 340, "Control array element '2' doesn't exist". I then added the following code to Command2, and commented out the existing for loop:
Code:
For Each ctl In Controls
    Debug.Print ctl.Name
    If TypeOf ctl Is TextBox Then
        Debug.Print ctl.Index
    End If
Next
After adding 5 text boxes, this had the following output:
Code:
Command2
Command1
Text1
 0 
Text1
 1 
Text1
 3 
Text1
 4 
Text1
 5
In other words Text1(2) is no longer in the Me.Controls collection, and it would seem that my code represents an example of how to remove a control completely from a control array.

So, maybe I don't understand your question. I have the feeling that what you're really concerned about is that the control array doesn't "fix itself up" by removing blank elements when you remove one of its controls. Anyway, feel free to clarify your concerns and we'll take another crack at it.

HTH

Bob
 
gdrenfrew,

Two comments:
1.You can't remove control programmatically if you set it in design mode. In other words, only programmatically added controls can be removed programmatically.
2. When you remove your controls from the array, go backward with step = - 1. Othervise, you will create a mess with your array bounds.

vladk
 
Thanks for the replies Bob and Vladk,

Bob, you are right, my concern is the control array not closing up the empty elements. I hoped I'd be able to ReDim Preserve with my control array, but I was unable to.

Another tack I took was to try and use the Control.Remove method - but the controls do not have unique names which I think is a requirement. I guess I could implement that, just I wanted to avoid trawling the code (4 years old, no comments etc etc) incase anything would fall over if I did so.

Vdlak, the step backward with -1 would surely only work if I removed the last element?

Thanks for everyones efforts, I'll try giving them unique names and see if that works. Cheers Bob, your example was above and beyond the call of duty!
 
Yeah, I thought that was what you were up to. Here's another trick, though: you might consider setting up another array of controls, which functions as a set of pointers to the valid controls in the control array. That array you can mess with any way you like.

So this code assumes that you have defined a myControls() array in the general declarations section:
Code:
Private Sub RemoveText1()Dim i as integer
Dim j as integer
dim strDummy as string
Redim myControls(Text1.Count-1) 'Don't preserve, just wipe it and redo it
for i = 0 to Text1.Ubound
   on error resume next
   strDummy = Text1(i).Name
   select case err.number
      case 0
         Set myControls(j) = Text1(i)
         j=j+1
      case 340
         err.clear
      case else
         err.raise err.number
   end select
Next i
End Sub
Now, if you call RemoveText1 every time you remove a control, you'll have a myControls array that has all of the valid controls that you're using. You can iterate around in that all you like, and only do the "check control exists" thing once for each time a control is removed. Well, or added too, so maybe "RemoveText1" isn't the best name.

Does that help?

Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top