Gordon McComb

How to Use VB.NET to Create WordPerfect Merge Data Files

Instantly build merge data files from any data source

Data, data, everywhere - but how to get that data into WordPerfect for merging?

From product databases to client lists to your latest roster of newsletter readers, today's business turns on data. This data must often be combined with - merged - boilerplate text to create brochures, Web pages, letters, labels, personalized fax and email, or whatever. WordPerfect's built-in merge feature is the perfect choice for this merging process.

Alas, your source data may not always be in a form that WordPerfect can readily use as merge data. WordPerfect lets you pull data from a number of sources (called providers), including comma delimited files, databases that support the ODBC standard - such as Microsoft Access files - even Quattro Pro worksheets.

Depending on the layout of the data, some of these data providers may present quite a challenge. Frustration can run high getting these providers to cooperate. Support for the full range of query and filtering options may be lacking, and for some formats (like text files), the merging process can be slow.

Use a WordPerfect Data Merge File Instead

These technical issues are avoided when using WordPerfect's native merge data files. These are ordinary WordPerfect document files, but are specially formatted to contain a list of optional field names at the top. One or more records then follow, each separated by ENDRECORD codes. Fields within each record are marked by ENDFIELD codes. Simple, and sweet.

Too, having your data in a WordPerfect file makes merging process easier for many users, especially those without extensive experience with the program.

Ideally, what you want is a way to convert the data from whatever non-WordPerfect form it is in now, to a real honest-to-goodness WordPerfect merge data file.

Sure, you could always retype the data, but a better way is to use the power of Visual Basic .NET to pull the data from any of several dozen supported provider formats, and then create a WordPerfect data file for direct use in your merge.

In this tutorial, we'll show how to collect data in a Visual Basic .NET program of your own devising, then build a ready-to-go WordPerfect merge file. The original source of the data is not of concern to us this time around - it could be an XML document, an ODBC source, an Excel spreadsheet, a SQL database, whatever.

We're mostly concerned with how to take the data and create a WordPerfect format file, complete with field names and field/record codes.

Setting Up the WordPerfect Merge Project

To save you time, you can download the demo project from the link at the bottom of this tutorial. The project was created in Visual Basic .NET 2008 Express. You can use this or any later version of VB.NET to open and run the project solution files.

Begin by creating a new project in Visual Basic .NET. You may give the project any name you wish. For the sample demo we've named the project WPMerge.

On the main form add two buttons and a set of labels and text boxes, as shown in the figure.

From top to bottom, the control names for the text boxes should be as follows:

  • txtName
  • txtEmail
  • txtPhone
  • txtFilePath

Name and label the buttons as follows:

  • Top button name: btnCreate
  • Top button text: Create
  • Bottom button name: btnClose
  • Button button text: Close

Open the code editor for the main form, and add the following line above the form class definition:

Imports System.Runtime.InteropServices

Add the following code block within the Form1 class definition:

Dim Filename As String = "c:\wpdata.wpd"
Dim Fieldnames As String = "Name;Email;Phone"
Dim FieldDataName As String = "Bill Johnson"
Dim FieldDataEmail As String = "bill.johnson@someplace.edu"
Dim FieldDataPhone As String = "800-987-1234"
Private FileHandle As IntPtr = Nothing
Private Sub Form1_Load(ByVal sender As Object, _
  ByVal e As System.EventArgs) Handles Me.Load
 txtName.Text = FieldDataName
 txtEmail.Text = FieldDataEmail
 txtPhone.Text = FieldDataPhone
 txtFilePath.Text = Filename
 End Sub

Private Sub btnCreate_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles btnCreate.Click
 Dim Coll As New Collection
 Coll.Add(txtName.Text, "Name")
 Coll.Add(txtEmail.Text, "Email")
 Coll.Add(txtPhone.Text, "Phone")
 If (txtFilePath.Text <> "") Then
   CreateDataFile(txtFilePath.Text, Fieldnames, Coll)
   MsgBox("Please provide a filename.")
 End If
End Sub

Private Sub btnClose_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles btnClose.Click
End Sub

Private Sub CreateDataFile( _
  ByVal FileName As String, _
  ByVal FieldNames As String, _
  ByVal Fields As Collection)
   FileHandle = WPFormat.InitDataFile(2, FileName)
   If (FileHandle.ToInt32 > 0) Then
     Dim Count As Integer
     Dim FieldNamesSplit = FieldNames.Split(";"c)
     For Count = 0 To FieldNamesSplit.Count - 1
     MsgBox("Some kind of freaky error occurred when attempting" & _ 
		   " to create the data file.")
   End If
   Catch ex As Exception
      MsgBox("Some really nasty kind of error occurred. Maybe the WPFormat.dll" & _
        " file cannot be found, or the you didn't provide a valid filename," & _
        " or you don't have write access to the file location you specified.")
   End Try
End Sub

Private Sub AddFieldNames(ByVal FieldNames As String)
   WPFormat.CreateFieldNames(FileHandle, FieldNames, FieldNames.Split(";"c).Count)
End Sub

Private Sub AddField(ByVal FieldValue As String)
   WPFormat.AddField(FileHandle, FieldValue)
End Sub

And finally, add the following text after the Form1 class definition:

Public Module WPFormat

<DllImport("WPFormat.dll", EntryPoint:="MRGInitDataFile")> _
Public Function InitDataFile(ByVal Version As Byte, _
<MarshalAs(UnmanagedType.LPStr)> ByVal DataFileName As String) As IntPtr
End Function <DllImport("WPFormat.dll", EntryPoint:="MRGCreateFieldNames")> _
Public Sub CreateFieldNames(ByVal FileHandle As IntPtr, _
<MarshalAs(UnmanagedType.LPStr)> ByVal FieldNames As String, _
ByVal FieldCount As Integer)
End Sub <DllImport("WPFormat.dll", EntryPoint:="MRGAddField")> _
Public Sub AddField(ByVal FileHandle As IntPtr, _
<MarshalAs(UnmanagedType.LPStr)> ByVal FieldText As String)
End Sub <DllImport("WPFormat.dll", EntryPoint:="MRGEndRecord")> _ Public Sub EndRecord(ByVal FileHandle As IntPtr) End Sub <DllImport("WPFormat.dll", EntryPoint:="MRGCloseDataFile")> _ Public Sub CloseDataFile(ByVal FileHandle As IntPtr) End Sub End Module

Testing and Running the Demo Application

Run the demo application by pressing F5 in the VB.NET program. The data form dialog should appear. Default text is provided, but you can change it by typing into the text boxes.

  • Click the Create button to generate the merge data file. If all goes well, a message box indicating "Done" should appear.
  • Click the Close button to exit the application.

Find the just-made merge file and open it in WordPerfect. You should see a document with a FIELDNAMES code at the top, followed by a single record.

The record is marked off with an ENDRECORD code. The three fields within the record are delimited with ENDFIELD codes.


The default data file location is c:\wpdata.wpd. You need access rights to the root folder of your c: drive in order to save a file here.

If you don't have sufficient rights, the file will not be written. In the File Path box specify a different file location where you have sufficient rights.

The WPFormat.dll File Does the Heavy Lifting

The "secret" behind the WPMerge demo is the use of the WPFormat.dll library file. This library, provided for free from Corel as part of their software development kit, does all the real work of turning data into a WordPerfect document. The WPFormat library file is included with the demo application, and is allowed to be redistributed.

Let's take a closer look at how the demo application works.

Private Variables for Default Data

A series of Dim statements appear at the top of the program to set up default data. The data is used for demonstration purposes.

In a real application, you wouldn't have these variable assignments. Instead, your record information would come from whatever data provider you are using. That can be any of several dozen sources, including of course manual entry into text boxes, just as we show here.

More than likely, though, you'll pull in data you've gotten from the SQL server in your office, or collected from an Excel worksheet, or queried from an ODBC data source. Or so on. For this tutorial we've kept the project simple, to help you more easily adapt it to whatever data resource you plan on using.

The Form1_Load routine takes the data stored in the private variables, and inserts them into the four text boxes when the application first starts.

Understanding the Button Events

The btnCreate_Click and btnClose_Click events handle what happens with the Create and Close buttons are clicked, respectively.

  • btnCreate_Click sets up a simple collection that imitates data from a tabular database. The data is defined as a value+key pair: The value is the field data itself; the key is the name for that field. The demo application defines three fields: Name, Email, and Phone. The source of the field value is the four text boxes on the main form.
  • btnClose_Click closes the form, which ends the demo.

Understanding the CreateDataFile Method

The bulk of the action takes places in the CreateDataFile method. The method is passed three parameters:

  • The name of the data file created by the demo application. The default is c:\wpdata.wpd.
  • The name of the fields you are using. The fields are separated by a semi-colon. This text is used not only to define the FIELDNAMES code, but also when iterating through the collection to match up key and value pairs.
  • The collection of field data. A For loop in the CreateDataFile method iterates through the collection, and inserts the fields one by one.

To begin, CreateDataFile uses a method of WPFormat.dll to create an empty WordPerfect data file. This WPFormat.dll method, called InitDataFile, expects two parameters: a version number (2 means create a WordPerfect 8 or later document), and a filename for the document.

The value returned by this method is a Windows file handle. If the number of the handle is greater than zero, we can assume the method worked, and the empty document was created. In that case, the demo application adds the field names and fields for the record, followed by yet another method of WPFormat.dll, CloseDataFile. This method completes and closes the file, making it ready for use.

CreateDataFile is aided by two "helper" methods, AddFieldNames and AddField. AddFieldNames uses a method of the WPFormat.dll to insert the FIELDNAMES code. AddField inserts the field text, as well as the ENDFIELD code.

Defining Access to the WPFormat.dll Methods

As noted previously, our demo program uses an external Windows library file - WPFormat.dll - to actually build the WordPerfect file. In order to access this library we have to define how to access the methods contained within it. This is the job of the WPFormat module, which appears outside of the Form1 class.

The contents of the module is a series of five DllImport definitions, each one specifying how to communicate with the five merge file methods of the WPFormat.dll library. For example, the first DllImport statement defines how the InitDataFile method is to be used.

Let's look at InitDataFile more closely. First off, the actual name of the method in the WPFormat.dll library is MRGInitDataFile, so this is noted. Also noted are the parameters the method expects, and the data type for each of the parameters.

Some methods in WPWFormat.dll return a value. These are defined as Functions. Those that don't return a value are defined as Subs.

A Note About 64-Bit Windows

The WPFormat.dll library is a 32-bit library. Unless you tell it otherwise, Visual Basic .NET will create an executable program file that can run either in 32-bit Windows, or 64-bit Windows.

When running your program in 64-bit Windows you should be sure to change the target platform, using Build, Configuration Manager. Select x86 for the Platform. This ensures that the program you create is defined as a 32-bit application. Doing so prevents an error from occurring when your program connects with the 32-bit WPFormat.dll library.

With 64-bit versions of Windows becoming more and more common, it's a good idea to get into the habit of always choosing the x86 platform when building any VB.NET program that relies on WPFormat.dll - or any 32-bit DLL file library, for that matter.

Automagically Put the WPFormat.dll File In the Program Output Directory

You do not need to copy the WPFormat.dll file to your Windows System folder. In fact, the better practice is to provide it in the same folder as your program. This is the default behavior of the demo application.

The WPFormat.dll library is added to the project as a resource, and is included as one of the project files.

The resource is then marked with the notation Copy if newer, which places a copy of the file into the program (output) directory. Copy if newer always puts a copy into whatever output directory you are using, but only makes the copy if the file there is not yet present in the program output directory, or is older than the one in your project files.

Setting it to Copy if newer prevents the file from being recopied needlessly each time you rebuild your project.

Download the WPMerge demo application source and program files by right-clicking, then saving to your computer. Unzip the files to your usual VB.NET projects directory.

Text and project Copyright © 2010, Gordon McComb. Released under Creative Commons Attribution-Share Alike license. You may use, reproduce, modify, and distribute this code, as long as the above copyright and attribution is retained.

The included WPFormat.dll file is Copyright © 1999 - 2005 by Corel Corporation. Redistribution is permitted, when done so following their licensing agreement. For more information see Corel Partners WordPerfect SDK.