Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 943
  • Last Modified:

Using VBA Find out if range is the first word of a sentence

Hello,

Using VBA in MS Word is there a way to find out if a range is the first word of a sentence.  Suppose my document contains the following sentence:

The quick brown fox jumped over the lazy programmer.

MyRange = "The"

How do I test if MyRange is the first word of the sentence.  Assume the sentence is not the first in the document.

Thanks
0
eshurak
Asked:
eshurak
  • 7
  • 4
  • 4
  • +2
2 Solutions
 
Surone1Commented:
if myrange = left("The quick brown fox jumped over the lazy programmer."",3) then
msgbox "I WIN"
end if
0
 
Surone1Commented:
if myrange = left("The quick brown fox jumped over the lazy programmer.",3) then
msgbox "I WIN"
end if
0
 
Surone1Commented:
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
eshurakAuthor Commented:
Let me put this into context as it's not as simple as you think.  I'm looping through my document searching for words that start with caps.  I want to do something with the words that are not the first word in a sentence.  Lets also say the document is forty pages just to give it some scope.
With searchrange.find
.text = "<[A_Z]"
.MatchWildcards = true
.forward = true
end with

Do while searchrange.find.execute

if not first word in sentence then

debug.print searchrange.text

end if

loop

Open in new window

0
 
aikimarkCommented:
A bit more detail will be helpful.  Your problem description uses a variable (MyRange) that might lead us to believe that it is a word object, rather than a string variable.  Are you describing a selected word in the document?

============
The problem we face will be distinguishing multiple words in the sentence might be identical to the first word in the sentence.  In the example below, I had selected the first word in the sentence in the document and then typed the question marked statements into the Immediate Window.  

How are you iterating the document content?
The SentLoop() routine iterates through the sentences in the document and prints the first "word" in each sentence in the Immediate Window.

NOTE: In MS-Word, a "word" includes the trailing space.
?selection
The 

?selection.Sentences(1)
The quick brown fox jumped over The lazy programmer.  

?selection.Sentences(1).Words(1)
The 


?selection.Sentences(1).Words(7)
The 

===================
Public Sub SentLoop()
  Dim oSent As Range
  For Each oSent In ActiveDocument.Sentences
    Debug.Print oSent.Words(1)
  Next
End Sub

Open in new window

0
 
eshurakAuthor Commented:
Hey aikimark - Thanks for your reply see my second post above for the details.
0
 
aikimarkCommented:
This might work.  If you comment the IF and EndIF statements, you will see all the capitalized words, not just those that occur other than the first word.
Option Explicit

Public Sub NotFirstWordCaps()
  Dim searchrange As Range
  Set searchrange = ActiveDocument.Range
  With searchrange.Find
    .Text = "<[A-Z]*[ .,\?]"
    .MatchWildcards = True
    .Forward = True
    .MatchWholeWord = True
  End With
  
  Do While searchrange.Find.Execute
    If searchrange.Start <> searchrange.Sentences(1).Words(1).Start Then
      Debug.Print searchrange.Text, searchrange.Start, searchrange.Sentences(1).Words(1).Start
    End If
  Loop

End Sub

Open in new window

0
 
aikimarkCommented:
For the following document text:
"Now is the Time for all good men to come to the aid of their country.  The quick brown fox jumped over The lazy programmer.  The good the bad the UGLY."

The commented version of the code produces the following lines:

Now            0             0 
Time           11            0 
The            71            71 
The            103           71 
The            125           125 
UGLY.          146           125 

Open in new window

0
 
GrahamSkanCommented:
This should answer the original question.
Function IsFirstWord(rng As Range) As Boolean
    Dim sen As Range
    Dim wrd As Range
    
    Set sen = rng.Sentences(1)
    Set wrd = sen.words(1)
    IsFirstWord = rng.InRange(wrd)
End Function

Open in new window

0
 
JohnBPriceCommented:
Word already has built in sentence parsing, try this



Sub showSentences()
For i = 1 To ActiveDocument.Sentences.Count
    MsgBox ActiveDocument.Sentences(i)
Next

End Sub

Open in new window

0
 
JohnBPriceCommented:
oops, GrahamSkan beat me to it.
0
 
aikimarkCommented:
@Graham & JohnB

Please try your code with sentences containing the same word in BOTH the first and non-first position in a sentence.  Neither of your routines is able to discriminate between the first and non-first words.
0
 
JohnBPriceCommented:
erm, the first word is the first word in the sentence.  This, for example, makes every non-first word bold.


Sub showSentences()
For i = 1 To ActiveDocument.Sentences.Count
    For w = 1 To ActiveDocument.Sentences(i).Words.Count
        MsgBox ActiveDocument.Sentences(i).Words(w)
        If w > 1 Then
            ActiveDocument.Sentences(i).Words(w).Bold = True
        End If
    Next
    
Next

End Sub

Open in new window

0
 
GrahamSkanCommented:
aikimark,

The function works in my tests.
0
 
aikimarkCommented:
@JohnBPrice

Your code is significantly different than what you posted previously.  While it does format (bold) the non-first words in every sentence, it does not handle the scenario posed in the question.  The member is iterating a FIND.EXECUTE method, looking for capitalized words and taking some action if the word is not the first word in the sentence.  You are iterating through all words in all sentences.

Performance tip: Use a For Each...Next looping construction when iterating across collections rather than a regular For...Next loop.  Use a different variable (boolean or long integer) as the basis for programmatic action, such as skipping the first item in a collection.

===============
@GrahamSkan

Your code should return a false positive on the second of my three test sentences:

"The quick brown fox jumped over The lazy programmer."

If passed the word "The"
0
 
GrahamSkanCommented:
It isn't passed text, it is passed a range.
0
 
aikimarkCommented:
@GrahamSkan

I stand corrected.  I had misread the code and not recognized the InRange() method as the equivalent to Excel VBA's Intersect() method.  Both of our methods use the starting position of the word in their calculations.  My rudimentary tests indicate that their performance is practically identical.

Here is the version of my routine, using the InRange() method, that I used for my testing.
Option Explicit

Public Sub NotFirstWordCaps()
  Dim searchrange As Range
  Set searchrange = ActiveDocument.Range
  With searchrange.Find
    .Text = "<[A-Z]*[ .,\?]"
    .MatchWildcards = True
    .Forward = True
    .MatchWholeWord = True
  End With
  Dim sngStart As Single
  sngStart = Timer
  Do While searchrange.Find.Execute
    If searchrange.InRange(searchrange.Sentences(1).Words(1)) Then
      Debug.Print searchrange.Text, searchrange.Start, searchrange.Sentences(1).Words(1).Start
    End If
  Loop
  Debug.Print "Elapsed ", Timer - sngStart
End Sub

Open in new window

0
 
GrahamSkanCommented:
I would plug it in to a find loop like this.
Sub FindCapWords()
Dim rng As Range
Set rng = ActiveDocument.Range

With rng.Find
    .MatchWildcards = True
    .Text = "<[A-Z][a-z]{1,}>"
    Do While .Execute
        If Not IsFirstWord(rng) Then
            MsgBox "Propercase word: " & rng.Text & " found"
        End If
        rng.Collapse wdCollapseEnd
        rng.End = ActiveDocument.Range.End
    Loop
End With
End Sub

Function IsFirstWord(rng As Range) As Boolean
    Dim sen As Range
    Dim wrd As Range
    
    Set sen = rng.Sentences(1)
    Set wrd = sen.words(1)
    IsFirstWord = rng.InRange(wrd)
End Function

Open in new window

0
 
eshurakAuthor Commented:
Thank you all so much.
0
 
eshurakAuthor Commented:
Aikimark, I'd love to understand the second half of

.Text = "<[A-Z]*[ .,\?]"

specifically what's happening after the *
0
 
aikimarkCommented:
>>specifically what's happening after the *

It is looking for the word terminator, following the capitalized word.  It isn't perfect.

==============
GrahamSkan uses a different search string to find capitalized words (a cap letter followed by at least one lower case letter, bounded by the end of the word).
    .Text = "<[A-Z][a-z]{1,}>"

Note: If a word is all caps, the string won't be found.  However, it does have the advantage of not including the word-terminating character.

==============
@GrahamSkan

If packaging the IsFirstWord() code as a function, I would eliminate the variable declarations as a stream-lining method.

Example:

Function IsFirstWord(rng As Range) As Boolean
    IsFirstWord = rng.InRange(rng.Sentences(1).words(1))
End Function

Open in new window

0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 4
  • 4
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now