none
Help.. range.find to find a word in a paragraph,then delete found word to the end of a paragraph. RRS feed

  • Question

  • 

    Word 2007 VBA (Added code at the bottom)

    I have a word document where > 90% of the paragraphs contain the word "Unique".  For each instance the word "Unique" is found, i want to delete the found word to the end of the paragraph. 

    **********************

     An example of the text would be (Understand that the example appears as single sentances, but my data is actually paragraphs):

    1.  Access the system.  Unique ID ####  (Phase 1)

    Note:  This section discusses how the system will.........................    Unique ID ####   (Phase 1)

            1.1  The system shall........   Unique ID #### (Phase 2)

            1.2  The system shall require......... Unique ID ####  (Phase1)

    *************************

    With my example, a document may be 250 -300 pages, so a lot of instances will be found when a search is performed.

    I  cant use fixed values to extend a range because the part i need to delete may go for two sentenances. 

    Primarily i have tried to utilize the range.find to perform my search, then range.setrange to extend to the end of the paragraph.  However i have two issues with my code. 

    1.  the code gets hung up when running because when it gets to the end of the document, the .paragraphs(i).count gets hung in a loop.

    2.  when it deletes the data thats found, it also deletes the outline number of the next paragraph and then all the individual paragraphs tend to run together.  Whats odd is that if i highlight the data, but not delete, then it doesnt highlight the outline number of the next paragraph.

    3.  I realize there are .paragraphs, .listparagraphs, ranges, and methods.  I would prefer to just use range/collections but i couldnt figure out how to refer to the paragraph, from within my search finds a word, using the range.find.  Although the range.find returns a range, i couldnt figure out how to use range.parent to give me the paragraph data.  All i have found was the extend or .setrange method.

    any help is appreciated.

    Thanks Wayne

    Sub FindWordToEndOfParagraph1()
        Dim rngWordFind As Range, l As Long
        For l = 1 To ActiveDocument.Paragraphs.Count
            Set rngWordFind = ActiveDocument.Paragraphs(l).Range
            rngWordFind.Find.Execute FindText:="Unique", Forward:=True, MatchCase:=True    
            If rngWordFind.Find.Found = True Then
                rngWodFind.SetRange Start:=rngWordFind.Start, End:=ActiveDocument.Paragraphs(l).Range.Endr
                rngWordFind.Delete
            End If
        Next l
    End Sub

    Wednesday, May 9, 2012 1:51 PM

Answers

  • Why use code?

    Try a wildcards Find and Replace.

    In the "Find and Replace" dialogue, on the "Replace" tab, check "Use wildcards"

    Then, in the "Find what:" field, type:

         Unique*(^13)

    Followed by

         \1

    in the "Replace with:" filed.

    Done!

    (Basically, you are telling Word to find each instance of the word "Unique" followed by any characters "*" up to a paragraph mark "(^13)". The brackets tell Word that this is a range you want to which you want to refer in the Replace field. And we do just that with "\1" which is a reference to the first set of brackets in the Find field (in this case we have only one, but you could have many...)

    • Marked as answer by Wayne Hilburn Wednesday, May 9, 2012 3:03 PM
    • Unmarked as answer by Wayne Hilburn Wednesday, May 9, 2012 3:03 PM
    • Marked as answer by Wayne Hilburn Wednesday, May 9, 2012 3:04 PM
    Wednesday, May 9, 2012 2:37 PM
  • I am nt sure what oyu mean by

    "
    However, If i could identify/extend ranges of text, i could perform multiple actions one time and only from word and then as i write the text to excel, it would all occur at once.
    "

    In any case, try this version:

    Dim SearchWord As String
    Dim rgeDoc As Range
    Dim rgeFound As Range
    
    Set rgeDoc = ActiveDocument.Content
    SearchWord = "Unique"
    
    With rgeDoc.Find
        .ClearFormatting
        .Text = SearchWord & "*(^13)"
        .Wrap = wdFindStop
        .MatchWildcards = True
        Do While .Execute
            'Do something to found text....
            Set rgeFound = .Parent.Duplicate
            With rgeFound
                .HighlightColorIndex = 3
                'Remove ¶ from range so as to preserve it
                .MoveEnd wdCharacter, -1
                .Delete
            End With
            'Reset Range.Find
            rgeDoc.Collapse wdCollapseEnd
        Loop
        
    End With
    I just use the .Find function and handle the replacement by code...

    • Marked as answer by Wayne Hilburn Thursday, May 10, 2012 2:54 PM
    Thursday, May 10, 2012 2:17 PM

All replies

  • Why use code?

    Try a wildcards Find and Replace.

    In the "Find and Replace" dialogue, on the "Replace" tab, check "Use wildcards"

    Then, in the "Find what:" field, type:

         Unique*(^13)

    Followed by

         \1

    in the "Replace with:" filed.

    Done!

    (Basically, you are telling Word to find each instance of the word "Unique" followed by any characters "*" up to a paragraph mark "(^13)". The brackets tell Word that this is a range you want to which you want to refer in the Replace field. And we do just that with "\1" which is a reference to the first set of brackets in the Find field (in this case we have only one, but you could have many...)

    • Marked as answer by Wayne Hilburn Wednesday, May 9, 2012 3:03 PM
    • Unmarked as answer by Wayne Hilburn Wednesday, May 9, 2012 3:03 PM
    • Marked as answer by Wayne Hilburn Wednesday, May 9, 2012 3:04 PM
    Wednesday, May 9, 2012 2:37 PM
  • Thanks Jean-Guy,

    That worked as advertised!

    I considered your answer the answer to my solution, but when i selected "mark as answer", it deleted my reply, so thats why you see "mark", "unmark", etc...

    for 99% of the purpose i need it for, it is recorded into a Macro so i dont have to try and remember any settings.

    For the other 1%, i would like to figure out how to solve the original answer.  The function i perform is to use code within Word to create an excel workbook, then i write data to different columns, depending on outline levels and such.  Afterwards, i have to use Arrays and Mid() functions to identify if certain words are in a c.value and then perfrom other actions.

    However, If i could identify/extend ranges of text, i could perform multiple actions one time and only from word and then as i write the text to excel, it would all occur at once. 

    i supplied the recorded code.  Is there a way to add a little code to return the data that will be deleted? Prior to deletion?

    thanks again,

    Wayne

    Sub DeleteFromWordToEndOfParagraph()
        Dim SearchWord As String
        SearchWord = "Unique"
        Selection.Find.ClearFormatting
        Selection.Find.Replacement.ClearFormatting
        With Selection.Find
            .Text = SearchWord & "*(^13)"
            .Replacement.Text = "\1"
            .Forward = True
            .Wrap = wdFindContinue
            .Format = False
            .MatchCase = False
            .MatchWholeWord = False
            .MatchAllWordForms = False
            .MatchSoundsLike = False
            .MatchWildcards = True
        End With
        Selection.Find.Execute Replace:=wdReplaceAll
    End Sub

    Wednesday, May 9, 2012 3:27 PM
  • I am nt sure what oyu mean by

    "
    However, If i could identify/extend ranges of text, i could perform multiple actions one time and only from word and then as i write the text to excel, it would all occur at once.
    "

    In any case, try this version:

    Dim SearchWord As String
    Dim rgeDoc As Range
    Dim rgeFound As Range
    
    Set rgeDoc = ActiveDocument.Content
    SearchWord = "Unique"
    
    With rgeDoc.Find
        .ClearFormatting
        .Text = SearchWord & "*(^13)"
        .Wrap = wdFindStop
        .MatchWildcards = True
        Do While .Execute
            'Do something to found text....
            Set rgeFound = .Parent.Duplicate
            With rgeFound
                .HighlightColorIndex = 3
                'Remove ¶ from range so as to preserve it
                .MoveEnd wdCharacter, -1
                .Delete
            End With
            'Reset Range.Find
            rgeDoc.Collapse wdCollapseEnd
        Loop
        
    End With
    I just use the .Find function and handle the replacement by code...

    • Marked as answer by Wayne Hilburn Thursday, May 10, 2012 2:54 PM
    Thursday, May 10, 2012 2:17 PM
  • Again, Jean-Guy, you came through!

    I was unaware of exactly how the .find method worked.  So with the combination of the various (.wrap = wdFindStop property, the .parent.duplicate property, and the .Collapse method) code, i was able to assign the range of text to a variable.  Now i can apply it to various "parts" of a paragraph and make my work alot easier.

    a little further explanation of how the macro will be used:

    we use documents that contain outlined/non-outlined data that are requirments that have to be decomposed into excel spread sheets for testing system implementation as it is traced back to functional user's requirements.

    We use the spreadsheets to create traceability and manage the development of our test profiles to functional user roles to requirments.

    We still want to use the word document because it is a little more pleasing to the eye and when viewed in outline form, we can collapse/expand whole sections. 

    because we so quickly become familiar with the breakdowns and sections of the requirments document, its easier to the eye to remove the unique id's and user roles from the document.  at this point we are only concerned with how the developer will decompose the requirment into a system requirement.

    So, because i create a (word)outline-to-(excel)multiple column approach, i can now further parse a paragraph into the 4 pieces of data that it contains:  Requirement Number, Requirement Text, Unique Database ID, and All the user roles associated; all from word in one operation.  This method will allow me to make the process agnostic to any specific project, and I can use a templated document that is generic with a push-button process so that the user of the macro would only have to select a file, then i will perform the process by creating a new .docx document that is parsed, a new .xlsx doc that is ready for analysis, and still maintain the original .docx that has been read-only. 

    BTW, When i ran the two methods YOU provided, it reduced one of the documents from 330 pages down to 163.  That certainly makes it easier on the eyes.

    Thanks Again!

    Wayne

    Thursday, May 10, 2012 3:15 PM