alog merge area", _ Title:="Incorrect Shape Type" End If End Sub
Now, we're ready to perform the catalog merge. The next code procedure executes the merge to a new publication, then assigns several tags to each page in the publication. These tags contain the following information:
- The file path and name of the data source used
- The table in the data source used
- The number of records included in the merge
- The publication that contains the catalog merge area used to generate the merge
- The data and time Publisher performed the merge
The code then calls two other procedures, which we'll examine in turn.
Sub TagMergePagesAndShapes() Dim d As Document Dim p As Page Set d = ActiveDocument.MailMerge.Execute(msoFalse, pbMergeToNewPublication) 'Add tags containing merge information 'to each page For Each p In d.Pages With p.Tags .Add "Data Source", ActiveDocument.MailMerge.DataSource.Name .Add "Data Source Table", ActiveDocument.MailMerge.DataSource.TableName .Add "Number of Records", ActiveDocument.MailMerge.DataSource.RecordCount .Add "Merge Pub", ActiveDocument.FullName .Add "Page Creation Date", CStr(Now) End With Next p 'Call sub to number tag shapes by record NumberRecordTags d, ActiveDocument 'Call sub to add values to the numbered tags AddValuesToTags d, ActiveDocument End Sub
The first of these functions numbers shapes containing tags sequentially throughout the publication. The code takes advantage of two facts:
- Publisher indexes Shape objects in the Shapes collection according to the order in which they were added to the page.
- When performing a merge, Publisher adds all the shapes for the first merge record, then all the shapes for the second, and so on throughout sequentially numbered pages.
Because of this, we can assume that the first shape in a publication with a tag named Item contains the Item data field value for the first record, and so on.
The code uses the FindShapesByTag method to identify all the shapes that contain a tag named for a specific data field (for example, Item). The code iterates through the resulting ShapeRange collection, sequentially numbering the value of each shape's Record tag. The first shape with an Item tag gets its Record tag value set to 1, the next shape to 2, and so on. The code does the same for tags named after each data field.
In essence, this code numbers shapes containing tags named after data fields sequentially. This enables us to determine relationships programmatically between the text boxes containing the tags. For example, the text box containing the Price tag where
Tags("Record").Value = 10 relates to the text box containing the Item tag where the Record tag value is 10 as well. We can tell which shapes contain data from which data record.
Function NumberRecordTags(d As Document, md As Document) Dim sr As ShapeRange Dim sh As Shape Dim t As Tag Dim i As Integer Dim ri As Integer With d 'For each data field in the merge data source For i = 1 To md.MailMerge.DataSource.DataFields.Count 'Find all shapes with a tag 'named the same as the specified data field Set sr = .FindShapesByTag(md.MailMerge.DataSource.DataFields.Item(i).Name) If Not sr Is Nothing Then ri = 1 For Each sh In sr For Each t In sh.Tags 'Find the corresponding Record tag 'in the shape 'and set its value If t.Name = "Record" Then t.Value = ri ri = ri + 1 Exit For End If Next t Next sh End If Next i End With End Function
We can go a step further. Now that we have the shapes containing the tags numbered sequentially, we can directly relate them to the records in the data source, which are also numbered sequentially. The following function sets the Value property of each tag named for a data field to the actual value in the corresponding data source record.
Again, the code uses the FindShapesByTag method to identify all the shapes that contain a tag named for a specific data field (for example, Item). Next, the code iterates through each record in the data source, setting each as the active record in turn.
Figure 2. Data source with selected active record
The code then finds the Shape object with the