Just as a foreword, I'm not much of a programmer. Just trying to band-aid a macro for a one off use.
Currently need to cycle through ~3700 lines in excel and find certain words in around ~100 word documents.
Basically line 1 needs to find the word "donkey" (cell A1) and searches the document listed in cell A4, then produces how many times the word was found and if greater than 2 times, marks the cell "YES".
My problem is, sometimes it will run to completion, sometimes when opening the next document I receive the error
Run-time error '91': Object variable or With block variable not set
Usually restarting excel or changing the file path of the documents being search fixes it for one or two runs. This makes me believe it has something to do with memory, but I'm unsure.
Any ideas what the issue is? Thanks!
Here's the code as-is, yes it's sloppy.
Sub FindName()
Dim wrdApp As Object
Dim wrdDoc As Object
Dim maxRowCount As Integer
Dim TP As String
Dim FindWord As String
Dim result As String
Dim RowCount As Integer
Dim i As Long
Dim iCount As Integer
TP = "003"
i = 115
maxRowCount = 140
On Error Resume Next
Set wrdApp = GetObject(, "Word.Application")
If Err.Number > 0 Then Set wrdApp = CreateObject("Word.Application")
On Error GoTo 0
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Open("C:\TP\X-" & TP & ".docx")
For i = i To maxRowCount
If Cells(i, 4).Text = TP Then
FindWord = Cells(i, 1).Text
'// Defines selection for Word's find function
wrdDoc.ActiveWindow.Selection.GoTo What:=wdGoToSection, Which:=wdGoToFirst
wrdDoc.SelectAllEditableRanges
iCount = 0
'// Word Find Method Setup Block
With wrdDoc.ActiveWindow.Selection.Find
.Text = FindWord
.Replacement.Text = ""
.Forward = True
.Wrap = 1 ' wdFindContinue (Word constant not defined in Excel)
.Format = False
.MatchCase = True
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
Do While wrdDoc.ActiveWindow.Selection.Find.Execute
iCount = iCount + 1
wrdDoc.ActiveWindow.Selection.MoveRight
' MsgBox iCount
Loop
End With
'// Unnecessary storing, I know
result = iCount
Cells(i, 6).Value = result
If result > 1 Then
Cells(i, 7).Value = "YES"
Else
Cells(i, 7).Value = "NO"
End If
Else
TP = Cells(i, 4).Text
FindWord = Cells(i, 1).Value
'// Close and don't save application
wrdApp.Quit SaveChanges:=0 ' wdDoNotSaveChanges (Word constant not defined in Excel)
Set wrdApp = Nothing
Set wrdDoc = Nothing
On Error Resume Next
Set wrdApp = GetObject(, "Word.Application")
If Err.Number > 0 Then Set wrdApp = CreateObject("Word.Application")
On Error GoTo 0
Set wrdDoc = wrdApp.Documents.Open("C:\TP\X-" & TP & ".docx")
'// Defines selection for Word's find function
wrdDoc.ActiveWindow.Selection.GoTo What:=wdGoToSection, Which:=wdGoToFirst
wrdDoc.SelectAllEditableRanges
iCount = 0
'// Word Find Method Setup Block
With wrdDoc.ActiveWindow.Selection.Find
.Text = FindWord
.Replacement.Text = ""
.Forward = True
.Wrap = 1 ' wdFindContinue (Word constant not defined in Excel)
.Format = False
.MatchCase = True
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
Do While wrdDoc.ActiveWindow.Selection.Find.Execute
iCount = iCount + 1
wrdDoc.ActiveWindow.Selection.MoveRight
Loop
End With
'// Unnecessary storing, I know
result = iCount
Cells(i, 6).Value = result
If result > 1 Then
Cells(i, 7).Value = "YES"
Else
Cells(i, 7).Value = "NO"
End If
End If
Next i
End Sub
Your syntax on the error line seems correct. You can:
- verify the filename by insrting a debug.print line to show the filename expression
- verify the Word instanciation by opening Word manually, removing the On error in your code, and running it again.
Related
I am using this code which is a batch find and replace macro. It finds and replaces the words in the document by reading the replacement words from another document (text.docx). This works absolutely fine when there are a handful of changes (i.e. less than 1 page). However, I hope to use this macro on documents that are 10-20 pages. When I use it, the word document just immediately crashes (starts not responding) and has to be forced to quit.
Does anyone have any tips on what can be done to prevent it from crashing? How can I modify the code to batch edit thousands of words? Code is below.
Thanks in advance!
Sub ReplaceFromTableList()
Dim oChanges As Document, oDoc As Document
Dim oTable As Table
Dim oRng As Range
Dim rFindText As Range, rReplacement As Range
Dim i As Long
Dim y As Integer
Dim sFname As String
Dim sAsk As String
sFname = "/Users/user/Desktop/test.docx"
Set oDoc = ActiveDocument
Set oChanges = Documents.Open(FileName:=sFname, Visible:=False)
Set oTable = oChanges.Tables(1)
y = 0
For i = 1 To oTable.Rows.Count
Set oRng = oDoc.Range
Set rFindText = oTable.Cell(i, 1).Range
rFindText.End = rFindText.End - 1
Set rReplacement = oTable.Cell(i, 2).Range
rReplacement.End = rReplacement.End - 1
With oRng.Find
.ClearFormatting
.Replacement.ClearFormatting
Do While .Execute(findText:=rFindText, _
MatchWholeWord:=True, _
MatchWildcards:=False, _
Forward:=True, _
Wrap:=wdFindStop) = True
oRng.Select
oRng.FormattedText = rReplacement.FormattedText
y = y + 1
Loop
End With
Next i
oChanges.Close wdDoNotSaveChanges
MsgBox (y & " errors fixed")
End Sub
Your use of the FormattedText method to reproduce the formatting necessitates a time-consuming loop for each expression. The more the find expression occurs in the target document, the longer the process will take. Your unnecessary use of oRng.Select (which you don't then do anything with) makes it even slower - especially since you don't disable ScreenUpdating. The following macro avoids the need for the FormattedText looping:
Sub BulkFindReplace()
Application.ScreenUpdating = False
Dim ThisDoc As Document, FRDoc As Document, Rng As Range, i As Long, j As Long, StrRep As String, StrCount As String
Set ThisDoc = ActiveDocument
Set FRDoc = Documents.Open("C:\Users\" & Environ("Username") & "\Downloads\FindReplaceTable.docx", _
ReadOnly:=True, AddToRecentFiles:=False, Visible:=False)
With ThisDoc.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Format = False
.Forward = True
.Wrap = wdFindContinue
'Process each word from the F/R Table
For i = 1 To FRDoc.Tables(1).Rows.Count
Set Rng = FRDoc.Tables(1).Rows(i).Cells(1).Range
Rng.End = Rng.End - 1
.Text = Rng
StrCount = StrCount & vbCr & Rng.Text & ":" & vbTab & _
(Len(ThisDoc.Range.Text) - Len(Replace(ThisDoc.Range, Rng.Text, ""))) / Len(Rng.Text)
Set Rng = FRDoc.Tables(1).Rows(i).Cells(2).Range
Rng.End = Rng.End - 1
With Rng
If Len(.Text) > 0 Then
.Copy
StrRep = "^c"
Else
StrRep = ""
End If
End With
.Replacement.Text = StrRep
.Execute Replace:=wdReplaceAll
If i Mod 20 = 0 Then DoEvents
Next
End With
FRDoc.Close False
MsgBox "The following strings were replaced:" & StrCount
Set Rng = Nothing: Set FRDoc = Nothing: Set ThisDoc = Nothing
Application.ScreenUpdating = True
End Sub
Try this:
Sub FindReplaceAll()
Dim MyDialog As FileDialog, GetStr(1 To 100) As String
'100 files is the maximum applying this code
On Error Resume Next
Set MyDialog = Application.FileDialog(msoFileDialogFilePicker)
With MyDialog
.Filters.Clear
.AllowMultiSelect = True
i = 1
If .Show = -1 Then
For Each stiSelectedItem In .SelectedItems
GetStr(i) = stiSelectedItem
i = i + 1
Next
i = i - 1
End If
Application.ScreenUpdating = False
For j = 1 To i Step 1
Set Doc = Documents.Open(FileName:=GetStr(j), Visible:=True)
Windows(GetStr(j)).Activate
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "Marriott International" 'Find What
.Replacement.Text = "Marriott" 'Replace With
.Forward = True
.Wrap = wdFindAsk
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
Application.Run macroname:="NEWMACROS"
ActiveDocument.Save
ActiveWindow.Close
Next
Application.ScreenUpdating = True
End With
MsgBox "operation end, please view", vbInformation
End Sub
The idea comes from here:
https://www.extendoffice.com/documents/word/1002-word-replace-multiple-files.html
I am writing a script that extract tables from Word file as copies it to a worksheet in Excel. However, the Word files I received do not have the same format and the tables I need are not always on the same page. Hence I cannot use the regular table index.
Each table is on a different page and only on that page there somewhere is a text string (may or may not be in the table itself) like 'material/material list'. What I'd like to do is scan each page of the Word document for a certain textstring and only if that string is present, use the corresponding table on that page. Is this possible and how would I go about this?
A complication of the inconsistent formatting is that on some pages, the data is not even in a table so for those files I'd like an alert if the trigger word is found on a page but no table is there.
Edited:
I have tried to redefine the range considered. My hope is that this is the easiest method; see where the keyword occurs and then use the first table after that. However this does not seem to work.
With ActiveDocument.Content.Find
.Text = "Equipment"
.Forward = True
.Execute
If .Found = True Then Set aRange = ActiveDocument.Range(Start:=0, End:=0)
End With
Edit:
I tried to combine the code from macropod with a vba in Excel that copies the table to the worksheet.
Sub LookForWordDocs()
Dim FolderName As String
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
On Error Resume Next
FolderName = .SelectedItems(1)
Err.Clear
On Error GoTo 0
End With
Dim sFoldPath As String: sFoldPath = FolderName ' Change the path. Ensure that your have "\" at the end of your path
Dim oFSO As New FileSystemObject ' Requires "Microsoft Scripting Runtime" reference
Dim oFile As File
' Loop to go through all files in specified folder
For Each oFile In oFSO.GetFolder(sFoldPath).Files
' Check if file is a word document. (Also added a check to ensure that we don't pick up a temp Word file)
If ((InStr(1, LCase(oFSO.GetExtensionName(oFile.Path)), "doc", vbTextCompare) > 0) Or _
(InStr(1, LCase(oFSO.GetExtensionName(oFile.Path)), "docx", vbTextCompare) > 0)) And _
(InStr(1, oFile.Name, "~$") = 0) And _
((InStr(1, oFile.Name, "k") = 1) Or (InStr(1, oFile.Name, "K") = 1)) Then
' Call the UDF to copy from word document
ImpTable oFile
End If
Next
End Sub
Sub ImpTable(ByVal oFile As File)
Dim oWdApp As New Word.Application
Dim oWdDoc As Word.Document
Dim oWdTable As Word.Table
Dim oWS As Excel.Worksheet
Dim lLastRow$, lLastColumn$
Dim s As String
s = "No correct table found"
With Excel.ThisWorkbook
Set oWS = Excel.Worksheets.Add
On Error Resume Next
oWS.Name = oFile.Name
On Error GoTo 0
Set sht = oWS.Range("A1")
Set oWdDoc = oWdApp.Documents.Open(oFile.Path)
oWdDoc.Activate
'Application.ScreenUpdating = False
Dim StrFnd As String, Rng As Word.Range, i As Long, j As Long
j = 0
StrFnd = "equipment"
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = StrFnd
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
End With
Do While .Find.Found
i = .Information(wdActiveEndAdjustedPageNumber)
Set Rng = Word.ActiveDocument.Goto(What:=wdGoToPage, Name:=i)
Set Rng = Rng.Goto(What:=wdGoToBookmark, Name:="\page")
If Rng.Tables.Count > 0 Then
With Rng.Tables(1)
Set oWdTable = Rng.Tables(1)
oWdTable.Range.Copy
sht.PasteSpecial xlPasteValues, xlPasteSpecialOperationNone
j = 1
End With
End If
.Start = Rng.End
.Find.Execute
Loop
End With
If j = 0 Then sht.Value = s
'Application.ScreenUpdating = True
oWdDoc.Close savechanges:=False
oWdApp.Quit
End With
Set oWS = Nothing
Set sht = Nothing
Set oWdDoc = Nothing
Set oWdTable = Nothing
Set Rng = Nothing
End Sub
For the first file, the code works fine. However on the second run I get a run-time error "The remote Server Machine does not Exist or is unavailable" on line
"Word.ActiveDocument.Range". I added a couple of qualifications for elements but this still did not solve the problem. Am I missing another line?
BTW When I place "Word" before ActiveDocument.Range the code does not work any more.
Since you've changed the text from 'material/material list' to 'Equipment', it's a bit hard to know quite what you want. Try something along the lines of:
Sub Demo()
Application.ScreenUpdating = False
Dim StrFnd As String, Rng As Range, i As Long
StrFnd = InputBox("What is the Text to Find")
If Trim(StrFnd) = "" Then Exit Sub
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = StrFnd
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = True
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
End With
Do While .Find.Found
i = .Information(wdActiveEndAdjustedPageNumber)
Set Rng = ActiveDocument.GoTo(What:=wdGoToPage, Name:=i)
Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\page")
If Rng.Tables.Count > 0 Then
MsgBox Chr(34) & StrFnd & Chr(34) & " and table found on page " & i & "."
With Rng.Tables(1)
'process this table
End With
Else
MsgBox Chr(34) & StrFnd & Chr(34) & " found on page " & i & " but no table."
End If
.Start = Rng.End
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
Note: the above code will test all pages on which the Find text is found.
Situation:
I am trying to search through a word document for Keyword/IDs contained in an excel, and add comments from the spreadsheet to the word document for every occurrence of the Keyword/IDs then save. The sample code I have runs through the list of Keyword/IDs, but only comments the first occurrence
Give:
The word file is located at C:\Test\ACBS.docx and the excel executing the VBA macro is located separately. In the Excel the search term variable “FindWord” is in column A , and the comment is the variable “CommentWord” in column B.
Problem:
How can I get this to search through the entire word document and comment each occurrence of the Keyword/IDs?
Code:
Sub Comments_Excel_to_Word()
'Author: Paul Keahey
'Date: 2017-10-30
'Name:Comments_Excel_to_Word
'Purpose: To bring in comments From Excel to Word.
'Comments: None
Dim objWord
Dim objDoc
Dim objSelection
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Open("C:\Test\ACBS.docx")
objWord.Visible = True
Set objSelection = objWord.Selection
Dim oRng As Word.range
Set oRng = objSelection.range
Set oScope = oRng.Duplicate
Dim oCol As New Collection
Dim FindWord As String
Dim CommentWord As String
Dim I As Integer
'initalize list of varables
For I = 2 To range("A1").End(xlDown).Row
FindWord = Sheet1.range("A" & I).Value
CommentWord = Sheet1.range("B" & I).Value
With oRng.Find
.Text = FindWord
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = True
.MatchSoundsLike = False
.MatchAllWordForms = False
Do While .Execute = True
If oRng.InRange(oScope) Then
On Error Resume Next
'MsgBox "oRng.InRange(oScope)"
oCol.Add oRng.Text, oRng.Text
On Error GoTo 0
oRng.Collapse wdCollapseEnd
Else
ActiveDocument.Comments.Add oRng, CommentWord
Exit Do
End If
Loop
End With
Next I
objDoc.Save
End Sub
I'm not sure I understand the Word component of this setup, but if you want to list all comments in your Excel file, you can use the script below to do that.
Sub ShowCommentsAllSheets()
'Update 20140508
Dim commrange As Range
Dim rng As Range
Dim ws As Worksheet
Dim newWs As Worksheet
Set newWs = Application.Worksheets.Add
newWs.Range("A1").Resize(1, 4).Value = Array("Sheet", "Address", "Value", "Comment")
Application.ScreenUpdating = False
On Error Resume Next
For Each ws In Application.ActiveWorkbook.Worksheets
Set commrange = ws.Cells.SpecialCells(xlCellTypeComments)
If Not commrange Is Nothing Then
i = newWs.Cells(Rows.Count, 1).End(xlUp).Row
For Each rng In commrange
i = i + 1
newWs.Cells(i, 1).Resize(1, 4).Value = Array(ws.Name, rng.Address, rng.Value, rng.Comment.Text)
Next
End If
Set commrange = Nothing
Next
newWs.Cells.WrapText = False
Application.ScreenUpdating = True
End Sub
I am trying to modify code from http://www.ozgrid.com/forum/showthread.php?t=174699
which looks in all word documents in a folder and returns an 'x' in columns if a searched value is found.
The column names are the documents in the folder. The row names are the searched strings.
I would like the routine to return rather a value or a string that is found in a word document to the right or next to the searched strings.
This would be a great tool to collect dates, invoice values, names etc. from unstructured data in word documents to excel table.
With oDOC.Content.Find
.ClearFormatting
.Text = rCell.Value
.MatchCase = False
.MatchWholeWord = False
.Execute
If .Found Then
'Sheet1.Cells(rCell.Row, lngCol).Value = "x" , returns an "x" if the word is found.
End If
End With
The complete code looks as follows:
Public Sub SearchDocs()
Dim oWRD As Object '** Word.Application
Dim oDOC As Object '** Word.Document
Dim oFound As Object '** Word.Range
Dim rCell As Excel.Range
Dim lngCol As Long
Dim strFile As String
On Error GoTo ErrHandler
Application.ScreenUpdating = False
lngCol = 1
'** Set oWRD = New Word.Application
Set oWRD = CreateObject("Word.Application")
oWRD.Visible = True
'// XL2007 specific
Sheet1.Range("B2:XFD100000").ClearContents
strFile = Dir$(Sheet1.Range("B1").Value & "\*.doc?")
lngCol = 2
'// loop matching files
Do While strFile <> vbNullString
'open
Set oDOC = oWRD.Documents.Open(Sheet1.Range("B1").Value & "\" & strFile)
With Sheet1.Cells(2, lngCol)
.Value = strFile
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 90
.EntireColumn.ColumnWidth = 3.35
End With
For Each rCell In Sheet1.Range("A3:A" & Range("A" & Rows.Count).End(xlUp).Row)
With oDOC.Content.Find
.ClearFormatting
.Text = rCell.Value
.MatchCase = False
.MatchWholeWord = False
.Forward = False
.Execute
If .Found Then
'Selection.Collapse wdCollapseEnd
'Selection.Expand wdWord
'Sheet1.Cells(rCell.Row, lngCol).Value = "x"
'Sheet1.Cells(rCell.Row, lngCol).Value = .Text
Sheet1.Cells(rCell.Row, lngCol).Value = .Parent.Selection.Text
End If
End With
Next
Application.ScreenUpdating = True
DoEvents
Application.ScreenUpdating = False
lngCol = lngCol + 1
oDOC.Close
'// get next file
strFile = Dir$()
Loop
MsgBox "Finshed...", vbInformation
ErrHandler:
Application.ScreenUpdating = True
oWRD.Application.Quit
End Sub
I am not able to find in the net, or figure out, how to return a range of the found text and then offset it to return the text/value to the right. I am aware that offset exists in vba excel. But how to offset the range of the found string and return the value found in this offset range to excel?
This approach might work. Start by initializing a Range object to the range you want to search
Set oFound = oDOC.Content
Then instead of With oDOC.Content.Find do
With oFound.Find
When .Found = True, oFound will be moved to the found text. You can then move oFound by 1 word with something like:
With oFound
.MoveEnd Unit:=wdWord, Count:=1
.MoveStart Unit:=wdWord, Count:=1
End With
You can adjust Unit and Count per your requirements. Depending on your needs the related range object methods MoveEndUntil, MoveEndWhile, MoveStartUntil and MoveStartWhile may give better functionality. Check out these and other Range.Move methods here.
Hope that helps
The credit goes to xidgel. Thanks so much. It works like a charm.
The edited code, according to xidgel's direction may be of help to others, let me paste it:
Public Sub SearchDocs()
Dim oWRD As Object '** Word.Application
Dim oDOC As Object '** Word.Document
Dim oFound As Object '** Word.Range
Dim rCell As Excel.Range
Dim lngCol As Long
Dim strFile As String
'On Error GoTo ErrHandler
Application.ScreenUpdating = False
lngCol = 1
'** Set oWRD = New Word.Application
Set oWRD = CreateObject("Word.Application")
oWRD.Visible = True
'// XL2007 specific
Sheet1.Range("B2:XFD100000").ClearContents
strFile = Dir$(Sheet1.Range("B1").Value & "\*.doc?")
lngCol = 2
'// loop matching files
Do While strFile <> vbNullString
'open
Set oDOC = oWRD.Documents.Open(Sheet1.Range("B1").Value & "\" & strFile)
Set oFound = oDOC.Content
With Sheet1.Cells(2, lngCol)
.Value = strFile
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 90
.EntireColumn.ColumnWidth = 3.35
End With
For Each rCell In Sheet1.Range("A3:A" & Range("A" & Rows.Count).End(xlUp).Row)
With oFound.Find 'With oDOC.Content.Find
Debug.Print rCell.Value
.ClearFormatting
.Text = rCell.Text
.MatchCase = False
.MatchWholeWord = False
.Forward = True
.MatchWildcards = True
.Wrap = wdFindContinue
.Execute
Debug.Print .Found
If .Found Then
With oFound
.Collapse wdCollapseEnd
.Expand wdWord
.MoveStart Unit:=wdWord, Count:=1
.MoveEnd Unit:=wdWord, Count:=5
End With
Sheet1.Cells(rCell.Row, lngCol).Value = oFound.Text
Debug.Print oFound.Text
End If
End With
Next
Application.ScreenUpdating = True
DoEvents
Application.ScreenUpdating = False
lngCol = lngCol + 1
oDOC.Close
'// get next file
strFile = Dir$()
Loop
MsgBox "Finshed...", vbInformation
ErrHandler:
Application.ScreenUpdating = True
oWRD.Application.Quit
End Sub
I am in the process of putting together a Word macro (below) that parses a table of acronyms in one Word document and highlights every occurrence of these acronyms in another Word document. This appears to be functional.
However, I would like to also have the macro differentiate acronyms that are in parentheses from those that are not. For example,
The soldier is considered Away Without Leave (AWOL). AWOL personnel are subject to arrest.
It seems as though the range "oRange" that defines the found acronym could be evaluated, if it is first expanded in the Do-While loop using this code:
oRange.SetRange Start:=oRange.Start - 1, End:=oRange.End + 1
However, none of my attempts to code a solution seem to work (they put the macro into an infinite loop or result in error messages). I'm fairly new to VBA programming and am obviously missing something regarding how the loops are operating.
My question is: is there a way to duplicate the range "oRange" for subsequent manipulation or is there some other method that I should be using?
Thanks for any assistance you can provide!
Sub HighlightAcronyms()
Dim wdDoc As Object
Dim wdFileName As Variant
Dim TableNo As Integer 'table number in Word
Dim oRow As Row
Dim oCell As Cell
Dim sCellText As String
Dim oDoc_Source As Document
Dim strListSep As String
Dim oRange As Range
Dim n As Long
Dim sCellExpanded As String
'Application.ScreenUpdating = False
strListSep = Application.International(wdListSeparator)
'*** Select acronym file and check that it contains one table
wdFileName = WordApplicationGetOpenFileName("*.docx", True, True)
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set wdDoc = GetObject(wdFileName) 'open Word file
With wdDoc
TableNo = wdDoc.Tables.Count
If TableNo = 0 Then
MsgBox "The file """ & wdFileName & """ contains no tables.", _
vbExclamation, "Import Word Table"
ElseIf TableNo > 1 Then
MsgBox "The file """ & wdFileName & """ contains multiple tables.", _
vbExclamation, "Import Word Table"
End If
End With
'*** steps through acronym column
wdDoc.Tables(1).Cell(1, 1).Select
Selection.SelectColumn
For Each oCell In Selection.Cells
' Remove table cell markers from the text.
sCellText = Left$(oCell.Range, Len(oCell.Range) - 2)
sCellExpanded = "(" & sCellText & ")"
n = 1
'need to find foolproof method to select document for highlighting
Documents(2).Activate
Set oDoc_Source = ActiveDocument
With oDoc_Source
Set oRange = .Range
With oRange.Find
.Text = sCellText
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = True
.MatchWildcards = False
Do While .Execute
If n = 1 Then
oRange.HighlightColorIndex = wdGreen
Else
oRange.HighlightColorIndex = wdYellow
End If
'trying to add code here to expand oRange and compare it to sCellExpanded
n = n + 1
Loop
End With
End With
Next oCell
Set wdDoc = Nothing
End Sub
Try This
Define two ranges instead of merging the oRange.
See this sample code (TRIED AND TESTED)
Sub Sample()
Dim strSearch As String, sCellExpanded As String
Dim oRange As Range, newRange As Range
strSearch = "AWOL"
sCellExpanded = "(" & strSearch & ")"
Set oRange = ActiveDocument.Range
With oRange.Find
.ClearFormatting
.Text = strSearch
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
Do While .Execute
If n = 1 Then
oRange.HighlightColorIndex = wdGreen
Else
oRange.HighlightColorIndex = wdYellow
End If
'~~> To check if the found word is not the 1st word.
If oRange.Start <> 0 Then
Set newRange = ActiveDocument.Range(Start:=oRange.Start - 1, End:=oRange.End + 1)
If newRange.Text = sCellExpanded Then
'
'~~> Your code here
'
newRange.Underline = wdUnderlineDouble
End If
End If
n = n + 1
Loop
End With
End Sub
SNAPSHOT
Unable to upload image at the moment. imgur server is down at the moment.
You may see this link
http://wikisend.com/download/141816/untitled.png