by Finian Lennon
| Warning! This is a long and complex article and it's not for
the faint of heart! Finian shows us how he integrated his Alpha Five
application with Microsoft Word®. The same techniques could apply to Corel
Wordperfect® or any other word processor that supports command-line macros.
When he isn't hanging out at Alpha's web site, Finian will reply to email sent to finianl@ix.netcom.com |
Given Alpha Fives excellent report writer and letter writer module, the question may fairly be asked.-"Why bother to merge with a word processor at all. Why go to all this trouble?" It's a fair question to which there are a couple of answers. The first is that there are times when the limitations of A5's abilities to format text within a document could be considered unacceptable. For example, A5 can't do fully justified text at all. What if a business uses this as its standard format for correspondence? Or, suppose you are developing an application for others to use. As you do so, you will soon find that users want a lot more flexibility in their correspondence than in the data reports A5 produces to a pre-designed and agreed-upon format. It's true that you can design multiple letter formats, but why not let the users create their own letters according to their own preferences? This really can't be done any other way in an A5 application.
The following techniques will work with both MS Word and WordPerfect. The activities described here were developed using MS Word (Office 97 version) exclusively.
There are two primary methods of getting data out of Alpha Five to an external program:
The method described here uses Export/Import. DDE obviously has its place but for what I wanted and needed to do, it seemed to be too limited. The key to successfully using the export/import method is Alpha's ability to create a character separated ascii text file and its SYS_SHELL function. These capabilities, married to the word processing program's ability to accept multiple commands in the program startup line, give us a fast, flexible method to integrate Alpha with your word processor.
It is apparent that you need to think about your user environment before proceeding. From the start of our project, I knew that the merge facility was to be used in a network environment. In our situation we wanted to enable our clients (primarily Oral Surgeons) to customize correspondence arising from treatment of their patients. For example, a typical use to which the merge is put is to create a letter to a referring doctor. Such a letter is (obviously) addressed to the referring doctor, includes the patient's name and also a description of the procedure(s) performed during the visit.
| Finian's merge includes 95 fields from 13 different tables. |
As you might expect, this information is available in the BILL.SET in which bills are created. I knew I could create an interim table to accept the "consolidated" data from the set and use this table as the source of the export. But the procedures (and fees) are stored in a child table, linked one to many with the header table. Merging data with a flat file appeared to be easy but how would I deal with the one-to-many relationship which contains the most important information we need to have available for the merge? There is no way to predict how many procedures are likely to be performed. As I thought about it I decided I would deal with the information in the child records by "gathering" all of the information we needed into a single memo field of the interim table. Our BILL.SET is comprised of 13 tables from which we selected 95 fields to be made available for merge.
As I envisioned it, the structure would be something like the following. I would place a button with Xbasic code on our main bill form. When clicked, the code would:
| Finian started with single-bill merges but added a batch merge capability. |
This would happen all at once and looked to be fairly straightforward. Almost immediately, though, I realized that if we enabled the user to merge with a single record in the BILL.SET, as soon as she mastered the task it would take only 30 seconds before she would want to be able to merge with multiple records. No problem, I thought, because all I have to do is "scale up". Instead of writing the data to one interim table, I'll have two. The first, WORDMERGE.DBF, would be for the one-off quick merges. The second, creatively called WORDMERGE2.DBF would hold multiple records until the batch is completed. At that time I could run the export from WORDMERGE2.DBF except that now it would contain data from multiple records.
As I focused on this issue, I realized that I had been overlooking a key problem. I knew I could put a copy of WORDMERGE.DBF in my main application folder and "lock" it while I populated it and exported the data. But what about the text file itself? My MS Word template documents would all have to use the same text file as their data source. If another user ran a merge at the same time what would happen to the text file then? And what would happen when two users started to accumulate a batch of records to be merged in the future? One user's names would surely be mixed in with another's. It was obvious I needed to find a way that would keep each user's information safely separated from all others.
Happily this proved to be not that difficult to do .
| Finian violates one of the prime directives in distributing his tables! |
I suspect that the most frequently given advice concerning Alpha Five database design is to "make sure you keep all of the tables relating to your application in a single folder." This is indeed good advice. It resolves numerous issues and simplifies the process of moving an application from one location (in computer, on drive or in folder) to another. When you open the database Alpha assumes that, unless instructed otherwise, all associated files are in the same folder. Before proceeding further, open one of your databases, go to the Control Panel, click on the Table/Sets tab, right click in the white area and select View/Details. This view lets you see the detailed path to the tables and sets in your application. If you have followed the advice previously offered, the path to all the tables and sets will be the same.
Let's try a quick experiment. Create a new table or make a copy of an existing table (its structure is completely unimportant) let's call it TEMP.DBF and place it in a "remote" folder say in C:\TEMP. Now, in your database Control Panel, Right click in the white area of the Tables/Sets tab, select "Add a Table" and add to the database the table you have just placed in C:\TEMP. It will stick out like a sore thumb in the list because of its different path of C:\TEMP\TEMP.DBF but only if you continue to view the Table/Sets tab in detail mode. Now, using the Windows Explorer, copy the entire contents of this database folder to a new folder, preferably on a different drive. Don't touch TEMP.DBF. Open the database in its new location and once again select the Tables/Sets tab and View/Details. Well, as you would expect, the path indicates that all of the tables and sets are located in the new folder to which you copied them but you should also notice that the path to the remote table C:\TEMP\TEMP.DBF is unchanged. The A5 database understands that as you add tables and sets to the *.adb definition from within the same folder that you always want to keep them together relative to each other. And it also understands that when you add a table from a different folder, i.e. a remote table, it should hard code that path into its definition. In this way the database can always locate the remote file should the database and its related files be moved to and then opened in a different location.
In a typical network situation, the application files are placed in a shared folder on a server computer. This folder is then accessed by multiple users from different workstations which have mapped the server location to a common drive name (say S:). In the scenario we have just described, when each workstation user opens the database, all of the tables and sets are seen by each user as being on drive S: - the shared server drive - with the exception of the remote TEMP.DBF which is still shown in the Control Panel as being mapped to C:\TEMP. The only difference is that now C:\TEMP\TEMP.DBF is on a different computer from the rest of the files on the S: drive. The local workstation and each user now has a private copy of that table for her or his use. What we have done, in effect, is to use the database properties to implement actual shared and private paths for the application.
| Finian needs to keep each user's merge data separate from every other user's data. He solves his problem by putting a single table on each user's local drive. That's one approach, but I would have solved the problem by adding a new field, "user", to the wordmerge.dbf file. Each user could be restricted by query filters and form filters to only their own records in the merge table. |
So how does this apply to my dilemma regarding the word merge setup? Hopefully the answer will be readily apparent to you. I could leave WORDMERGE.DBF where it was in the main application folder and keep it "locked" while it was being populated and exporting its data. But I would resolve my multi-user issues by placing the exported ascii text file AND the WORDMERGE2.DBF table in a folder on the local C drive which I would call C:\OSOMDOCS. By so doing, I could allow each user to operate their word merge pretty much completely independently of the other.
Let me enter a couple of warnings right away. If the folder C:\OSOMDOCS and WORDMERGE2.DBF do not exist on THE SERVER and the application is opened by a user ON the server, then the database will give an error when the user tries to refer to any file in the C\OSOMDOCS folder. If the folder C:\OSOMDOCS and WORDMERGE2.DBF do not exist on a workstation , then any process which addresses that path will fail for that workstation, usually without an error. Using this method definitely increases your database housekeeping by a significant margin. However these are setup issues that need usually be addressed only once.
So it turns out that the "golden rule" of database design was made to be broken after all. But only for this purpose and I can't think of any other reason to do it. One final digression: don't attempt to extend this method by including any table placed in a remote folder in a set definition. This is truly a recipe for disaster. Don't do it ever.
And now back to word integration!
In the final version, (and this is reflected in the sample scripts that are included here) I have not one memo field, but four. Each memo field contains a slightly different parsing of the information gathered from the child records. One consequence of "gathering " the child records into a memo field is that their "orderly" appearance in the browse is lost. While for some people this would be a good - even desirable result, for most it is unacceptable. it is therefore necessary to be able to reconstruct the neat appearance from the browse when the data is merged into MS Word. This is accomplished by putting a special marker character (usually the | or "pipe" character) into the data as it is gathered by the Xbasic script. When the data is merged into MS Word, a macro can then search for this character and reformat the text accordingly.
| Finian could not use Alpha's export operation because the normal export operation truncates memo fields. Fortunately the memo_write_to_file() method has no such limitation. |
In my first effort to complete the merge project, I used the Alpha Five Xbasic export methods to create the ascii WORDMERGE.TXT file. This worked beautifully. Until I realized the contents of the memo fields were being cut off after (at that time) 256 characters! As a result I was forced to write the export routine that is included here. Using the memo_write_to_file method enables me not to care how much data is included in the memo field. (I recently tested the export method for the latest pre-release of A5 V4.02 and it appears that the cutoff is now 1024 characters. This may be enough for most cases, but I'm sticking with my home grown export routine!)
When exporting to the text file, you will also export the field names. Users will then be able to select the fields they want to be able to use for merge purposes in MS Word. For this reason, make sure that you give the fields in WORDMERGE.DBF and WORDMERGE2.DBF more intuitive names than you might have given them in the original source table.
When selecting the data fields to be exported select more rather than fewer. It's easier not to use an available merge field than it is to add a field to be merged after everything is set up. We selected 95.
If you expect to have a lot of text in your source data, then watch out for commas. You'll need to do as I do here which to creat a comma, quote delimited text file.
Before you start to write any Xbasic code, you can create all of the components and test each element to make sure that it is doing what you expect. Once all the indiividual components in place you can use the Alpha Five script recorder to help you create the Xbasic.
OK, I know this is about alpha Five, but we need to spend a little time discussing the way that word processors do their merge thing. What I say here applies specifically to MS Word, but will also apply pretty generally to WordPerfect.
A merge document in a word processor is a document that has special characteristics. As far as we are concerned, the most important characteristic is that the merge document has, embedded within it, a link to a data file. In our case the data file is WORDMERGE.TXT. When the merge file is opened it has, by default, on its toolbar a button that says "Insert Merge Field". When you click this button (assuming that the exported file contained valid field names) a list appears containing all the fields that the user can include in the merge document.
Obviously there's a sequence issue here. You can't create the merge file until you create the text file which you can only create when you have created the interim table and run the export. OK, so know you know where to start!
I've referred to using MS Word macros a number of times and they are crucial to successfully using this method. I would hope that people would not be put off by the necessity of creating a few macros in MS Word. I can honestly say that I spent no more than a couple of hours on the macro end of this development effort. You can record the macro keystrokes and then edit them for elegance and refinement if you wish.
In order to keep the macros associated with merge documents it is necessary to create, save and keep a MS Word template document (*.dot) containing those macros in the same folder as the merge documents. You can also include the macros in the MS Word standard template. Both approaches work well. There is a bug in MS Word which causes the merge document to lose track of its related data source file if it id moved from one drive to another. You will probably get an "ODBC Connectivity" error the first time you try to merge after the move. This is bothersome but not fatal. You need to open the merge document in MS Word, re-establish the connection to the data file and re-save the file.
One crucial benefit of using this method is that every document which is created based on one of these merge documents itself inherits all of the characteristics of the parent document i.e. it is associated with the same source data file and contains the same macros. Consequently the user is now able to create an unlimited number of new working template files.
To execute the merge, Alpha Five runs sys_shell() which launches MS Word and a selected document simultaneously. When the document is loaded, a selected macro is run. The macro contains the commands to execute the merge with the data source (WORDMERGE.TXT) and execute formatting commands.
The command line to do this is constructed in the attached script. Let me apologize in advance for my continued use of the \ (backslash escape) character in the scripts!
I have included one script. It has been edited to remove repetitive lines that do not add to the understanding of the script itself. I have not included the scripts relating to the creation of batches. They basically copy and append files and contain slightly modified versions of the script included here.
'OMS Merge
dim t as p
dim batch_line as c
dim winopen as c
dim macroname as c
dim batfile as L
dim inv as c
dim ada_descript as c
dim proc_date as c
dim code as c
dim descript1 as c
dim descript2 as c
dim descript as c
dim tnum as c
dim procfee as c
dim prc_place as c
dim tcpt as c
dim memo1 as c
dim memo2 as c
dim memo3 as c
dim memo4 as c
dim memo5 as c
dim memo6 as c
dim memo7 as c
dim memo8 as c
dim global word_location as c
'This refers to the location of WINWORD.EXE and is entered in the
application autoexec script
'This location must be the same for all users a limitation in
some situations
dim textfilename as c
dim tries as n
textfilename="C:\OSOMDOCS\WORDMERGE.TXT"
'The script is placed in a button located on the main data entry form
'for the BILL Set
t=table.current(1)
inv=t.inv_number
on error goto locked
a_tbl=table.open("wordmerge.dbf",file_rw_exclusive)
on error goto 0
a_tbl.zap(.T.)
a_tbl.close()
on error goto locked
a_tbl=table.open("wordmerge.dbf", file_rw_exclusive)
on error goto 0
a_tbl.enter_begin()
a_tbl.provider=t.provider
a_tbl.provider_number=t.prov_numb
a_tbl.Invoice_Number=t.inv_number
t8=table.current(8)
a_tbl.adains1_name=t8.carr1_name
'Lines removed here
t10=table.current(10)
a_tbl.adains2_name=t10.carr1_name
'Lines removed here
t9=table.current(9)
a_tbl.hcfains1_name=t9.carr2_name
'Lines removed here
t11=table.current(11)
a_tbl.hcfains2_name=t11.carr1_name
'Lines removed here
t5=table.current(5)
a_tbl.patient_title=t5.title
a_tbl.patient_first=t5.first
a_tbl.patient_middle=t5.middle
a_tbl.patient_last=t5.last
a_tbl.patient_dob=t5.dob
a_tbl.patient_ssn=t5.soc_sec_nu
'Lines removed here
t6=table.current(6)
a_tbl.prirefer_last=t6.last
'Lines removed here
t7=table.current(7)
a_tbl.secrefer_last=t7.last
'Lines removed here
a_tbl.enter_end(.T.)
'proced.dbf is the table containing the child records.
'First I check to see if there are child records for this record.
'I realize that I could also have used the Scanning() function here
tproc=table.open("proced.dbf",file_ro_shared)
query.description="LineItems"
query.order="Line"
query.filter="Between(Inv_number,\""+inv+"\",\""+inv+"\")"
query.options=""
prdx=tproc.query_create()
recs=prdx.records_get()
if recs=0 then
goto finish
end if
memo3=""
memo4=""
memo6=""
memo8=""
'How I format the memo field depends on whether the line contains a fee
'the following script lines parse each child record according to its
type
tproc.fetch_first()
while .not. tproc.fetch_eof()
if UT(tproc.pay_type)="F"
proc_date=dtoc(tproc.date)
code=alltrim(tproc.ada)
descript1=alltrim(tproc.descipt)
descript2=lookupc("F",code,"descrip2","codes.dbf","ada")
tnum=if(alltrim(tproc.t_number)<>"","#"+alltrim(tproc.t_number),"")
tcpt=alltrim(tproc.cpt)
procfee=ltrim(str(tproc.fee,10,2))
proc_place=alltrim(tproc.place)
if alltrim(descript2)="" then
descript=alltrim(descript1)
else
descript=alltrim(descript2)
end if
'for example, memo 1 contains $ amounts, the others do not
memo1=proc_date+space(1)+code+space(1)+descript+space(1)+tnum+\
space(1)+tcpt+space(1)+"$"+procfee+space(1)+proc_place
memo2=proc_date+space(1)+code+space(1)+descript+space(1)+tnum+\
space(1)+tcpt
memo5=descript+space(1)+tnum
end if
if UT(tproc.pay_type)="R" .or. UT(tproc.pay_type)="P"\
.or. UT(tproc.pay_type)="C" .or. UT(tproc.pay_type)="I"
then
proc_date=dtoc(tproc.date)
descript1=alltrim(tproc.descipt)
procfee=ltrim(str(tproc.fee,10,2))
memo7=proc_date+space(1)+descript1+space(1)+"$"+procfee
end if
tproc.fetch_next()
'Now the character marker is added
memo3=memo3+if(alltrim(memo1)<>"",memo1+"|","")
memo4=memo4+if(alltrim(memo2)<>"",memo2+"|","")
memo6=memo6+if(alltrim(memo5)<>"",memo5+"|","")
memo8=memo8+if(alltrim(memo7)<>"",memo7+"|","")
memo1=""
memo2=""
memo5=""
memo7=""
end while
'these lines needed to get the fields properly formatted
memo3=substr(alltrim(memo3),1,len(alltrim(memo3))-1)
memo4=substr(alltrim(memo4),1,len(alltrim(memo4))-1)
memo6=substr(alltrim(memo6),1,len(alltrim(memo6))-1)
memo8=substr(alltrim(memo8),1,len(alltrim(memo8))-1)
prdx.drop()
tproc.close()
'The table is re-opened and the values written into the memo fields
a_tbl.change_begin()
a_tbl.procwithamounts=memo3
a_tbl.procnoamounts=memo4
a_tbl.procnodetails=memo6
a_tbl.procpaydetails=memo8
a_tbl.change_end(.T.)
a_tbl.close()
'Now the finish:
'==============
'Export records in a table
dim fn as c 'fieldname
dim fv as c 'fieldvalue
dim crlf as c
'These lines write the field names into the text file
'The field names and data are surrounded by quotes
'and separated by commas
on error goto locked
t=table.open("wordmerge.dbf",file_rw_exclusive)
on error goto 0
t.fetch_first()
filename=textfilename
crlf=chr(13)+chr(10)
file=file.create(filename,file_rw_exclusive)
file.flush()
file.close()
no_fields=t.fields_get()
file=file.open(filename,file_rw_exclusive)
for i=1 to no_fields
fh=t.field_get(i)
fn=fh.name_get()
size=file.bytes_get()
file.seek(size)
file.write("\""+fn+"\",")
next
size=file.bytes_get()
fv=crlf 'write a crlf into file
file.seek(size)
file.write(fv)
file.flush()
file.close()
file=file.open(filename,file_rw_exclusive)
while .not. t.fetch_eof()
for i=1 to no_fields
fh=t.field_get(i)
ftype=fh.type_get()
select
case ftype="N"
fv=ltrim(str(fh.value_get()))
size=file.bytes_get()
file.seek(size)
file.write("\""+fv+"\",")
case ftype="D"
'fv=if(isblank("\"+fh.name_get()+\""),"",dtoc(fh.value_get()))
fv=if(dtoc(fh.value_get())=" / /","",dtoc(fh.value_get()))
'fv=dtoc(fh.value_get())
size=file.bytes_get()
file.seek(size)
file.write("\""+fv+"\",")
case ftype="C"
fv=alltrim(fh.value_get())
size=file.bytes_get()
file.seek(size)
file.write("\""+fv+"\",")
case ftype="M"
fv="\""
size=file.bytes_get()
file.seek(size)
file.write(fv)
file.flush()
file.close()
fh.memo_write_to_file(filename,memo_append)
file=file.open(filename,file_rw_exclusive)
size=file.bytes_get()
fv="\","
file.seek(size)
file.write(fv)
end select
next
size=file.bytes_get()
fv=crlf
file.seek(size)
file.write(fv)
t.fetch_next()
end while
file.flush()
file.close()
t.close()
'==============================
'if for some reason the text file is not created, the
'script will terminate with the error below
dim found as l
found=file.exists(textfilename)
if found=.F.
goto no_file
end
end if
file_path=a_db_current_path+"osomdocs\*.doc"
'The choice line below should be on one line
choice=ui_get_radio("Choose a Merge Option", 1,\
"QuickMerge","Add Bill to Batch","Manage Batch\
Merges","Edit Merge Document","Create New Merge\
Document")
if choice="" then
end
end if
'================
if choice="QuickMerge"
name=ui_get_file("Select the Letter You Want to Merge",\
"Word Document (*.doc)",file_path, "X")
if name="" then
end
end if
choose=ui_get_radio("Choose Layout for Procedure (Bill Line)\
Details", 1, "Aligned Vertically", "\
Paragraph Style - Word Wrapped", "Does Not Apply")
if choose="Aligned Vertically"
'Perhaps I'll redo this using the apostrophe shorthand method - but not now!
macroname="/mmrgeoms1"
winopen="\""+word_location+"\""+"\""+name+"\" \""+macroname+"\""
sys_shell(""+winopen+"",1)
end if
if choose="Paragraph Style - Word Wrapped"
macroname="/mmrgeoms2"
winopen="\""+word_location+"\""+"
\""+name+"\" \""+macroname+"\""
sys_shell(""+winopen+"",1)
end if
if choose="Does Not Apply"
macroname="/mmrgeoms3"
winopen="\""+word_location+"\""+"\""+name+"\" \""+macroname+"\""
sys_shell(""+winopen+"",1)
end if
end if
'================
if choice="Add Bill to Batch"
script_play("OMS_Merge2")
end
end if
'================
if choice="Manage Batch Merges"
if is_object("BatchMerge") then
BatchMerge.show()
BatchMerge.activate()
else
:Form.view("BatchMerge")
end if
END
end if
'================
if choice="Edit Merge Document"
name=ui_get_file("Select the Letter You Want to Merge", "Word
Document (*.doc)",file_path, "X")
if name="" then
end
end if
winopen="\""+word_location+"\""+"
\""+name+"\""
sys_shell(""+winopen+"",1)
end if
'================
if choice="Create New Merge Document"
'Empty.doc is a word merge document which contains detailed
instructions for the user
'on how to create a merge document
name=a_db_current_path+"osomdocs\empty.doc"
macroname="/mmrgeoms4"
winopen="\""+word_location+"\""+"\""+name+"\" \""+macroname+"\""
sys_shell(""+winopen+"",1)
end if
'================
end
no_file:
ui_msg_box("Merge File", "was not found. Call OMS Comp, Inc.
for support.", 16)
end
locked:
on error goto 0
tries=tries+1
if tries<4
sleep(1)
resume 0
end if
ui_msg_box("Can't Do This Now", "the table is locked ... try
again later.")
Script 1. XBasic script to create and manage merge documents
| Editorial comment: There is one aspect of Finian's script that might
cause a conflict in the future. Finian uses a_tbl as a table pointer.
This should be discouraged - Alpha Software uses a_ as the prefix to
many system variables, and although I know of no use of a_tbl at
present, it may be pre-empted by Alpha Five in the future. What is particularly imaginative about Finian's script is his use of memo fields to export child records to Word. He keeps appending child records to the memo fields, and thereby achieves the effect of a "detail section" in Word. |
The Word Macros were first recorded using keystrokes, (Tools/Macro/Record) and later edited in the macro editor. I named the macros mergeoms1, mergeoms2 etc. Here's a sample of what the macro looks like. Don't be put off by the syntax, it's created by the macro recorder (much like the A5 V4 Script Recorder) and is remarkably easy to edit. I had NEVER seen the macro editor prior to this project and was able to make the very slight modifactions I needed by recording small actions and pasting the code into the target macro.
'========
Sub mrgeoms1()
'
' mrgeoms1 Macro
' Macro recorded 02/01/99 by Finian Lennon
'"
With ActiveDocument.MailMerge
.Destination = wdSendToNewDocument
.MailAsAttachment = False
.MailAddressFieldName = ""
.MailSubject = ""
.SuppressBlankLines = True
With .DataSource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=True
End With
Windows(2).Activate
ActiveWindow.Close (wdDoNotSaveChanges)
Selection.HomeKey Unit:=wdStory
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "|"
.Replacement.Text = "^l"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
Script 2. The Word macro
Suppose you have a MS Word document called primary referral.doc which
is located in the e:\a5\docs folder and that this document contains a saved
macro called merge1. To have MS Word start, load this document and
automatically run the macro, you will need to place the following command line
in a Win95/98/NT Shortcut:
"C:\Program Files\Microsoft Office\Office\WINWORD.EXE"
"E:\A5\DOCS\Primary Referral.doc" "/Mmerge1"
OK, it's a mouthful. Each section of the command is surrounded by quotes and
you need the full path to each file. The command to run the macro is /M
followed by the macro name. To have the Word merge system work from Alpha, this
command has to be parsed in a way that the sys_shell command can understand. In
the script, this is taken care of by the following lines:
name=ui_get_file("Select the Letter You Want to Merge",\
"Word Document (*.doc)",file_path, "X")
'the name variable supplies the document name with full path
dim global word_location as c
'this contains the path:
' "C:\Program Files\Microsoft Office\Office\WINWORD.EXE"
'and is entered in the application autoexec script
macroname="/mmrgeoms1"
winopen="\""+word_location+"\""+" \""+name+"\" \""+macroname+"\""
sys_shell(""+winopen+"",1)
5/14/99
Don't forget, we need your feedback to make this site better!