I have a word document which is updated periodically. I can go into that Word document, select the contents of an entire table and copy, then go into an Excel spreadsheet and paste it. It's screwed up; however, I fix it as follows:
sht.Cells.UnMerge
sht.Cells.ColumnWidth = 14
sht.Cells.RowHeight = 14
sht.Cells.Font.Size = 10
This manual copy-paste works regardless of whether the table is has merged fields.
Then I can start to manipulate it manually: parsing, checking, computations, etc.
I can do this one table at a time, but it's tedious and of course error prone.
I want to automate this. I found some code:
Sub read_word_document()
Dim sht As Worksheet
Dim WordDoc As Word.Document
Dim WordApp As Word.Application
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
On Error GoTo ErrHandler
Set WordDoc = WordApp.Documents.Open("Z:\mydir\myfile1.DOC", ReadOnly:=True)
j = 0
For i = 1 To WordDoc.Tables.Count
DoEvents
Dim s As String
s = WordDoc.Tables(i).Cell(1, 1).Range.Text
Debug.Print i, s
WordDoc.Tables(i).
Set sht = Sheets("temp")
'sht.Cells.Clear
sht.Cells(1, 1).Select
sht.PasteSpecial (xlPasteAll)
End If
Next i
WordDoc.Close
WordApp.Quit
GoTo done
ErrClose:
On Error Resume Next
ErrHandler:
Debug.Print Err.Description
On Error GoTo 0
done:
End Sub
Of course this would just overwrite the same sheet again and again - and that's okay. This is just a test. The problem is this will work for those tables that do not have merged cells. However, it fails if the table has merged cells. I have no control over the file I get. It contains almost a hundred tables. Is there a way to do the copy paste the EXACT WAY that I do when I perform the operation manually?
Something like this:
Sub read_word_document()
Const DOC_PATH As String = "Z:\mydir\myfile1.DOC"
Dim sht As Worksheet
Dim WordDoc As Word.Document
Dim WordApp As Word.Application
Dim i As Long, r As Long, c As Long
Dim rng As Range, t As Word.Table
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
Set WordDoc = WordApp.Documents.Open(DOC_PATH, ReadOnly:=True)
Set sht = Sheets("Temp")
Set rng = sht.Range("A1")
sht.Activate
For Each t In WordDoc.Tables
t.Range.Copy
rng.Select
rng.Parent.PasteSpecial Format:="Text", Link:=False, _
DisplayAsIcon:=False
With rng.Resize(t.Rows.Count, t.Columns.Count)
.Cells.UnMerge
.Cells.ColumnWidth = 14
.Cells.RowHeight = 14
.Cells.Font.Size = 10
End With
Set rng = rng.Offset(t.Rows.Count + 2, 0)
Next t
WordDoc.Close
WordApp.Quit
End Sub
Related
I'm writing a macro to copy a bunch of discussion points from our underwriting workbook and paste them into a Word doc for upload to our UWing system. I've managed to write the macro below and it seems to loop through each range successfully, however, when it gets done, an error pops up. Specifically, Run-time error '4198': command failed.
I'm not sure what's causing it, I've tried ending the For loop, but when I do, it stops it after the first pass through the array. Any help would be greatly appreciated.
Sub PasteToWord_DiscussionPoints()
Application.CutCopyMode = False
Dim wordapp As Word.Application
Dim worddoc As Word.Document
Dim Rng As Variant
Dim excRng As Range
Dim rngarray As Variant
'Create New Word Instance
Set wordapp = New Word.Application
wordapp.Visible = True
wordapp.Activate
Set worddoc = wordapp.Documents.add
'Populate range array with what I want to copy
rngarray = Array(Sheet1.Range("A5:A23"), Sheet1.Range("A25:A39"), _
Sheet1.Range("A94:A108"), Sheet1.Range("A128:A132"), _
Sheet1.Range("A134:A163"), Sheet1.Range("A192"), _
Sheet1.Range("A394"), Sheet1.Range("A404"), _
Sheet1.Range("A416"))
'Loop through each range in array copy/paste
For Each Rng In rngarray
Set excRng = Rng
excRng.Copy
'pause to allow Excel to catch up
Application.Wait Now() + #12:00:05 AM#
With wordapp.Selection
.PasteSpecial DataType:=wdPasteText
End With
wordapp.ActiveDocument.Sections.add
'Go to newly created page
wordapp.Selection.Goto what:=wdGoToPage, which:=GoToNext
Application.CutCopyMode = False
Next
MsgBox "Huzzah"
End Sub
I have the macro below to add a column to Word tables and paste a value in each cell to last row. It runs perfectly in Word, but when run inside an Excel macro it adds the new columns correctly, but then gives a type mismatch error for the ranges (tblA, tblB, tblC). Can someone please help identify the error? Many thanks!
Sub AddTeamColumn()
Dim WordApp As Object, WordDoc As Object
Dim arrFileList As Variant, Filename As Variant
Dim tblA As Range, tblB As Range, tblC As Range
'On Error Resume Next
arrFileList = Application.GetOpenFilename("Word files (*.doc; *.docx),*.doc;*.docx", 2, _
"Select files", , True)
If Not IsArray(arrFileList) Then Exit Sub
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
For Each Filename In arrFileList
Set WordDoc = WordApp.Documents.Open(Filename, ReadOnly:=False)
WordDoc.Tables(3).Columns.Add
WordDoc.Tables(4).Columns.Add
WordDoc.Tables(5).Columns.Add
Set tblA = WordDoc.Range(Start:=WordDoc.Tables(3).Cell(2, 8).Range.Start, _
End:=WordDoc.Tables(3).Rows.Last.Range.End)
Set tblB = WordDoc.Range(Start:=WordDoc.Tables(4).Cell(2, 9).Range.Start, _
End:=WordDoc.Tables(4).Rows.Last.Range.End)
Set tblC = WordDoc.Range(Start:=WordDoc.Tables(5).Cell(2, 5).Range.Start, _
End:=WordDoc.Tables(5).Rows.Last.Range.End)
WordDoc.Tables(1).Cell(1, 1).Select
Selection.Copy
'tblA.PasteSpecial DataType:=wdPasteText 'Word
tblA.PasteSpecial xlPasteValues 'Excel
WordDoc.Tables(1).Cell(1, 1).Select
Selection.Copy
'tblB.PasteSpecial DataType:=wdPasteText 'Word
tblA.PasteSpecial xlPasteValues 'Excel
WordDoc.Tables(1).Cell(1, 1).Select
Selection.Copy
'tblC.PasteSpecial DataType:=wdPasteText 'Word
tblC.PasteSpecial xlPasteValues 'Excel
WordDoc.Save
Next Filename
WordApp.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
When running from Excel you have to define the tbl-Ranges explicitly as Word.Range - otherwise they expect Excel-Ranges (therefore the type mismatch) - or use object if you want to keep with late binding.
If you can go with early binding then you have to add Microsoft Word as Reference to your VBA project.
'early binding
Dim tblA As Word.Range, tblB As Word.Range, tblC As Word.Range
'late binding
Dim tblA As object, tblB As object, tblC As object
Same thing with Selection: you have to use wordapp.Selection otherwise Excel selection is referenced.
I have a database in Excel, each entry runs horizontally for 8 cells (A2:H10 for example).
I am trying to create Word documents enmasse from each 8 cell entry that inject vertically into a Word document table that is 8 cells total.
Here is an example of the code I have tried.
Sub CreateEntry()
Dim wdApp As Object
Dim wd As Object
Dim myarray As Variant
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set wdApp = CreateObject("Word.Application")
End If
On Error GoTo 0
Set wd = wdApp.Documents.Add
wdApp.Visible = True
Sheets("Accommodation").Activate
Set Rng = ThisWorkbook.ActiveSheet.Range("A1:E76")
myarray = Range("A2:H2")
Range("A2:H2").Value = myarray
Range("A40:A48").Value = Application.WorksheetFunction.Transpose(myarray)
Set Rng = ThisWorkbook.ActiveSheet.Range("A40:A48")
Rng.Copy
With wd.Range
.Collapse Direction:=0
.InsertParagraphAfter
.Collapse Direction:=0
.PasteSpecial False, False, True
End With
End Sub
You can create tables directly in Word using the Word object model. That gives you more control over how it turns out.
Sub CreateEntry()
Dim doc As Object, rw As Range, tbl As Object
Dim n As Long
For Each rw In ThisWorkbook.Sheets("Accommodation").Range("A2:H3").Rows
Set doc = GetWordDoc()
Set tbl = doc.tables.Add(doc.Range, rw.Cells.Count, 1)
For n = 1 To rw.Cells.Count
tbl.Cell(n, 1).Range.Text = rw.Cells(n).Text
Next n
Next rw
End Sub
Function GetWordDoc() As Object
Dim wdApp As Object
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True
End If
On Error GoTo 0
Set GetWordDoc = wdApp.Documents.Add
End Function
I am trying to copy a table from excel to word and then back again to excel using VBA. I have a script to do both of those things but how can I make the copy from word back to excel from the active word file that got created with "Copy2word" so that I dont have to specify the location of the word document in "Copy2excel"?
Sub Copy2word()
Dim wdApp As Object
Dim wdDoc As Object
Dim wkSht As Worksheet
'\\ Stay on any sheet from which you want to copy data
Set wkSht = ActiveSheet
wkSht.UsedRange.Copy
'\\ Start word and create new document to paste data
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
If wdApp Is Nothing Then
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True
End If
Set wdDoc = wdApp.Documents.Add
'\\ Paste Data from Excel
wdDoc.Range.PasteExcelTable False, False, True
'\\ Stop Excel's cut copy mode
Application.CutCopyMode = False
MsgBox "Copy to Word Finished!", vbInformation, "Copy to Word"
End Sub
Sub Copy2excel()
Const DOC_PATH As String = "C:\Users\MASS\Desktop\Test\TK1.docx"
Dim sht As Worksheet
Dim WordDoc As Word.Document
Dim WordApp As Word.Application
Dim i As Long, r As Long, c As Long
Dim rng As Range, t As Word.Table
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
Set WordDoc = WordApp.Documents.Open(DOC_PATH, ReadOnly:=True)
Set sht = Sheets("Sheet4")
Set rng = sht.Range("A20")
sht.Activate
For Each t In WordDoc.Tables
t.Range.Copy
rng.Select
rng.Parent.PasteSpecial Format:="Text", Link:=False, _
DisplayAsIcon:=False
With rng.Resize(t.Rows.Count, t.Columns.Count)
.Cells.UnMerge
.Cells.ColumnWidth = 14
.Cells.RowHeight = 14
.Cells.Font.Size = 10
End With
Set rng = rng.Offset(t.Rows.Count + 2, 0)
Next t
WordDoc.Close
WordApp.Quit
End Sub
I'm trying to copy a content from excel into a bookmark in MS word. But I'm getting run time error 424. Kindly help me with it. I'm very new to Visual basics and programming as well. I have attached my code.
Thanks
Sub WordDoc()
Dim wrdApp As Object
Dim Number As String
Dim wrdDoc As Object
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Open("H:\IP Automation\createDoc.docx")
Number = Worksheets("Sheet1").Range("A2")
Call InsBookmark(ID, Number)
End Sub
Sub InsBookmark(strBMName, strVariable)
If strVariable <> "" Then
If ActiveDocument.Bookmarks.Exists(ID) Then
ActiveDocument.Bookmarks(ID).Select
Selection.Delete
Selection.InsertAfter (strVariable)
End If
End If
End Sub
You shouldn't seperate this into two subs, as the word doc will not persist across them so "ActiveDocument" wont work. just copy the code from the second sub into the first and replace ActiveDocument with wrdDoc
This should work for you. Give it a go and see how you get along.
Sub Export_Table_Word()
'Name of the existing Word doc.
Const stWordReport As String = "Final Report.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
'Initialize the Excel objects.
Set wbBook = ThisWorkbook
Set wsSheet = wbBook.Worksheets("PwC Contact Information")
Set rnReport = wsSheet.Range("Table1")
'Initialize the Word objets.
Set wdApp = New Word.Application
Set wdDoc = wdApp.Documents.Open(wbBook.Path & "\" & stWordReport)
Set wdbmRange = wdDoc.Bookmarks("Report").Range
Dim tbl As Table
For Each tbl In wdDoc.Tables
tbl.Delete
Next tbl
'If the macro has been run before, clean up any artifacts before trying to paste the table in again.
On Error Resume Next
With wdDoc.InlineShapes(1)
.Select
.Delete
End With
On Error GoTo 0
'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
.Paste
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
End Sub