Add Fields To Word  
Author Message
Bob Gatto





PostPosted: Visual FoxPro General, Add Fields To Word Top

Hello out there:

I'm trying to figure out a way to add a field to a Word document so when the document is called using Word Automation in Visual FoxPro, I can place a FoxPro table field value in it. I've seen it done before, I just can't figure out how to do it. Could someone out there help me Thanks.




Visual FoxPro2  
 
 
CetinBasoz





PostPosted: Visual FoxPro General, Add Fields To Word Top

Bob,

There are more than one ways. Word field, word mergefield, word form field, bookmark etc. Depends on what you're doing really. For a single document bookmarks seem to be easiest. For multiple documents mergefields sound to be more effective.

If you would add fields yourself as a template then from VFP:

oWord.Documents.Open( <fulpath to your doc> )

oWord.ActiveDocument.Variables("varname").Value = "New value"

oWord.ActiveDocument.Fields.Update

Bookmarks sample:

#include wdconstants.h
#Define NL Chr(13)+Chr(10)
*** set the LOCALEID to English
nlLocaleId=Sys(3004) && Save local id
=Sys(3006,1033)  && We will be sending instructions in English

Use _samples+'data\employee' && test table

* Create template document with bookmarks

m.lcFileName = Sys(5)+Curdir()+'myBoookmarkTest.doc'
oWordDocument=Createobject("word.application") && Create word object
With oWordDocument
 .Documents.Add && Create a new doc
 Scan
  .Selection.TypeText(Transform(emp_id)+NL+First_Name-(' '+Last_Name)+NL)
  .Selection.Collapse(wdCollapseEnd)
  lnRangeStart = .Selection.Range.End
  .Selection.TypeText(Nvl(notes,'')+NL+NL)
  lnRangeEnd  = .Selection.Range.End
  .Activedocument.Bookmarks.Add('b'+Alltrim(Transform(emp_id)),.Activedocument.Range(lnRangeStart,lnRangeEnd))
 Endscan
 .Activedocument.SaveAs(m.lcFileName)
 .Activedocument.Saved = .T.
 .Quit
Endwith
* Saved template and quit

***********************************************
* Now create a new file based on saved template
* and change text based on bookmarks
Select employee
lcEmployeeRecnos = '1,3,4,5,6'
lnEmployee = Alines(aEmpNo,lcEmployeeRecnos,.T.,',')
Dimension aBookmarks[lnEmployee,2] && Change text for only few employee
For ix=1 To lnEmployee
 Go Val(aEmpNo[m.ix])
 aBookmarks[m.ix,1] = 'b'+Alltrim(Transform(emp_id))
 aBookmarks[m.ix,2] = 'Notes for employee '+First_Name-(' '+Last_Name)+NL+NL
Endfor

* assumed typing replaces text option is set
oWord = Createobject('Word.Application')
With oWord
 .Documents.Add(m.lcFileName) && New file based on template file
 .Visible = .T.
 For ix=1 To Alen(aBookmarks,1)
  If .Activedocument.Bookmarks.Exists(aBookmarks[m.ix,1])
   * preserves bookmark, inserts text replacing old one
*   .Selection.Goto(wdGotoBookmark,,,aBookmarks[m.ix,1])

   .Activedocument.Bookmarks(aBookmarks[m.ix,1]).Select
   With .Selection
    .Font.Color = Rgb(255,0,0)
    .Font.Bold = .T.
    .TypeText( aBookmarks[m.ix,2] )
   Endwith
  Endif
 Endfor

 .Visible = .T.
 .Activate
Endwith
**** Set the LocaleId to the previous value
=Sys(3006,Val(nlLocaleId))
This one is probably the easiest. It uses mergefields for multiple documents (mailmerge). It can be used for a single document or multiple. Here showing it in edit mode but might silently send to printer or multiple documents merged.
Select * From customer Where country='USA' Into Cursor mergethese
MergeIt('mergethese')

Function MergeIt
Lparameters tcAlias, tcTemplateDoc
Local nLocaleID,lcTemp,lcHeader
Local loWord,llToPrinter,lcSourceDoc

*** set the LOCALEID to English
nlLocaleId=Sys(3004) && Save local id
=Sys(3006,1033)    && We will be sending instructions in English
*** set the LOCALEID to English

* Prepare source
Select (m.tcAlias)
lcTemp = Sys(2015)+'.tmp'
Copy To (lcTemp) Type Delimited With "" With Tab
lcHeader = ''
For ix = 1 To Fcount()
  lcHeader = lcHeader + ;
    Iif(Empty(m.lcHeader),'',Chr(9)) + ;
    Field(m.ix)
Endfor
lcSourceDoc = Sys(5)+Curdir()+'MergeSource.txt'
Strtofile(m.lcHeader+Chr(13)+Chr(10)+Filetostr(m.lcTemp),m.lcSourceDoc)
Erase (m.lcTemp)

loWord=Createobject("word.application") && Create word object
With loWord
  If Empty(m.tcTemplateDoc) && No template
    .documents.Add() && New file
  Else
    .documents.Add(m.lcTemplateDoc) && Open a template
  Endif
  With .Activedocument.Mailmerge
    .OpenDataSource(m.lcSourceDoc) && Set file as data source for mailmerge
    .EditMainDocument && Activate the main document

* Just to sample programmatic writing
    .Application.Selection.TypeText("Company : ")
    .Fields.Add(.Application.Selection.Range,'company')
    .Application.Selection.TypeText(Chr(13)+"Dear contact : ")
    .Fields.Add(.Application.Selection.Range,'contact')
    .Application.Selection.TypeText(Chr(13)+"Blah blah ...."+Chr(13))
* Just to sample programmatic writing

  Endwith
  .Visible = .T. && Show word app
  .Activate && Make it the active foreground app
Endwith

**** Set the LocaleId to the previous value
=Sys(3006,Val(nlLocaleId))