Data dynamically populating from drop-down list correctly; however, how may I get the Word document to close properly in between each entry?
Problem:
The Word document doesn't close properly in between each new entry in the Excel dynamic drop-down list.
What is occurring:
The loop is executing over each hospital; however, Word isn't closing in between each new entity. Result is that all the addresses and tables are inserting without interruption.
What should occur:
Each hospital with it's own unique data in a new Word document (attached, the Excel sheet "Table" has a drop-down in call B2 that autopopulates the table 1 and the hospital's address; the Word document has bookmarks to insert this data).
In advance, thank you very much for your expertise. I have tried various commands to close the active document in Word (not shown) but then cannot get Word to open up again with the template. Realize there is likely a simple solution to incorporate into the existing code.
Regards,
Karen
Sub MMISPMT()
Worksheets("table").Activate
'Declare variables
Dim WordApp As Object
Dim WordDoc As Object
Dim dvCell As Range
Dim inputRange As Range
Dim c As Range
ActiveWindow.View = xlNormalView
'Set variables
'Which cell has data validation
Set dvCell = Worksheets("Table").Range("B2") 'this is a drop-down box of entity name values that
populates address info and table 1 in Word document
'Determine where validation comes from
Set inputRange = Evaluate(dvCell.Validation.Formula1)
Set WordApp = New Word.Application ' based on the template ref'd in WordDoc
'Word template to be used
Set WordDoc = WordApp.Documents.Add(Template:="C:\<pathway>\letter.docx", NewTemplate:=False,
DocumentType:=0)
'Begin loop
Application.ScreenUpdating = False
For Each c In inputRange
dvCell = c.Value
MsgBox dvCell
Debug.Print dvCell
Dim table1 As Range
Dim HosName As Range
Dim address1 As Range
Dim city As Range
Dim zip As Range
'Declare variables
Set table1 = Range("a10:g15")
Set HosName = Range("b2")
Set address1 = Range("ad5")
Set city = Range("ad6")
Set zip = Range("ad7")
HosName.Select
Selection.Copy
WordApp.Visible = True
WordApp.ActiveDocument.Bookmarks("HosName").Select
Set objSelection = WordApp.Selection
objSelection.PasteSpecial DataType:=wdPasteText
address1.Select
Selection.Copy
WordApp.Visible = True
WordApp.ActiveDocument.Bookmarks("address1").Select
Set objSelection = WordApp.Selection
objSelection.PasteSpecial DataType:=wdPasteText
city.Select
Selection.Copy
WordApp.Visible = True
WordApp.ActiveDocument.Bookmarks("city").Select
Set objSelection = WordApp.Selection
objSelection.PasteSpecial DataType:=wdPasteText
zip.Select
Selection.Copy
WordApp.Visible = True
WordApp.ActiveDocument.Bookmarks("zip").Select
Set objSelection = WordApp.Selection
objSelection.PasteSpecial DataType:=wdPasteText
table1.Select
Selection.CopyPicture Appearance:=xlScreen, Format:=xlPicture
WordApp.Visible = True
WordApp.ActiveDocument.Bookmarks("table1").Select
Set objSelection = WordApp.Selection
objSelection.Paste
'Generate the Word template per hospital with data
WordApp.ActiveDocument.SaveAs2 Filename:="C:\<pathway>\" & HosName & " " & Format((Year(Now() + 1)
Mod 100), "20##") & _
Format((Month(Now() + 1) Mod 100), "0#") & _
Format((Day(Now()) Mod 100), "0#") & "-report.docx", _
FileFormat:=wdFormatXMLDocument
Next c
Application.ScreenUpdating = True
End Sub
You need to open the template at the top of the loop, then save and close the document at the bottom of the loop.
Also you can tidy up your code by factoring the copy/paste into a separate method.
Sub MMISPMT()
Dim WordApp As Object
Dim WordDoc As Object
Dim dvCell As Range
Dim inputRange As Range
Dim c As Range, wsTable As Worksheet
Set wsTable = Worksheets("Table")
Set dvCell = Worksheets("Table").Range("B2")
Set inputRange = Evaluate(dvCell.Validation.Formula1)
Set WordApp = New Word.Application ' based on the template ref'd in WordDoc
For Each c In inputRange.Cells
Set WordDoc = WordApp.Documents.Add(Template:="C:\<pathway>\letter.docx", _
NewTemplate:=False, DocumentType:=0)
dvCell = c.Value
CopyToBookmark wsTable.Range("B2"), WordDoc, "HosName"
CopyToBookmark wsTable.Range("AD5"), WordDoc, "address1"
CopyToBookmark wsTable.Range("AD6"), WordDoc, "city"
CopyToBookmark wsTable.Range("AD7"), WordDoc, "zip"
CopyToBookmark wsTable.Range("A10:G15"), WordDoc, "table1", False
WordDoc.SaveAs2 Filename:="C:\<pathway>\" & HosName & " " & _
Format((Year(Now() + 1) Mod 100), "20##") & _
Format((Month(Now() + 1) Mod 100), "0#") & _
Format((Day(Now()) Mod 100), "0#") & "-report.docx", _
FileFormat:=wdFormatXMLDocument
WordDoc.Close
Next c
End Sub
'transfer/copy data from a Range into a named bookmark in doc
' either directly as text or copy/paste as table
Sub CopyToBookmark(rng As Range, doc As Word.document, bmk As String, _
Optional AsValue As Boolean = True)
If AsValue Then
doc.bookmarks(bmk).Range.Text = rng.Value
Else
rng.Copy
doc.bookmarks(bmk).Range.Paste
End If
End Sub
Related
to do that i started with the microsoft word 16.0 object library.
I need to take the value of the E10 cell (number). Who said how many lines i will have in my hostname's column.
to just copy that range of cells and export each one of those strings in a label formated word.
At the time this code insert all the value just in the first label with <> and not each strings to each label...
Thanks you.
Excel
Word labels template
Sub LabelMerge()
Dim oWord As Word.Application, oDoc As Word.Document
Dim strFile As String
Dim sPath As String
Dim i As Integer
Dim oHeaders As Range 'tab var data
Set oHeaders = Range("D48").CurrentRegion.Rows(1) 'select data from excel
sPath = ThisWorkbook.FullName 'path acces
Set oWord = CreateObject("Word.Application") 'create object word
'Set oDoc = oWord.Documents.add
Set oDoc = oWord.Documents.Open("file.docx")
oWord.Visible = True
oDoc.MailMerge.MainDocumentType = wdMailingLabels 'publipostage
'oWord. Dialogs (wdDialogLabeloptions) .Show
'oDoc.Activate
Dim x As Integer
x = 48 + Range("E10").Value
With oDoc.MailMerge.Fields
For i = 48 To x 'while i < lenght data
.Add oWord.Selection.Range, Cells(i, 4).Value
'oWord.Selection.TypeParagraph ‘OR: TypeText " "
Next i
End With
oDoc.MailMerge.OpenDataSource sPath
oWord.WordBasic.mailmergepropagatelabel
oDoc.MailMerge.ViewMailMergeFieldCodes = False
oDoc.ActiveWindow.View.ShowFieldCodes = False
'oDoc.MailMerge.Destination = wdSendToNewDocument 'add to doc
'oDoc.MailMerge.Execute
Set oDoc = Nothing
Set oWord = Nothing
End Sub
I'm working with the below code that copies and pastes a bunch of named ranges from Excel to Word as pictures which already saves me a bunch of time.
To really cap it off I'm wondering if there is a way to insert these images at set places within a word document?
Sub copypaste()
'Create new word document
Dim objWord As Object
Dim objDoc As Object
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.documents.Add()
Dim intCounter As Integer
Dim rtarget As Word.Range
Dim wbBook As Workbook
Set wbBook = ActiveWorkbook
'Loop Through names
For intCounter = 1 To wbBook.Names.Count
Debug.Print wbBook.Names(intCounter)
With objDoc
Set rtarget = .Range(.Content.End - 1, .Content.End - 1)
'Insert page break if not first page
If intCounter > 1 Then rtarget.insertbreak Type:=wdPageBreak
'Write name to new page of word document
rtarget.Text = wbBook.Names(intCounter).Name & vbCr
'Copy data from named range
Range(wbBook.Names(intCounter)).Copy
Set rtarget = .Range(.Content.End - 1, .Content.End - 1)
rtarget.PasteSpecial , DataType:=wdPasteMetafilePicture
End With
Next intCounter
End Sub
I have a an Excel workbook with that creates a table and exports the table to MS word. My client now wants to also insert a drop down list into the last column of the word table. I cannot find any material on this. Can it be done? I would like to create a combobox and insert it into each cell in the "Interpretation" column. Can someone point me in the right direction or supply some sample code?
Current code:
Sub ExportToWord()
Dim ws As Worksheet
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Dim objRange As Word.Range
Dim bWeStartedWord As Boolean
Dim newDoc As Boolean, onSave As Boolean
Dim rng As Range
Dim lRow As Integer, s As Integer
If UF_Load.check_new = True Then
newDoc = True
Else
newDoc = False
End If
Set ws = ThisWorkbook.Sheets("UI")
On Error Resume Next
Set wrdApp = GetObject(, "Word.Application")
On Error GoTo 0
Application.ScreenUpdating = False
Application.EnableEvents = False
s = ws.Range("rng_demo").Row - 1
c = ws.Range("rng_demo").Column
lRow = ws.Cells(Rows.count, s).End(xlUp).Row
Set rng = ws.Range("A" & s).Resize(lRow, 8)
rng.Copy
If wrdApp Is Nothing Then
Set wrdApp = CreateObject("Word.Application")
bWeStartedWord = True
End If
'Handle if Word Application is not found
If Err.Number = 429 Then
MsgBox "Microsoft Word document could not be found, aborting", vbExclamtion, "Microsoft Word Error 429"
GoTo SafeExit:
End If
On Error GoTo 0
'Make MS Word Visible and Active
wrdApp.Visible = True
wrdApp.Activate
'
wrdApp.Visible = True
If newDoc = True Then
Set wrdDoc = wrdApp.Documents.Add 'create as new word document
'Copy table data to word doc
Set tbl = rng 'ThisWorkbook.Sheets("UI").Range("A4:H25")
tbl.Copy
'Paste Table into Word doc
wrdDoc.Paragraphs(1).Range.PasteExcelTable _
LinkedToExcel:=False, _
WordFormatting:=False, _
RTF:=False
'Autofit table to Word doc
Set wordtable = wrdDoc.Tables(1)
wordtable.AutoFitBehavior (wdAutoFitWindow)
Else
'or open an existing document
Set wrdDoc = wrdApp.Documents.Open(filepath) 'wrdApp.Documents.Open("C:\Users\Apache Paint\Desktop\Clients\Stephen Schmitz\TestDocument.docx")
'Copy table data to word doc
With wrdDoc
Set tbl1 = .Tables.Add(Range:=wrdDoc.Paragraphs.Last.Range, _
NumRows:=1, NumColumns:=8, _
AutoFitBehavior:=wdAutoFitWindow) 'autofit content 'DefaultTableBehavior:=wdWord9TableBehavior,
With tbl1
.PreferredWidthType = wdPreferredWidthPercent
.PreferredWidth = 100
End With
Set tbl = rng 'ThisWorkbook.Sheets("UI").Range("A4:H25")
tbl.Copy
Set objRange = wrdDoc.Content
With objRange
.Collapse Direction:=0 'wdCollapseEnd
.InsertAfter vbCrLf
.Collapse Direction:=0
.InsertBreak Type:=wdPageBreak
.Paste '<< paste the table
End With
'Autofit the document
Set wordtable = objRange.Tables(1)
wordtable.AutoFitBehavior (wdAutoFitWindow)
With wordtable
.PreferredWidthType = wdPreferredWidthPercent
.PreferredWidth = 100
End With
End With
filepath = ""
End If
SafeExit:
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.CutCopyMode = False
End Sub
I was able to get it to work with the code below. Thanks to those who suggested I look into ContentControl.
Now I am intermittently getting 'Run-time error 462. The remote server machine does not exist or is unavailable.'
I will update the cooment back here when it is fully resolved.
'Copy table data to word doc
Set tbl = rng 'ThisWorkbook.Sheets("UI").Range("A4:H25")
tbl.Copy
'Paste Table into Word doc
wrdDoc.Paragraphs(1).Range.PasteExcelTable _
LinkedToExcel:=False, _
WordFormatting:=False, _
RTF:=False
'Autofit table to Word doc
Set Wordtable = wrdDoc.Tables(1)
Wordtable.AutoFitBehavior (wdAutoFitWindow)
Dim oRow As Row
'Dim oRng As Range
'Loop through last table column and add Combobox
With Wordtable
For Each oRow In Wordtable.Rows
'Set oRng = oRow.Cells(1).Range
If Len(oRow.Cells(7).Range.Text) > 11 Then
Set objCC = ActiveDocument.ContentControls.Add(wdContentControlDropdownList, oRow.Cells(8).Range)
objCC.Title = "Interpretation"
If objCC.ShowingPlaceholderText Then
objCC.SetPlaceholderText , , "-Select-"
objCC.DropdownListEntries.Add "Far Below Expectaions"
objCC.DropdownListEntries.Add "Below Expectaions"
objCC.DropdownListEntries.Add "Slightly Below Expectaions"
objCC.DropdownListEntries.Add "Significant Difference"
objCC.DropdownListEntries.Add "Valid"
objCC.DropdownListEntries.Add "WNL"
Debug.Print Len(oRow.Cells(7).Range.Text)
End If
Else
End If
Next
End With
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 developing a macro that transfers a range of cells from excel to word bookmark. The problem I am having is that not the whole of the range I selected is transfered. Not sure if there is a limit to how big the range can be? Also want the transfered content to autofit to the word documents margins?
The code I have so far is:
'Name of the existing Word doc.
Const stWordReport As String = "Exporting a Table to a Word Document 2.docx"
'Word objects.
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim wdbmRange As Word.Range
'Excel objects.
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim rnReport As Range
'Dim Table1 As Range
Dim coluna As Integer
coluna = Worksheets("Planilha1").Cells(1, Worksheets("Planilha1").Columns.Count).End(xlToLeft).Column
Table1 = Worksheets("Planilha1").Range(Cells(4, 4), Cells(16, coluna))
'Initialize the Excel objects.
Set wbBook = ThisWorkbook
Set wsSheet = wbBook.Worksheets("Planilha1")
Set rnReport = wsSheet.Range("Table1")
'Initialize the Word objects.
Set wdApp = New Word.Application
Set wdDoc = wdApp.Documents.Open(wbBook.Path & "\" & stWordReport)
Set wdbmRange = wdDoc.Bookmarks("Report").Range
'Turn off screen updating.
Application.ScreenUpdating = False
'Copy the report to the clipboard.
rnReport.Copy
'Select the range defined by the "Report" bookmark and paste in the report from clipboard.
With wdbmRange
.Select
.PasteSpecial Link:=False, _
DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, _
DisplayAsIcon:=False
End With
'Save and close the Word doc.
With wdDoc
.Save
.Close
End With
'Quit Word.
wdApp.Quit
'Null out your variables.
Set wdbmRange = Nothing
Set wdDoc = Nothing
Set wdApp = Nothing
'Clear out the clipboard, and turn screen updating back on.
With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
MsgBox "The report has successfully been " & vbNewLine & _
"transferred to " & stWordReport, vbInformation
I expect the content on the word document to have the same formatting as the excel one and to be fitted to the page.
Word's maximum column count is 63; there is no set row limit. In any event, since you are pasting what you've copied as a picture, the table limits aren't relevant. I suspect the real issue is with how you're determining coluna. Try:
'Initialize the Excel objects.
Set wbBook = ThisWorkbook
Set wsSheet = wbBook.Worksheets("Planilha1")
Set rnReport = wsSheet.Range("Table1")
coluna = wsSheet.UsedRange.Cells.SpecialCells(xlCellTypeLastCell).Column
Table1 = wsSheet.Range(Cells(4, 4), Cells(16, coluna))