| IntroductionOriginally, I wrote a C++ parser which | | | | As I mentioned before, all your data types are |
| was used to parse given MS Word documents | | | | going to be of Variant. So we declare a Variant |
| and put them into some form of a structure that | | | | data type called wordTables to represent Tables |
| was more useful for data processing. After I | | | | object in our Document object.Variant |
| wrote the parser, I started working with .NET and | | | | wordTables = |
| C# to re-create the parser. In the process, I also | | | | wordActiveDocument.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 got | | | | have to use the OlePropertyGet( "Tables" ); to |
| some time to put something together. I have | | | | get the value.long table_count = |
| written this article with the intention of making it | | | | wordTables.OlePropertyGet( "count" ); |
| easier for someone who is looking for quick | | | | The line above will return the number of tables in |
| answers. I hope that people can benefit from the | | | | out Tables object. This is done by calling the |
| information provided and help them get started | | | | OlePropertyGet( "count" ); to return us the |
| faster.BackgroundNo special background is | | | | value.You might be wondering where do I get this |
| necessary. Just have some hands on experience | | | | information from? The answer to that question is |
| with C++.Using the codeI think the best way to | | | | in the first article: Automating MS Word Using |
| present the code would be to first give you the | | | | Visual Studio .NET.The next block of code will |
| critical sections which you need to get an instance | | | | demonstrate how to extract content from the |
| of MS Word, and then give you snapshots of | | | | Tables 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 the | | | | int 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 used | | | | Replace..."; |
| for COM and OLE.// Vahe Karamian - 04-20-2004 | | | | vk_timerTimer( Sender |
| - For Code Project | | | | );wordSelectionFind.OleFunction( "Execute", |
| / | | | | "^l",false, false, false, false, false, true, 1, false," ", |
| ------- | | | | 2, false, false, false, false ); |
| #include | | | | wordSelectionFind.OleFunction( "Execute", "^p", |
| #pragma hdrstop// We need this for the OLE | | | | false,false, false, false, false, true, 1, false," ", 2, |
| object | | | | false, false, false, false );// Save the new |
| #include | | | | document |
| #include | | | | vk_converted_document.OleFunction( "SaveAs", |
| #include "Unit1.h" | | | | vk_converted_filename );// Close the new |
| #include | | | | document |
| / | | | | 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 COM | | | | are opening an existing document with |
| Object. This is the object which will be used to | | | | vk_this_doc = vk_word_doc.OleFunction( "Open", |
| access MS Word application functions. To see | | | | vk_filename );. Next we add a new document |
| what functions are available, you can do within MS | | | | with Variant vk_converted_document = |
| Word. Refer to the first article, Automating MS | | | | vk_word_doc.OleFunction( "Add" );. Then we |
| Word Using Visual Studio .NET.As before, you can | | | | want to select the content from the existing |
| either make a Windows Forms Application or a | | | | document and paste them in our new document. |
| Command Line application, the process is the | | | | This portion is done by Variant |
| same. The code below is based on a Windows | | | | vk_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, the | | | | vk_this_doc_selection = |
| Button1Click(TObject *Sender) event will be called | | | | vk_word_app.OlePropertyGet( "Selection" ); to |
| and the code executed.Note: To better | | | | get a reference to the actual selection. Then we |
| understand the code, ignore everything in the | | | | have to copy the selection using |
| code except the portions that are in bold.TForm1 | | | | vk_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(TObject | | | | we are going to be using them both to do our |
| *Sender) | | | | special paste using |
| {...// used for the file nameOleVariant | | | | vk_converted_document_selection.OleFunction( |
| fileName;fileName = openDialog->FileName;Variant | | | | "PasteSpecial", 0, false, 0, false, 2 );. Now, we |
| my_word;Variant my_docs;// create word | | | | have 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 make | | | | to 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 document | | | | simply 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 OleVariant | | | | vk_word_app.OlePropertyGet( "Selection" );. Next, |
| data type called fileName, we assign a file path to | | | | we create a Find object with Variant |
| our fileName variable. In the code above, this is | | | | wordSelectionFind = |
| 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 you | | | | to perform our find and replace with |
| like, i.e., c:\test.doc.Next, we define two Variant | | | | wordSelectionFind.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.application | | | | false, false, false, false );.That's all there is to |
| object and my_docs will be used to create a | | | | it!Points of InterestPutting structure to a Word |
| documents object.Next, we define another | | | | document 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 do | | | | documents. Nevertheless, it would help for |
| what we want! In this case, we are going to open | | | | organizations to start modeling their documents. |
| the given MS Word document.Notice that most of | | | | This will allow them to apply XML schema to their |
| the variables are of type Variant.At this point, we | | | | documents and make extracting content from |
| have a Word document that we can start | | | | them much easier. This is a challenging task for |
| performing functions on. At first, it might take a | | | | most companies; usually, either they are lacking |
| while for you to see how it works, but once you | | | | the expertise or the resources. And such projects |
| get a hang of it, anything in MS Word domain is | | | | are huge in scale due to the fact that they will |
| possible.Let's take a look at the following code, it | | | | affect more than one functional business area. But |
| is going to be dealing with tables within a MS | | | | on 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. |