Solved

.net MS Word Interop - Find text and return a Word.Range

Posted on 2008-10-24
7
2,379 Views
Last Modified: 2012-05-05
What I'm trying to do is take Indentifiers that I type into a word doc and set bookmarks on them.

Say I have a Word Doc with the following text

"The Raven" is a narrative poem by the American <Goody> Edgar Allan Poe, first published in January 1845. It is noted for its musicality, <HereIAm> language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, <AnotherWord> the man's slow descent into madness. The lover, often identified as being a student,[1][2] is lamenting the loss of his love, Lenore. The raven, sitting on a bust of Pallas, seems to further instigate his distress with its constant repetition of the word, "Nevermore". Throughout the poem, Poe makes allusions to folklore and various classical works.

I Would like to use something like a Regex to find strings formated like <[SomeText]> and then create a bookmark over <[SomeText]>. IE, in the above paragraph I would create bookmarks fro <AnotherWord>, <Goody>, And <HereIAm>

To do this using Word, I would highlight the <[SomeText]> then goto Insert->Bookmark.

I believe I can figure out how to add the bookmark as long as I get can a Range object that covers the text range of the <[SomeText]> identifier. I've tried running a regex on the Word.Content.Text using Text.RegularExpression.Regex and I get find the matches but when I try to create a range from the starting index of the match and the index of the last character its not selecting the right text.

Another problem that I noticed, is if Word.Content.Text is used, it does not return text that is inside a head or footer. I will also need code that can find these identifiers within header and footer fields.

Thanks
0
Comment
Question by:joshkrak
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 22800453
Word has its own Find method which can use Wild Cards similar to Regular expressions.

It is a method of a Range (or Selection) object and will set the object to the found range.

This is a VBA snippet to set a series of bookmarks. I accepts text between the <> signs provided that is comprises letters or space characters.
    Dim doc As Word.Document
    Dim rng As Word.Range
    '...
    Set rng = doc.Range.Duplicate
    Dim i As Integer
    With rng.Find
        .Text = "\<[A-Za-z ]{1,}\>"
        .MatchWildcards = True
        Do While .Execute()
            i = i + 1
            doc.Bookmarks.Add "bmk" & i, rng
            rng.Collapse wdCollapseEnd
            rng.End = doc.Range.End
        Loop
    End With

Open in new window

0
 

Author Comment

by:joshkrak
ID: 22803750
Thank you for the help. Your solution does for for the most part but there are some problems

First, just so I'm clear, I'm not working inside of the Word app so its not just a macro I'm looking for. However, the interop dll supplied by microsoft to automate Word in .Net uses the same basic syntax and object naming so I was easily able to convert your solution.

The problems I still have are

1) The loop never advances. It just keeps returning the first identifier and loops indefinitely. I Did get around this by Changing the text in the found range to something that would not watch the RegEx so its not that big of a deal but just wanted to let you know.

2) This method does not find identifiers that are within Header or Footer fields. Goto View->Header and Footers then type some text and some indentifiers in there and try your script again. I MUST have it able to find and bookmark within the Header and Footers as well.


All in all though, I'm much further than I could have ever gotten on my own, so thank you for that. Just try to take a stab at the Header/Footer problem and we'll call it done.

-Josh
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 22804759
I do realise that you are not writing for a Word macro, but I don't have the application that you are using or the experience to write in the precise code that will work in your scenario, but I hope to provide enough for you to see how it is done and to apply it in your situation.

Given that, I am not sure why it is not working as designed. The intention is that, once an instance that matches the criteria has been found, the next search looks for another occurrence in the rest of the main part of the document.
Headers and Footers are not part of the main document range. They are displayed and - more important,ly -  printed around each page to which they apply.

Word has several separate range types, called Stories, and it is possible to step through the first of each :

Dim stry As Range
For Each stry In wdDoc.StoryRanges
'...
 
 
0
Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

 
LVL 76

Accepted Solution

by:
GrahamSkan earned 500 total points
ID: 22804792
Sorry - hit Submit too soon.
I actually prefer to walk through each document section, and through each header and/or footer within the section.
    Dim doc As Word.Document
    Dim rng As Word.Range
    Dim hdr As Word.HeaderFooter
    Dim ftr As Word.HeaderFooter
    Dim sec As Word.Section
    Dim i As Integer
    '...
    For Each sec In doc.Sections
        For Each hdr In sec.Headers
            Set rng = hdr.Range.Duplicate
            With rng.Find
                .Text = "\<[A-Za-z ]{1,}\>"
                .MatchWildcards = True
                '...
            End With
        Next hdr
        For Each ftr In sec.Footers
            Set rng = ftr.Range.Duplicate
            With ftr.Find
                .Text = "\<[A-Za-z ]{1,}\>"
                .MatchWildcards = True
                '...
            End With
        Next hdr
    Next sec

Open in new window

0
 

Author Comment

by:joshkrak
ID: 22804895
Lol, np, as soon as you said storys I was able to play around and get it working before your next post. My final solution in VB.NET is shown below.

Thanks again, GrahamSkan! Wish I could give ya more than 500.
                wordApp = New Word.ApplicationClass
                wordDoc = wordApp.Documents.Add(DirectCast(FullFileName, Object))
                Dim SearchStorys() As Word.WdStoryType = {Word.WdStoryType.wdFirstPageHeaderStory, Word.WdStoryType.wdMainTextStory, Word.WdStoryType.wdFirstPageFooterStory}
                For Each Story As Word.WdStoryType In SearchStorys
                    Dim Range As Word.Range = wordDoc.StoryRanges.Item(Story)
                    Dim i As Integer = 0
                    Range.Find.Text = "\<[A-Za-z0-9_]{1,}\>"
                    Range.Find.MatchWildcards = True
                    While Range.Find.Execute
                        Dim BmText As String = Range.Text.Trim(New Char() {"<"c, ">"c})
                        Range.Text = "<!" & BmText & "!>"
                        If Not Al.Contains(BmText) Then
                            Dim objRange As Object = Range
                            wordDoc.Bookmarks.Add(BmText, objRange)
                            Al.Add(BmText)
                        End If
                        Range.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
                        Range.End = wordDoc.Range.End
                    End While
                Next
                Dim objFullFileName As Object = FullFileName
                wordDoc.SaveAs(objFullFileName)

Open in new window

0
 

Author Closing Comment

by:joshkrak
ID: 31509739
Excellent expert advice! He definitely knows his shit!
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 22805059
That's excellent news. Thank you.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
I recently resolved a client's Office 2013 installation problem and wanted to offer an observation that may help you with troubleshooting similar issues. The client ordered three Dell Optiplex system units with the Windows 7 downgrade option inst…
This video walks the viewer through the process of creating Hyperlinks for the web and other documents. Select the "Insert" tab: Click "Hyperlink":  Type "http://" followed by a web address to reference a website or navigate to a document to ref…
The view will learn how to download and install SIMTOOLS and FORMLIST into Excel, how to use SIMTOOLS to generate a Monte Carlo simulation of 30 sales calls, and how to calculate the conditional probability based on the results of the Monte Carlo …

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question