What are Control Arrays?
Just as you can have an array of numbers, strings, variants or even objects in your code, Visual Basic also allows you to have arrays of controls on your form.
The easiest way to see this in action is to open VB and and create a new empty project.
...
Yes go on do it now....
OK, now draw a control, let's use a textbox, onto the current form.
Name the text box control txtField
Check the value of Index property. It should be blank.
Now click on the textbox and press CTRL + C (Copy) and then CTRL +V (Paste).
VB should now prompt you with a question asking if you want to convert this control to a control array. Click Yes then repeat the whole process so that you have two new textboxes on the screen. (Make sure you move them away from the centre as they will be one on top of the other)
Note check the property screen for each control noting the Index property for each. They should be numbered 0 to 2.
Note that the textboxes all have the same name.
[img]images/smilies/cool.gif[/img]Cool, you have now created a control array.
You can also create a control array by changing one control's name to another's (they must be the same type though.)
VB will ask you the magic question again.
You can also just put a number in the Index property and turn that control into a control array.
How do you access a Control Array in code?
Double click on one of the textboxes in the control array on the form.
This should open the form's code module window and display the text box's Change event. It should look like this...
VB:
Notice that there is a new argument in the change event declaration, Index. For a normal text box, this is empty.
This is how you access each individual control in a control array, exactly like any other array in VB.
E.G. To change the second (index = 1) text box's background colour:
VB:
Also notice how when you just type the Me.txtField you get a set of methods that relate to the control array giving you the upper and lower bounds of the control array and the number of controls in it. So you could loop through a control array and change all the background colours to Yellow like this:
VB:
However there is a problem with this because
The index numbers do not have to be sequential, you can have any index number (from 0 to 32767) for a control in the array.
So if you have three text boxes all called txtField that you have indexed with 1, 10 and 11, the above code will cause an error because it will step from 1 (Me.txtField.LBound) to 2 and there is no control with an index of 2.
You get around this by looping through your control array using the For ... Each construct. This way, if there are gaps in your indexes, you won't get an error. (If you add controls later, the for ... each will still step through in index number order, not the order in which controls were added, whew!)
The following code will not error:
VB:
Why use Control Arrays?
Glad you asked?
Imagine, being the exceptional programmer that you are, that you want to implement that neat feature seen often in windows of automatically selecting the text in a textbox when a user tabs to or clicks on the text box. This is easily achieved in the GotFocus event seen below. The issue can be, if you have a form with 23 textboxes (say a customer edit) you have to put the code (or at least a reference to a global function that runs the code) in the GotFocus event of every individual textbox (23 times).
If instead you have used a control array of 23 texboxes all named txtField then this is a cinch as all the gotfocus events are handled in the one event.
VB:
Not only have you cut your coding down, but you maintain integrity as you know all the textboxes are calling the same code. If you add another text box on the form 2 months down the track. The handling of the GotFocus is done as a matter of course (and you don't have customers whinging how one box doesn't work like the others!)
OK, but why have indexes that aren't in sequence?
Ha, glad you asked. (My you are the astute one!)
Ok, now think of the problems with having only one event handler for each event of the text boxes. Say four of the text boxes held phone numbers and you want to make sure that only numbers and brakets are entered.
(OK, you could use a masked edit box, but for the example lets stick with simple text boxes.)
Here is where the power of enums come into play. You can assign a certain range of indexes for phone number containing text boxes and so perform certain actions on them. If you add another phone type text box later on, you only need number it accordingly and all the code is handled for you.
E.g. Here is an example of the text being filtered for phone type boxes using an enum declared at the top of the form's code. You can use any nameing convention.
VB:
If you wanted to colour the background of all address boxes yellow, you can do it easily by looping through the textbox array using the fiIDXFirst_Address to fiIDXLast_General indexes.
Hope this gives you some ideas.
mrbofh and Yama
Just as you can have an array of numbers, strings, variants or even objects in your code, Visual Basic also allows you to have arrays of controls on your form.
The easiest way to see this in action is to open VB and and create a new empty project.
...
Yes go on do it now....
OK, now draw a control, let's use a textbox, onto the current form.
Name the text box control txtField
Check the value of Index property. It should be blank.
Now click on the textbox and press CTRL + C (Copy) and then CTRL +V (Paste).
VB should now prompt you with a question asking if you want to convert this control to a control array. Click Yes then repeat the whole process so that you have two new textboxes on the screen. (Make sure you move them away from the centre as they will be one on top of the other)
Note check the property screen for each control noting the Index property for each. They should be numbered 0 to 2.
Note that the textboxes all have the same name.
[img]images/smilies/cool.gif[/img]Cool, you have now created a control array.
You can also create a control array by changing one control's name to another's (they must be the same type though.)
VB will ask you the magic question again.
You can also just put a number in the Index property and turn that control into a control array.
How do you access a Control Array in code?
Double click on one of the textboxes in the control array on the form.
This should open the form's code module window and display the text box's Change event. It should look like this...
VB:
| Code: |
| Private Sub txtField_Change(Index As Integer)
End Sub |
Notice that there is a new argument in the change event declaration, Index. For a normal text box, this is empty.
This is how you access each individual control in a control array, exactly like any other array in VB.
E.G. To change the second (index = 1) text box's background colour:
VB:
| Code: |
| Me.txtField(1).BackColor = vbRed |
Also notice how when you just type the Me.txtField you get a set of methods that relate to the control array giving you the upper and lower bounds of the control array and the number of controls in it. So you could loop through a control array and change all the background colours to Yellow like this:
VB:
| Code: |
| Dim lngIndex As Long
For lngIndex = Me.txtField.LBound To Me.txtField.UBound ' Colour the background of each 'Field' text box Me.txtField(lngIndex).BackColor = vbYellow Next lngIndex |
However there is a problem with this because
The index numbers do not have to be sequential, you can have any index number (from 0 to 32767) for a control in the array.
So if you have three text boxes all called txtField that you have indexed with 1, 10 and 11, the above code will cause an error because it will step from 1 (Me.txtField.LBound) to 2 and there is no control with an index of 2.
You get around this by looping through your control array using the For ... Each construct. This way, if there are gaps in your indexes, you won't get an error. (If you add controls later, the for ... each will still step through in index number order, not the order in which controls were added, whew!)
The following code will not error:
VB:
| Code: |
| Dim txtRef As TextBox
For Each txtRef In Me.txtField ' Colour the background of each 'Field' text box txtRef.BackColor = vbRed Next lngIndex |
Why use Control Arrays?
Glad you asked?
Imagine, being the exceptional programmer that you are, that you want to implement that neat feature seen often in windows of automatically selecting the text in a textbox when a user tabs to or clicks on the text box. This is easily achieved in the GotFocus event seen below. The issue can be, if you have a form with 23 textboxes (say a customer edit) you have to put the code (or at least a reference to a global function that runs the code) in the GotFocus event of every individual textbox (23 times).
If instead you have used a control array of 23 texboxes all named txtField then this is a cinch as all the gotfocus events are handled in the one event.
VB:
| Code: |
| Private Sub txtField_GotFocus(Index As Integer)
With Me.txtField(Index) .SelStart = 0 .SelLength = Len(.Text) End With End Sub |
Not only have you cut your coding down, but you maintain integrity as you know all the textboxes are calling the same code. If you add another text box on the form 2 months down the track. The handling of the GotFocus is done as a matter of course (and you don't have customers whinging how one box doesn't work like the others!)
OK, but why have indexes that aren't in sequence?
Ha, glad you asked. (My you are the astute one!)
Ok, now think of the problems with having only one event handler for each event of the text boxes. Say four of the text boxes held phone numbers and you want to make sure that only numbers and brakets are entered.
(OK, you could use a masked edit box, but for the example lets stick with simple text boxes.)
Here is where the power of enums come into play. You can assign a certain range of indexes for phone number containing text boxes and so perform certain actions on them. If you add another phone type text box later on, you only need number it accordingly and all the code is handled for you.
E.g. Here is an example of the text being filtered for phone type boxes using an enum declared at the top of the form's code. You can use any nameing convention.
VB:
| Code: |
| Option Explicit
' Enum used to identify what data is in each text box '---------------------------------------------------- Private Enum FieldIndexEnum fiIDXFirst_General = 1 ' The first index for general details fiFName = 1 fiLName = 2 fiTitle = 3 fiIDXLast_General = 3 ' The last index for general details fiIDXFirst_Phone = 100 ' The first index for phone type details fiPhoneHome = 100 fiPhoneMobile = 101 fiPhoneFax = 102 fiIDXLast_Phone = 102 ' The last index for phone type details fiIDXFirst_Address = 200 ' The first index for Address details fiAddrStreet = 200 fiAddrExtra = 201 fiAddrCity = 202 fiAddrPCode = 203 fiIDXLast_Address= 203 ' The last index for Address details End Enum Private Sub txtField_GotFocus(Index As Integer) With Me.txtField(Index) .SelStart = 0 .SelLength = Len(.Text) End With End Sub Private Sub txtField_KeyPress(Index As Integer, KeyAscii As Integer) ' Format textboxes according to their assigned category '------------------------------------------------------ Select Case Index Case fiIDXFirst_Phone To fiIDXLast_Phone ' format the phone textbox by checking what key has been pressed Select Case UCase$(Chr$(KeyAscii)) Case "A" To "Z", "(", ")" ' Pass Case vbKeyBack, vbKeySpace ' Let backspace and space through Case Else ' Not allowed KeyAscii = 0 End Select Case fiAddrPCode ' We can also check individual text boxes Select Case KeyAscii Case vbKeyBack, vbKeySpace ' Let backspace and space through Case vbKey0 To vbKey9 ' Post code must be numeric Case Else KeyAscii = 0 End Select End Select End Sub |
If you wanted to colour the background of all address boxes yellow, you can do it easily by looping through the textbox array using the fiIDXFirst_Address to fiIDXLast_General indexes.
Hope this gives you some ideas.
mrbofh and Yama
