Word helper (Microsoft Word automation wrapper)

User projects written in or related to FreeBASIC.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Word helper (Microsoft Word automation wrapper)

Postby phishguy » Apr 16, 2010 15:04

As some of you may know, I have previously written a wrapper for Excel automation called xlhelper. I have now started a new Word automation wrapper called wordhelper (of course!). It is still very preliminary and there are many, many features that need to be added. Here is a quick preview demo:

(you will need to edit the code to use your desired image file)


wordhelper.bas
http://cid-53bce305c32e0874.skydrive.live.com/self.aspx/freebasic%20code/wordhelper.bas

demo code

Code: Select all

'----------------------------
'      Wordhelper demo code
'----------------------------
#include "wordhelper.bas"

wordstart
wordfontsize(14)
wordfontcolor(wdcolorred)

For x As Integer = 1 To 50
    wordfontitalic
   
    If x/2 = Int(x/2) Then
        wordfontbold
       
    End If
   
    If x/4 = Int(x/4) Then
        wordfontunderline(1)
        wordfontshading(wdColorbluegray)
    Else
        wordfontunderline(0)
    End If
   
   
    wordtypetext("This is line number " & Str(x)) & "."
    wordfontshading
    wordparagraph
   
    If x > 10 Then
        wordhome
        wordend(wdline,wdextend)
        worddelete
        wordend(wdstory)
    End If
   
    Sleep 200
   
Next x
Kill ("c:\freebasic\mytestdoc.doc")

wordpicture("c:\freebasic\fblogo.bmp") 'use your path and filename

wordsaveas("c:\freebasic\mytestdoc.doc")

'wordprintout 'uncomment to send to printer

Sleep 2000

wordhome

wordfindreplacetext("line","goofy")

Print "Word Count = ";worddocstatistics

Sleep 5000

For x As Integer = 1 To 10
    Sleep 500
    wordhome
    wordend(wdline,wdextend)
    worddelete
Next x

worddrawshape(smileyface,100,50,100,100)
wordshapefillcolor(wdcoloryellow)

Sleep 5000

wordsaved
wordquit
wordrelease

Sleep

Last edited by phishguy on Apr 28, 2010 21:37, edited 14 times in total.
square1
Posts: 97
Joined: Nov 12, 2007 2:27

Postby square1 » Apr 17, 2010 10:41

Awesome stuff, thanks for posting this!

What I'd find really useful would be to be able to open a word document, find certain tags in it (like <address>) and replace them with actual values. Your efforts here make it look quite achievable.

A question - other than the official docs, are there any resources around to help me understand the disphelper syntax better and where do you find all the names of the methods that you are using within word?

Thanks heaps.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 17, 2010 12:40

The only other resources that I have found to help understand the disphelper syntax is this forum.

The names of the methods to be used can be found on MSDN. I also find it handy to use Word's (or Excel) macro recorder to record a function that I'm interested in automating. You can then go into edit the macro to view the Visual Basic equivalent. The Visual Basic editor also has an object browser that shows the objects, methods, and constants within Word.

The search and replace should be fairly simple. I believe I saw an example of that on MSDN. I'll check into that and see if I can come up with something.

<edit>
OK, I added the wordfindreplacetext feature. I updated the demo above for an example.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 17, 2010 16:51

added: wordsaveas

see first post
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 17, 2010 17:27

Added: worddocstatistics

This will allow statistics such as word , character, line, paragraph, and page counts.

see first post
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 17, 2010 21:26

Added a lot of the drawing functions that were in my xlhelper wrapper. The wrapper and demo code are now split up and in my first post.
square1
Posts: 97
Joined: Nov 12, 2007 2:27

Postby square1 » Apr 19, 2010 3:49

This is so cool, thank you! I had been starting to automate stuff in word by calling small programs written in FB via Word macros and exchanging variables via the clipboard. This opens up a huge new field of exciting possibilities ... now I just need a function that makes a day have more than 24 hours, so I get enough time for playing around with it :)
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 19, 2010 13:07

This is so cool, thank you!


You're welcome!

I still have plenty of functions that need to be added. Let me know if there is anything in particular that you would like to see as a feature, or let me know if you have any questions. The next thing I plan to add is the macro insertion and calling features that I have in the Excel wrapper. This will allow you to directly use a VBS macro within your program. That can come in handy if you have an example macro that you're not quite sure how to convert.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 19, 2010 13:47

Added the macro functions. In order to use this, the macro security must be disabled.

Here is an example:

Code: Select all

#include "wordhelper.bas"
dim macro as string
wordstart
open "mymacro.txt" for binary access read as #1
if lof(1) > 0 then
   macro = String(LOF(1),0)
    Get #1,,macro
  End If
  Close #1
  wordaddmodule
  wordaddmacro(macro)
  wordrunmacro("macro1")
  wordrelease
 


and here is an example macro
save as mymacro.txt

Code: Select all

Sub Macro1()
'
' Macro1 Macro
' Macro recorded 4/19/2010 by RClark
'
    ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=2, NumColumns:= _
        5, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
        wdAutoFitFixed
    With Selection.Tables(1)
        If .Style <> "Table Grid" Then
            .Style = "Table Grid"
        End If
        .ApplyStyleHeadingRows = True
        .ApplyStyleLastRow = True
        .ApplyStyleFirstColumn = True
        .ApplyStyleLastColumn = True
    End With
    Selection.TypeText Text:="1"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="2"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="3"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="4"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="5"
    Selection.MoveDown Unit:=wdLine, Count:=1
    Selection.MoveLeft Unit:=wdCharacter, Count:=4
    Selection.TypeText Text:="Bob"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="Charlie"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="Sam"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="Tom"
    Selection.MoveRight Unit:=wdCell
    Selection.TypeText Text:="Harvey"
    Selection.TypeParagraph
    Selection.TypeBackspace
End Sub



There is an example on how to set the macro security programmatically here: http://www.freebasic.net/forum/viewtopic.php?t=10768&start=150
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 25, 2010 22:40

Added wordgettext

returns the selected text
square1
Posts: 97
Joined: Nov 12, 2007 2:27

Postby square1 » Apr 27, 2010 5:19

Gettext is very neat, haven't had time to play with the macro functions.

Keep up the good work :)
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 27, 2010 21:37

Added
wordcaption - sets the title bar caption
wordhandle - gets the handle of the Word app

Example:

Code: Select all

#include "wordhelper.bas"
 
wordstart
 
wordtypetext("This is a test of changing the title bar caption and getting the window handle.")
wordparagraph
wordtypetext("The caption will change in 5 seconds.")
wordparagraph
sleep 5000
wordcaption("This is the new caption")
wordtypetext( "The title bar caption has changed.")
wordparagraph
 
wordtypetext ("The windows handle for this Word session is " & wordhandle )
wordparagraph
wordtypetext ("Word will shut down in 10 seconds.")
wordparagraph
sleep 10000
wordsaved
wordquit
 
wordrelease
 
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 27, 2010 23:28

Added:
wordversion - returns the version of Word. Also can be used to detect if Word has closed.


example:

Code: Select all

#include "wordhelper.bas"
wordstart
print wordversion
wordtypetext ("This is a test of wordversion")
wordparagraph
sleep 2000
wordtypetext ("The version of word you are running is " & wordversion)
wordparagraph
sleep 2000
wordtypetext("Wordversion will return -1 if the Word window is closed.")
wordparagraph
sleep 2000
wordtypetext("Close this instance of Word and you will see the program quit.")
wordparagraph
wordsaved
do
    if wordversion = -1 then
        exit do
    end if
    sleep 1
loop


wordrelease
 
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 28, 2010 16:32

I'm debating whether I should add this to my wrapper. Within the Word VBA, it is possible to list the running programs (visible or not) and also close a selected program (or suspend). Does anyone have a practical need for this?

Here is an example (not in wrapper):

Code: Select all

#include once "windows.bi"
#define unicode
#include "disphelper\disphelper.bi"
width 120
Dim Shared wordtask As idispatch Ptr
Dim Shared wordapp As idispatch Ptr
Dim Shared wordDoc As IDispatch Ptr
Dim Shared wordSelection As IDispatch Ptr

dhInitialize(TRUE)
dhToggleExceptions(true)
dhcreateobject("Word.Application",NULL,@wordApp)
dhGetvalue("%o",@wordDoc,wordApp,".Documents.Add")
dhGetvalue("%o",@wordSelection,wordApp,".Selection")
dhPutvalue(wordApp,".Visible = %b",false)

dhgetvalue("%o",@wordtask,wordapp,".Tasks")
Dim count As Integer
Dim text As Zstring Ptr
Dim visible As Integer
dim n as integer
dhgetvalue("%d",@count,wordtask,".count")

For x As Integer = 1 To count
    dhgetvalue("%b",@visible,wordtask,".item(%d).visible",x)
   
    If visible = -1 Then
        dhgetvalue("%s",@text,wordtask,".item(%d).name",x)
        print x,*text
        'dhcallmethod(wordselection,".TypeText(%s)",*text)
        'dhcallmethod(wordSelection,".TypeParagraph")
    End If
   
Next x

input "Enter number of program to terminate (0 to exit) : ";n

if n <> 0 then
dhcallmethod(wordtask,".item(%d).close",n)
end if

dhPutvalue(wordDoc,".Saved = %b",TRUE)
dhcallmethod(wordapp,".quit")
SAFE_RELEASE(wordApp)
SAFE_RELEASE(wordDoc)
SAFE_RELEASE(wordSelection)
SAFE_RELEASE(wordtask)
dhUninitialize(TRUE)
sleep
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Apr 29, 2010 20:56

Here is another function that I probably won't include in my wrapper. Why? Because it is too slow. Anyways, I'm posting it as an example to list a directory of files in your Word document. You will need the latest wrapper to run (see first post for link). Give it a couple of minutes to give the file list. Change the path and filespec to whatever suits you.

Code: Select all

Code deleted - see next post
 



<edit>
Hmm, I tried it on my home pc and it was quick. Maybe I will wrap the functions for this.

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 2 guests