A
Alex St-Pierre
Hi,
Does anyone has already reproduce an excel table in word. I'm trying to do
that (the programmation is below) but it is very complex. I'm looking for
information to help me to progress.
What the program do is a mailmerge executed from Excel. The excel file
contains a sheet for mail merge data and others sheets (table1.1, table1.2,
etc.) for tables used in the mailmerge document. When I execute the macro in
excel, the Word Macro is executed and all the tables are formatted in word
just before the mailmerge execution.
The table formating seems to be very complex because:
1) Text with bold and exponents, italic, size caracter, ...
tbl.cell(i,j) = rngExcel.Cells(i, j).Format 'give format of the first
character and not of all character. Does anyone know how to paste all cell
formatting in word? I don't know if doing a copy and paste is the best
solution because, some cells are merged in excel and I have to adjust
formatting (borders,horizontal alignment) thereafter.
2) In excel table, some cell contains text that go on the following cells. I
have to merge the table cells in Word to take this into account. Also, it is
possible that the cells are merge in excel.
3) Want to respect column width, borders, alignment etc.
4) I added a section to take NumberFormat from Excel.
etc.
Does anyone have already done something similar to this ?
Is there a simpler way to have great word table formatting without having to
program each things? example: copy paste the table using a pre-determined
table formating. After that, adjust borders, column width, some alignments, ..
Thanks a lot !
Alex
Sub Merge_Word()
Dim appWord As Word.Application
Dim docWord1 As Word.Document
Dim docWord2 As Word.Document
Dim appExcel As Excel.Application
Dim wbExcel As Excel.Workbook
Dim tbl As Word.Table
Dim oRow As Row
Dim rngExcel As Excel.Range
Dim pathExcel, strFormat, strBookMark As String
Dim iCol As Integer
Set appWord = Word.Application
Set docWord1 = appWord.ActiveDocument
On Error Resume Next
Set appExcel = GetObject(, "Excel.Application")
If appExcel Is Nothing Then
Set appExcel = CreateObject("Excel.Application")
End If
On Error GoTo 0
pathExcel = appExcel.ActiveWorkbook.Path & "\" &
appExcel.ActiveWorkbook.Name
' PathExcel = ActiveDocument.MailMerge.DataSource.Name
fileExcel = LCase(Right(pathExcel, Len(pathExcel) - InStrRev(pathExcel,
"\")))
On Error Resume Next
Set wbExcel = appExcel.Workbooks(fileExcel)
If wbExcel Is Nothing Then
Set wbExcel = appExcel.Workbooks.Open(FileName:=pathExcel,
UpdateLinks:=True, ReadOnly:=True)
' Set wbExcel = GetObject(PathExcel, "Excel.Workbook")
End If
On Error GoTo 0
For nbTab = 1 To 3
If nbTab = 1 Then
Set rngExcel = wbExcel.Application.sheets("table1.1").Range("table1_1")
Set rng = docWord1.Bookmarks("Table1_1").Range
ElseIf nbTab = 2 Then
Set rngExcel = wbExcel.Application.sheets("table1.2").Range("table1_2")
Set rng = docWord1.Bookmarks("Table1_2").Range
ElseIf nbTab = 3 Then
Set rngExcel = wbExcel.Application.sheets("table1.3").Range("table1_3")
Set rng = docWord1.Bookmarks("Table1_3").Range
End If
Set tbl = rng.Tables(1)
'1- Adjust number of rows
DerLineExcel = rngExcel.Rows.Count
DerLineWord = tbl.Rows.Count
j = DerLineExcel - DerLineWord
For k = 1 To j
tbl.Rows.Add
Next k
For k = 1 To -j
tbl.Cell(5, 1).Select
Selection.SelectRow
Selection.Rows.Delete
Next k
'2- Adjust number of columns
'3- Adjust column width
With tbl.Rows
.LeftIndent = 0
End With
UsableWidth = 432
TableWidth = 0
For CellNo = 1 To rngExcel.Rows(1).Cells.Count
TableWidth = TableWidth + rngExcel.Columns(CellNo).ColumnWidth
Next CellNo
For j = 1 To tbl.Columns.Count
For i = 1 To tbl.Rows.Count
tbl.Cell(i, j).Width = UsableWidth * rngExcel.Columns(j).ColumnWidth
/ TableWidth
Next i
Next j
'4- MergeCells
For i = 1 To rngExcel.Rows.Count
j = 1
Do Until j >= rngExcel.Columns.Count
With rngExcel
If .Cells(i, j).MergeCells = True Then
iCol = .Cells(i, j).MergeArea.Columns.Count
tbl.Cell(i, j).Select
Selection.MoveRight Unit:=wdCharacter, Count:=iCol - 1, Extend:=wdExtend
Selection.Cells.Merge
j = j + iCol
Else
j = j + 1
End If
End With
Loop 'j
Next i
'5- Remove all borders
With tbl
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
.Borders(wdBorderRight).LineStyle = wdLineStyleNone
.Borders(wdBorderVertical).LineStyle = wdLineStyleNone
.Borders(wdBorderDiagonalDown).LineStyle = wdLineStyleNone
.Borders(wdBorderDiagonalUp).LineStyle = wdLineStyleNone
.Borders(wdBorderHorizontal).LineStyle = wdLineStyleNone
.Borders(wdBorderVertical).LineStyle = wdLineStyleNone
End With
'6- Add borders
With tbl
For i = 1 To tbl.Rows.Count
For j = 1 To tbl.Columns.Count
With rngExcel.Cells(i, j)
With .Borders(xlEdgeTop)
If .LineStyle = xlContinuous Then
C = wdLineStyleSingle
tbl.Cell(i, j).Borders(wdBorderTop).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderTop).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderTop).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderTop).LineStyle =
wdLineStyleNone
End If
End With
With .Borders(xlEdgeBottom)
If .LineStyle = xlContinuous Then
tbl.Cell(i, j).Borders(wdBorderBottom).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderBottom).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderBottom).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderBottom).LineStyle =
wdLineStyleNone
End If
End With
With .Borders(xlEdgeLeft)
If .LineStyle = xlContinuous Then
tbl.Cell(i, j).Borders(wdBorderLeft).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderLeft).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderLeft).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderLeft).LineStyle =
wdLineStyleNone
End If
End With
With .Borders(xlEdgeRight)
If .LineStyle = xlContinuous Then
tbl.Cell(i, j).Borders(wdBorderRight).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderRight).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderRight).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderRight).LineStyle =
wdLineStyleNone
End If
End With
End With
'With Selection.ParagraphFormat
' .LeftIndent = CentimetersToPoints(0)
' .SpaceBeforeAuto = False
' .SpaceAfterAuto = False
'End With
'7- Add data with formating
strData = rngExcel.Cells(i, j)
If IsNumeric(strData) And strData <> "" Then
strFormat = rngExcel.Cells(i, j).NumberFormat
If strFormat = "#,##0_);(#,##0)" Or strFormat = "# ##0_-;(#
##0)" Or strFormat = "#,##0_-;(#,##0)" Then ' voir ajout de n'importe quel _)
strFormat = "#,##0;(#,##0)"
End If
strData = Format(strData, strFormat)
If Right(strData, 1) = ")" Then
.Cell(i, j).Select
With Selection.ParagraphFormat
.RightIndent = CentimetersToPoints(-0.13)
.SpaceBeforeAuto = False
.SpaceAfterAuto = False
End With
Else
.Cell(i, j).Select
With Selection.ParagraphFormat
.RightIndent = CentimetersToPoints(0)
.SpaceBeforeAuto = False
.SpaceAfterAuto = False
End With
End If ')"
End If 'IsNumeric
.Cell(i, j).Range.text = strData
Next j
Next i
End With
Next nbTab
Exit Sub
'8- Add text to document
strBookMark = wbExcel.Path & "\bookmark1.doc"
Set docWord2 = appWord.Documents.Open(strBookMark, ReadOnly:=False)
docWord2.Bookmarks(1).Range.Select
Selection.Copy
docWord1.Bookmarks("Bookmark1").Range.Select
Selection.Paste
docWord2.Close
'9- Mailmerge execution
With docWord1.MailMerge
ActiveDocument.MailMerge.OpenDataSource Name:= _
pathExcel, ConfirmConversions:=False, ReadOnly:= _
True, LinkToSource:=True, AddToRecentFiles:=False,
PasswordDocument:="", _
PasswordTemplate:="", WritePasswordDocument:="",
WritePasswordTemplate:= _
"", Revert:=False, Format:=wdOpenFormatAuto, Connection:= _
"Provider=Microsoft.Jet.OLEDB.4.0;Password="""";User ID=Admin;Data
Source=C:\rap_modele_ameliorations.xls;Mode=Read;Extended
Properties=""HDR=YES;IMEX=1;"";Jet OLEDB:System database="""";Jet
OLEDB:Registry Path="""";Jet OLEDBatabase Password="""";Jet OLEDB:Engine " _
, SQLStatement:="SELECT * FROM `merge$`", SQLStatement1:="",
SubType:= _
wdMergeSubTypeAccess
.Destination = wdSendToNewDocument
With .DataSource
.FirstRecord = 1
.LastRecord = 1
End With
.Execute Pause:=False
End With
docWord1.Close (False)
' AppWord.Application.Quit
'10- Reset variables
Set appWord = Nothing
Set docWord1 = Nothing
Set appExcel = Nothing
Set wbExcel = Nothing
Set rngExcel = Nothing
Set rng = Nothing
Set tbl = Nothing
Set docWord2 = Nothing
End Sub
Sub Mailmerge_execution_from_excel()
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
Dim Chemin, Fichier, Chemin_Fichier, Source As String
ChDrive ActiveWorkbook.Path
ChDir ActiveWorkbook.Path
Chemin_Fichier = Application.GetOpenFilename()
Source = ActiveWorkbook.Name
PathExcel = ActiveWorkbook.Path & "\" & Source
On Error Resume Next
Set WordApp = GetObject(, "Word.application")
If WordApp Is Nothing Then
Set WordApp = CreateObject("Word.Application")
End If
On Error GoTo 0
Fichier = LCase(Right(Chemin_Fichier, Len(Chemin_Fichier) -
InStrRev(Chemin_Fichier, "\")))
Set WordDoc = WordApp.Documents.Open(Filename:=Chemin_Fichier)
WordApp.Visible = True
WordApp.Documents(Fichier).Activate
WordApp.Run "merge_word"
With WdDoc
Name:=Source, _
LinkToSource:=True, _
Format:=wdOpenFormatAuto, _
SQLStatement:="SELECT * FROM `Données_Mailing$`"
End With
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
Does anyone has already reproduce an excel table in word. I'm trying to do
that (the programmation is below) but it is very complex. I'm looking for
information to help me to progress.
What the program do is a mailmerge executed from Excel. The excel file
contains a sheet for mail merge data and others sheets (table1.1, table1.2,
etc.) for tables used in the mailmerge document. When I execute the macro in
excel, the Word Macro is executed and all the tables are formatted in word
just before the mailmerge execution.
The table formating seems to be very complex because:
1) Text with bold and exponents, italic, size caracter, ...
tbl.cell(i,j) = rngExcel.Cells(i, j).Format 'give format of the first
character and not of all character. Does anyone know how to paste all cell
formatting in word? I don't know if doing a copy and paste is the best
solution because, some cells are merged in excel and I have to adjust
formatting (borders,horizontal alignment) thereafter.
2) In excel table, some cell contains text that go on the following cells. I
have to merge the table cells in Word to take this into account. Also, it is
possible that the cells are merge in excel.
3) Want to respect column width, borders, alignment etc.
4) I added a section to take NumberFormat from Excel.
etc.
Does anyone have already done something similar to this ?
Is there a simpler way to have great word table formatting without having to
program each things? example: copy paste the table using a pre-determined
table formating. After that, adjust borders, column width, some alignments, ..
Thanks a lot !
Alex
Sub Merge_Word()
Dim appWord As Word.Application
Dim docWord1 As Word.Document
Dim docWord2 As Word.Document
Dim appExcel As Excel.Application
Dim wbExcel As Excel.Workbook
Dim tbl As Word.Table
Dim oRow As Row
Dim rngExcel As Excel.Range
Dim pathExcel, strFormat, strBookMark As String
Dim iCol As Integer
Set appWord = Word.Application
Set docWord1 = appWord.ActiveDocument
On Error Resume Next
Set appExcel = GetObject(, "Excel.Application")
If appExcel Is Nothing Then
Set appExcel = CreateObject("Excel.Application")
End If
On Error GoTo 0
pathExcel = appExcel.ActiveWorkbook.Path & "\" &
appExcel.ActiveWorkbook.Name
' PathExcel = ActiveDocument.MailMerge.DataSource.Name
fileExcel = LCase(Right(pathExcel, Len(pathExcel) - InStrRev(pathExcel,
"\")))
On Error Resume Next
Set wbExcel = appExcel.Workbooks(fileExcel)
If wbExcel Is Nothing Then
Set wbExcel = appExcel.Workbooks.Open(FileName:=pathExcel,
UpdateLinks:=True, ReadOnly:=True)
' Set wbExcel = GetObject(PathExcel, "Excel.Workbook")
End If
On Error GoTo 0
For nbTab = 1 To 3
If nbTab = 1 Then
Set rngExcel = wbExcel.Application.sheets("table1.1").Range("table1_1")
Set rng = docWord1.Bookmarks("Table1_1").Range
ElseIf nbTab = 2 Then
Set rngExcel = wbExcel.Application.sheets("table1.2").Range("table1_2")
Set rng = docWord1.Bookmarks("Table1_2").Range
ElseIf nbTab = 3 Then
Set rngExcel = wbExcel.Application.sheets("table1.3").Range("table1_3")
Set rng = docWord1.Bookmarks("Table1_3").Range
End If
Set tbl = rng.Tables(1)
'1- Adjust number of rows
DerLineExcel = rngExcel.Rows.Count
DerLineWord = tbl.Rows.Count
j = DerLineExcel - DerLineWord
For k = 1 To j
tbl.Rows.Add
Next k
For k = 1 To -j
tbl.Cell(5, 1).Select
Selection.SelectRow
Selection.Rows.Delete
Next k
'2- Adjust number of columns
'3- Adjust column width
With tbl.Rows
.LeftIndent = 0
End With
UsableWidth = 432
TableWidth = 0
For CellNo = 1 To rngExcel.Rows(1).Cells.Count
TableWidth = TableWidth + rngExcel.Columns(CellNo).ColumnWidth
Next CellNo
For j = 1 To tbl.Columns.Count
For i = 1 To tbl.Rows.Count
tbl.Cell(i, j).Width = UsableWidth * rngExcel.Columns(j).ColumnWidth
/ TableWidth
Next i
Next j
'4- MergeCells
For i = 1 To rngExcel.Rows.Count
j = 1
Do Until j >= rngExcel.Columns.Count
With rngExcel
If .Cells(i, j).MergeCells = True Then
iCol = .Cells(i, j).MergeArea.Columns.Count
tbl.Cell(i, j).Select
Selection.MoveRight Unit:=wdCharacter, Count:=iCol - 1, Extend:=wdExtend
Selection.Cells.Merge
j = j + iCol
Else
j = j + 1
End If
End With
Loop 'j
Next i
'5- Remove all borders
With tbl
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
.Borders(wdBorderRight).LineStyle = wdLineStyleNone
.Borders(wdBorderVertical).LineStyle = wdLineStyleNone
.Borders(wdBorderDiagonalDown).LineStyle = wdLineStyleNone
.Borders(wdBorderDiagonalUp).LineStyle = wdLineStyleNone
.Borders(wdBorderHorizontal).LineStyle = wdLineStyleNone
.Borders(wdBorderVertical).LineStyle = wdLineStyleNone
End With
'6- Add borders
With tbl
For i = 1 To tbl.Rows.Count
For j = 1 To tbl.Columns.Count
With rngExcel.Cells(i, j)
With .Borders(xlEdgeTop)
If .LineStyle = xlContinuous Then
C = wdLineStyleSingle
tbl.Cell(i, j).Borders(wdBorderTop).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderTop).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderTop).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderTop).LineStyle =
wdLineStyleNone
End If
End With
With .Borders(xlEdgeBottom)
If .LineStyle = xlContinuous Then
tbl.Cell(i, j).Borders(wdBorderBottom).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderBottom).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderBottom).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderBottom).LineStyle =
wdLineStyleNone
End If
End With
With .Borders(xlEdgeLeft)
If .LineStyle = xlContinuous Then
tbl.Cell(i, j).Borders(wdBorderLeft).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderLeft).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderLeft).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderLeft).LineStyle =
wdLineStyleNone
End If
End With
With .Borders(xlEdgeRight)
If .LineStyle = xlContinuous Then
tbl.Cell(i, j).Borders(wdBorderRight).LineStyle =
wdLineStyleSingle
If .Weight = xlThin Then
tbl.Cell(i, j).Borders(wdBorderRight).LineWidth =
wdLineWidth025pt
ElseIf .Weight = xlMedium Then
tbl.Cell(i, j).Borders(wdBorderRight).LineWidth =
wdLineWidth150pt
Else
'MsgBox ("non defined excel border")
End If
Else
tbl.Cell(i, j).Borders(wdBorderRight).LineStyle =
wdLineStyleNone
End If
End With
End With
'With Selection.ParagraphFormat
' .LeftIndent = CentimetersToPoints(0)
' .SpaceBeforeAuto = False
' .SpaceAfterAuto = False
'End With
'7- Add data with formating
strData = rngExcel.Cells(i, j)
If IsNumeric(strData) And strData <> "" Then
strFormat = rngExcel.Cells(i, j).NumberFormat
If strFormat = "#,##0_);(#,##0)" Or strFormat = "# ##0_-;(#
##0)" Or strFormat = "#,##0_-;(#,##0)" Then ' voir ajout de n'importe quel _)
strFormat = "#,##0;(#,##0)"
End If
strData = Format(strData, strFormat)
If Right(strData, 1) = ")" Then
.Cell(i, j).Select
With Selection.ParagraphFormat
.RightIndent = CentimetersToPoints(-0.13)
.SpaceBeforeAuto = False
.SpaceAfterAuto = False
End With
Else
.Cell(i, j).Select
With Selection.ParagraphFormat
.RightIndent = CentimetersToPoints(0)
.SpaceBeforeAuto = False
.SpaceAfterAuto = False
End With
End If ')"
End If 'IsNumeric
.Cell(i, j).Range.text = strData
Next j
Next i
End With
Next nbTab
Exit Sub
'8- Add text to document
strBookMark = wbExcel.Path & "\bookmark1.doc"
Set docWord2 = appWord.Documents.Open(strBookMark, ReadOnly:=False)
docWord2.Bookmarks(1).Range.Select
Selection.Copy
docWord1.Bookmarks("Bookmark1").Range.Select
Selection.Paste
docWord2.Close
'9- Mailmerge execution
With docWord1.MailMerge
ActiveDocument.MailMerge.OpenDataSource Name:= _
pathExcel, ConfirmConversions:=False, ReadOnly:= _
True, LinkToSource:=True, AddToRecentFiles:=False,
PasswordDocument:="", _
PasswordTemplate:="", WritePasswordDocument:="",
WritePasswordTemplate:= _
"", Revert:=False, Format:=wdOpenFormatAuto, Connection:= _
"Provider=Microsoft.Jet.OLEDB.4.0;Password="""";User ID=Admin;Data
Source=C:\rap_modele_ameliorations.xls;Mode=Read;Extended
Properties=""HDR=YES;IMEX=1;"";Jet OLEDB:System database="""";Jet
OLEDB:Registry Path="""";Jet OLEDBatabase Password="""";Jet OLEDB:Engine " _
, SQLStatement:="SELECT * FROM `merge$`", SQLStatement1:="",
SubType:= _
wdMergeSubTypeAccess
.Destination = wdSendToNewDocument
With .DataSource
.FirstRecord = 1
.LastRecord = 1
End With
.Execute Pause:=False
End With
docWord1.Close (False)
' AppWord.Application.Quit
'10- Reset variables
Set appWord = Nothing
Set docWord1 = Nothing
Set appExcel = Nothing
Set wbExcel = Nothing
Set rngExcel = Nothing
Set rng = Nothing
Set tbl = Nothing
Set docWord2 = Nothing
End Sub
Sub Mailmerge_execution_from_excel()
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
Dim Chemin, Fichier, Chemin_Fichier, Source As String
ChDrive ActiveWorkbook.Path
ChDir ActiveWorkbook.Path
Chemin_Fichier = Application.GetOpenFilename()
Source = ActiveWorkbook.Name
PathExcel = ActiveWorkbook.Path & "\" & Source
On Error Resume Next
Set WordApp = GetObject(, "Word.application")
If WordApp Is Nothing Then
Set WordApp = CreateObject("Word.Application")
End If
On Error GoTo 0
Fichier = LCase(Right(Chemin_Fichier, Len(Chemin_Fichier) -
InStrRev(Chemin_Fichier, "\")))
Set WordDoc = WordApp.Documents.Open(Filename:=Chemin_Fichier)
WordApp.Visible = True
WordApp.Documents(Fichier).Activate
WordApp.Run "merge_word"
With WdDoc
Name:=Source, _
LinkToSource:=True, _
Format:=wdOpenFormatAuto, _
SQLStatement:="SELECT * FROM `Données_Mailing$`"
End With
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub