| Using InDesign CS and Access for Data-generated Page Composition: A Basic Example
by Max Dunn, Silicon Publishing |
||||
|
Adobe InDesign can be used as a powerful data-generated page composition system with
virtually any sort of database, thanks to the scripting support that InDesign provides on the
Macintosh and PC platforms. On the Macintosh, this can be done with AppleScript, while on the PC this
can be done with VB or any of its variants (VBA, VBScript, VB.NET).
Let's look at a basic example of data-generated page composition with InDesign: a watch catalog scripted with VBA from within Microsoft Access. |
||||
| Running the Example | ||||
|
Example Files
To run the example, download the .zip file and extract its contents into a new folder, leaving "use folder names" checked so that unzipping creates an "Images" sub-folder within the folder you extract to. First*, open InDesign. Then open the database, and click on "Run Example". If all goes right, the program should create a simple watch catalog. Pretty cool, eh? Imagine, all you have to do is change the database content, perhaps change the watch images, and re-running the program will recreate the directory with updated content. * Note: The template depends on two fonts: Myriad Pro Condensed, and Myriad Pro Bold Condensed. If you don't have these fonts, before running it you will want to open StartTemplate.indd, set the paragraph and character styles to reference fonts that are on your system, then save and close the file. |
||||
| Coding the Catalog | ||||
|
How did that work? Let's go step-by-step through the creation of the catalog. Keep in mind that there are many ways to do this sort
of thing, this example uses but one approach.
Before working in VBA, we should understand the Indesign output that we are going to want for the catalog. In this case, we first create a blank Indesign template (StartTemplate.indd) that contains the basic layout preferences, as well as Paragraph and Character styles that we'll use when we actually add some content. The script will start by opening this file.
|
||||
| Creating a Source Query in Access | ||||
The table we'll be generating our catalog from has the following design:
![]() However, rather than basing our output directly on the table itself, we
will base it on a query (or in some cases a SQL statement defining a query). This lets us control the way the output
is filtered and/or sorted. So in the Access database we will create a query, "qryOutput" which we will reference in the VBA code. In this case it is
a very simple query - in design view it looks like:
|
||||
| Working with VBA in Access | ||||
|
To code the VBA in access, we will first create a new module. From the Database window in Access, click on "Modules" then "New." This will
open up the VBA editor, where we'll write the code.
The first step in working with VBA in Access is to set the references properly: Access by default doesn't know about InDesign, and we are going to use a data access method that is not the default method of Access either. So it is necessary to tell Access where these libraries are:
Now we can start coding. First, let's type "Option Explicit" at the top of the module: this forces us to declare every variable we use - this may sound tedious, but it pays off in the long run. Then, we'll create the function that creates the catalog. You can paste the source code of this function into your module (below Option Explicit), then run the code by clicking anywhere in the function and Choosing Run\Run Sub (or by clicking on the triangular blue "Run" button on the standard toolbar). |
||||
| Looking at the VBA Code | ||||
While it might at first look like a huge program, the VBA function can be analyzed in terms of its sections and their sub-sections and
things will become more clear. There are four main sections:
|
||||
| The Main Loop | ||||
|
Looping through the recordset is of course where the main work is done, and that itself can be divided into subsections. Let us consider the loop itself. The loop is the whole body of code going from: Do While Not rs.EOFuntil: LoopThe first bit, "Do While Not rs.EOF" means "keep going until the recordset (rs) has an end-of-file condition (EOF)": in other words, move through the whole recordset. One cycle of the loop corresponds to one of the 12 products on a page. Importantly, right before the "Loop" line (which means "go back to the 'Do While...' at the top"), there is the line: rs.MoveNextwhich means "move to the next record" (if we didn't have this, the loop would be infinite, as it would stay on the current record and EOF would never be met). So the loop iterates through each row of the query that we've set our recordset object (rs) to refer to. Within the loop, what are we doing? We are creating one box on the page for the current record, including the rectangle, line, image, and text that we identified earlier when we were considering the layout. Within the loop the program follows the following steps:
|
||||
| Writing Text from the Database | ||||
|
Populating the text frame itself involves using insertion points to output static text as well as values from the database. The output for each of the fields is similar: ' Product code
Set oPoint = oPoints.Item(oPoints.Count)
oPoint.AppliedParagraphStyle = oDocument.ParagraphStyles.Item("Body Text")
oPoint.AppliedCharacterStyle = oDocument.CharacterStyles.Item("Bold")
oPoint.Contents = "Product Code: " & vbTab
Set oPoint = oPoints.Item(oPoints.Count)
oPoint.AppliedCharacterStyle = oDocument.CharStyles.Item("Plain")
sBuf = rs.Fields("ProductCode")
oPoint.Contents = sBuf & vbLf
First the current insertion point is set to the latest one in the current story (in this example each text frame has its own story: the 12 textframes on a
page are not threaded together). Then the paragraph style is set, which will apply to the entire story. Then the
"Bold" character style is applied to the insertion point, before writing the static text corresponding to the
current field. A tab ("vbTab" is the Visual Basic variable for a tab, the VB concatenation operator is "&") is concatenated
to the static text to properly position the field value after its name: before outputting the value, the current insertion point
is established and the "Plain" character style set.
Most fields are separated by a linefeed ("vbLf" is the Visual Basic variable for a linefeed): Retail Price and Sale Price, however, stay on the same line, so the output of the sale price ends with a tab instead of a linefeed.
|
||||
Conclusion
|
||||
| This should provide a general introduction to data-generated page composition with InDesign and Access. Feel free to e-mail any questions or suggested improvements to the code. A great source of additional information is the InDesign Scripting forum at Adobe user to user forums. | ||||