Converting Word 2010 Documents from the DOCM to DOCX File Format by Using the Open XML SDK 2.0
Summary: Use the strongly typed classes in the Open XML SDK 2.0 to convert a Word document including VBA code (with a DOCM extension) to a standard document (with a DOCX extension), without loading the document into Microsoft Word.
Last modified: September 12, 2012
Applies to: Excel 2010 | Office 2010 | Open XML | PowerPoint 2010 | VBA | Word 2010
Published: September 2010
Provided by: Ken Getz, MCW Technologies, LLC
The Open XML file formats make it possible to programmatically modify the structure of Microsoft Word documents, but doing this requires some effort. The Open XML SDK 2.0 adds strongly typed classes that simplify access to the Open XML file formats: The SDK simplifies the tasks of modifying the parts of a document. The code sample that is included with this Visual How To shows how to the use the SDK to do this.
The sample provided with this Visual How To includes the code that is required to convert a Word 2007 or Word 2010 document that contains VBA code (and has a DOCM extension) to a standard document (with a DOCX extension). The following sections describe the code in detail.
Set Up References
To use the code from the Open XML SDK 2.0, you must add references to your project. The sample project includes these references, but in your own code, you must explicitly reference the following assemblies:
You should also add the following using/Imports statements to the top of your code file.
Examine the Procedure
The WDConvertDOCMtoDOCX procedure accepts a single parameter that indicates the name of the document to modify (string).
The procedure modifies the document that you specify, verifying that the document contains a VBA part, and if so, deleting the part. After the code deletes the part, it changes the document type internally and renames the document by using the DOCX extension. To call the procedure, pass the parameter value, as shown in the code example. Ensure that you provide a document named C:\temp\WithMacros.docm, which contains at least a single VBA procedure, before you run this sample code.
Access the Document
The code starts by opening the document by using the WordprocessingDocument.Open method and indicating that the document should be open for read/write access (the final true parameter). The code then retrieves a reference to the Document part by using the Document property of the MainDocumentPart property of the word processing document.
Using document = WordprocessingDocument.Open(fileName, True) Dim docPart = document.MainDocumentPart.Document ' Code removed here… End Using
Locate and Delete the VBA Part
If the passed-in document contains VBA code, the document stores that code in a discrete VBA part. The sample code next verifies that the VBA part exists, and if so, deletes the part and saves the document. To find the VBA part, the sample code retrieves the VbaProjectPart property of the document. It calls the DeletePart method to delete the VBA part, and then calls the Save method of the document to save the changes.
' Look for the VBA part. If it is there, delete it. Dim vbaPart = docPart.VbaProjectPart If vbaPart IsNot Nothing Then docPart.DeletePart(vbaPart) docPart.Document.Save() ' Code removed here… End If
Converting the Document Type
It is not enough to delete the VBA part from the document. You must also convert the document type, internally. The Open XML SDK 2.0 provides a simple means of performing this task: You can call the document ChangeDocumentType method and indicate the new document type (in this case, supply the WordProcessingDocumentType.Document enumerated value).
You must also rename the file. However, you cannot do that while the file is open. The using block closes the file at the end of the block. Therefore, you need some way to indicate to code after the block that you have modified the file: The fileChanged Boolean variable tracks this information for you.
' Change the document type so that it no ' longer thinks it is macro-enabled. document.ChangeDocumentType(WordprocessingDocumentType.Document) ' Track that the document has been changed. fileChanged = True
Renaming the File
The code then renames the newly modified document. To do this, the code calculates a new file name by changing the extension; verifies that the output file exists and deletes it, if so; and finally moves the file from the old file name to the new file name.
If fileChanged Then Dim newFileName = Path.ChangeExtension(fileName, ".docx") If File.Exists(newFileName) Then File.Delete(newFileName) End If File.Move(fileName, newFileName) End If
The Sample Procedure
The following code example contains the complete sample procedure.
Public Sub WDConvertDOCMtoDOCX(ByVal fileName As String) Dim fileChanged As Boolean = False Using document As WordprocessingDocument = WordprocessingDocument.Open(fileName, True) Dim docPart = document.MainDocumentPart ' Look for the VBA part. If it is there, delete it. Dim vbaPart = docPart.VbaProjectPart If vbaPart IsNot Nothing Then docPart.DeletePart(vbaPart) docPart.Document.Save() ' Change the document type so that it no ' longer thinks it is macro-enabled. document.ChangeDocumentType(WordprocessingDocumentType.Document) ' Track that the document has been changed. fileChanged = True End If End Using ' If anything goes wrong in this file handling, ' the code will raise an exception back to the caller. If fileChanged Then Dim newFileName = Path.ChangeExtension(fileName, ".docx") If File.Exists(newFileName) Then File.Delete(newFileName) End If File.Move(fileName, newFileName) End If End Sub
The sample that is included with this Visual How To shows code that converts a document by using VBA code (and a DOCM extension) to a standard document (with a DOCX extension). To use the sample, install the Open XML SDK 2.0, available from the link listed in the Explore It section. The sample also uses a modified version of code included as part of a set of code examples for the Open XML SDK 2.0. The Explore It section also includes a link to the full set of code examples. Be aware that you can use the sample without downloading and installing the code examples.
The sample application shows only some available properties and methods that are provided by the Open XML SDK 2.0 that you can interact with when modifying document structure. For more information, investigate the documentation that is included with the Open XML SDK 2.0 Productivity Tool: Click the Open XML SDK Documentation tab in the lower-left corner of the application window, and search for the class that you have to study. Although the documentation does currently not include code examples, given the sample shown here and the documentation, you should be able to successfully modify the sample application.
About the Author