I created a code that sopose to take a Word file template and fill it with data from my excel table.
Sub CreateWordDocs()
Dim CustRow, CustCol, LastRow, TemplRow As Long
Dim DocLoc, TagName, TagValue, TemplName, FileName As String
Dim WordDoc, WordApp As Object
With Sheet1
If ActiveCell.Value = Empty Then
MsgBox "pick a different cell"
End If
DocLoc = Sheet2.Range("K2").Value
'Open File
On Error Resume Next 'if Word ia already running
Set WordApp = GetObject("Word.Application")
If Err.Number <> 0 Then
Err.Clear
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
End If
LastRow = .Range("B999").End(xlUp).Row
For CustRow = ActiveCell.Row To LastRow
Set WordDoc = WordApp.Documents.Open(FileName:=DocLoc, ReadOnly:=False)
For CustCol = 2 To 8
TagName = Cells(3, CustCol)
TagValue = Cells(CustRow, CustCol).Value
With WordDoc.Content.find
.Text = TagName
.Replacement.Text = TagValue
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next CustCol
FileName = ThisWorkbook.Path & "\" & .Range("B" & CustRow).Value & ".docx"
WordDoc.SaveAs FileName
Next CustRow
WordDoc.Display
End With
End Sub
when I run the code it just opens Word without creating any file....
I am assuming here:
If ActiveCell.Value = Empty Then
MsgBox "pick a different cell"
End If
you wanted the code to stop executing if the selected cell in your Excel Worksheet was empty. If so, then you need to put a Exit Sub after MsgBox:
If ActiveCell.Value = Empty Then
MsgBox "pick a different cell"
Exit Sub
End If
I am also assuming that you have at least two Worksheets in your Excel doc because of:
Line 5: With Sheet1
Line 11: DocLoc = Sheet2.Range("K2").Value
It seems that you only use Sheet2 in your code to get the path of your Word Template, and everything else (Cells and Range statements) is meant to be referenced to Sheet1.
Even if the above assumptions are correct, it is not clear if you want to close the re-saved Word documents once they are filled.
If you don't close the individual Word docs once they are filled and saved, you may end up having huge amount of Word documents open depending how many Customers you have in your Excel Worksheet.
Your PC may run out of free memory, slows down very much, or who knows.
Based on the above assumptions, I made some changes in your code to make it run.
Let me know if you wanted it to do something else.
Make sure you have Microsoft Word Object Library enabled in VBA Editor, Tools -> References.
Depending on the version of your Office installed, the module to be enabled might have a different version number.
This is the complete code block after the edits:
Sub CreateWordDocs()
Dim CustRow, CustCol, LastRow, TemplRow As Long
Dim DocLoc, TagName, TagValue, TemplName, FileName As String
Dim WordDoc, WordApp As Object
Dim WBook As Workbook
Set WBook = Application.ActiveWorkbook
Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet
Set Sheet1 = WBook.Worksheets(1)
Set Sheet2 = WBook.Worksheets(2)
With Sheet1
If ActiveCell.Value = "" Then
MsgBox "pick a different cell"
Exit Sub
End If
DocLoc = Sheet2.Range("K2").Value
On Error Resume Next
'Set WordApp = GetObject("Word.Application")
Set WordApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Err.Clear
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
End If
'LastRow = .Range("B999").End(xlUp).Row
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
For CustRow = ActiveCell.Row To LastRow
Set WordDoc = WordApp.Documents.Open(FileName:=DocLoc, ReadOnly:=False)
For CustCol = 2 To 8
TagName = .Cells(3, CustCol).Value
TagValue = .Cells(CustRow, CustCol).Value
With WordDoc.Content.Find
.Text = TagName
.Replacement.Text = TagValue
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next CustCol
FileName = ThisWorkbook.Path & "\" & .Range("B" & CustRow).Value & ".docx"
WordDoc.SaveAs FileName
WordDoc.Close
Next CustRow
'WordDoc.Display
End With
End Sub
Related
What is the BEST option to create Hover Texts for 25k Definitions?
(Excel to Word using VBA)
Screen Tips?
Tool Tips?
Foot Notes?
Glossary?
Book Marks?
Other Options?
Over 25K Definitions in Table
Based on feedback and countless HOURS, Im having a tough time figuring out the best option for a Text Hover Effect.
Ive tried Bookmarks and Screen Tips and ran into many issues.
Ive also attempted to tweak the below VBA code to work with Hyperlinks to no avail.
3 STEPS
Select the Term from Column:A
Find the Term in Word Document
ADD Definition From Column:B as a HOVER effect in Word
| Column A | Column B |
| ----------- | ------------------------ |
| Example A | Definition Example.... |
| Example B | Definition Example.... |
Column: A1:A25000 = Term
Column: B1:B25000 = Definition
*The below code works great for finding and highlighting the Terms, But I haven't figured out the Hover Effect.
Favor 2023
`'Version #1: Only loops through Word Document Content for text to Find and Replace.
'Leverage & Lean "Less Clicks, More Results"
Sub FindReplaceAcrossMultipleWordDocumentsFreeMacro()
' Means variable is in use
Dim FindReplaceCounter As Integer '
Dim FolderPath As String '
Dim LastRow As Integer '
Dim LastRowPath As Integer '
Dim MyRange As Object '
Dim oFile As Object '
Dim oFolder As Object '
Dim oFSO As Object '
Dim WordApp As New Word.Application '
Dim WordCounter As Integer '
Dim WordDocument As Object '
On Error GoTo LeverageLean
Set WordApp = New Word.Application 'Forces a New Word Application each and every time. (Prevents Error 462)
If Cells(2, 3).Value <> "" Then 'If a path to Word Documents exist
WordCounter = 2
LastRowPath = Cells(Rows.Count, 3).End(xlUp).Row 'Identify Last Row in Column C
Do Until WordCounter > LastRowPath 'Loop through any Word Documents in Column C
Set WordDocument = WordApp.Documents.Open(Cells(WordCounter, 3).Value)
WordApp.Visible = True
FindReplaceCounter = 2
LastRow = Cells(Rows.Count, 1).End(xlUp).Row 'Identify Last Row in Column A
Do Until FindReplaceCounter > LastRow 'Complete the Find and Replace for all values in Column A & B
Set MyRange = WordApp.ActiveDocument.Content
With MyRange.Find
.Format = True
.MatchWholeWord = True
'.MatchWildcards = True 'Find and Replace Uppercase & Lowercase Text
.Wrap = wdFindContinue
.Forward = True
.Text = Cells(FindReplaceCounter, 1).Value
'.Replacement.Highlight = True 'Highlight the Replacement Text Found
.Replacement.Text = Cells(FindReplaceCounter, 2).Value
.Execute Replace:=wdReplaceAll
End With
FindReplaceCounter = FindReplaceCounter + 1
Loop
WordApp.ActiveDocument.Save
WordApp.ActiveDocument.Close 'Close Active Word Document
WordCounter = WordCounter + 1
Loop
ElseIf Cells(2, 3).Value = "" Then 'If NO paths to Word Documents exist
FolderPath = Left(ActiveWorkbook.FullName, Len(ActiveWorkbook.FullName) - Len(ActiveWorkbook.Name)) 'Active Workbook File Path
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(FolderPath)
For Each oFile In oFolder.Files 'Loop through every File in Active Workbook's folder path
If InStr(1, oFile.Type, "Microsoft Word") <> 0 And InStr(1, oFile.Name, "~") = 0 Then 'If the File Type contains the phrase Microsoft Word and is NOT Lock File
Set WordDocument = WordApp.Documents.Open(FolderPath & oFile.Name)
WordApp.Visible = True
FindReplaceCounter = 2
LastRow = Cells(Rows.Count, 1).End(xlUp).Row 'Identify Last Row in Column A
Do Until FindReplaceCounter > LastRow 'Complete the Find and Replace for all values in Column A & B
Set MyRange = WordApp.ActiveDocument.Content
With MyRange.Find
.Format = True
.MatchWholeWord = True
.Wrap = wdFindContinue
.Forward = True
.Text = Cells(FindReplaceCounter, 1).Value
'.Replacement.Highlight = True 'Highlight the Replacement Text Found
.Replacement.Text = Cells(FindReplaceCounter, 2).Value
.Execute Replace:=wdReplaceAll
End With
FindReplaceCounter = FindReplaceCounter + 1
Loop
WordApp.ActiveDocument.Save
WordApp.ActiveDocument.Close 'Close Active Word Document
End If
Next oFile
End If
WordApp.Quit
MsgBox "The Find and Replace has been completed. Stay Awesome!"
Set oFSO = Nothing
Set oFolder = Nothing
Set oFile = Nothing
Set WordApp = Nothing
Set WordDocument = Nothing
Exit Sub
LeverageLean:
MsgBox (Err.Number & " - " & Err.Description & vbNewLine & vbNewLine & "Don't hesitate to email me: brentschneider#leveragelean.com")
End Sub
'Stay Awesome`
I am trying to copy all the text, with formatting intact, from each of multiple Word Documents, and paste the text of each into a new cell in a single Excel Spreadsheet, placing the name of the Word Doc in an adjacent cell.
So the file name of "Document 1" goes in cell A1, and the entire contents of "Document 1" goes in cell A2.
We have several hundred Documents that need to be imported onto pages on our new corporate Intranet, and the migration tool provided only works off data in an Excel workbook.
I've checked out a number of threads, videos, and searches and tried to cobble together a couple of different attempts but neither is working. The first, if it did work, may not handle the File Name copy and it seems to run into issues with selecting the destination cell for the copy.
The second seems to be exactly what I want, but I can;t get the Paste into Excel bit working.
The first runs into an issue when it hits the "Range("LastRow").PasteSpecial xlPasteValues" line, saying the range is invalid (I have defined "LastRow" in the Excel Workbook but it doesn't help) :
Sub Copy_Data_From_Multiple_WordFiles()
Dim FolderName As String
Dim FileName As String
Dim NewWordFile As New Word.Application
Dim NewDoc As New Word.Document
Application.DisplayAlerts = False
'Application.ScreenUpdating = False
FolderName = "C:\Test\"
FileName = Dir(FolderName)
'Loop start
Do While FileName ⋖⋗ ""
Set NewDoc = NewWordFile.documents.Open(FolderName & FileName)
NewDoc.Range(0, NewDoc.Range.End).Copy
Range("LastRow").PasteSpecial xlPasteValues
NewDoc.Close SaveChanges:=wdDoNotSaveChanges
NewWordFile.Quit
FileName = Dir()
Loop
End Sub
NB: LastRow is defined in Excel Name Manager as:=OFFSET(CopyDataFromWord!$A$1,COUNTA(CopyDataFromWord!$A:$A),0,1,1)
I have tried a second set of code I got from a post on here, which should be closer to what I'm seeking, but again, won't quite get there. This one fails with a "Run-Time error '424': Object Required" at the line where it should paste into Excel. It doesn't seem to be recognising the Object "objDoc"?
Sub Excel_Word()
Dim WordApp As Object 'New Word.Application
Dim objDoc As Object ' New Word.Document
Dim Range As Object 'Word.Range
Dim WordDoc As String
Dim sPath As String
Dim i As Long
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
sPath = "C:\Users\jdodd\Documents\Cleaned\"
WordDoc = Dir(sPath & "*.docx")
Do While WordDoc <> ""
Set objDoc = WordApp.Documents.Open(sPath & WordDoc)
objDoc.Range.Copy
i = i + 1
ImportPolicyfromWord.Cells(i, 1).Value = objDoc
ImportPolicyfromWord.Cells(i, 2).Value = objDoc.Range.PasteSpecial
WordDoc = Dir()
Loop
WordApp.Quit
'elimina variabili
'Set WordApp = Nothing
'Set objDoc = Nothing
End Sub
Appreciate any advice or help
Try:
Sub GetDocData()
'Note: this code requires a reference to the Word object model.
'See under the VBE's Tools|References.
Application.ScreenUpdating = False
Dim strFolder As String: strFolder = GetFolder: If strFolder = "" Then GoTo ErrExit
Dim wdApp As New Word.Application, wdDoc As Word.Document
Dim strFile As String, WkSht As Worksheet, r As Long
Set WkSht = ActiveSheet
'Disable any auto macros in the documents being processed
wdApp.WordBasic.DisableAutoMacros
'Disable any alerts in the documents being processed
wdApp.DisplayAlerts = wdAlertsNone
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
Set wdDoc = wdApp.Documents.Open(Filename:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With wdDoc
.ConvertNumbersToText (wdNumberAllNumbers)
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchWildcards = True
.Text = "[^12^13^l]{1,}"
.Replacement.Text = "¶"
.Execute Replace:=wdReplaceAll
.Text = "[^t]"
.Replacement.Text = " "
.Execute Replace:=wdReplaceAll
End With
r = WkSht.UsedRange.Cells.SpecialCells(xlCellTypeLastCell).Row
If r > 1 Then r = r + 2
WkSht.Range("A" & r).Value = .Name
.Range.Copy
r = r + 1
WkSht.Paste Destination:=WkSht.Range("A" & r)
.Close SaveChanges:=False
End With
strFile = Dir()
Wend
ErrExit:
wdApp.Quit
WkSht.UsedRange.Replace What:="¶", Replacement:=Chr(10), LookAt:=xlPart, SearchOrder:=xlByRows
Set wdDoc = Nothing: Set wdApp = Nothing: Set WkSht = Nothing
Application.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
Simply select the folder to process. As coded, the macro places the document name above the contents, which are all pasted into one cell. If you want the document name on the same row, but beside the contents, change:
r = r + 1
WkSht.Paste Destination:=WkSht.Range("A" & r)
to:
WkSht.Paste Destination:=WkSht.Range("B" & r)
Problem:
I would like to create letters using 2 different letter templates based on a cell value in a column in Excel.
My Question is an extension to the following question:
VBA Automated Mailmerge using 2 templates based on cell value
Example:
In the example below, the value in column C should dictate which letter template will be used for each row. (If cell value is YES use letter template "Yes.docx" otherwise use letter template "No.docx")
Solution proposed by #user3598756 (modified to the above example):
Option Explicit
Sub CommandButton2_Click()
Dim wordApp As Object
Set wordApp = GetWordObject '<--| get a Word object
If wordApp Is Nothing Then Exit Sub '<--| if no Word Object has been gotten then exit sub
With ThisWorkbook.Sheets("Sheet1") '<--| reference your letter worksheet
With Application.Intersect(.UsedRange, Range("A1:C1").EntireColumn) '<--| reference your data range as that in referenced worksheet columns D:H used range
CreateWordDocuments .Cells, "YES", wordApp, "C:\Users\camil\Desktop\YES.docx" '<--| process "YES" documents
CreateWordDocuments .Cells, "NO", wordApp, "C:\Users\camil\Desktop\NO.docx" '<--| process "NO" documents
End With
.AutoFilterMode = False '<--| show all rows back and remove autofilter
End With
'"dispose" Word
wordApp.Quit True '<--| quit Word and save changes to open documents
Set wordApp = Nothing
End Sub
Sub CreateWordDocuments(dataRng As Range, criteria As String, wordApp As Object, templateDocPath As String)
Dim cell As Range
With dataRng '<--| reference data range
.AutoFilter Field:=3, Criteria1:=criteria '<--| filter it on its column 3 with given criteria
If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then '<--| if any cell has been filtered
For Each cell In .Offset(1).Resize(.Rows.Count - 1, 1).SpecialCells(xlCellTypeVisible) '<--| loop through filtered cells
wordApp.Documents.Add templateDocPath '<-- open the passed Word template
wordApp.Run "Module1.SaveIndividualWordFiles" '<--| run your macro
Next cell
End If
End With
End Sub
Function GetWordObject() As Object
Dim wordApp As Object
On Error Resume Next
Set wordApp = GetObject(, "Word.Application") '<--| try getting a running Word application
On Error GoTo 0
If wordApp Is Nothing Then Set wordApp = CreateObject("Word.Application") '<--| if no running instance of Word has been found then open a new one
Set GetWordObject = wordApp '<--| return the set Word application
wordApp.Visible = False
End Function
Request:
Unfortunately, the original poster of the question didn't share his "SaveIndividualWordFiles" macro.
I tried to fill in the gap with parts of the VBA I usually use to mailmerge from Word, when I only have one letter template. (Seen below)
However I can't fit the pieces together.
Sub Merge_To_Individual_Files()
Application.ScreenUpdating = False
Dim StrFolder As String, StrName As String, MainDoc As Document, i As Long, j As Long
Const StrNoChr As String = """*./\:?|"
Set MainDoc = ActiveDocument
With MainDoc
StrFolder = .Path & Application.PathSeparator
For i = 1 To .MailMerge.DataSource.RecordCount
With .MailMerge
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
.FirstRecord = i
.LastRecord = i
.ActiveRecord = i
If Trim(.DataFields("Col A")) = "" Then Exit For
StrName = .DataFields("Col A") & " " & .DataFields("Col C")
End With
.Execute Pause:=False
If Err.Number = 5631 Then
Err.Clear
GoTo NextRecord
End If
End With
For j = 1 To Len(StrNoChr)
StrName = Replace(StrName, Mid(StrNoChr, j, 1), "_")
Next
StrName = Trim(StrName)
With ActiveDocument
.SaveAs FileName:=StrFolder & StrName & ".docx", FileFormat:=wdFormatXMLDocument, AddToRecentFiles:=False
.SaveAs FileName:=StrFolder & StrName & ".pdf", FileFormat:=wdFormatPDF, AddToRecentFiles:=False
.Close SaveChanges:=False
End With
NextRecord:
Next i
End With
Application.ScreenUpdating = False
End Sub
Any help is appreciated.
ok, so here we go, I have tried to conquer this on my own for the past two days have have tried a lot of solutions. I am working with data in a Excel Spreadsheet that populates a word file. The specific problem I have is placing a table at the end of the word document. I have tried to create the table, and append a word doc that just has the table in it. nether seems to get done. My latest attempt was to just use sendkeys to copy and paste the table from the open documents.
I am willing to try anything at this point, short of doing it manually as I have to generate thousands of files.
Stripped code is below:
Option Explicit
Sub CreateWordDocuments()
Dim CustRow, CustCol, LastRow, TemplRow, DaysSince, FrDays, ToDays As Long
Dim DocLoc, TagName, TemplName, FileName As String
Dim TagValue As String
Dim myData As DataObject
Dim CurDt As Date
Dim LastAppDt As Date
Dim WordDoc As Object
Dim WordTable As Object
Dim WordApp As Object
Dim WordContent As Word.Range
Dim oWorkbookEA As Workbook
Set oWorkbookEA = Workbooks.Open(FileName:="M:\Form.xlsx")
Set myData = New DataObject
Dim oTable As Table
Dim oCell As Cell
Dim oPrevRow As Row, oNewRow As Row
Dim iColumn As Long
Dim myRange As Range
Dim NoCol As Integer
Dim NoRow As Integer
With Sheet1
DocLoc = "M:\WIP_Rev4.docx" 'Word Document Filename
'Open Word Template
On Error Resume Next 'If Word is already running
Set WordApp = GetObject("Word.Application")
If Err.Number <> 0 Then
'Launch a new instance of Word
Err.Clear
'On Error GoTo Error_Handler
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True 'Make the application visible to the user
End If
Set WordTable = WordApp.Documents.Open(FileName:="M:\Table.docx", ReadOnly:=True)
LastRow = .Range("E9999").End(xlUp).Row 'Determine Last Row in Table
For CustRow = 6 To 7 'LastRow
DaysSince = .Range("M" & CustRow).Value
Set WordDoc = WordApp.Documents.Open(FileName:=DocLoc, ReadOnly:=False) 'Open Template
'For CustCol = 5 To 13 'Move Through 9 Columns
TagValue = .Cells(CustRow, 2).Value 'Tag Value
With WordDoc.Content.Find
.Text = "$Product$"
.Replacement.Text = TagValue
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll 'Find & Replace all instances
End With
myData.SetText oWorkbookEA.Sheets("Company Info").Shapes("TextBox 6").TextFrame.Characters.Text
myData.PutInClipboard
With WordDoc.Content.Find
.Text = "$VarS$"
.Replacement.Text = "^c"
.Wrap = wdFindStop
.Execute Replace:=wdReplaceOne 'Find & Replace all instances
End With
myData.SetText oWorkbookEA.Sheets("Company Info").Shapes("TextBox 14").TextFrame.Characters.Text
myData.PutInClipboard
'This table works fine as it is preexisting
Set oTable = WordDoc.Tables(4)
Set oPrevRow = oTable.Rows(oTable.Rows.Count)
oPrevRow.Cells(1).Range.Text = "Ingredient Name"
oPrevRow.Cells(2).Range.Text = "No."
oPrevRow.Cells(3).Range.Text = "Percentage"
oTable.Rows.Add
Set oNewRow = oTable.Rows(oTable.Rows.Count)
oNewRow.Cells(1).Range.Text = "Lidocaine"
oNewRow.Cells(2).Range.Text = ""
oNewRow.Cells(3).Range.Text = Format(.Range("E" & CustRow).Value, "#.#%")
oTable.Rows.Add
Set oNewRow = oTable.Rows(oTable.Rows.Count)
oNewRow.Cells(1).Range.Text = "Glycol"
oNewRow.Cells(2).Range.Text = ""
oNewRow.Cells(3).Range.Text = Format(.Range("F" & CustRow).Value, "#.#%")
oTable.Rows.Add
Set oNewRow = oTable.Rows(oTable.Rows.Count)
oNewRow.Cells(1).Range.Text = "Glycerin"
oNewRow.Cells(2).Range.Text = ""
oNewRow.Cells(3).Range.Text = Format(.Range("G" & CustRow).Value, "#.#%")
'With WordDoc
' .Tables(.Tables.Count).Rows(1).Cells(1).Select
' MsgBox (.Tables.Count)
'End With
With oTable.Borders
.InsideLineStyle = wdLineStyleSingle
'.OutsideLineStyle = wdLineStyleDouble
End With
'The begining of my problems
WordDoc.Selection.Collapse Direction:=wdCollapseEnd
WordTable.Active
WordTable.SendKeys ("^a")
WordTable.SendKeys ("^c")
WordDoc.Active
WordDoc.SendKeys ("^v")
FileName = ThisWorkbook.Path & "\" & .Range("A" & CustRow).Value & "_" & ".pdf" 'Create full filename & Path with current workbook location, Last Name & First Name
WordDoc.ExportAsFixedFormat OutputFileName:=FileName, ExportFormat:=wdExportFormatPDF
WordDoc.Close False
.Range("N" & CustRow).Value = TemplName 'Template Name
.Range("O" & CustRow).Value = Now
WordDoc.PrintOut
WordDoc.Close
'Kill (FileName) 'Deletes the PDF or Word that was just created
Next CustRow
WordApp.Quit
End With
End Sub
Table document is Table.docx that I have tried to append to the end. That would be my ideal solution.
Thanks for any help you can give
Here's an example of copying a table from one document and pasting it at the end of another:
Sub Tester()
Dim wd As Word.Application
Dim docTbl As Word.Document, docMain As Word.Document
Dim tbl As Word.Table, objRange As Word.Range
Set wd = GetObject(, "Word.application") 'Word already running with the 2 docs open
Set docMain = wd.Documents("Document1")
Set docTbl = wd.Documents("Document2")
Set tbl = docTbl.Tables(1)
tbl.Range.Copy '<< copy the table
Set objRange = docMain.Content
objRange.Collapse Direction:=0 'wdCollapseEnd
objRange.InsertAfter vbCrLf
objRange.Collapse Direction:=0
objRange.Paste '<< paste the table
End Sub
FYI I find the dataobject.putinclipboard approach pretty unreliable in later versions of Excel, so I'd avoid that if you can.
I am writing a VBA script that I want to do smarter mail merge functions with.
Basically, I have 3 word templates that are formatted differently with replacement tags in different places. We'll call these templates 1-3.
I have a table where each row has the necessary replacement data as strings, with a max of 6 strings per row. To the left of this table, in column B, I have the number of strings in the table listed, and based on this number I want it to choose the correct template. I think I may have the LeftCell dim configured incorrectly, or my code is choosing a template correctly the first time, but applying it to all the other rows. If I run the script it always seems to choose the first template.
Sub CreateWordDocuments()
Dim CustRow, CustCol, LastRow, LeftCell, TemplRow As Long
Dim DocLoc, TagName, TagValue, TemplName, FileName As String
Dim WordDoc, WordApp As Object
Dim WordContent As Word.Range
With Sheet1
If .Range("B3").Value = Empty Then
MsgBox "Please select a template from the dropdown list"
.Range("G3").Select
Exit Sub
End If
TemplRow = .Range("B3").Value 'Set Template Row
TemplName = .Range("G3").Value 'Set Template Name
DocLoc = Sheet2.Range("F" & TemplRow).Value 'Word Doc Filename
'Open Word Template
On Error Resume Next 'If Word is already running
Set WordApp = GetObject("Word.Application")
If Err.Number <> 0 Then
'Launch a new instance of Word
Err.Clear
'On Error GoTo Error_Handler
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True 'Make the application visible to the user
End If
LastRow = .Range("E999").End(xlUp).Row 'Determine last row
LeftCell = .Range("B" & (ActiveCell.Row)).Value
For CustRow = 8 To LastRow
If LeftCell = 6 Then
Set WordDoc = WordApp.Documents.Open("C:\Users\jhabermann\Desktop\Excel VBA Test Environment\Template 1.docx", ReadOnly:=False) 'Open Template
ElseIf LeftCell = 4 Then
Set WordDoc = WordApp.Documents.Open("C:\Users\jhabermann\Desktop\Excel VBA Test Environment\Template 2", ReadOnly:=False) 'Open Template
Else: LeftCell = 3
Set WordDoc = WordApp.Documents.Open("C:\Users\jhabermann\Desktop\Excel VBA Test Environment\Template 3.docx", ReadOnly:=False) 'Open Template
End If
For CustCol = 5 To 10 'Move through 3 columns
TagName = .Cells(7, CustCol).Value 'Tag Name
TagValue = .Cells(CustRow, CustCol).Value 'Tag Value
With WordDoc.Content.Find
.Text = TagName
.Replacement.Text = TagValue
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll, Forward:=True, Wrap:=wdFindContinue
End With
Next CustCol
WordDoc.PrintOut
WordDoc.Close
Kill (FileName) 'Deletes the Word File just created
Next CustRow
WordApp.Quit
End With
End Sub
Ignore the few lines of code regarding b3 and g3, I am saving that for later functionality to perhaps choose different sets of templates.
You need to move Leftcell inside your loop and increment it with every iteration:
For CustRow = 8 To LastRow
LeftCell = .Range("B" & CustRow).Value
If LeftCell = 6 Then
Set WordDoc = WordApp.Documents.Open("C:\Users\jhabermann\Desktop\Excel VBA Test Environment\Template 1.docx", ReadOnly:=False) 'Open Template
ElseIf LeftCell = 4 Then
Set WordDoc = WordApp.Documents.Open("C:\Users\jhabermann\Desktop\Excel VBA Test Environment\Template 2", ReadOnly:=False) 'Open Template
Else: LeftCell = 3
Set WordDoc = WordApp.Documents.Open("C:\Users\jhabermann\Desktop\Excel VBA Test Environment\Template 3.docx", ReadOnly:=False) 'Open Template
End If
For CustCol = 5 To 10 'Move through 3 columns
TagName = .Cells(7, CustCol).Value 'Tag Name
TagValue = .Cells(CustRow, CustCol).Value 'Tag Value
With WordDoc.Content.Find
.Text = TagName
.Replacement.Text = TagValue
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll, Forward:=True, Wrap:=wdFindContinue
End With
Next CustCol
WordDoc.PrintOut
WordDoc.Close
Kill (FileName) 'Deletes the Word File just created
Next CustRow
As a note, not sure what you're doing on that Else: LeftCell = 3 line - why set LeftCell to anything? I think you meant for another ElseIf there.