That was my gut feeling. I figured if calling a macro from the spreadsheet
is slow (I've seen several references to that fact), then it must also be
slow going the other way. Hence, I opted for the pattern toggling code
that
I posted.
Now that is interesting.
I would agree with that.
The way I this over in the compiled VB world (which works here in the
Excel
VBA world as well) is like this...
Do While InStr(SomeText, " ") > 0
SomeText = Replace(SomeText, " ", " ")
Loop
In the compiled VB world, our tendency is to avoid calling out to any kind
of scripting type object as this is very slow to do from a compiled
executable and, very often, businesses have scripting completely turned
off
for security reasons. However, since VBA macros or UDFs are not compiled
executable, I have no feeling for the efficiency calling a scripting
object
from within one.
Rick
OK, after reading about all these delays, I decided to do some timing
tests and
I find that the differences in time related to the procedure calls are far
outweighed by the time involved in reading or writing to/from a cell.
Here is the first run just picking out if a word is present in a string
and
writing the results to a cell:
========================================
Option Explicit
Sub foo()
Range("a:d").Clear
Range("a:a").Value = "Now is the time for all"
Dim t As Long
t = Timer
test1
Debug.Print "InStr test", Format(Timer - t, "#.00") & " sec"
t = Timer
test2
Debug.Print "RegExp early binding Test", Format(Timer - t, "#.00") & "
sec"
t = Timer
test3
Debug.Print "RegExp late binding test", Format(Timer - t, "#.00") & " sec"
End Sub
Sub test1()
Dim c As Range
For Each c In Range("a:a")
If InStr(1, c.Text, "time") > 0 Then
c.Offset(0, 1).Value = "time"
End If
Next c
End Sub
Sub test2()
Dim c As Range
Dim re As New RegExp
Dim mc As MatchCollection
re.Pattern = "time"
For Each c In Range("a:a")
Set mc = re.Execute(c.Text)
c.Offset(0, 3) = mc(0)
Next c
End Sub
Sub test3()
Dim c As Range
Dim re As Object, mc As Object
Set re = CreateObject("vbscript.regexp")
re.Pattern = "time"
For Each c In Range("a:a")
Set mc = re.Execute(c.Text)
c.Offset(0, 3) = mc(0)
Next c
End Sub
============================================
InStr test 15.53 sec
RegExp early binding Test 15.45 sec
RegExp late binding test 16.59 sec
==============================================
And again, just testing your double space removal routine:
================================================
Option Explicit
Sub foo()
Range("a:d").Clear
Range("a:a").Value = " Now is the time for all "
Dim t As Long
t = Timer
test1
Debug.Print "InStr test", Format(Timer - t, "#.00") & " sec"
t = Timer
test2
Debug.Print "RegExp early binding Test", Format(Timer - t, "#.00") & "
sec"
t = Timer
test3
Debug.Print "RegExp late binding test", Format(Timer - t, "#.00") & " sec"
End Sub
Sub test1()
Dim c As Range
Dim SomeText As String
For Each c In Range("a:a")
SomeText = c.Text
Do While InStr(SomeText, " ") > 0
SomeText = Replace(SomeText, " ", " ")
Loop
c.Offset(0, 1) = SomeText
Next c
End Sub
Sub test2()
Dim c As Range
Dim re As New RegExp
Dim mc As MatchCollection
re.Pattern = "\s{2,}"
re.Global = True
For Each c In Range("a:a")
c.Offset(0, 3) = re.Replace(c.Text, " ")
Next c
End Sub
Sub test3()
Dim c As Range
Dim re As Object, mc As Object
Set re = CreateObject("vbscript.regexp")
re.Pattern = "\s{2,}"
re.Global = True
For Each c In Range("a:a")
c.Offset(0, 3) = re.Replace(c.Text, " ")
Next c
End Sub
========================================================
InStr test 16.72 sec
RegExp early binding Test 15.95 sec
RegExp late binding test 16.47 sec
======================================
Removing the read/write part, setting a reference to Regular Expressions,
and
doing 1,000,000 operations, some differences show up:
=============================================================
Option Explicit
Sub foo()
Range("a:d").Clear
Range("a:a").Value = " Now is the time for all "
Dim t As Long
t = Timer
test1
Debug.Print "Instr Test", Format(Timer - t, "#.00") & " sec"
t = Timer
test3
Debug.Print "RegExp test", Format(Timer - t, "#.00") & " sec"
End Sub
Sub test1()
Dim sTxt As String
Dim i As Long
sTxt = Range("a1").Text
For i = 1 To 2 ^ 20
Do While InStr(sTxt, " ") > 0
sTxt = Replace(sTxt, " ", " ")
Loop
Next i
Debug.Print sTxt
End Sub
Sub test3()
Dim re As New RegExp
Dim sTxt As String
Dim i As Long
sTxt = Range("a1").Text
re.Global = True
re.Pattern = "\s{2,}"
For i = 1 To 2 ^ 20
sTxt = re.Replace(sTxt, " ")
Next i
Debug.Print sTxt
End Sub
==============================================================
Now is the time for all
Instr Test .25 sec
Now is the time for all
RegExp test 2.05 sec
=============================================================
I also ran a test which shot down my expectation that the morefunc.xll
addin
would run faster:
========================================
Option Explicit
Sub foo()
Range("a:d").Clear
Range("a:a").Value = " Now is the time for all "
Dim t As Long
t = Timer
test1
Debug.Print "Instr Test", Format(Timer - t, "#.00") & " sec"
t = Timer
test2
Debug.Print "morefunc test", Format(Timer - t, "#.00") & " sec"
t = Timer
test3
Debug.Print "RegExp test", Format(Timer - t, "#.00") & " sec"
End Sub
Sub test1()
Dim sTxt As String
Dim i As Long
sTxt = Range("a1").Text
For i = 1 To 2 ^ 20
Do While InStr(sTxt, " ") > 0
sTxt = Replace(sTxt, " ", " ")
Loop
Next i
Debug.Print sTxt
End Sub
Sub test2()
Dim sTxt As String, sPat As String
Dim i As Long
sTxt = Range("a1").Text
sPat = "\s{2,}"
For i = 1 To 2 ^ 20
sTxt = Run([regex.substitute], sTxt, sPat, " ")
Next i
Debug.Print sTxt
End Sub
Sub test3()
Dim re As New RegExp
Dim sTxt As String
Dim i As Long
sTxt = Range("a1").Text
re.Global = True
re.Pattern = "\s{2,}"
For i = 1 To 2 ^ 20
sTxt = re.Replace(sTxt, " ")
Next i
Debug.Print sTxt
End Sub
====================================================
Now is the time for all
Instr Test .75 sec
Now is the time for all
morefunc test 173.48 sec
Now is the time for all
RegExp test 2.28 sec
===================================
So really, the question comes up as to whether or not the timing
differences
make a difference in the usual VBA applications, or will the timing
differences
be irrelevant given the timings of the rest of the routines.
--ron