Randy Wallin
COB System Designs, Inc
Introduction
Even in the middle of an object oriented world, the report designer’s primary purpose has not changed: to enable users to quickly and effectively produce reports that convey meaningful information based on the data stored in the data source.
Some of the things we will be covering in this session include:
Once you’ve created a report that you like for style and content, it would be great to save that report as a “Template” for future reports.
In FoxPro 2.x, you could create a default report with appropriate fonts, headings, logos, etc. and save it to a report called UNTITLED.FRX. Then the next time you created a report, the same defaults were applied to the new report. This 2.x tip relied on the fact that each new report would be called UNTITLED. If FoxPro found one, it would use it, otherwise one would be created.
In Visual FoxPro, the report designer does not rely on a file called UNTITLED but follows the Office standard where each new report created will have a sequential number associated with it. For example, if you start a new VFP session and create a report, the default name is REPORT1, the second report created in that session starts out as REPORT2, etc. So, how do we trick VFP to use a “Template”? Actually, it is the same process as you did in 2.x—create a report, alter all the style and content, save it as “UNTITLED”. The one difference is that you must implicitly ask for the untitled report file to be used as your template. To implement this 2.x tip in 3.0, enter: CREATE REPORT UNTITLED
Adding Label Styles to the Label Designer:
To add the standard label definitions to your resource file in FoxPro 2.x, you ran ADDLABEL.APP. In 3.0, you use the same program to accomplish the same task, with the additional ability to add custom label definitions. To add a label definition, you will need the following information:
Example: Avery 5162
Example: 5162 1-1/3” 4” 2
Don’t be put off by the 1/10,000 of an inch measurements. This roughly cor-relates to 1 inch is equal to 10,000 hundredths. So from our example above where the Height of the label was 1-1/3”, you would enter 13,333 thousandths of an inch (that’s 10,000 for the inch and 3,333 for the 1/3”). Enter 40,000 thousandths of an inch to reflect the 4” width of the label.
Printer Control:
FoxPro 2.x stored the printer setup information in the fields Tag and Tag2. The information was stored as a binary blob, so programmatically you had little control over the layout, paper size, printer, etc. In 3.0, the print setup settings will be saved in an ASCII format to give you the option to change it at run-time. You’ll find the printer setup information in the TAG field of the first record of the .FRX.
Here’s a simple example of how you could code a quick printer property change in a 3.0 report.
* Program...: chngprnt.prg
* Compiler..: FoxPro 3.0
* Abstract..: Simple routine to update the tag
* information for print settings
* Changes...:
*
* PARAMETERS: ReportName, Property to be changed, Change to
*
* EXAMPLE...: To insure the DRAFT Report will have Portrait Orientation
* IF ChngPrnt("DRAFT","Orientation","Portrait")
* ....
* ELSE
* WAIT WINDOW [Report not updated.]
* ENDIF &&* ChngPrnt("DRAFT","Orientation","Portrait")
*
LPARAMETERS cReportName, cProperty, eChange
LOCAL nSelect, nRecno, nLocation, cLine, cNewLine, lText
* make sure we have an extension on the cReportName
cReportName=IIF("."$cReportName,cReportName,cReportName+".FRX")
* make sure the file exists
IF ""==LOCFILE((cReportName),"FRX","Where is "+cReportName+"?")
RETURN .F.
ENDIF &&* ""==LOCFILE((cReportName),"FRX","Where is "+cReportName+"?")
* lText determines if we have a Text property to change
lText = (TYPE("eChange")=="C")
nSelect=SELECT()
nRecno=RECNO()
SELECT 0
USE (cReportName) AGAIN
nLocation=ATC(cProperty,TAG)
IF nLocation<>0
* build a line to change out with the new line
cLine=SUBSTR(TAG,nLocation)
cLine=SUBSTR(cLine,1,AT(CHR(13),cLine))
IF lText
cNewLine=LEFT(cLine,AT([=],cLine))+["]+eChange+["]
ELSE
cNewLine=LEFT(cLine,AT([=],cLine))+ALLTRIM(STR(eChange))
ENDIF &&* lText
REPLACE TAG WITH STRTRAN(Tag,cLine,cNewLine)
ELSE
IF lText
REPLACE TAG WITH ALLTRIM(TAG)+CHR(13)+cProperty+"="+["]+eChange+["]
ELSE
REPLACE TAG WITH ALLTRIM(TAG)+CHR(13)+cProperty+"="+ALLTRIM(STR(eChange))
ENDIF &&* lText
ENDIF &&* nLocation<>0
USE
SELECT (nSelect)
IF nRECNO>0
GO nRecno
ENDIF &&* nRECNO>0
RETURN .T.
Print Preview at runtime:
One of the new options that we have with the PRINT PREVIEW is the NOWAIT option. In essence, it makes the PREVIEW modeless.
For example, REPORT FORM Customer NOWAIT will load the PREVIEW window and immediately return to the program’s control.
Printing to a File:
Under 2.x and 3.0, you can output a report to a file for later printing with the REPORT FORM <<FRXNAME>> TO FILE command. When you want to print out the report, you have two options:
COPY FILE <ReportOutput.txt> TO LPT1.PRN
COPY <ReportOut.txt> PRN /B
here the /B signifies it is a binary file.
In 2.x, if you wanted to print the report to disk for later reviewing, you had several other problems to resolve:
The ASCII option in no way depends on the Generic / Text print driver or any special formatting of the report.
The new ASCII keyword works in conjunction with 2 system variables: _ASCIICOLS and _ASCIIROWS to set the width and height, respectively, of the report output. The default width is 80 characters and the default height is 63.
Happy reports using happy code:
Currently, adding code to a FoxPro 2.x report has been limited to expressions that are inserted via report variables. Within the VFP report designer, there are several different ways to incorporate code into your report:
Allow expressions to be used On Entry and On Exit of that band
Overcome the 2.x problem of not dropping the variable in a place where they would be correctly updated. These are evaluated on entry and on exit of the band.
What kind of things can you do with an ON ENTRY and ON EXIT expression? Percentage of total reports, perform lookup table evaluation before processing the band, resetting the text variable in the next child band based on the previous band’s results, etc.
Allows code, not just expressions, to be placed in the following events: BeforeOpenTables, Destroy, Error, and others.
The Data Environment always gets created and saved with the report. So, any code you enter in these methods will be saved with the report as well.
The BeforeOpenTables and Destroy events closely model the Load Event and Destroy Event methods in the form designer.
If you base your report on information that is apart of a DBC, you can utilize the “Stored Procedures” contained in the DBC to place your “report expressions”.
For example, the BASEBALL.DBC contains a table called PROS.DBF. The PROS report that is based on that table requires an expression to expand the players positions into meaningful expressions. For instance, “1B” becomes “First Base”, “CA” becomes “Catcher”, etc. In the report, ProsFrxExpandPos(“Position”) is inserted in the detail bands as an expression. In the stored procedures of BASEBALL, a function called ProsFrxExpandPos is created to return the correct expression based on the position passed to it.