Tuesday, March 08, 2005

VFP: Call Report Writer from COM

We needed to move a number of existing VFP reports to the web quickly. One technique is to issue REPORT FORM ASCII TO from a COM object.

After digging around and testing we found that it was possible. There are two things to keep in mind.

1) COM objects cannot raise UI events.
The commands to ensure this are:
SET NOTIFY OFF
SET TALK OFF
REPORT FORM myRepo NOCONSOLE ASCII TO myrepo.txt

2) COM objects must be compiled as OUT OF PROCESS (EXE) not IN-PROCESS (DLL).
(Special thanks to Malcolm Greene of ProFox for this tip)

Here is the code we used to test the premise:


* run as is, assumes you have a FOXUSER file in use
***************************************************
* clear prior runs, create report from FOXUSER
CLEAR
CLOSE ALL
CLEAR ALL
ERASE myrepo*.*
USE SET("RESOURCE",1) AGAIN IN 0
CREATE REPORT myrepo FROM ALIAS()

* create main program with COM class
TEXT TO cMain NOSHOW
DEFINE CLASS myRepo AS Custom OLEPUBLIC
PROCEDURE DoReport(tlTest)
SET NOTIFY OFF
SET TALK OFF
SET SAFETY OFF
IF m.tlTest
STRTOFILE("This is a test","myrepo.txt")
ELSE
REPORT FORM myRepo NOCONSOLE ASCII TO myrepo.txt
ENDIF
SET SAFETY ON
RETURN FILE("myrepo.txt")
ENDPROC
ENDDEFINE
ENDTEXT

* write out the main program
SET SAFETY OFF
STRTOFILE(m.cMain, "myrepo.prg")

* add to project, compile EXE (not DLL)
CREATE PROJECT myrepo NOWAIT NOSHOW
_VFP.ACTIVEPROJECT.FILES.ADD("myrepo.prg")
BUILD EXE myrepo FROM myrepo
RELEASE WINDOWS PROJECT
SET SAFETY ON

* call without com
SET PROCEDURE TO myrepo.prg
o=CREATEOBJECT("myrepo")
TryMyRepo(o)
RELEASE o
SET PROCEDURE TO

* call with com
o=CREATEOBJECT("myrepo.myrepo")
TryMyRepo(o)

PROCEDURE TryMyRepo(o)
TRY
? o.DoReport(.T.)
? o.DoReport()
CATCH TO oExc
? oExc.MESSAGE
ENDTRY
ENDPROC

No comments: