Borland C++ MS Word Automation

IntroductionOriginally, I wrote a C++ parser whichAs I mentioned before, all your data types are
was used to parse given MS Word documentsgoing to be of Variant. So we declare a Variant
and put them into some form of a structure thatdata type called wordTables to represent Tables
was more useful for data processing. After Iobject in our Document object.Variant
wrote the parser, I started working with .NET andwordTables =
C# to re-create the parser. In the process, I alsowordActiveDocument.OlePropertyGet( "Tables" );
wrote my first article for Code Project,The line above will return all Table objects that
Automating MS Word Using Visual Studio .NET.are within our active Document object. Since
Several people have requested to see the C++Tables is a property of a Document object, we
version of the application, hence, I finally gothave to use the OlePropertyGet( "Tables" ); to
some time to put something together. I haveget the value.long table_count =
written this article with the intention of making itwordTables.OlePropertyGet( "count" );
easier for someone who is looking for quickThe line above will return the number of tables in
answers. I hope that people can benefit from theout Tables object. This is done by calling the
information provided and help them get startedOlePropertyGet( "count" ); to return us the
faster.BackgroundNo special background isvalue.You might be wondering where do I get this
necessary. Just have some hands on experienceinformation from? The answer to that question is
with C++.Using the codeI think the best way toin the first article: Automating MS Word Using
present the code would be to first give you theVisual Studio .NET.The next block of code will
critical sections which you need to get an instancedemonstrate how to extract content from the
of MS Word, and then give you snapshots ofTables object..
code that perform specific functions. I believe this.
way will help you get started faster in developing.
your own programs.The following block is theint t, r, c;try
header portion of the CPP file.Note: The most{for( t=1; tPanels->Items[0]->Text = "Find &
important include files are and . These are usedReplace...";
for COM and OLE.// Vahe Karamian - 04-20-2004vk_timerTimer( Sender
- For Code Project);wordSelectionFind.OleFunction( "Execute",
/"^l",false, false, false, false, false, true, 1, false," ",
-------2, false, false, false, false );
#includewordSelectionFind.OleFunction( "Execute", "^p",
#pragma hdrstop// We need this for the OLEfalse,false, false, false, false, true, 1, false," ", 2,
objectfalse, false, false, false );// Save the new
#includedocument
#includevk_converted_document.OleFunction( "SaveAs",
#include "Unit1.h"vk_converted_filename );// Close the new
#includedocument
/vk_converted_document.OleProcedure( "Close" );
-------#pragma package(smart_init)//
#pragma resource "*.dfm"-------------------------------------------------------------------
TForm1 *Form1;So what we are doing in the code above, we
The following block creates MS Word COMare opening an existing document with
Object. This is the object which will be used tovk_this_doc = vk_word_doc.OleFunction( "Open",
access MS Word application functions. To seevk_filename );. Next we add a new document
what functions are available, you can do within MSwith Variant vk_converted_document =
Word. Refer to the first article, Automating MSvk_word_doc.OleFunction( "Add" );. Then we
Word Using Visual Studio .NET.As before, you canwant to select the content from the existing
either make a Windows Forms Application or adocument and paste them in our new document.
Command Line application, the process is theThis portion is done by Variant
same. The code below is based on a Windowsvk_this_doc_select = vk_this_doc.OleFunction(
Forms application, that has a button to start the"Select" ); to get a select object and Variant
process. When the user clicks the button, thevk_this_doc_selection =
Button1Click(TObject *Sender) event will be calledvk_word_app.OlePropertyGet( "Selection" ); to
and the code executed.Note: To betterget a reference to the actual selection. Then we
understand the code, ignore everything in thehave to copy the selection using
code except the portions that are in bold.TForm1vk_this_doc_selection.OleFunction( "Copy" );.
*Form1;Next, we perform the same task for the new
/document with Variant
-------vk_converted_document_select =
__fastcall TForm1::TForm1(TComponent*vk_converted_document.OleFunction( "Select" );
Owner): TForm(Owner)and Variant vk_converted_document_selection =
{vk_word_app.OlePropertyGet( "Selection" );. At
}this time, we have a selection object for the
/existing document and the new document. Now,
-------void __fastcall TForm1::Button1Click(TObjectwe are going to be using them both to do our
*Sender)special paste using
{...// used for the file nameOleVariantvk_converted_document_selection.OleFunction(
fileName;fileName = openDialog->FileName;Variant"PasteSpecial", 0, false, 0, false, 2 );. Now, we
my_word;Variant my_docs;// create wordhave our original content pasted in a special
objectmy_word = Variant::CreateObject(format in the newly created document. We have
"word.application" );// make word visible, to maketo do a new select call in the new document
invisible put falsemy_word.OlePropertySet(before we do our find and replace. To do so, we
"Visible", (Variant) true );// get documentsimply use the same calls
objectmy_docs = my_word.OlePropertyGet(vk_converted_document_select =
"documents" );Variant wordActiveDocument =vk_converted_document.OleFunction( "Select" );
my_docs.OleFunction( "open", fileName );...and vk_converted_document_selection =
So a brief explanation, we define a OleVariantvk_word_app.OlePropertyGet( "Selection" );. Next,
data type called fileName, we assign a file path towe create a Find object with Variant
our fileName variable. In the code above, this iswordSelectionFind =
done using a OpenDialog object. Of course, you( "Find" ); and finally, we can use our find object
can just assign a whole path for testing if youto perform our find and replace with
like, i.e., c:\test.doc.Next, we define two VariantwordSelectionFind.OleFunction( "Execute", "^l",
data types called my_word, and my_docs.false, false, false, false, false, true, 1, false, " ", 2,
my_word will be used to create a word.applicationfalse, false, false, false );.That's all there is to
object and my_docs will be used to create ait!Points of InterestPutting structure to a Word
documents object.Next, we define anotherdocument is a challenging task, given that many
Variant data type called myActiveDocument.people have different ways of authoring
Using this referenced object, we can now dodocuments. Nevertheless, it would help for
what we want! In this case, we are going to openorganizations to start modeling their documents.
the given MS Word document.Notice that most ofThis will allow them to apply XML schema to their
the variables are of type Variant.At this point, wedocuments and make extracting content from
have a Word document that we can startthem much easier. This is a challenging task for
performing functions on. At first, it might take amost companies; usually, either they are lacking
while for you to see how it works, but once youthe expertise or the resources. And such projects
get a hang of it, anything in MS Word domain isare huge in scale due to the fact that they will
possible.Let's take a look at the following code, itaffect more than one functional business area. But
is going to be dealing with tables within a MSon the long run, it will be beneficial to the
Word document...Variant wordTables =organization as a whole. The fact that your
wordActiveDocument.OlePropertyGet( "Tables"documents are driven by structured data and not
);long table_count = wordTables.OlePropertyGet(by formatting and lose documents has a lot of
"count" );..value added to your business.