Early & Late Binding

Mile-O

Back once again...
Local time
Today, 00:47
Joined
Dec 10, 2002
Messages
11,316
I see so many people using the ! notation over the . notation (i.e. Me!txtBox over Me.txtBox) and was wondering where everyone gets the 'instinct' to use the late binding (!) notation.

I understand that it has its benefits but early binding (.) and it's ability to ensure disambiguation and speed up code is so much better.

Where does this ! trend stem from?
 
I think Microsoft is itself responsible for the ! notation in it's documentation. When I first learned Access, it was the common notation, so I used it.

One article I read on MSDN suggests that the ! operator is best to use when you know the name of the object being referenced, as in Forms!MyForm, but if you don't know the name of the particular form, like when you're working with a variable form name, you should use Forms(strFormName) notation. Here is the article: Microsoft Access 2000: Building Applications with Forms and Reports.

I've also only seen the ! in relation to Access. I've never seen it mentioned in articles pertaining to Excel, for example though the notation works there as well.
 
In general, the rule of thumb I use is to move my thumb before I swing the hammer.... oh, wait! Wrong forum.

The way I learned this has to do with whether there is any variability in the thing being referenced.

For instance, let's take a control that can be visible or not. The property is Visible and you have no control over that name, so you use the . (I guess because there is nothing dynamic and the binding issue is moot - same result either way). But if you created it or if there is a dynamic component, you might wish to use the ! instead of the .

Also, oddly enough, there are times when you think either one would work, but 'tain't so.

A long time ago, back in the DBW (days before Windows), I used to use Paradox for DOS. It had both flavors of object selection and there were some bizarre rules about which one was used for which thing. I believe properties were ALWAYS dot (.) and field names in SQL were always bang (!). Did I just give away my age by revealing that little tid-bit? And old DEC Datatrieve also used the dot and bang notation for various elements in databases. On the other hand, old ShareBase databases didn't seem to care.
 
Control Objects

!; Implicitly refer to the control
.; Explicitly refer to the control

! is faster

Have a great day!
________
Ferrari F50 Gt
 
Last edited:
Code:
Option Explicit
Option Compare Text

Public Declare Function timeGetTime Lib "Winmm.dll" () As Long

[color=green]'   For DAO recordsets...
'
'   The ! appears to be 5% faster than the .
'   Both seem to be swamped out by the Edit and Update.
'
'   Tested on 64280 records
'[/color]
Sub Test1()
    Dim lngStart      As Long
    Dim rstLocalities As DAO.Recordset
    
    lngStart = timeGetTime()
    
    Set rstLocalities = CurrentDb.OpenRecordset("tblLocalities", dbOpenDynaset)
    
    Do Until rstLocalities.EOF
        rstLocalities.MoveNext
    Loop
    
    Set rstLocalities = Nothing
    
    MsgBox timeGetTime() - lngStart   [color=green]'  141 milliseconds[/color]

End Sub


Sub Test2()
    Dim lngStart      As Long
    Dim rstLocalities As DAO.Recordset
    
    lngStart = timeGetTime()
    
    Set rstLocalities = CurrentDb.OpenRecordset("tblLocalities", dbOpenDynaset)
    
    Do Until rstLocalities.EOF
        rstLocalities.Edit
        rstLocalities.Update
        rstLocalities.MoveNext
    Loop
    
    Set rstLocalities = Nothing
    
    MsgBox timeGetTime() - lngStart  [color=green]'  2995 milliseconds[/color]

End Sub


Sub Test3()
    Dim lngStart      As Long
    Dim rstLocalities As DAO.Recordset
    
    lngStart = timeGetTime()
    
    Set rstLocalities = CurrentDb.OpenRecordset("tblLocalities", dbOpenDynaset)
    
    Do Until rstLocalities.EOF
        rstLocalities.Edit
        rstLocalities!TestText = "ABC_"
        rstLocalities.Update
        rstLocalities.MoveNext
    Loop
    
    Set rstLocalities = Nothing
    
    MsgBox timeGetTime() - lngStart  [color=green]'  3195 milliseconds[/color]

End Sub


Sub Test4()
    Dim lngStart      As Long
    Dim rstLocalities As DAO.Recordset
    
    lngStart = timeGetTime()
    
    Set rstLocalities = CurrentDb.OpenRecordset("tblLocalities", dbOpenDynaset)
    
    Do Until rstLocalities.EOF
        rstLocalities.Edit
        rstLocalities.Fields("TestText") = "ABC_"
        rstLocalities.Update
        rstLocalities.MoveNext
    Loop
    
    Set rstLocalities = Nothing
    
    MsgBox timeGetTime() - lngStart  [color=green]'  3205 milliseconds[/color]

End Sub
[color=green]'
'   For what it is worth, those are the times I got.
'
'   Regards,
'   Chris.[/color]
 
Nice Work.

Ctrl+F; Replace

Replace "." with "!"

:D :eek:
________
Og kush
 
Last edited:
Just my view but I disagree.

In my view 5% is not worth thinking about and I try to write source code for clarity, hell I might even have to come back and read it someday.

To me: -

rstLocalities.Edit
rstLocalities!TestText = "ABC_"
rstLocalities.Update
rstLocalities.MoveNext

reads better than: -

rstLocalities.Edit
rstLocalities.Fields("TestText") = "ABC_"
rstLocalities.Update
rstLocalities.MoveNext

because of the difference between the . and the ! i.e. three properties as opposed to one field.
(Plus, there is less typing and less to read which is a good thing.)

I would certainly not compromise clarity of source code for speed if it produced so little difference.
It just so happens that in this case what I think is easier to read also runs a little faster.
(In the timing above, the increase is 0.31% overall, and is not even worth considering.)

As to whether or not this is important in a Control collection on a Form seems a mute point.
The control count can’t get to 64K+.

Perhaps someone would like to demonstrate a worthwhile speed improvement, which would require a particular method of accessing controls on a Form or Report.

Regards,
Chris.
 
Last edited:
To clarify, the ! is used when referencing user defined objects and the . is used when referencing internal methods and properties. The place where there is overlap is in the fields collections of forms and reports. In this case, and in this case only, you may use the . and ! interchangably because your recordsource fields and the forms controls are all part of the fields collection.

ChrisO, I'd like to suggest a more valid comparison. Try timings of the following ways to refer to a control in a form.

Me.YourControlName ' dot
Me!YourControlName ' bang
YourControlName 'unqualified
Forms!YourFormName!YourControlName 'formal full name

Make sure that YourControlName is bound and the name of the control is different from the name of its controlsource field.
 
Thanks Pat and I’ll give it a shot.

Could be difficult to time since referring to one control may be below the 1 millisecond resolution I have available to me.

Worth the effort and I’ll give it my best shot. (Could take a while to build a reasonable test case.)

Regards,
Chris.
 
Perhaps you can throw:
Forms("YourFormName")("YourControlName")
int the mix, while you're at it.
 
Actually Pat there is a little more to say on this subject before I get started trying to produce a test case.

When you say “a more valid comparison” there may be no more valid comparison than that which is already posted.

In this thread Milo posted a speed method that seems to be invalid under DAO.

The current thread was not started about DAO but about Controls. But the similarity and timing are remarkable and that is why I prefaced my remarks as “For DAO recordsets... “

However, I will still try to time a control collection.

Why I think it will be difficult to arrive and any concrete answer is because the collection will be restricted in size. I’m not a fond believer of wrapping test cases in a For Next loop as the first pass might have to bring the data to memory and subsequent iterations may not be running “in the real world” with the same overhead.

But it is still worth a shot.

If you have any timing information or the ways to test it, it would be much appreciated.

Regards,
Chris.
 
G’day dcx693

Thanks for the alternative.

Forms("YourFormName")("YourControlName")

Will be included if I can figure a valid way to time it.

If anyone has a valid method, or another reference method, I would like to hear it so it can be included in the testing.

Regards,
Chris.
 
I said “a more valid comparison” because when people talk about bang vs dot they are invariable referring to how to reference a control or field on a form or report rather than the references you timed originally.

I would start with a loop that just sets a variable to the control.
 
Thanks Pat.

One of my concerns here it that once a point is stated then some readers want others to do all the work. It is not easy to time code, as you will most surly know, but I think that sometimes some people require us to do all the work and somehow provide a concrete solution.

In this case I think it will be difficult to prove.

For example, I’m currently trying to write a non-looping 400-iteration test case to try to prevent ambiguity between first pass and subsequent passes. I don’t want it said that the test case is false, particularly by someone that has not taken the time to run the test for themselves.

As you will know, it is a simple fact that timing needs to be timed.

PS
And may I add it is going to take a while. (A few days.)

Regards,
Chris.
 
Last edited:
Code:
Option Explicit
Option Compare Text


Private Sub cmdGo_Click()
    Dim lngStart     As Long
    Dim lngLoopCount As Long
    
    [color=green]'  Looping time results.
    '  850MHz PIII
    '
    '  Text box named txtTestText
    '  bound to field TestText
    '  100,000 loops
    '  times in milliseconds[/color]
    
    lngStart = timeGetTime()
    For lngLoopCount = 1 To 100000
        Me.txtTestText = "ABC_"
    Next lngLoopCount
    Debug.Print timeGetTime() - lngStart  [color=green]'  3425[/color]

    lngStart = timeGetTime()
    For lngLoopCount = 1 To 100000
        Me!txtTestText = "ABC_"
    Next lngLoopCount
    Debug.Print timeGetTime() - lngStart  [color=green]'  3986[/color]

    lngStart = timeGetTime()
    For lngLoopCount = 1 To 100000
        txtTestText = "ABC_"
    Next lngLoopCount
    Debug.Print timeGetTime() - lngStart  [color=green]'  3425[/color]

    lngStart = timeGetTime()
    For lngLoopCount = 1 To 100000
        Forms!Form1!txtTestText = "ABC_"
    Next lngLoopCount
    Debug.Print timeGetTime() - lngStart  [color=green]'  4957[/color]
    
    lngStart = timeGetTime()
    For lngLoopCount = 1 To 100000
        Forms("Form1")("txtTestText") = "ABC_"
    Next lngLoopCount
    Debug.Print timeGetTime() - lngStart  [color=green]'  4917[/color]
   
    lngStart = timeGetTime()
    For lngLoopCount = 1 To 100000
        Me("txtTestText") = "ABC_"
    Next lngLoopCount
    Debug.Print timeGetTime() - lngStart  [color=green]'  3986[/color]
   
    MsgBox "Done"

End Sub
 
So, to summarize, with the last column indicating how much longer that particular reference style took over the quickest reference style:
Code:
Reference	                         Time	
Me.txtTestText	                         3425	0%
Me!txtTestText	                         3986	16%
txtTestText	                         3425	0%
Forms!Form1!txtTestText                 4957	45%
Forms("Form1")("txtTestText")         	4917	44%
Me("txtTestText")	                3986	16%
Interesting. It's what I would've expected based on what I'd read, but as ChrisO did point out, it's hard to get accurate timing since timing needs to be timed.

Besides, the differences in time all seem rather small. Each loop was executed 100,000 times with the biggest difference being between 3.425 seconds and 4.957 seconds.
 
Last edited:
G’day dcx693

If we can take those timing numbers as correct then your last point is perhaps the important one, for 500 controls on a Form the max. difference would amount to 7.66 milliseconds.

I would still like to make up a Form with 500 different text boxes and write code to go through them without looping. (Which of course means 500 lines of code per each of 6 methods.)

Won’t be able to do much today, visiting relatives, but might have something for tomorrow.

Any other methods to reference controls on a form you might like timed?

Regards,
Chris.
 
ChrisO, thanks again for taking the time to do this. Good job.

I always did wonder if there was any speed difference between:
Me("txtTestText")
Me.Controls("txtTestText")
 
I need to leave shortly to see the rels. but you can have a play with this as it stands.

It’s a bit of an eye opener if you create a command button on one of the Forms and tie it to the update routine.

Timing is not what it seems. :eek:

Regards,
Chris.
 

Attachments

I am sorry Chris. I wasn't trying to disparage your work. It was in fact a fine piece of work. It just wasn't testing what I thought was the relevant reference styles. The second set of timings showed exactly what I expected it to do. With Forms!Form1!txtTestText being the most expensive style of reference. This style is necessary when you are outside of the form and need to reference something on it but too many people simply use it all the time.

As you can see the time difference is really very small and probably would not make much difference unless it were within a long running code loop. The point though is to know what is the most efficient style and use that whenever possible because ultimately inefficient methods compound themselves and the cumulative time does become measurable.

Thank you for the work you have done to expand our understanding.
 

Users who are viewing this thread

Back
Top Bottom