Counting text occurrences

E

Edward Thrashcort

What's the most elegant way of counting the number of occurrences of a
string within a range?

I'm tempted to use the good old instr() function but wondered if there's an
OO method?

Eddie
 
D

Doug Robbins - Word MVP

The following will display the number of instances of the word "the" in the
range that is selected when the macro is run:

Dim myrange As Range
Dim i As Long
Set myrange = Selection.Range
'Selection.HomeKey wdStory
Selection.Find.ClearFormatting
i = 0
With Selection.Find
Do While .Execute(findText:="the", MatchWholeWord:=True, Forward:=True,
Wrap:=wdFindStop) = True
With Selection.Range
If .Start >= myrange.Start And .End <= myrange.End Then
i = i + 1
End If
End With
Loop
End With
MsgBox i


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP
 
K

Klaus Linke

Hi Eddie,

You could also use Split, and then check UBound.
? UBound(Split("SomeTestNextTestNewTestMoreText","Test"))

(You'd use yourRange.Text instead of the example string)

Regards,
Klaus
 
T

Tony Jollans

Or ...

Full = Selection.Text
Part = "Test"
MsgBox (Len(Full) - Len(Replace(Full, Part, ""))) / Len(Part)
 
E

Edward Thrashcort

Thanks Doug, that looks like a neat solution.
I've tidied it up a bit and created the following function


Function fCountWithinSelection(text) As Long
'Counts the number of occurrences of "text" within a selection
Dim oRange As Range
Dim i As Long

Set oRange = Selection.Range
Selection.Find.ClearFormatting
i = 0
With Selection.Find
Do While .Execute(FindText:=text, MatchWholeWord:=True, _
Forward:=True, Wrap:=wdFindStop)

With Selection.Range
If .start >= oRange.start And .End <= oRange.End Then
i = i + 1
End If
End With
Loop
End With
oRange.Select
Set oRange = Nothing

fCountWithinSelection = i
End Function


Eddie
 
E

Edward Thrashcort

Now THAT's clever :)

Eddie
Hi Eddie,

You could also use Split, and then check UBound.
? UBound(Split("SomeTestNextTestNewTestMoreText","Test"))

(You'd use yourRange.Text instead of the example string)

Regards,
Klaus
 
K

Klaus Linke

Agree, I picked it up here on the newsgroups.
But your original idea of using InStr would be faster, Tony's probably
too... if that's a consideration.

Regards,
Klaus
 
E

Edward Thrashcort

Speed isn't really a major concern, but I like code that's efficient and
compact. One-liners are great. If I don't particularly understand a one
line function, I simply treat it as a "black box"

Eddie
 
J

Jonathan West

Edward Thrashcort said:
Speed isn't really a major concern, but I like code that's efficient and
compact. One-liners are great. If I don't particularly understand a one
line function, I simply treat it as a "black box"

One-liners may be "efficient" in terms of lines coded, but I would query
whether they are necessarily efficient in other terms, such as whether the
code is easily readable (and therefore maintainable) or whether it executes
quickly.

As it happens, in this particular case, it is relatively readable and
understandable, and generally speaking, string-handling routines are so
quick compared to operations on the Word object model that execution speed
is not a concern - the time spent executing string handling stuff is usually
a trivial proportion of the total execution time.

But that doesn't necessarily apply to all one-liners.

--
Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup
Keep your VBA code safe, sign the ClassicVB petition www.classicvb.org
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top