This problem is ideal for automation. To me it seems you should be able to have a basic template and fill in the information pretty much purely based on the Excel spreadsheet with the Machine information.
Bookmarks in Word are you friend here. You can use them to initially place your tables and figures and also to update them if new information becomes available (although this requires extra effort).
I’ve done a fair bit of work importing data from Excel to Word as tables and would definitely recommend against importing tables as pictures. Your file size will balloon out really quickly and people that want to electronically extract data from the tables will want to stab you with rusty teaspoons.
From the information you’ve provided I’d probably begin your code in Excel with the Excel template as the active workbook. This is the way I’d set it up:
- Start with an add-in that displays a ribbon tab. This can be used for any ‘machine’ excel template.
- Use OLE automation to open Word and create a new document from the Word template (there is plenty of info on the net to do this)
- Read in the structure of the document from the Excel Template and set up the word document. Since you know the layout you can populate placeholders (bookmarks) for all of the figures and tables along with captions.
- Loop through all the tables and insert them first. The trick with inserting tablular data from Excel to Word is to insert the table as delimited text and then convert it to a table.
- Loop through and insert all the figures.
- If you encapsulate the figures with a bookmark and add a bookmark to the tables you can then update them individually as needed.
Note, that none of these options are that trivial by themselves. If you want to apply extra formatting like bold headings, merged cells or tables that split over pages then it is considerably more work.
You can use field codes to sequentially update table and figure numbers and again bookmarks to provide cross-references.
The question is quite broad to provide a lot of code, but the following example subs and functions should be enough to get you started. If you have further questions you should start a new question for them.
With an input of the Word Document (created from the Template and already populated with the bookmarks defining table locations) and the names of all the tables you have, the following functions will populate those tables into Word.
Sub PopulateTables(wdDoc As Word.Document, vTableArray As Variant)
Dim ii As Integer, rInputData As Range
'Loop through all the bookmarks
For ii = LBound(vTableArray) To UBound(vTableArray)
'Get the name of the current table from the list in the Excel template
sTableName = vTableArray(ii)
'Check if the bookmark exists in the document
If wdDoc.Bookmarks.Exists("tblplc_" & sTableName) Then
'Use the function to check if there is a table already at the bookmark
Call CheckTableBookMark(wdDoc, "tblplc_" & sTableName)
'Get the range of the information to be put into the table here.
'THIS WILL BE YOUR OWN CUSTOM FUNCTION
Set rInputData = GetMyInputData(sTableName)
'Insert the data into Word
Call CreateTableFromString(wdDoc.Bookmarks("tblplc_" & sTableName).Range, rInputData)
End If
Next ii
End Sub
This function will delete any existing table at a bookmark and ensure there is a fresh bookmark for new data:
Sub CheckTableBookMark(wdDoc As Word.Document, sTargetBM As String)
'Function to delete any existing tables at a bookmark.
With wdDoc
.Activate
.Bookmarks(sTargetBM).Select
'If the bookmark has a table in it then we need to delete it
If .Bookmarks(sTargetBM).Range.Tables.Count > 0 Then
.Bookmarks(sTargetBM).Range.Tables(1).Delete
'If the bookmark was 'inside' the table it may have been deleted. Put it back in
If Not .Bookmarks.Exists(sTargetBM) Then
.Application.Selection.TypeParagraph
.Application.Selection.MoveLeft Unit:=wdCharacter, Count:=1
.Bookmarks.Add sTargetBM
Else
.Bookmarks(sTargetBM).Range.Select
.Application.Selection.TypeParagraph
End If
'Do custom formatting here as required.
.Bookmarks(sTargetBM).Range.Style = "Normal"
.Bookmarks(sTargetBM).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter
End If
End With
End Sub
The following two functions will Build a string containing the data and then convert it into a table for you:
Sub CreateTableFromString(ByRef rWordRange As Word.Range, rFromRange As Range)
Dim tblWordTarget As Word.Table
'Build the data from the Excel Spreadsheet and set it to the word range
rWordRange.Text = BuildDataString(rFromRange)
Set tblWordTarget = rWordRange.ConvertToTable(vbTab, AutoFitBehavior:=wdAutoFitFixed, DefaultTableBehavior:=wdWord8TableBehavior)
'Do stuff with the table here (eg apply formatting etc)
Set tblWordTarget = Nothing
End Sub
Function BuildDataString(rFromRange As Range) As String
Dim sData As String, nrRow As Long, nrCol As Integer, iTotalColumns As Integer
'Convert the input range to a variable and determine the number of columns
vData = rFromRange.Value
iTotalColumns = UBound(vData, 2)
'Loop through all the elements in the array
For nrRow = LBound(vData, 1) To UBound(vData, 1)
For nrCol = 1 To iTotalColumns
'Depending on what type of data is encountered either add it to the string or substitute something
'You'll want to modify this as needed
If IsError(vData(nrRow, nrCol)) Then
sData = sData & "Error"
ElseIf vData(nrRow, nrCol) = "" Or vData(nrRow, nrCol) = 0 Or vData(nrRow, nrCol) = "-" Then
sData = sData & VBA.Chr$(150)
Else
sData = sData & vData(nrRow, nrCol - iIncrement)
End If
'Use tab delimiters for Word to know where the columns are
If nrCol < iTotalColumns Then sData = sData & vbTab
Next nrCol
'Add a carriage return for each new line
If nrRow < UBound(vData, 1) Then sData = sData & vbCr
Next nrRow
'Return the completed string
BuildDataString = sData
End Function
Current Template
This Word VBA macro will display the current template:
Sub DisplayCurrentTemplate()
'displays full path of template active document
MsgBox ActiveDocument.AttachedTemplate.FullName, , "Template location"
End Sub
Make New Template
This Word VBA macro will make a new template:
Sub MakeNewTemplate()
'creates a new doc and saves as a template
Dim strName As String
Dim strPath As String
Dim oDoc As Document
strPath = Options.DefaultFilePath(wdUserTemplatesPath) & Application.PathSeparator 'find where templates are stored at user's computer
strName = "Sample automateexcel.com template.dotm"
Set oDoc = Documents.Add 'create a new doc and asign it to oDoc variable
'write some text in the new doc reffering to it using oDoc variable
oDoc.Range.InsertBefore "Sample template"
oDoc.Range.InsertParagraphAfter
oDoc.Range.InsertAfter "Visit https://www.automateexcel.com/vba-code-library"
oDoc.SaveAs FileName:=strPath & strName, FileFormat:=wdFormatXMLTemplateMacroEnabled, AddToRecentFiles:=False
oDoc.Close wdDoNotSaveChanges 'close doc
End Sub
Всем привет. Написал отдельный модуль (класс), вроде работает. Прикладываю в спойлер.
Ну и пример использования. Если кто найдет ошибку, с радостью приму комментарии
Код |
---|
Set act = New WordGenerator With act .template_add "courtиск.docx" 'Добавили шаблон в папке templates проекта .template_add "С:претензия.docx" 'добавили шаблон абсолютного пути .dialog = True 'И этого нам мало, мы спрашиваем юзера, чтобы тоже указал шаблоны .multiselect = True 'да и пусть еще мог бы выбрать сразу несколько в диалоговом окне .closeafter = True 'Юзер не хочет редактировать готовый файл, закрываем его .marker = "Иванов 2017" 'а это припишется к каждому создаваемому файлу .SetSaveFolder = "Все по Иванову" 'а это папка, куда будет складываться все с этого объекта .pair_add "ФИО", "Иванов Иван Иванович" 'парочка пар на замену, можно и сотню .pair_add "[должность]", "директор" .Start 'запускаем процесс, смотрим как открываются ворд файлики, 'производятся замены. сохраняется и закрывается, результат ищем в папках End With |
Скрытый текст |
---|