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
Related
I currently have this VBA macro that can search through a single folder for docx files and run find and replace in headers and footers. I am new to VBA and just good and manipulations of code, and was wondering how I can could modify this one to add in the ability to search subfolders as well?
Sub FindAndReplaceInFolder()
Dim objDoc As Document
Dim strFile As String
Dim strFolder As String
Dim strFindText As String
Dim strReplaceText As String
Dim xSelection As Selection
Dim xSec As Section
Dim xHeader As HeaderFooter
Dim xFooter As HeaderFooter
' Pop up input boxes for user to enter folder path, the finding and replacing texts.
strFolder = InputBox("Enter folder path here:")
strFile = Dir(strFolder & "" & "\*.docx", vbNormal)
strFindText = InputBox("Enter finding text here:")
strReplaceText = InputBox("Enter replacing text here:")
' Open each file in the folder to search and replace texts. Save and close the file after the action.
While strFile \<\> ""
Set objDoc = Documents.Open(FileName:=strFolder & "" & strFile)
With objDoc
For Each xSec In objDoc.Sections
For Each xHeader In xSec.Headers
xHeader.Range.Select
Set xSelection = objDoc.Application.Selection
With xSelection
.HomeKey Unit:=wdStory
With xSelection.Find
.Text = strFindText
.Replacement.Text = strReplaceText
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
xSelection.Find.Execute Replace:=wdReplaceAll
End With
Next xHeader
For Each xFooter In xSec.Footers
xFooter.Range.Select
Set xSelection = objDoc.Application.Selection
With xSelection
.HomeKey Unit:=wdStory
With xSelection.Find
.Text = strFindText
.Replacement.Text = strReplaceText
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
xSelection.Find.Execute Replace:=wdReplaceAll
End With
Next xFooter
Next xSec
objDoc.Save
objDoc.Close
strFile = Dir()
End With
Wend
End Sub
Not sure how to get started with this so looking for some help
My goal is to create a spread sheet that will feed information into a form letter, create a new folder, then save the letter to the new folder and repeat.
The code below completes one iteration, but runs into an error on the second loop
remote procedure call failed
I think it is an issue with re-opening the template on the second run.
Public Sub WordFindAndReplace()
Dim ws As Worksheet, msWord As Object, itm As Range, fileName As String, Path As String
Set ws = ActiveSheet
Set msWord = CreateObject("Word.Application")
Set objdoc = msWord.Documents.Add
For i = 1 To 4
fileName = Cells(i, 4).Value
Path = "C:\Users\jarafat\Desktop\Variation1\" & fileName & "\" & fileName & ".docx"
If Len(Dir("C:\Users\jarafat\Desktop\Variation1\" & fileName, vbDirectory)) = 0 Then
MkDir "C:\Users\jarafat\Desktop\Variation1\" & fileName
End If
With msWord
.Visible = True
.Documents.Open "C:\Users\jarafat\Desktop\Variation1\VariationTemplate1.docx"
.Activate
With .Activedocument.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "#address"
.Replacement.Text = ws.Cells(i, 1).Value
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
With .Activedocument.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "#address1"
.Replacement.Text = ws.Cells(i, 2).Value
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
With .Activedocument.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "#Description"
.Replacement.Text = ws.Cells(i, 3).Value
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
With msWord.Activedocument
.SaveAs Path
End With
.Quit SaveChanges:=True
End With
Next i
End Sub
The problem comes because the Word application is exited within the loop. So it's no longer available for the second (and following) loops:
.Quit SaveChanges:=True
End With
Next i
You need to do it like this, and it's a good idea to get into the habit of correctly releasing objects (set to Nothing) to outside applications, as well.
End With
Next i
msWord.Quit SaveChanges:=True
Set msWord = Nothing
I also recommend you declare and use a Document object rather than relying on ActiveDocument. There's always the chance that the active document isn't the one you expect. For example:
'At the beginning of the code
Dim doc as Object
'More code...
Set doc = .Documents.Open "C:\Users\jarafat\Desktop\Variation1\VariationTemplate1.docx"
'No need to activate, now...
'Activate
With doc.Content.Find
'And so on until...
.SaveAs Path
'You're done with the document, so release the object
Set doc = Nothing
End With
In addition to Cindy's solution...
Instead of repeating this multiple times with slight variations:
With .Activedocument.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "#address"
.Replacement.Text = ws.Cells(i, 1).Value
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
you can make a separate sub:
Sub ReplaceText(doc As Object, findWhat, replaceWith)
With doc.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = findWhat
.Replacement.Text = replaceWith
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
End sub
...and call it from within your loop
Dim doc
With msWord
.Visible = True
Set doc = .Documents.Open("C:\Users\jarafat\Desktop\Variation1\VariationTemplate1.docx")
ReplaceText doc, "#address", ws.Cells(i, 1).Value
ReplaceText doc, "#address1", ws.Cells(i, 2).Value
ReplaceText doc, "#Description", ws.Cells(i, 3).Value
'etc
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 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.
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