I need to automate formatting specific words at the end of each line in MS Word. Since I could not record a macro to do the job owing to limitations of Word macros, I have to post it here. All I need is to do the following:-
Check each line for a start of (
Start selecting the text inside parenthesis (including the parenthesis) till ) is found as end of a sentence
Format text to bold
Do this till the end of file
Exception: Don't format headings which are already bolded and underlined.
How could I do that? Or please rectify my code as it is doing nothing at all.
Sub m1()
'
' m1 Macro
'
'
Dim i As Integer
With Selection.Find
For i = 1 To lastRow
.Forward = True
.ClearFormatting
.MatchCase = False
.Wrap = wdFindContinue
.Execute FindText:="("
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Font.Bold = wdToggle
Selection.Font.BoldBi = wdToggle
Next
End With
End Sub
You might not need a macro is you know the Style of your document’s body text is always a certain designated style other than a Heading style. Setup your Find and Replace like this:
If the wildcard code is difficult to read from the screen clip it is: [(]*[)]
I finally succeeded in building this code:
Sub m1()
Selection.HomeKey Unit:=wdStory
With Selection.Find
Do While .Execute(FindText:="(", Forward:=True, MatchWildcards:=False) = True
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Font.Bold = wdToggle
Selection.Font.BoldBi = wdToggle
Selection.EndKey Unit:=wdLine
Loop
End With
End Sub
It Workded! :) Thanks for the support!
MS Word does not work with lines. The following VBA code will find paragraphs which end with parentheses and bold them together with the contents.
Sub Bold_ending_parentheses()
Dim par As Word.Paragraph
Dim str As String
Dim closes As Byte
Dim opens As Long
For Each par In ActiveDocument.Paragraphs
str = StrReverse(par.Range.Text)
closes = InStr(Left(str, 4), ")")
If closes Then
opens = InStr(str, "(")
If opens Then
With par.Range
.Find.Text = StrReverse(Mid(str, closes, opens - closes + 1))
Do
.Find.Execute
If .Find.Found Then .Font.Bold = True
Loop While .Find.Found
End With
End If
End If
Next
End Sub
EDIT:
An example of using Find and Replace. Using this, all the text in parentheses is bolded (not taking into account the requirement of being at the end of paragraph/line):
Sub ApplyBoldWithinParentheses()
With ActiveDocument.Content.Find
.ClearFormatting
.Text = "[(]*[)]"
.Replacement.Font.Bold = True
.Format = True
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
End Sub
Related
We have an array of documents to be formatted for better visibility.
As the output of our speech to text protocols we get a transcript.
The VBA script should format the text bold after every (return), and the text after a (:) not bold until the next return.
Example:
Speaker1 Question1: Answer Answer Answer
Speaker1 Question2: Answer Answer Answer
This is not working as expected already at the first part of the function.
Sub BoldGenerator()
' BoldGenerator Macro
Selection.WholeStory
'Make each .Method belong to Selection.Find for readability
With Selection.Find
'Set search criteria for break font
.Text = "^l"
'Find next occurrence
.Execute
Do While .Found
Selection.Text = Selection.Font.Bold = True
.Execute
Loop
End With
'
Call BoldGenerator
End Sub
This should bold everything between a (return) (actually it is a new line or a carriage return) and a colon (:)
It is not an easy VBA. Regular expressions are used which are not native in VBA, so we need to get them from VBScript library. We use regular expressions to find all instances starting after a carriage return and ending with a colon. Regular expressions are not able to change the format (to bold). So we need to use .Find method too. We again find what we previously found, but this time we make it bold.
You will see the first instance will not become bold, because it does not start after a carriage return.
Sub BoldGenerator()
Dim RE As Object
Dim REMatches As Object
Dim mch As Object
Selection.HomeKey wdStory
Selection.WholeStory
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = "\r(.+?:)"
End With
Set REMatches = RE.Execute(Selection.Text)
If REMatches.Count > 0 Then
Selection.HomeKey wdStory
With Selection.Find
.ClearFormatting
.Forward = True
.Format = False
.MatchCase = True
For Each mch In REMatches
.Text = mch
.Execute
Selection.Font.Bold = True
Selection.MoveRight wdCharacter
Next
End With
Selection.HomeKey wdStory
End If
Set RE = Nothing
Set REMatches = Nothing
Set mch = Nothing
End Sub
I want to highlight my client's name in some places in the document using a macro. There are some places where the name should be highlighted and some places where it should not.
I've tried moving around the wdNoHighlight code to different locations without any luck; wherever I seem to put it, I get the same result: the entire paragraph after the name is highlighted.
'''
ClientName = "Barry Allen"
Call HighlightName(ClientName)
Selection.TypeText Text:="Some more text after the client's name, which I don't want to be highlighted"
Selection.TypeParagraph
Selection.TypeText Text:="This text will not be highlighted"
Sub HighlightName(NametoHighlight)
Selection.MoveLeft Unit:=wdCharacter, Count:=Len(NametoHighlight),
Extend:=wdExtend
Options.DefaultHighlightColorIndex = wdYellow
Selection.Range.HighlightColorIndex = wdYellow
Selection.EndKey Unit:=wdStory
Options.DefaultHighlightColorIndex = wdNoHighlight
Selection.Range.HighlightColorIndex = wdNoHighlight
End Sub
'''
My code works when the name is in its own paragraph, but when the name is part of a paragraph, the entire paragraph that is after the name is highlighted, but I only want the name highlighted.
I found a way to make it work. You insert a paragraph and then backspace to get rid of the extra paragraph. Not the most elegant solution, but it does what I need it to do. The code I added to the bottom of the HighlightName Sub was:
Selection.TypeParagraph
Selection.TypeBackspace
If anyone has a more elegant solution, please let me know!
For instance:
Sub Demo()
Options.DefaultHighlightColorIndex = wdYellow
Const ClientName As String = "Barry Allen"
With Selection
.Text = "Some text before the client's name" & ClientName & " some more text after the client's name" & vbCr & "Next paragraph"
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = ClientName
.Replacement.Text = "^&"
.Replacement.Highlight = True
.Format = True
.MatchWildcards = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
End With
End Sub
I'm generating some security report in Microsoft Word - importing SOAP xml requests and responses...
I want to automate this process as much as I can and I need to highlight some text in these requests/responses. How to do that? In general I need to highlight non-standart inputs in requests (every time different - bad data types and so on) and fault strings in responses (in majority looks like this <faultstring>some error</faultstring>).
Heres code Im trying:
Sub BoldBetweenQuotes()
' base for a quotes finding macro
Dim blnSearchAgain As Boolean
' move to start of doc
Selection.HomeKey Unit:=wdStory
' start of loop
Do
' set up find of first of quote pair
With Selection.Find
.ClearFormatting
.Text = "<faultstring>"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Execute
End With
If Selection.Find.Found Then
Selection.MoveRight Unit:=wdCharacter, Count:=1
' switch on selection extend mode
Selection.Extend
' find second quote of this pair
Selection.Find.Text = "</faultstring>"
Selection.Find.Execute
If Selection.Find.Found Then
Selection.MoveLeft Unit:=wdCharacter, Count:=Len(Selection.Find.Text)
' make it bold
Selection.Font.Bold = True
Selection.Collapse Direction:=wdCollapseEnd
Selection.MoveRight Unit:=wdCharacter, Count:=1
blnSearchAgain = True
Else
blnSearchAgain = False
End If
Else
blnSearchAgain = False
End If
Loop While blnSearchAgain = True
End Sub
It highlights just the first faultstring, but other appearences stay unformated nad I dont know why.... Thanks for your reply.
The most efficient way to do this is to work with multiple Range objects. Think of a Range as being like an invisible selection, with the important difference that, while there can be but one Selection object there can be multiple Range objects in your code.
I've adapted your code, adding three Range objects: one for the entire document; one for finding the starting tag; one for finding the end tag. The Duplicate property is used to "copy" one Range from another (this due to an oddity in Word if you Set one Range to another, which links them).
For clarity I also added a couple more Boolean test values for your Ifcomparisons. In my experience, it's more reliable to pick up the "success" directly from Execute than to rely on Find.Found after-the-fact.
Sub BoldBetweenQuotes()
' base for a quotes finding macro
Dim blnSearchAgain As Boolean
Dim blnFindStart As Boolean
Dim blnFindEnd As Boolean
Dim rngFind As word.Range
Dim rngFindStart As word.Range
Dim rngFindEnd As word.Range
Set rngFind = ActiveDocument.content
Set rngFindStart = rngFind.Duplicate
Do
' set up find of first of quote pair
With rngFindStart.Find
.ClearFormatting
.Text = "<faultstring>"
.Replacement.Text = ""
.Forward = True
.wrap = wdFindStop
blnFindStart = .Execute
End With
If blnFindStart Then
rngFindStart.Collapse wdCollapseEnd
Set rngFindEnd = rngFindStart.Duplicate
rngFindEnd.Find.Text = "</faultstring>"
blnFindEnd = rngFindEnd.Find.Execute
If blnFindEnd Then
rngFindStart.End = rngFindEnd.Start
' make it bold
rngFindStart.Font.Bold = True
rngFindStart.Start = rngFindEnd.End
rngFindStart.End = rngFind.End
blnSearchAgain = True
Else
blnSearchAgain = False
End If
Else
blnSearchAgain = False
End If
Loop While blnSearchAgain = True
End Sub
My goal is to write a VBA Macro for Word 2003, where the user selects part of a table (especially a column), and the macro maps input characters to specific output characters, e.g. any of a e i o u become V; some sequences like eh uw become V; one character (exclamation mark) is deleted; anything not turned into "V" is turned into "C". My problem is that after the first replace, the selection gets "unset", so changes affect something other than the original selection.
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.MatchWildcards = True
.Replacement.Text = "V"
.Text = "[aeiouáéíóú]"
.Execute Replace:=wdReplaceAll
'replace certain sequences
.Text = "[mn" & ChrW(618) & ChrW(650) & "]" & ChrW(769)
.Execute Replace:=wdReplaceAll
.Text = "[mn]" & ChrW(768)
.Execute Replace:=wdReplaceAll
'delete !
.Text = "[\!]"
.Replacement.Text = ""
.Execute Replace:=wdReplaceAll
'everything else becomes C
.Text = "[!V]"
.Replacement.Text = "C"
.Execute Replace:=wdReplaceAll
End With
How do you get find/replace to only operate on the selected cells? I notice that after the first replace, Selection.End changes to the same value as Selection.Start. I do not understand how column selection works in Word.
I created some macros to facilitate this. This will start an answer on how to move around columns.
Sub GoToTop()
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument ' This takes the pointer to the body of the document ' place cursor the body of the document in case you are located on the header
Selection.EndKey Unit:=wdStory 'key ctrl end
Selection.HomeKey Unit:=wdStory 'key ctrl end
End Sub
Sub GoToColumnTable() 'place cursor inside of the first column
Selection.GoTo What:=wdGoToTable
End Sub
Sub ColumnMove() 'move from one column to the other one
Selection.Move Unit:=wdColumn, Count:=1
End Sub
Sub ColumnSelect() 'select the entire column in which the cursor is
Selection.SelectColumn
End Sub
Sub ColumnDelete() 'delete a column that was selected
Selection.Columns.Delete
End Sub
Every week I get a large MS Word file that needs some simple formatting. I need to look for a Bible book name on a line by itself and it ends with a carriage return and then concatenate this line with the next line. Like this:
I need to put my cursor at the end of "Gen." add a space and hit the delete key to make it look like this:
If "Gen." appears anywhere else in the document (other than the only text on the line) I need to leave it alone. I need to search each line of the entire document looking for 5 books, "Gen.", "Exo.", "Lev.", "Num.", "Deut." (in the end I will need to look for 66 books). I have been working on a VBA script (getting help from this site) to do this with no success. It seems like it should be relatively simple, but I have not been able to get it to work. My poor attempt is below. Any help would be greatly appreciated.
Public Sub ConCatVerses()
Selection.HomeKey Unit:=wdStory
For Each line_in_para In ActiveDocument.Paragraphs
text_in_line = line_in_para.Range.Text
If InStr(text_in_line, "Gen.") Then
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine
Selection.Delete Unit:=wdCharacter, Count:=1
Selection.TypeText Text:=" "
Selection.MoveDown Unit:=wdLine, Count:=1
End If
Next line_in_para
End Sub
Thanks for the help. I took your suggestion and added the other elements I needed. Hopefully someone will get some help from this working code. Now this one VBA script will go through the entire document and make the necessary changes.
Sub ConCatVerses1()
'
' Concatenate 2 lines
'
'
Dim myArray1, myArray2 As Variant
Dim x As Integer
myArray1 = Array("Gen.^p", "Exo.^p", "Lev.^p", "Num.^p", "Deut.^p")
myArray2 = Array("Gen. ", "Exo. ", "Lev. ", "Num. ", "Deut. ")
For x = LBound(myArray1) To UBound(myArray1)
BKNAMEF = myArray1(x)
BKNAMER = myArray2(x)
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = BKNAMEF
.Replacement.Text = BKNAMER
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
Next x
End Sub
You may actually not need any VBA. Try Finding "Gen.^p" and replace with "Gen. ". This should work. If Gen. line contains Gen. + " " (space) you may have to Find "Gen. ^p". ^p is the carriage return character. I placed quotes "" for you to understand the exact strings. You will need to remove it when you do Find Replace.