Retrieving Custom Building Blocks from Templates in Word 2007
Applies to: 2007 Microsoft Office System, Microsoft Office Word 2007
Joel Krist, Akona Systems
May 2007
Code It | Read It | Explore It
Code It
This how to topic demonstrates how to programmatically retrieve a custom building block from a template by walking through five key steps:
Create a Windows console application in Microsoft Visual Studio 2005.
Add a reference to the Word 12.0 Object Library.
Import the Word interop assembly namespace.
Declare the appropriate variables.
Implement the custom building block retrieval code.
Note |
---|
The example code assumes that there is a custom headers building block named "Header Test" in the "Building Block Tests" category of the "Building Blocks.dotx" template. |
Create a Windows Console Application in Visual Studio 2005
This how-to topic creates a Microsoft Windows console application to illustrate how to retrieve a custom building block from a template. However, the example code is not specific to a Windows console application and you can use it in a variety of application types.
To create a Windows console application in Visual Studio 2005
Start Visual Studio.
On the File menu, select New, and then Project. The New Project dialog box appears.
In the Project Types pane, select Visual C# or Visual Basic and then select the Windows category.
In the Templates pane, select Console Application.
Specify a name for the project.
Specify a location for the project and click OK. Visual Studio generates a Windows Console Application project with a single source file in it called Program.cs or Module1.vb, depending on the language you selected.
Add a Reference to the Word 12.0 Object Library
You must add a reference to the Microsoft Word 12.0 Object Library to the Visual Studio project to enable the Excel object model to be programmed against.
To add the reference to the Microsoft Word 12.0 Object Library
On the Project menu, select Add Reference. The Add Reference dialog box appears.
In the Add Reference dialog box, select the COM tab, then locate and select the Microsoft Word 12.0 Object Library component.
Click OK to add the reference.
Figure 1. Adding a Reference
Import the Word Interop Namespace
Import the Microsoft.Office.Interop.Word namespace to allow the objects defined in the namespace to be used without having to specify the fully qualified namespace path. To import the namespace, open the Program.cs or Module1.vb source file and add the following code to the top of the source file. For a Microsoft Visual Basic project, add the code to the very top of the source file, above the Module statement. For a Microsoft Visual C# project, add the code before the namespace statement and right after the default using statements created by Visual Studio.
Imports Microsoft.Office.Interop.Word
using Microsoft.Office.Interop.Word;
Declare Appropriate Variables
Add the following code to declare variables to hold references to the Word objects that are used in the custom building block retrieval code. For a Visual Basic project, add all of the following variable declarations within Sub Main(). For a C# project, add all of the following variable declarations within the Main() function.
Dim wordApplication As ApplicationClass = Nothing
Dim wordDocument As Document = Nothing
Dim wordTemplate As Template = Nothing
Dim wordBuildingBlock As BuildingBlock
ApplicationClass wordApplication = null;
Document wordDocument = null;
Template wordTemplate;
BuildingBlock wordBuildingBlock;
The custom building block retrieval code shown later inserts the retrieved building block into a new document and saves the file. Add the following statement to declare a variable to hold the path and file name of the new document. Replace the Path placeholder with a path to an appropriate folder.
Dim paramDocPath As String = "Path\Test.docx"
Object paramDocPath = @"Path\Test.docx";
Next, add the following code to declare variables for the properties of the building block to retrieve.
Dim paramBBType As WdBuildingBlockTypes = _
WdBuildingBlockTypes.wdTypeCustomHeaders
Dim paramBBCategory As String = "Building Block Tests"
Dim paramBBName As String = "Header Test"
WdBuildingBlockTypes paramBBType = WdBuildingBlockTypes.wdTypeCustomHeaders;
object paramBBCategory = "Building Block Tests";
object paramBBName = "Header Test";
Next, declare the following C# variables to help with calling methods in the Word object model that accept optional parameter and by reference parameters:
object paramMissing = Type.Missing;
object paramTemplateIndex = 1;
object paramFalse = false;
The paramMissing variable is used when calling methods that accept optional parameters. Optional parameters are only optional when using Visual Basic. A value must be specified for optional parameters when using C#. Using Type.Missing as the value for an optional parameter tells the method being called that the parameter is not being specified and that the method should use the parameter's default value.
The paramTemplateIndex variable and the paramFalse variable are used to ease calling the ApplicationClass.Templates.get_Item method and the Document.Close method that accept parameters of type object passed by reference. By declaring and initializing the variables for the parameters as objects, it is possible to pass them by reference.
Implement the Building Block Retrieval Code
The next step is to add code that retrieves a custom building block. The code in the following code example does the following:
Starts Word and creates a new document.
Gets the "Building Blocks.dotx" template to retrieve the building block from.
Retrieves the "Header Test" custom headers building block from the "Building Blocks.dotx" template.
Inserts the building block into the primary header of the first section of the document.
Saves the document and closes Word.
The shutdown-related code closes the Word document, quits the Word application, releases references to the underlying Word COM objects, and makes calls to the garbage collector in the .NET Framework. For more information about releasing COM objects when using managed code, see Chapter 2: Basics of Office Interoperability (Part 2 of 3), from the book, Microsoft .NET Development for Microsoft Office.
Try
' Start an instance of Word.
wordApplication = New ApplicationClass()
' Create a new document.
wordDocument = wordApplication.Documents.Add()
' Load the "Building Blocks.dotx" template.
' After calling LoadBuildingBlocks Building Blocks.dotx
' will be Templates(1).
wordApplication.Templates.LoadBuildingBlocks()
wordTemplate = wordApplication.Templates(1)
' Access the "Header Test" custom headers building block
' through its type, category, and name.
wordBuildingBlock = _
wordTemplate.BuildingBlockTypes.Item(paramBBType) _
.Categories.Item(paramBBCategory).BuildingBlocks.Item(paramBBName)
' Insert the building block into the primary header of the first
' section of the document.
wordBuildingBlock.Insert(wordDocument.Sections(1) _
.Headers(WdHeaderFooterIndex.wdHeaderFooterPrimary).Range)
' Save the document.
wordDocument.SaveAs(paramDocPath)
Catch ex As Exception
' Respond to the error.
Finally
' Release references to the Word objects.
wordBuildingBlock = Nothing
wordTemplate = Nothing
' Close and release the Document object.
If Not wordDocument Is Nothing Then
wordDocument.Close(False)
wordDocument = Nothing
End If
' Quit Word and release the ApplicationClass object.
If Not wordApplication Is Nothing Then
wordApplication.Quit()
wordApplication = Nothing
End If
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
try
{
// Start an instance of Word.
wordApplication = new ApplicationClass();
// Create a new document.
wordDocument = wordApplication.Documents.Add(ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing);
// Load the "Building Blocks.dotx" template.
// After calling LoadBuildingBlocks Building Blocks.dotx
// will be Templates(1).
wordApplication.Templates.LoadBuildingBlocks();
wordTemplate = wordApplication.Templates.get_Item(
ref paramTemplateIndex);
// Access the "Header Test" custom headers building block
// through its type, category, and name.
wordBuildingBlock =
wordTemplate.BuildingBlockTypes.Item(paramBBType)
.Categories.Item(ref paramBBCategory)
.BuildingBlocks.Item(ref paramBBName);
// Insert the building block into the primary header of the first
// section of the document.
wordBuildingBlock.Insert(wordDocument.Sections[1]
.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range,
ref paramMissing);
// Save the document.
wordDocument.SaveAs(ref paramDocPath, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing);
}
catch (Exception ex)
{
// Respond to the error
}
finally
{
// Release references to the Word objects.
wordBuildingBlock = null;
wordTemplate = null;
// Close and release the Document object.
if (wordDocument != null)
{
((_Document)wordDocument).Close(ref paramFalse, ref paramMissing,
ref paramMissing);
wordDocument = null;
}
// Quit Word and release the ApplicationClass object.
if (wordApplication != null)
{
wordApplication.Quit(ref paramMissing, ref paramMissing,
ref paramMissing);
wordApplication = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
Read It
The example C# code shown in the previous example uses the Type.Missing object to specify that an optional parameter was not provided and that the default parameter value should be used. To change the behavior to use something other than the defaults, specify the appropriate parameter types and values. For more information about the methods used in the sample code and the parameters they accept, see the Word 2007 Object Model Reference.