Borland C++ MS Word Automation

IntroductionOriginally, I wrote a C++ parser which wastable_count = wordTables.OlePropertyGet( "count" );..
used to parse given MS Word documents and putAs I mentioned before, all your data types are going
them into some form of a structure that was moreto be of Variant. So we declare a Variant data type
useful for data processing. After I wrote the parser, Icalled wordTables to represent Tables object in our
started working with .NET and C# to re-create theDocument object.Variant wordTables =
parser. In the process, I also wrote my first article forwordActiveDocument.OlePropertyGet( "Tables" );
Code Project, Automating MS Word Using VisualThe line above will return all Table objects that are
Studio .NET. Several people have requested to seewithin our active Document object. Since Tables is a
the C++ version of the application, hence, I finally gotproperty of a Document object, we have to use the
some time to put something together. I have writtenOlePropertyGet( "Tables" ); to get the value.long
this article with the intention of making it easier fortable_count = wordTables.OlePropertyGet( "count" );
someone who is looking for quick answers. I hope thatThe line above will return the number of tables in out
people can benefit from the information provided andTables object. This is done by calling the
help them get started faster.BackgroundNo specialOlePropertyGet( "count" ); to return us the value.You
background is necessary. Just have some hands onmight be wondering where do I get this information
experience with C++.Using the codeI think the bestfrom? The answer to that question is in the first article:
way to present the code would be to first give youAutomating MS Word Using Visual Studio .NET.The
the critical sections which you need to get an instancenext block of code will demonstrate how to extract
of MS Word, and then give you snapshots of codecontent from the Tables object..
that perform specific functions. I believe this way will.
help you get started faster in developing your own.
programs.The following block is the header portion ofint t, r, c;try
the CPP file.Note: The most important include files are{for( t=1; tPanels->Items[0]->Text = "Find & Replace...";
and . These are used for COM and OLE.// Vahevk_timerTimer( Sender
Karamian - 04-20-2004 - 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 OLE objectfalse,false, false, false, false, true, 1, false," ", 2, false,
#includefalse, false, false );// Save the new document
#includevk_converted_document.OleFunction( "SaveAs",
#include "Unit1.h"vk_converted_filename );// Close the new document
#includevk_converted_document.OleProcedure( "Close" );
/// -------------------------------------------------------------------
#pragma package(smart_init)So what we are doing in the code above, we are
#pragma resource "*.dfm"opening an existing document with vk_this_doc =
TForm1 *Form1;vk_word_doc.OleFunction( "Open", vk_filename );.
The following block creates MS Word COM Object.Next we add a new document with Variant
This is the object which will be used to access MSvk_converted_document =
Word application functions. To see what functions arevk_word_doc.OleFunction( "Add" );. Then we want to
available, you can do within MS Word. Refer to theselect the content from the existing document and
first article, Automating MS Word Using Visual Studiopaste them in our new document. This portion is done
.NET.As before, you can either make a Windowsby Variant vk_this_doc_select =
Forms Application or a Command Line application, thevk_this_doc.OleFunction( "Select" ); to get a select
process is the same. The code below is based on aobject and Variant vk_this_doc_selection =
Windows Forms application, that has a button to startvk_word_app.OlePropertyGet( "Selection" ); to get a
the process. When the user clicks the button, thereference to the actual selection. Then we have to
Button1Click(TObject *Sender) event will be called andcopy the selection using
the code executed.Note: To better understand thevk_this_doc_selection.OleFunction( "Copy" );. Next, we
code, ignore everything in the code except the portionsperform the same task for the new document with
that are in bold.TForm1 *Form1;Variant vk_converted_document_select =
/vk_converted_document.OleFunction( "Select" ); and
Variant vk_converted_document_selection =
__fastcall TForm1::TForm1(TComponent* Owner):vk_word_app.OlePropertyGet( "Selection" );. At this
TForm(Owner)time, we have a selection object for the existing
{document and the new document. Now, we are going
}to be using them both to do our special paste using
/vk_converted_document_selection.OleFunction(
void __fastcall TForm1::Button1Click(TObject *Sender)"PasteSpecial", 0, false, 0, false, 2 );. Now, we have our
{...// used for the file nameOleVariantoriginal content pasted in a special format in the newly
fileName;fileName = openDialog->FileName;Variantcreated document. We have to do a new select call in
my_word;Variant my_docs;// create wordthe new document before we do our find and replace.
objectmy_word = Variant::CreateObject(To do so, we simply use the same calls
"word.application" );// make word visible, to makevk_converted_document_select =
invisible put falsemy_word.OlePropertySet( "Visible",vk_converted_document.OleFunction( "Select" ); and
(Variant) true );// get document objectmy_docs =vk_converted_document_selection =
my_word.OlePropertyGet( "documents" );Variantvk_word_app.OlePropertyGet( "Selection" );. Next, we
wordActiveDocument = my_docs.OleFunction( "open",create a Find object with Variant wordSelectionFind =
fileName );...vk_converted_document_selection.OlePropertyGet(
So a brief explanation, we define a OleVariant data"Find" ); and finally, we can use our find object to
type called fileName, we assign a file path to ourperform our find and replace with
fileName variable. In the code above, this is done usingwordSelectionFind.OleFunction( "Execute", "^l", false,
a OpenDialog object. Of course, you can just assign afalse, false, false, false, true, 1, false, " ", 2, false, false,
whole path for testing if you like, i.e., c:\test.doc.Next,false, false );.That's all there is to it!Points of
we define two Variant data types called my_word,InterestPutting structure to a Word document is a
and my_docs. my_word will be used to create achallenging task, given that many people have different
word.application object and my_docs will be used toways of authoring documents. Nevertheless, it would
create a documents object.Next, we define anotherhelp for organizations to start modeling their
Variant data type called myActiveDocument. Using thisdocuments. This will allow them to apply XML schema
referenced object, we can now do what we want! Into their documents and make extracting content from
this case, we are going to open the given MS Wordthem much easier. This is a challenging task for most
document.Notice that most of the variables are ofcompanies; usually, either they are lacking the expertise
type Variant.At this point, we have a Word documentor the resources. And such projects are huge in scale
that we can start performing functions on. At first, itdue to the fact that they will affect more than one
might take a while for you to see how it works, butfunctional business area. But on the long run, it will be
once you get a hang of it, anything in MS Wordbeneficial to the organization as a whole. The fact that
domain is possible.Let's take a look at the followingyour documents are driven by structured data and not
code, it is going to be dealing with tables within a MSby formatting and lose documents has a lot of value
Word document...Variant wordTables =added to your business.
wordActiveDocument.OlePropertyGet( "Tables" );long