I am not familiar with Word VBA and am having a problem with Selection.Find.
I want to replace commas by decimal points in a range of cells in a table. However I can only get Selection.Find to replace either all commas in the document or only the first comma in the range.
What I would like is something like Selection.Replace What:=".", Replacement:="," in Excel, but Word does not support that.
Suggestions very gratefully received!
CJ
Sub Replace_Percent_Separator()
'Correct percent separator in row 6, table 2
Dim PcentCells As Range
Path = "C:\xxx\Word\"
file = Dir(Path & "*.docx")
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Do While file <> ""
Documents.Open Filename:=Path & file
With ActiveDocument
Set PcentCells = .Range(Start:=.Tables(2).Cell(6, 2).Range.Start, _
End:=.Tables(2).Cell(6, 10).Range.End)
PcentCells.Select
With Selection.Find
.Text = ","
.Replacement.Text = "."
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll '<-- replaces throughout document
'.Execute Replace:=wdReplaceOne '<-- replaces in first cell but no other cells
End With
End With
ActiveDocument.Save
ActiveDocument.Close
file = Dir()
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Given your problem description, your code can be reduced to:
Sub Replace_Percent_Separator()
'Correct percent separator in row 6, table 2
file = Dir("C:\xxx\Word\*.docx")
Do While file <> ""
Documents.Open FileName:=Path & file, AddToRecentFiles:=False, Visible:=False
With ActiveDocument
With .Tables(2).Row(6).Range.Find
.Text = ","
.Replacement.Text = "."
.Forward = True
.Wrap = wdFindStop
.Format = False
.Execute Replace:=wdReplaceAll
End With
.Close SaveChanges:=True
End With
file = Dir()
Loop
End Sub
As can be seen, there is no need to select anything and, by using wdFindStop instead of wdFindContinue, the Find/Replace stops where it should.
Related
I currently have code which can replace images individually, however I hope to use a loop so that I do not have hundreds of separate subs. I tried using a for loop to iterate through a file path which contains the photos I hope to update.
Sub ForLoop()
Dim sFigName As String
Dim sFigPath As String
' Change to the folder path for given park
sFigPath = "M:\JOBS\NPS\SEM Study\SEM (YR1) 2022\Final Reporting\1-PINN\Figure PNGs\"
' Change to marker text.
For i = 1 To Len(sFigPath)
Dim sMarkerText As String
sMarkerText = sFigPath(i)
' Search through document for marker text
Selection.Find.ClearFormatting
With Selection.Find
.Text = sMarkerText
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
While Selection.Find.Found
sFigName = Mid(Selection, 2, Len(Selection) - 2)
Selection.Delete
Selection.InlineShapes.AddPicture FileName:= _
sFigPath & sFigName, LinkToFile:=False, _
SaveWithDocument:=True
Selection.Find.Execute
Wend
With ActiveDocument.InlineShapes(i)
.AlternativeText = "Alternative Text for Figure " + i
End With
Next i
End Sub
I don't have much experience with VBA but I'm sure there is a better way to accomplish this. Thank you for any help you can give!
I'm trying to replace multiple "placeholders" in a single word document by breaking the text in my clipboard into various string.
Sample clipboard text would be something like this:
Placeholder1=
Test1
Placeholder2=
First sentence.
Second Sentence.
Third Sentence.
Placeholder3=
2044 to 2045
Placeholder4=
five
So far, I can take the text my clipboard and paste it to replace a single placeholder. I can also insert the date.
Here's what I have so far:
Sub FillPlaceHolder()
'Prints a new label in bottom left of sticker sheet based on clipboard data
'To use the clipboard you need a reference to the following library
'Go to Tools > References and select Microsoft Forms Object Library
'If it's not visible, click browse and find FM20.dll in your system32 folder
Dim DataObj As MSForms.DataObject
Set DataObj = New MSForms.DataObject
'Set error handling, will skip the code if the clipboard is empty
On Error GoTo Error
'Set variable for clipboard string
Dim myString As String
Dim myDate As Date
'Get data object from clipboard
DataObj.GetFromClipboard
'Set mystring to the first text in the clipboard
myString = DataObj.GetText(1)
myString = ClearFormatting
'Open the Word document
Documents.Open FileName:=GetFolder() & "Auden_perm_template.doc"
'Replaces the PlaceHolder text
With Selection.Find
.Text = "PLACEHOLDER2"
.Replacement.ClearFormatting
.Replacement.Text = myString
.Execute
End With
Selection.Paste
TodaysDate2
InsertDate
TodaysDate
InsertDate
'
'BELOW TO ADD PRINT
' Application.OnTime When:=Now + TimeValue("00:00:10"), Name:="Print_Label"
'Process this error for empty clipboards
Error:
If Err <> 0 Then MsgBox "Data on clipboard is empty"
End Sub
Sub TodaysDate2()
'
' Macro3Date Macro
'
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "TODAYSDATE2"
.Replacement.Text = "02/25/19"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.Find.Execute
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "TODAYSDATE2"
.Replacement.Text = "02/25/19"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
End Sub
Sub InsertDate()
'
' Macro3 Macro
'
'
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldDate
End Sub
Sub TodaysDate()
'
' Macro3Date Macro
'
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "TODAYSDATE"
.Replacement.Text = "02/25/19"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.Find.Execute
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "TODAYSDATE2"
.Replacement.Text = "02/25/19"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
End Sub
I'm struggling to figure out how to break the clipboard into multiple strings. What do you recommend?
You can break the string into an array using Split
For example:
myString = split(DataObj.GetText(1),vblf)
Change the Dim for myString from String to Variant
Then you can loop through the array with something like:
For X = lbound(myString) to ubound(myString)
If myString(X) = "PLACEHOLDER1" then
'Do Something when placeholder1 found
ElseIf myString(X) = "PLACEHOLDER2" then
'Do Something when placeholder2 found
ElseIf myString(X) = "PLACEHOLDER3" then
'Do Something when placeholder3 found
End IF
next
You will need to Dim X as a Long
You can set up a couple of variables to set the start and end of each placeholder then you can cycle through those parts joining each element back together with a vblf as the delimeter in order to create what you want.
I am trying to use a Word Macro to select all text with the style "Number_List" and call the .ConvertNumbersToText function on it. I am having trouble only finding the list or that specific style.
Dim selBkUp As Range
Set selBkUp = ActiveDocument.Range(ActiveDocument.Range.Start, ActiveDocument.Range.End)
With ActiveDocument.Range.Find
.Style = ActiveDocument.Styles("Number_List")
.Forward = True
.Wrap = wdFindContinue
Dim SearchSuccessful As Boolean
SearchSuccessful = .Execute
If SearchSuccessful Then
selBkUp.Select
Selection.Range.ListFormat.ConvertNumbersToText
Else
' code
End If
End With
I select the entire document and covert all of the lists numbers to text, but I am trying to only select ones with that specific style or avoid the other 5 styles that may or may not be present. Any help would be appreciated!
The following code will search for one style and, if found, will convert to another style. Below this code is another subroutine that will list all styles found in a document.
' From http://forums.codeguru.com/showthread.php?448185-Macro-to-Change-Styles-in-Word
' This code will search for a specified Style and convert that to another Style
Sub FindReplaceStyle()
Selection.HomeKey wdStory
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Style = "Normal" ' Look for 'Normal'
'.Text = ""
.Replacement.Style = "Heading 1" ' Change to 'Heading 1'
' .Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Do While Selection.Find.Execute()
If Selection.Start = Selection.Paragraphs.First.Range.Start Then
Selection.Style = "Heading 1"
End If
Selection.Collapse wdCollapseEnd
Loop
End Sub
The code below will produce a list of all styles found in a document.
Also, I get an error trying to use your "Number_List"
' Following code from: http://www.vbaexpress.com/forum/showthread.php?41125-How-to-get-all-the-applied-Paragraph-Styles-of-a-document
Sub GetActiveStyles()
Application.ScreenUpdating = False
Dim RngStory As Range, oSty As Style, StrType As String, StrStyles As String
With ActiveDocument
For Each oSty In .Styles
For Each RngStory In .StoryRanges
With RngStory.Find
.ClearFormatting
.Text = ""
.Replacement.Text = ""
.Style = oSty.NameLocal
.Forward = True
.Wrap = wdFindStop
.Format = True
.Execute
If .Found Then
Select Case oSty.Type
Case wdStyleTypeCharacter: StrType = "Character"
Case wdStyleTypeList: StrType = "list"
Case wdStyleTypeParagraph: StrType = "Paragraph"
Case wdStyleTypeTable: StrType = "Table"
End Select
StrStyles = StrStyles & oSty.NameLocal & " (" & StrType & ")" & vbCr
Exit For
End If
End With
Next RngStory
Next oSty
End With
Debug.Print StrStyles
'MsgBox StrStyles
Application.ScreenUpdating = True
End Sub
I am a novice at this but I convert .RTF files in a whole folder to .DOCX files using this code below.
Sub BatchConvertToDocx()
Application.ScreenUpdating = False
Dim strFolder As String, strFile As String, wdDoc As Document
strFolder = GetFolder
If strFolder = "" Then Exit Sub
strFile = Dir(strFolder & "\*.rtf", vbNormal)
While strFile <> ""
Set wdDoc = Documents.Open(FileName:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With wdDoc
.SaveAs2 FileName:=Left(.FullName, InStrRev(.FullName, ".")) & "docx", FileFormat:=wdFormatXMLDocument, AddToRecentFiles:=False
.Close wdDoNotSaveChanges
End With
strFile = Dir()
Wend
Set wdDoc = Nothing
App
lication.ScreenUpdating = True
End Sub
Function GetFolder() As String
Dim oFolder As Object
GetFolder = ""
Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
Set oFolder = Nothing
End Function
Could somebody please tell me how to hide text that is between square braces in the output .docx file?
For example
Hi [This is the text that should be hidden] there.
Also, while converting the .docx file back to .rtf file, the text should reappear in the output .rtf file.
I see 2 different ways to do this.
Hard remove/delete the text with find/replace. Here I see no possibility to bring that text back in any way. Gone is gone.
Hide the text from printing with formatting it as hidden text.
Hard Remove
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "\[*\]"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
Hide from printing
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Font.Hidden = True
With Selection.Find
.Text = "\[*\]"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
'if this line is not used the text might be visible on the screen but not on print.
ActiveWindow.ActivePane.View.ShowAll = False
Unhiding the text from printing
This should un hide the text when converting back to .rtf
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Find.Font.Hidden = True
Selection.Find.Replacement.Font.Hidden = False
With Selection.Find
.Text = "\[*\]"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
I need to take existing word files that were created with smart quotes, I have to open each document and replace the quotes, then save and close. I wrote the macro, that works perfectly using the recorder function on word.
Now I've seen people write macros that can run the macro in a loop on each file in the folder but I have no idea where I actually run that macro from.
Sub Macro1()
'
' Macro1 Macro
'
'
ActiveDocument.Convert
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = """"
.Replacement.Text = """"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = "'"
.Replacement.Text = "'"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
ChangeFileOpenDirectory _
"\\EXPRESS-SERVER\MTMQuote\Quote Archive\Quote Archive (Out Dated)\Expert Quotes\120001-130000 (2013-)\125001-126000 (2015)\Updated\"
ActiveDocument.SaveAs2 FileName:= _
(ActiveDocument.Name) _
, FileFormat:=wdFormatDocumentDefault, LockComments:=False, Password:="", _
AddToRecentFiles:=True, WritePassword:="", ReadOnlyRecommended:=False, _
EmbedTrueTypeFonts:=False, SaveNativePictureFormat:=False, SaveFormsData _
:=False, SaveAsAOCELetter:=False, CompatibilityMode:=15
ActiveDocument.Close
Application.Quit
End Sub
How do I run this over and over? there are about 1000 files in the folder on my desktop called "MTMUPDATES"
Use this:
(but don't name them all the same thing, make whatever you use to name the docs count up or something)
Sub replacer()
Dim MyDialog As FileDialog, GetStr(1 To 1000) As String '1000 files is the maximum applying this code
On Error Resume Next
Set MyDialog = Application.FileDialog(msoFileDialogFilePicker)
With MyDialog
.Filters.Clear
.Filters.Add "All WORD File ", "*.*", 1
.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 = "'" 'find what
.Replacement.Text = "'" '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"
docname = InputBox("Enter file name", "docname") 'replace this with some sort of naming device or use the next thing
newname = docname & ".doc"
ActiveDocument.SaveAs FileName:=newname
'ActiveDocument.Save 'use this if you just want to save the document. remove the apostrophe before and delete the previous little expression or put apostrophes in front of it
ActiveWindow.Close
Next
Application.ScreenUpdating = True
End With
MsgBox "operation end, please view", vbInformation
End Sub