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
Related
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
I am new to VBA. I want to search a Word document for all occurrences of the string "the", and select all the occurrences at once.
Currently, I have this code, which finds the string, but I need to run the subroutine over and over. And it doesn't select all occurrences at once.
Sub FindThe()
With Selection.Find
.ClearFormatting
.Text = "the"
.Execute Forward:=True
End With
End Sub
If I understood your question, you may use a code like this to make whatever format or change you want on the found pieces of text, at once:
Sub FindThe()
With ActiveDocument.Content.Find
.ClearFormatting
.Font.Bold = False 'Does not find a bold text
With .Replacement
.ClearFormatting
.Font.Bold = True 'Format in bold the found texts
.Font.Italic = True 'Format in italic the found texts
.Font.TextColor = wdColorGold 'Format color to Gold for the found texts
End With
'Replace all the ocurrences of "the" with "<<Found THE>>"
.Execute FindText:="the", ReplaceWith:="<<Found THE>>", _
Format:=True, Replace:=wdReplaceAll
End With
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 new to VBA for Word (have used it a fair bit in Excel). I am trying to organise large word documents that contain copied and pasted emails. I want to find the date/time of each email and copy and paste it to the top of the page. All lines containing the date start with "Date:" so it is easy enough to find them. I wrote a code to try and copy them to the tops of pages but it currently pastes all of the date lines to the top of the document. I can see why, I just can't work out how to change it.
What I will then be able to do is make the first line of each page into a heading which I can sort by.
My initial code is as follows:
Sub Copy_Dates_to_Top()
If Selection.StoryType <> wdMainTextStory Then
With ActiveDocument.ActiveWindow.View
.Type = wdPrintView
.SeekView = wdSeekMainDocument
End With
End If
Selection.HomeKey Unit:=wdStory
With Selection.Find
.Text = "Date: "
.Format = False
.Forward = True
.MatchWildcards = False
.Wrap = wdFindStop
While .Execute
Selection.Expand Unit:=wdLine
Selection.Copy ' Unit:=wdLine
Selection.GoTo What:=wdGoToBookmark, Name:="\Page"
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.Paste
Wend
End With
End Sub
You can achieve this quite easily by applying a unique Style to the dates, then referencing that Style via a STYLEREF field in the page header. For example, the following macro employs Word's built-in 'Strong' character Style for this.
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "Date: [0-9]{1,2}/[0-9]{1,2}/[0-9]{4}"
.Replacement.Text = "^&"
.Forward = True
.Format = True
.Replacement.Style = "Strong"
.Wrap = wdFindContinue
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
.Fields.Add Range:=.Sections.First.Headers(wdHeaderFooterPrimary).Range, _
Type:=wdFieldEmpty, Text:="STYLEREF Strong", PreserveFormatting:=False
End With
Application.ScreenUpdating = True
End Sub
Word's 'Strong' Style applies bold formatting, which make the dates stand out more in the document body also.
Note: The macro assumes your dates are in either a d/m/y or m/d/y format; the Find expression could be changed to match a different date format.
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.