Discussion on:

5
Comments

Join the conversation!

Follow via:
RSS
Email Alert
Hello Peter,

This is a very nice trick (which you can use in many ways). But there a catch here, its works but it's slow.

2 reasons behind this.

1st - You're accessing the ctl in late-binding. It is always slower and moreover more error prone as the compiler cannot check if the method or attribute really exists

2nd - The TypeOf operator does pretty cool stuff in the back. Cool but slower too.

A faster and safer implementation of the code in your article would be:

Dim c As Control
Dim txt As TextBox

For Each c In Me.Controls
On Error Resume Next
Set txt = c
On Error GoTo 0
If Not txt Is Nothing Then
txt.ForeColor = vbRed
End If
Next


Regards!
@myrdhrin,

Regarding your comments:

1. late binding
* there's no way to early bind the variables to a control defined on a form a design time.
* There are efficiencies gained with different datatypes of iteration variables as well as the method of control type comparison and whether you are limiting your actions to one type of control or different types of controls.
Iteration variable control datatype speeds, from fastest to slowest: As Variant, As Object, As Textbox, As Control.

Iteration variable datatype test example:
Dim objThing As Object
sngStart = Timer
For lngLoop = 1 To lngIteration '=100000
For Each objThing In Form1.Controls
lngCount = lngLoop
Next
Next
sngStop = Timer

Note: perf. order based on 100000 iterations
Note: All controls on Form1 are textboxes
Note: "lngCount = lngLoop" is meant to test effect of the datatype on looping performance by eliminating control property references. The compiler might not do the same type of looping if it detects an empty loop.

Since the construct is limited to those circumstances where a boolean value can be used, a developer is constricted in their ability to determine the type of a control and (safely) act on different properties, based on the type of control. There are two operators that can be used (TypeOf and TypeName) and two different program constructs that can be used (If and Select Case) inside the For Each loop that iterates over a form's controls.

In general, the TypeName() function performs worse than the TypeOf operator in ALL situations. This is due to the fact that the TypeName() function returns a string and string comparisons are ALWAYS slower than numeric comparisons.
The TypeName() Performance test with Select Case clauses ordered to match the most likely controls at the top, a Variant iteration variable took 4.957 seconds and an Object iteration variable took 6.4375 seconds in a 100000 sample.

Note: a Boolean value is really an Integer datatype

Despite what you read in the Microsoft online help, you CAN use the TypeOf operator in a Select Case structure as well as an If structure. Comparing a test with two different over 100000 samplings, we get the following results:
Object iterator (If Else If TypeOf): 1.832 secs
Object iterator (Select Case True): 1.832 secs
Control iterator (Select Case True): 2.324 secs
Variant iterator (If Else If TypeOf): 3.408 secs
Control iterator (If Else If TypeOf): 4.281 secs

==========================================
2. The purpose of Peter's use of the TypeOf operator was to prevent 'safety' problems. I'm not a fan of this type of 'safety' (catching errors). Furthermore, I'm not convinced that it is a better performer than the TypeOf when it encounters a mixture of controls on a form that contains hundreds of controls.

================================
IMHO: As a software instructor, I'm very much against using a perceived 'double negative' in your If statement:


I would recommend any of the following:
If txt Is Nothing Then
Else
txt.ForeColor = vbRed
End If

Or
If Not(txt Is Nothing) Then
txt.ForeColor = vbRed
End If

However, I still wouldn't advise the catching of errors if they can be avoided with reasonable performance and code maintainability.

================================
If you want to optimize runtime performance when changing properties on many controls, you should do the following:
a. create collection objects for each set of controls you will need to iterate on the form. You can go so far as to create a collection of collections.

b. When the form loads, use a TypeOf interation like the one suggested by Peter, adding the controls to their set.

c. When you need to access all these controls, iterate over the appropriate set through your collection and not the Me.Controls collection.
I tried using TypeOf with For Each...Next in VBA MS Excel and it did not work.
Kumar,

If you wanted some help with your problem, you should realize that we don't have enough information from your post to discern the cause of your problem. Please describe what you are trying to do, preferably with a code snippet. Also, we will need to know any error conditions that are raised when you run your code.
0 Votes
+ -
In fact, I use VBA and Excel and don't work.... Please if you find solutions send me mail to l l a e v 2 0 0 5 @ g m a i l . c o m

Thanks !!!!

p.d. Sorry for my writting, I am spanish! wink
Keyboard Shortcuts:
Prev
Next
Toggle
Join the conversation
Formatting +
BB Codes - Note: HTML is not supported in forums
  • [b] Bold [/b]
  • [i] Italic [/i]
  • [u] Underline [/u]
  • [s] Strikethrough [/s]
  • [q] "Quote" [/q]
  • [ol][*] 1. Ordered List [/ol]
  • [ul][*] · Unordered List [/ul]
  • [pre] Preformat [/pre]
  • [quote] "Blockquote" [/quote]

Join the TechRepublic Community and join the conversation! Signing-up is free and quick, Do it now, we want to hear your opinion.