Reputation: 353
Does anyone know if there is a VBA statement to recognize successive adjacent characters as "words" rather than counting each and every non-alpha character (as a word) along the way?
My research indicates that most people who want to ignore punctuation and/or non-alpha characters are focused on trimming or deselecting the characters. I want to retain these characters, but I also want the non-alpha character ignored while the macro is determining how many "words" to select.
Consider the following examples of "visual" words versus "Word words":
Ms. Smith-Harris (visually 2; Word 5) 9:00 a.m. (visually 2; Word 7) and/or (visually 1, Word 3)
I have hundreds of macros that I access easily (with mnemonic shortcuts) via a text expander, among them dozens of macros that will select and perform an action (e.g., highlight, bold, uppercase, italicize, delete, etc.) on varying amounts of text to my left or right - something I do quite often in my transcription and editing work.
So, for example, my cursor might be to the right of Ms. Smith-Harris, and perhaps I want to highlight it or make it uppercase or delete it. It's much easier and faster for my eyes to quickly assess that string of characters as 2 "words" (of adjacent text) rather than stop and perform the tedious task of counting all the disruptive non-alpha characters that Word counts as "words" when selecting text, to figure out that it's 5 "words" by Word standards.
Although the text expander itself is capable of performing all the functions I might want to do to the text directly from within the program, it's much faster and more efficient to have it instead invoke a Word macro to perform the function, especially since the macro can intelligently trim unwanted spaces from the selection
But alas, if I run, for example, the Highlight2PreviousWords macro (shown below) while my cursor is to the right of Ms. Smith-Harris, it would only highlight "-Harris."
Here are two examples of my "select X number of words" macros:
Sub h1lw_HighlightPrevious1Word()
Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdExtend
Dim oRng As Word.Range
Set oRng = Selection.Words(1)
Do While oRng.Characters.Last = " "
oRng.MoveEnd wdCharacter, -1
Loop
oRng.Select
Selection.Range.HighlightColorIndex = wdYellow
Selection.Collapse Direction:=wdCollapseEnd
End Sub
Sub h2lw_HighlightPrevious2Words()
'
Selection.MoveLeft Unit:=wdWord, Count:=2, Extend:=wdExtend
Dim oRng As Range
Set oRng = Selection.Range
Do While oRng.Characters.Last = " "
oRng.MoveEnd wdCharacter, -1
Loop
oRng.Select
Selection.Range.HighlightColorIndex = wdYellow
Selection.Collapse Direction:=wdCollapseEnd
End Sub
All of my "select some words and then do something" macros look the same, except for the "do something" part, of course. So all of the "select 1 word to the left and do something" macros look like the first one, and all of the "select 2+ words to the left and do something" look like the second one. I usually don't go beyond 5 words because in the time it takes to visually count beyond that, I could just manually select the text.
So the macros work great for straight-text words, but not so great when other characters are in the mix. I'd love to be able to ignore the non-alpha characters and define all strings of adjacent text as "words."
Does anyone know of a way to accomplish this?
Upvotes: 0
Views: 1126
Reputation: 19067
Two tips first:
real
information about number of words you could use something like Range.ComputeStatistics() method
ActiveDocument.Range(startingPosition, EndingPosition)
Here is your first subroutine improved. It could be not 100% of what you need but I believe it is a good starting point (tested with Ms. Smith-Harris :) ).
Sub h1lw_HighlightPrevious1Word()
Dim curSection As Range
Dim curEnd As Long
curEnd = Selection.End
Dim newStart As Long
Do
newStart = Selection.Start
Selection.MoveLeft Unit:=WdUnits.wdWord, _
Count:=1
Set curSection = ActiveDocument.Range(Selection.Start, curEnd)
Debug.Print curSection.Text 'test
Loop While curSection.ComputeStatistics(wdStatisticWords) < 2
Set curSection = ActiveDocument.Range(newStart, curEnd)
Debug.Print curSection.Text 'test
'removing ending spaces
Do While curSection.Characters.Last = " "
Set curSection = ActiveDocument.Range(curSection.Start, curSection.End - 1)
Loop
With curSection
.HighlightColorIndex = wdYellow
ActiveDocument.Range(.End, .End).Select
End With
End Sub
Ps. I believe there is a shorter solution but I could not figure it out. I think one could use RegEx here as an alternative.
Upvotes: 3