PDA

View Full Version : Finding a phrase in word, and pasting the word + context in a new document



justcracked
02-18-2015, 12:11 PM
Good afternoon

I have been searching the internet for a macro which does the following:


Searches the document I have open for a phrase
Copies this phrase, highlights it together with the unhighlighted context (say 20 characters either side) and pastes into column 'A' of a 2 column table created in new word document
Copies the page number that the above selection is on and pastes that into column 'B' (same row as above) of the above table in the same new document
This would then be repeated throughout the document for each instance of the phrase (creating a new line in the table of the new document for each instance)


I have been able to find some macros which enables parts of the above and then I stumbled upon this beautiful macro below (Credit: Mario Cancro)

Sub CopyKeywordPlusContext()
'
' Makro created on 22.01.2013
'
Dim SearchTerm As String, WordsAfter As Long, WordsBefore As Long, i As Long
Dim Rng As Range, Doc As Document, RngOut As Range
SearchTerm = InputBox("Enter your search terms, Maria Cancro!" & vbCr & _
"Then, sit back, relax, and let this macro do some heavy lifting." & vbCr & _
vbCr & "It's okay - it works out!")
SearchTerm = LCase(Trim(SearchTerm))
If Len(SearchTerm) = 0 Then Exit Sub
WordsBefore = InputBox("Enter the number of words before your search term to find.")
WordsAfter = InputBox("Enter the number of words after your search term to find.")
ActiveDocument.Range(0, 0).Select
With Selection
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = SearchTerm
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.Execute
End With
If .Find.Found Then
Set CurrentDoc = ActiveDocument
Set Doc = Documents.Add(Visible:=False)
Doc.Content.InsertAfter "Search results for """ & SearchTerm & """ + context in " & """" & CurrentDoc.Name & """"
Doc.Content.Font.Bold = True
Doc.Content.InsertParagraphAfter
Doc.Content.InsertParagraphAfter
Dim CheckAuto As Integer
CheckAuto = MsgBox("Should all findings be copied automatically ('yes') or do you want to check each occurence manually ('no') ?", vbYesNo, "Automatically oder manually?")
Dim CopyThis As Boolean
Do While .Find.Found
CopyThis = False
Set Rng = .Range.Duplicate
With Rng
.Select
Dim SelectionStart, SelectionEnd
SelectionStart = Selection.Range.Start
SelectionEnd = Selection.Range.End
ActiveDocument.Range(SelectionStart, SelectionStart).Select
Dim PageNumber, LineNumber As Integer
PageNumber = Selection.Information(wdActiveEndPageNumber)
LineNumber = Selection.Information(wdFirstCharacterLineNumber)
.MoveStart wdWord, -WordsBefore
.MoveEnd wdWord, WordsAfter + 2
.Select
Selection.MoveStart Unit:=wdLine, Count:=-1 'Comment this out if you
Selection.MoveEnd Unit:=wdLine, Count:=1 ' don't want the selection to be extended to the start / end of line
If CheckAuto = vbYes Then
CopyThis = True
Else
Dim Check As Integer
Check = MsgBox(.Text, vbYesNoCancel, "Copy this block?")
If Check = vbCancel Then
Exit Do
ElseIf Check = vbYes Then
CopyThis = True
End If
End If
If CopyThis = True Then
Selection.Copy
Doc.Activate
With Selection
.EndKey Unit:=wdStory
.Font.Bold = True
.Font.Underline = True
.Font.ColorIndex = wdDarkBlue
Call macrobutton(PageNumber, LineNumber, CurrentDoc.Name, SearchTerm)
.Font.Bold = True
.Font.Underline = False
.Font.ColorIndex = wdBlack
'.InsertAfter "S. " & PageNumber
'.InsertAfter ", Z. " & LineNumber
.TypeText "______________________________________________________________" & vbCr
.InsertParagraphAfter
.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove
.Paste
.InsertParagraphAfter
.InsertParagraphAfter
.MoveDown Unit:=wdLine, Count:=2, Extend:=wdMove
End With
CurrentDoc.Activate
End If
End With
.Collapse wdCollapseEnd
.Find.Execute
Loop
Doc.Activate
End If
End With
With Doc.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = SearchTerm
.Replacement.Text = "^&"
.Replacement.Highlight = True
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.Execute Replace:=wdReplaceAll
End With
Options.ButtonFieldClicks = 1
Selection.HomeKey Unit:=wdStory
ActiveWindow.Visible = True
End Sub


This lets me search for a word (via a prompt), specify how many characters before and after it to copy (via a prompt) and then pastes a highlighted version in a new document with a hyperlink to the occurrence in the original document. I wanted to maybe try and streamline this as follows if possible:

Instead of the first prompt asking which word I wanted to find; I would like it to use an excel spreadsheet (lets call it checklist) with a list of phrases on seperate lines in cloumn 'A' (example: nation wide) as a source
Instead of asking how many characters before and after: I would like it to be hard coded to be 20
Instead of asking if each occurrence is copied: I would like it to copy all occurrences

I don't know if this is possible, but was hoping that it was and would be grateful if someone could point me in the right direction, as I'm stumbling at getting the amendments to work.

Many thanks for looking at this post

Cheers

Pablo

gmaxey
02-18-2015, 04:07 PM
Well you didn't post Macrobutton so I have no idea what you are doing with that. I'll let you figure out the Excel part. For now I've just used a string array:


Sub CopyKeywordPlusContext()
'Modified 2-17-2015 GKM
'Makro created on 22.01.2013
Dim oDoc As Document, oDocRecord As Document
Dim strSearch As String, arrSearch() As String
Dim lngCharTrailing As Long, lngCharLeading As Long, lngIndex As Long, lngCount As Long
Dim lngPgNum, lngLineNum As Integer
Dim oRng As Word.Range, oRngSpan As Word.Range
Dim bFound As Boolean
Dim oTbl As Word.Table
strSearch = vbNullString
arrSearch = Split("Nationwide,Phrase 2,Phrase 3", ",")
lngCharLeading = 20
lngCharTrailing = 20
Set oDoc = ActiveDocument
For lngIndex = 0 To UBound(arrSearch)
ResetFRParams
bFound = False
lngCount = 0
Set oRng = oDoc.Range
With oRng.Find
.Text = LCase(arrSearch(lngIndex))
While .Execute
bFound = True
If oDocRecord Is Nothing Then
Set oDocRecord = Documents.Add
Set oTbl = oDocRecord.Tables.Add(oDocRecord.Range, 1, 2)
End If
lngCount = lngCount + 1
If lngCount = 1 Then
oTbl.Rows.Add
With oTbl.Rows.Last.Previous
.Cells.Merge
With .Cells(1).Range
.Text = "Search results for """ & arrSearch(lngIndex) & """ + context in " & """" & oDoc.Name & """"
.Font.Bold = True
End With
End With
End If
Set oRngSpan = oRng.Duplicate
oRngSpan.Select
lngPgNum = Selection.Information(wdActiveEndPageNumber)
lngLineNum = Selection.Information(wdFirstCharacterLineNumber)
With oRngSpan
.MoveStart wdCharacter, -lngCharLeading
.MoveEnd wdCharacter, lngCharTrailing
Do While oRngSpan.Characters.First = vbCr
oRngSpan.MoveStart wdCharacter, -1
Loop
Do While oRngSpan.Characters.Last = vbCr
oRngSpan.MoveEnd wdCharacter, 1
If oRngSpan.End = oDoc.Range.End Then
oRngSpan.End = oRngSpan.End - 1
Exit Do
End If
Loop
End With
oTbl.Rows.Last.Range.Cells(1).Range.Text = Trim(oRngSpan.Text)
oTbl.Rows.Last.Range.Cells(2).Range.Text = "Page: " & lngPgNum & " Line: " & lngLineNum
oTbl.Rows.Add
Wend
End With
If bFound Then
ResetFRParams
With oDocRecord.Range.Find
.Text = LCase(arrSearch(lngIndex))
.Replacement.Text = "^&"
.Replacement.Highlight = True
.Format = True
.Execute Replace:=wdReplaceAll
End With
End If
Next lngIndex
oTbl.Rows.Last.Delete
End Sub
Sub ResetFRParams()
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Replacement.Text = ""
.Replacement.Highlight = False
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
End With
lbl_Exit:
Exit Sub
End Sub

justcracked
02-19-2015, 10:16 AM
Well you didn't post Macrobutton so I have no idea what you are doing with that. I'll let you figure out the Excel part. For now I've just used a string array:


Apologies for that


[Sub macrobutton(Page, Line As Integer, Filename, SearchTerm As String)
'
' Makro created on 22.01.2013
'
Dim oField As Field, MyRange As Range
Set MyRange = Selection.Range
Set oField = Selection.Fields.Add(Range:=MyRange, Type:=wdFieldEmpty, Text:= _
"MACROBUTTON GoToAPageAndLine S. " & Page & ", Z. " & Line & "", PreserveFormatting:= _
False)
Set oRange = ActiveDocument.Range(oField.Code.Start + 1, oField.Code.Start + 1)
ActiveDocument.Fields.Add Range:=oRange, Type:=wdFieldPrivate, Text:="" & Filename & "|" & SearchTerm, PreserveFormatting:=False
End Sub

Does that aide you?

Many thanks for your help so far!!!!

gmaxey
02-19-2015, 04:04 PM
Well that creates a macrobutton field that runs another macro that you didn't post. It is hard to guess what you might or might not want.

justcracked
02-20-2015, 10:35 AM
Well that creates a macrobutton field that runs another macro that you didn't post. It is hard to guess what you might or might not want.

Again, many apoogies for this. It appears I'm on the rather stupid side :dunno



Hopefully this is what you were looking for originally. This (afaik) is what I should have posted originally


Sub GoToAPageAndLine() '
' Makro created on 22.01.2013
'
Dim TargetDocName, Searchterm, MyString As String, TargetDoc As Document
Dim PosDelimiter, PosMakroButton, Page, Line
'Read Private Field which contains The Document Name
MyString = Mid$(Selection.Fields(2).Code, 10)
MyString = Left$(MyString, Len(MyString) - 1)
PosDelimiter = InStr(MyString, "|")
TargetDocName = Left$(MyString, PosDelimiter - 1)
Searchterm = Mid$(MyString, PosDelimiter + 1)
'MsgBox TargetDocName
'Read the MakroButton Text which contains Page Number and Line
MyString = Mid$(Selection.Fields(1).Code, 1)
PosMakroButton = InStr(MyString, "MACROBUTTON")
MyString = Mid$(MyString, PosMakroButton + 32)
PosDelimiter = InStr(MyString, ", ")
Page = Left$(MyString, PosDelimiter - 1)
Line = Mid$(MyString, PosDelimiter + 4)
'MsgBox Page
'MsgBox Line
On Error GoTo Errhandler
Set TargetDoc = Documents(TargetDocName)
TargetDoc.Activate
Selection.GoTo What:=wdGoToPage, Which:=wdGoToAbsolute, Count:=Page, Name:=""
If Line - 1 > 0 Then
Selection.GoTo What:=wdGoToLine, Which:=wdGoToRelative, Count:=Line - 1, Name:=""
End If
If Searchterm <> "" Then
Selection.Find.ClearFormatting
With Selection.Find
.Text = Searchterm
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
End If
Errhandler:
Select Case Err
Case 4160: 'Error 4160 = Bad file name
MsgBox "The file """ & TargetDocName & """ isn't open. Please open the file first."
End Select
End Sub
Sub macrobutton(Page, Line As Integer, Filename, Searchterm As String)
'
' Makro created on 22.01.2013
'
Dim oField As Field, MyRange As Range
Set MyRange = Selection.Range
Set oField = Selection.Fields.Add(Range:=MyRange, Type:=wdFieldEmpty, Text:= _
"MACROBUTTON GoToAPageAndLine S. " & Page & ", Z. " & Line & "", PreserveFormatting:= _
False)
Set oRange = ActiveDocument.Range(oField.Code.Start + 1, oField.Code.Start + 1)
ActiveDocument.Fields.Add Range:=oRange, Type:=wdFieldPrivate, Text:="" & Filename & "|" & Searchterm, PreserveFormatting:=False
End Sub
Sub CopyKeywordPlusContext()
'
' Makro created on 22.01.2013
'
Dim Searchterm As String, WordsAfter As Long, WordsBefore As Long, i As Long
Dim Rng As Range, Doc As Document, RngOut As Range
Searchterm = InputBox("Enter your search terms, Maria Cancro!" & vbCr & _
"Then, sit back, relax, and let this macro do some heavy lifting." & vbCr & _
vbCr & "It's okay - it works out!")
Searchterm = LCase(Trim(Searchterm))
If Len(Searchterm) = 0 Then Exit Sub
WordsBefore = InputBox("Enter the number of words before your search term to find.")
WordsAfter = InputBox("Enter the number of words after your search term to find.")
ActiveDocument.Range(0, 0).Select
With Selection
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = Searchterm
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.Execute
End With
If .Find.Found Then
Set CurrentDoc = ActiveDocument
Set Doc = Documents.Add(Visible:=False)
Doc.Content.InsertAfter "Search results for """ & Searchterm & """ + context in " & """" & CurrentDoc.Name & """"
Doc.Content.Font.Bold = True
Doc.Content.InsertParagraphAfter
Doc.Content.InsertParagraphAfter
Dim CheckAuto As Integer
CheckAuto = MsgBox("Should all findings be copied automatically ('yes') or do you want to check each occurence manually ('no') ?", vbYesNo, "Automatically oder manually?")
Dim CopyThis As Boolean
Do While .Find.Found
CopyThis = False
Set Rng = .Range.Duplicate
With Rng
.Select
Dim SelectionStart, SelectionEnd
SelectionStart = Selection.Range.Start
SelectionEnd = Selection.Range.End
ActiveDocument.Range(SelectionStart, SelectionStart).Select
Dim PageNumber, LineNumber As Integer
PageNumber = Selection.Information(wdActiveEndPageNumber)
LineNumber = Selection.Information(wdFirstCharacterLineNumber)
.MoveStart wdWord, -WordsBefore
.MoveEnd wdWord, WordsAfter + 2
.Select
Selection.MoveStart Unit:=wdLine, Count:=-1 'Comment this out if you
Selection.MoveEnd Unit:=wdLine, Count:=1 ' don't want the selection to be extended to the start / end of line
If CheckAuto = vbYes Then
CopyThis = True
Else
Dim Check As Integer
Check = MsgBox(.Text, vbYesNoCancel, "Copy this block?")
If Check = vbCancel Then
Exit Do
ElseIf Check = vbYes Then
CopyThis = True
End If
End If
If CopyThis = True Then
Selection.Copy
Doc.Activate
With Selection
.EndKey Unit:=wdStory
.Font.Bold = True
.Font.Underline = True
.Font.ColorIndex = wdDarkBlue
Call macrobutton(PageNumber, LineNumber, CurrentDoc.Name, Searchterm)
.Font.Bold = True
.Font.Underline = False
.Font.ColorIndex = wdBlack
'.InsertAfter "S. " & PageNumber
'.InsertAfter ", Z. " & LineNumber
.TypeText "______________________________________________________________" & vbCr
.InsertParagraphAfter
.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove
.Paste
.InsertParagraphAfter
.InsertParagraphAfter
.MoveDown Unit:=wdLine, Count:=2, Extend:=wdMove
End With
CurrentDoc.Activate
End If
End With
.Collapse wdCollapseEnd
.Find.Execute
Loop
Doc.Activate
End If
End With
With Doc.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = Searchterm
.Replacement.Text = "^&"
.Replacement.Highlight = True
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.Execute Replace:=wdReplaceAll
End With
Options.ButtonFieldClicks = 1
Selection.HomeKey Unit:=wdStory
ActiveWindow.Visible = True
End Sub


Sorry for wasting your time Greg with erroneous info and many thanks for coming back to the thread.

The above macro lets me search for a word (via a prompt), specify how many characters before and after it to copy (via a prompt) and then pastes a highlighted version in a new document with a hyperlink to the occurrence in the original document.

Pablo

justcracked
02-20-2015, 12:39 PM
Ps: I used your code above and that is awesome work btw!!! :clap:

Though when I tried to paste a load of search arrays (approx 125) it wouldn't would not run. I'm assuming that it has to do with the amount of search functions.

Again, thanks for your help

gmaxey
02-20-2015, 12:54 PM
jc,

Instead of continuing to try to twist the original code to your will, what is the code I provided not doing that you want done. I've got a couple of paying jobs to tend to today so I won't be able to get back to this for a while.

justcracked
02-21-2015, 12:39 PM
jc,

Instead of continuing to try to twist the original code to your will, what is the code I provided not doing that you want done. I've got a couple of paying jobs to tend to today so I won't be able to get back to this for a while.

Hi Greg

Thanks for your reply and I understand your frustration. I was Just posting the code to show you what i was talking about. Your code worked beautifully and I thank you for that. I know you did me a huge favor with the code and i get that it was a freebie (i know the feeling, just in a different field). I'll try andsource how to extend the list of search words myself.

Again,many thanks for this code as it is totally awesome.


Thanks for your time.

Pablo