Repetitive search in VB (Word) - vba

I have written a macro in Word to convert US spellings to UK. In summary, it looks like this:
US_spelling = analyze
UK-spelling = analyse
Call Spell_change (US_spelling, UK_spelling)
The Spell_change sub changes the spelling, adds a comment to the document, and adds 1 to a counter.
I repeat the above three lines, i.e. call the Spell_change sub, about 140 times (for 'program', 'dialog' etc).
Is there a more efficient way of doing this?
Many thanks.

Since you've changed the tag to refer to VBA, perhaps:
Sub Demo()
Application.ScreenUpdating = False
Dim StrFnd As String, StrRep As String, i As Long, Cmt As Comment, StrOut As String
StrFnd = "analyze,color,labor"
StrRep = "analyse,colour,labour"
StrOut = "US_spelling" & vbTab & "UK_spelling"
With ActiveDocument
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = True
For i = 0 To UBound(Split(StrFnd, ","))
.Text = Split(StrFnd, ",")(i)
.Replacement.Text = Split(StrRep, ",")(i)
.Execute Replace:=wdReplaceAll
If .Found = True Then StrOut = StrOut & vbCr & Split(StrFnd, ",")(i) & vbTab & Split(StrRep, ",")(i)
Next
End With
Set Cmt = .Comments.Add(Range:=.Range(0, 0), Text:=StrOut & vbCr & "Total: " & UBound(Split(StrOut, vbCr)))
With Cmt
.Author = ""
With .Range.Paragraphs
.First.Range.Font.Bold = True
.Last.Range.Font.Bold = True
End With
End With
End With
Application.ScreenUpdating = True
End Sub
The above code inserts a comment at the top of the document with a record of all words found & changed, plus a count of those words (but not how many times each word was replaced).

Related

Find first instance of the acronym

Any help would be awesome. I have a macro that finds acronyms and applies a spell out of the acronym with the acronym in parenthesis. It is applying the spell out and acronym once but randomly. I need the macro to identify the first instance and apply the spell out only to that first instance. So if the first instance should look like this:
Be Right Back (BRB) some text BRB some text BRB
Right know it looks like this: BRB some text Be Right Back (BRB) some text BRB
The macro has the code " .Execute Replace:=wdReplaceOne" but it doesn't seem to be working.
Here's the code I am using:
Sub AcronymManager()
Application.ScreenUpdating = False
Dim FRDoc As Document, FRList As String, j As Long, StrExp As String, StrAcc As String
'Load the strings from the reference doc into a text string to be used as an array.
Set FRDoc = ThisDocument
'Alternative code to use a different document the reference doc:
'Set FRDoc = Documents.Open("C:\Users" & Environ("UserName") & "\Documents\AcronymList.doc")
If ActiveDocument = FRDoc Then
MsgBox "Error: Cannot process this document - it's the source document", vbCritical
Exit Sub
End If
FRList = FRDoc.Range.Text
If FRDoc <> ThisDocument Then FRDoc.Close wdDoNotSaveChanges
Set FRDoc = Nothing
With ActiveDocument.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Replacement.Highlight = True
.MatchWholeWord = True
.MatchCase = True
.Wrap = wdFindContinue
'Process each word from the Check List. Tab-delimited strings are assumed, formatted as:
'Find text <Tab> Replace text
For j = 0 To UBound(Split(FRList, vbCr)) - 1
StrExp = Split(Split(FRList, vbCr)(j), vbTab)(0)
StrAcc = Split(Split(FRList, vbCr)(j), vbTab)(1)
.Text = StrExp
.Replacement.Text = StrAcc
.Execute Replace:=wdReplaceAll
.Text = "(" & StrAcc & ")"
.Execute Replace:=wdReplaceAll
.Text = StrAcc & "^w" & StrAcc
.Execute Replace:=wdReplaceAll
.Text = StrAcc
.Replacement.Text = StrExp & " (" & StrAcc & ")"
.Execute Replace:=wdReplaceOne
Next
End With
Application.ScreenUpdating = True
End Sub

(MSWord VBA) Add " symbol to search string

I'm trying to get a simple macro to work in MS word. The macro is supposed find a definition in contracts. These are typically marked within quotes (e.g. "Definition"). Hence, I want to select a word that I want to search the definition for and execute a search for the selected term in quotes. The makro should then just jump to the definition. (I'll add a part later to jump back to the reading positon, but that part works fine).
However, for some reason, I can't get it to work reliably. I've gone through the code debugging it, but the MySearchTrim variable ends up just containing
""selectiontest
This is what the variable content looks like
while I would need it to be
"selectiontest"
I've tried it with inserting the quotes by adding the quotes through
&"""
or through
"([" & ChrW(8220) & "-" & ChrW(8221) & _
"])" & MySearchTrim & "([" & ChrW(8220) & "-" & ChrW(8221) &"])"
but it only worked in 30% of the cases, which I find very confusing.
Can anyone help me spot the error?
Thanks!
Sub GehZuDefinition()
Dim MySearchterm
Dim MySearchTrim As String
Dim myWindow As Window
MySearchterm = Selection.Text
MySearchTrim = Chr(34) & Trim(MySearchterm) & Chr(34) ' trimming spaces after searchterm that are typically selected
Selection.Find.ClearFormatting
With Selection.Find
.Text = MySearchTrim
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = True
.MatchWholeWord = False
.MatchKashida = False
.MatchDiacritics = False
.MatchAlefHamza = False
.MatchControl = False
.MatchByte = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
End Sub
Your code only searches for terms in plain quotes. And, in any event can be both simplified and made more efficient. For example:
Sub GehZuDefinition()
Application.ScreenUpdating = False
Options.DefaultHighlightColorIndex = wdBrightGreen
With ActiveDocument.Range.Find
.ClearFormatting
.Text = """" & Trim(Selection.Text) & """"
.Replacement.Text = "^&"
.Replacement.Highlight = True
.Format = True
.Forward = True
.MatchCase = True
.MatchSoundsLike = False
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Application.ScreenUpdating = True
End Sub
Since you don't say what you want to do with the found terms, the above code simply highlights them in green.

Style to a variable in VBA

so i have this code, it replaces every X in the text with "Asunto (1,2,..): Expediente N°". I try to style this part of the code:
What i want is put that text that replaces the X in Arial 11 Bold
.Text = "Asunto" & " " & i & " " & "Expediente N°"
i tried this but the style applies to the whole document instead of just that text, i don´t know what else to try
Sub Macro1()
'
' Macro1 Macro
'
'
Application.ScreenUpdating = False
Dim i As Long
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "X"
.Replacement.Text = ""
.Format = False
.Forward = True
.Wrap = wdFindStop
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
i = i + 1
.Text = "Asunto" & " " & i & " " & "Expediente N°"
.Find.Execute
.Collapse wdCollapseEnd
.Find.Execute
Loop
With .Font
.Bold = True
.Name = "Arial"
.Size = 11
End With
Application.ScreenUpdating = True
MsgBox i & " Coincidencias."
End With
End Sub
You are NOT applying a Style - all you're doing is overriding whatever Style is already present with hard formatting. Do do with a Style, try for example:
Sub Demo()
Application.ScreenUpdating = False
Dim i As Long
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "X"
.Replacement.Text = ""
.Format = False
.Forward = True
.Wrap = wdFindStop
.MatchWildcards = True
End With
Do While .Find.Execute
i = i + 1
.Text = "Asunto" & " " & i & " " & "Expediente N°"
.Style = wdStyleStrong
.Collapse wdCollapseEnd
Loop
End With
Application.ScreenUpdating = True
MsgBox i & " instances found."
End Sub
In the above, I've employed Word's 'Strong' Style, via the constant wdStyleStrong. If your text is already 11pt Arial, that's all you need. Otherwise, you should define a suitable 11pt Arial Bold character Style and apply that.

Macro to Replace Pronouns with Conditional Merge Field

I need a macro that replaces his/her or he/she with a conditional merge field. Thanks to another website, I was able to replace these pronouns with a merge field, but not a conditional merge field without crashing MS Word. Below is the code that I used.
Sub TestAddIf()
Dim doc As Word.Document
Dim mRng As Range
Set doc = ActiveDocument
Set mRng = ActiveDocument.Range
With oRng.Find
Do While .Execute(FindText:="he")
doc.MailMerge.Fields.AddIf mRng, _
MERGEFIELD:="""Client_Sex""", Comparison:=wdMergeIfEqual, CompareTo:="M", _
truetext:="he", _
falsetext:="she"
mRng.Collapse wdCollapseEnd
Loop
End With
End Sub
Try the following macro, which deals with 'he', 'his', 'him', and 'male' throughout the document (delete the ',male' & ',female' terms if you don't want them).
Sub Demo()
Application.ScreenUpdating = False
Dim Rng As Range, RngFld As Range, StrFnd As String, StrRep As String, StrCode As String, i As Long, j As Long
StrM = "he,his,him,male": StrF = "she,her,her,female"
With ActiveDocument
For i = 0 To UBound(Split(StrM, ","))
StrCode = "IFX= ""M"" """ & Split(StrM, ",")(i) & """ """ & Split(StrF, ",")(i) & """"
j = Len(StrCode) + 4
Set Rng = .Range(0, 0)
.Fields.Add Range:=Rng, Type:=wdFieldEmpty, Text:=StrCode, PreserveFormatting:=False
Rng.End = Rng.End + j
.Fields.Add Range:=Rng.Characters(5), Type:=wdFieldEmpty, Text:="MERGEFIELD Client_Sex", PreserveFormatting:=False
Rng.Cut
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.MatchCase = False
.MatchWholeWord = True
.MatchWildcards = False
.Text = Split(StrM, ",")(i)
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceAll
End With
Next
End With
Application.ScreenUpdating = True
End Sub

Find, highlight and list count of instances of words found in document using VBA

I have a list of keywords that I need to search for in Word documents.
I made a script that searches the document and highlights all instances found, including matching all word forms (i.e. fix, fixed, fixing). After processing, a message box appears that is supposed to summarize the count of instances found for each word.
The problem is that although the highlighting routine allows for all word forms (.MatchAllWordForms = True), I'm missing something for the count, such that only exact matches are tallied.
Can you help me update this so that all words and word forms are both highlighted and summarized in the message box?
'
' Highlight Macro
Sub HighlightKeywords()
Dim range As range
Dim i As Long
Dim Keywords
' put list of terms to find here
Keywords = Array("wrong", "broke", "fix", "swap", "missing", "mistake", "revert", "oops", "backwards", "shatter", "drop")
For i = 0 To UBound(Keywords)
Set range = ActiveDocument.range
With range.Find
.Text = Keywords(i)
.Format = True
.MatchCase = True
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = True
Do While .Execute(Forward:=True) = True
range.HighlightColorIndex = wdYellow
Loop
End With
Next
ReDim numfound(0 To UBound(Keywords))
For Each wrd In ActiveDocument.Words
idx = 0
For Each var In Keywords
If Trim(wrd.Text) = Keywords(idx) Then
numfound(idx) = numfound(idx) + 1
End If
idx = idx + 1
Next var
Next wrd
idx = 0
For Each var In Keywords
strResults = strResults & Keywords(idx) & " : " & _
numfound(idx) & vbCr
idx = idx + 1
Next var
MsgBox strResults
End Sub
A message box has very limited output capacity. If you really want to go down that path, try:
Sub HighlightKeywords()
Application.ScreenUpdating = False
Dim i As Long, j As Long, Keywords, StrOut As String
' put list of terms to find here
Keywords = Array("wrong", "broke", "fix", "swap", "missing", "mistake", "revert", "oops", "backwards", "shatter", "drop")
For i = 0 To UBound(Keywords)
j = 0
With ActiveDocument.Range
With .Find
.Text = Keywords(i)
.Format = False
.MatchCase = True
.MatchAllWordForms = True
.MatchWildcards = False
.Forward = True
.Wrap = wdFindStop
.Execute
End With
Do While .Find.Found = True
j = j + 1
.Duplicate.HighlightColorIndex = wdYellow
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
StrOut = StrOut & vbCr & Keywords(i) & ": " & j
Next
Application.ScreenUpdating = True
MsgBox "Found the following:" & StrOut
End Sub