What's New in the VFP 8 Report WriterThis article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
What's New in the VFP 8 Report Writer
Yes, Hell has frozen over and pigs do fly! Microsoft has made some improvements to the Report Writer in Visual FoxPro 8.0. Some developers thought this day would never come, but surprisingly it has. Cathy Pountney explores.
Now, before you get too excited, the Visual FoxPro team at Microsoft didn't do any major rewrites to the Report Writer. They did, however, give us some much-needed minor improvements. For example, we now have the ability to get rid of the printer-specific binary codes without having to hack the FRX. We can also print "Page x of y" with ease. These changes aren't major—but they sure do make our lives easier!
In addition to giving us some new enhancements, the VFP team has also fixed a few bugs, described later in the article in the section "Bug fixes."
Design-time enhancementsVisual FoxPro 8.0 has several enhancements to the Report Designer, including a new check box to include or exclude the printer environment, the ability to drag and drop captions from the DBC, and a new Report tab on the Options dialog.
For peace of mind, the best thing you can do is strip out any printer-specific information from each report. Prior to Visual FoxPro 8.0, this wasn't easy. In fact, you had to hack the report's FRX file to do it. Luckily for us, though, it's very easy to do in VFP 8.0.
Select Report | Printer Environment from the main VFP Menu bar to toggle the Printer Environment setting. Checking this option tells Visual FoxPro to save the printer environment information in the EXPR, TAG, and TAG2 fields in the first record in the FRX file. Conversely, unchecking this box tells Visual FoxPro to not save any printer environment information in the FRX file. I recommend unchecking this option on all your reports.
Drag and drop DBC captions
The ability to drag and drop field captions is toggled on or off by a setting on the Report tab of the Options dialog (see the next section, "Report tab on the Options dialog").
Report tab on the Options dialog
The third report option, Drag and drop field captions, controls what happens from this point forward. At the time you initiate drag and drop in the Report Designer, Visual FoxPro looks at the setting in the Options dialog to determine whether to drop field captions alongside each field.
Running reportsVisual FoxPro 8.0 has some new enhancements for running reports, including the ability to suppress the Printing... dialog, the ability to chain multiple reports together, and a new system variable for determining whether the user is printing or previewing. Visual FoxPro 8.0 has also made an improvement to allow errors in reports to be trapped just like any other error in Visual FoxPro.
Suppress the Printing... dialog
Visual FoxPro 8.0 has introduced a new clause for the REPORT command that allows you to suppress the Printing... dialog. Use the NODIALOG clause as follows:
REPORT FORM MyReport TO PRINTER PROMPT NODIALOG PREVIEW
Adding the NODIALOG clause tells the Visual FoxPro Report Writer to skip creating or displaying the Printing... dialog. Be sure to put the NODIALOG clause between the TO PRINTER PROMPT and the PREVIEW clause, or an error will occur.
Is the user printing or previewing?
Visual FoxPro 8.0 introduces the SYS(2040) function to help you determine the state of printing. A return value of 0 means no report is printing or previewing at this time. A return value of 1 means the report is previewing, and a return value of 2 means the report is printing. Note that the return value is character, not numeric. Simply use SYS(2040) = '1' in the Print When expression of a report object if you only want the object displayed in preview mode. Use SYS(2040) = '2' if you only want the object printed on the hard copy.
But wait—there's more! This client's scenario gets a little trickier. Besides printing all three reports as one, they also want the page numbers to continue from one report to the next. For example, if each report consisted of three pages, report1 needs to show pages 1-3, report2 needs to show pages 4-6, and report3 needs to show pages 7-9 in the footer.
Visual FoxPro 8.0 has introduced a few new clauses to help you chain reports together. The NOPAGEEJECT clause tells the Report Writer to keep the print job open when the report finishes so another report can continue in the same print job. The NORESET clause tells the Report Writer to not reset the page number when printing a report so this report's page numbers pick up where the previous report's page numbers left off.
To chain three separate reports together, use the following code:
* Print the first report * Use NOPAGEEJECT to keep the print job open REPORT FORM Report1 TO PRINTER PROMPT NOPAGEEJECT * Print the second report * Don't use PROMPT * Use NOPAGEEJECT to keep the print job open * Use NORESET to keep the page numbers rolling REPORT FORM Report2 TO PRINTER NOPAGEEJECT NORESET * Print the last report * Don't use PROMPT * Don't use NOPAGEEJECT * Use NORESET to keep the page numbers rolling REPORT FORM Report3 TO PRINTER NORESET
I have to admit that I'm not thrilled at how Microsoft implemented this new feature. First, you may have noticed that I didn't include the PREVIEW clause in any of the commands. The reason is that previews don't get chained together. In other words, if the preceding example had included the PREVIEW clause, you would have seen three separate previews. Personally, I think this is extremely confusing to the user and will cause major support issues because the user won't think to press the printer button for each different report that appears.
Another issue I have is the fact that you, the developer, have to remember to exclude the NOPAGEEJECT clause from the last report printed so the print job gets closed. This might be fine when you're printing a known number of reports. However, when trying to chain reports together from inside a SCAN/ENDSCAN loop, you may not know when you're on the last report. This means that when you get done with the scan loop, you still have an open print job that has to be closed with a fudged report as follows:
REPORT FORM MyReport NEXT 0 TO PRINTER
I don't consider this a very smooth way to handle the situation, but it's about the only choice you have.
There's a handful of other issues that cause problems, such as combining landscape and portrait reports in one print job or using the new _PAGETOTAL system variable along with chained reports (discussed later in the section "Print 'Page x of y'"). But heck, at least this is better than nothing!
Error handling in reports
With Visual FoxPro 8.0, this changes. Errors that occur in reports during runtime will now trigger the normal FoxPro error handling, including any ON ERROR code you have in place. The LINE() and PROGRAM() functions return the REPORT FORM command that initiated the report. The ERROR() and MESSAGE() functions return information about the error that occurred. Of course, you still have to track down which object in the report triggered the error.
The best way to track down which report object triggered the error is to preview the report from the Report Designer. Many developers don't realize this, but when an error occurs while previewing a report from the Report Designer, you're notified of the error, and then the offending report object's dialog is displayed. Then it's up to you to investigate whether it's the expression, the Print When logic, or something else. This is a huge time-saver to have the Report Designer pinpoint the offending report object, instead of you having to go one-by-one through each object looking for the problem.
In many cases, it's hard to preview a report from the Report Designer because the report relies on cursors and tables and variables set up by the calling program. If you run into a report error in this situation, here's how to overcome it. In the program that runs the report, change the REPORT FORM command to the MODIFY REPORT command and then run your application. Now the application can prepare the data and variables as usual, but the Report Designer displays instead of the report trying to run. Once the Report Designer displays, just select Preview and voilà! The error is displayed and the offending report object's dialog appears.
New and improved featuresA new much-asked-for feature is the ability to print "Page x of y" on a report. In addition to this feature, the VFP team has improved a few existing features. Stretching and floating of objects in the Page Footer weren't allowed in versions prior to VFP 8.0, and printing the Page Header and Page Footer in the Summary band was tricky to say the least.
Print "Page x of y"
In Visual FoxPro 8.0 this has changed. Simply use the _PAGETOTAL system variable to print the page count in a Visual FoxPro report. Before processing a report, Visual FoxPro looks to see if the _PAGETOTAL variable is used anywhere. If it is, VFP does a two-pass process. The first pass is done to get the total page count, and the second pass is the final preview or print pass. If the _PAGETOTAL variable isn't used anywhere on the report VFP doesn't do the two-pass processing, so you don't have to take the performance hit when it's not necessary.
It's important to remember that using this new system variable causes the Report Writer to do a two-pass process, especially if you're calling a UDF or method call that updates other data. To avoid updating the data twice, wrap your code with an IF statement as follows:
IF _PAGETOTAL <> 0 * Do your updating here ENDIF
During the first pass, the _PAGETOTAL variable is zero. Therefore, it's a safe assumption that if the variable isn't zero, you're in the second pass, which is when you want to update your data.
Previously, I mentioned that chaining reports with the new NOPAGEEJECT clause doesn't work well with the new _PAGETOTAL variable. The problem is that the first report doesn't know about any reports that you're about to print. It only knows about itself and how many pages it has. The second report knows about the first report and itself, but it doesn't know about the third report and so on. What this means is that you'll get incorrect page counts on all but the last report of the print job. For example, if you're printing three reports, each having two pages, the page numbering appears as follows:
Page 1 of 2 Page 2 of 2 Page 3 of 4 Page 4 of 4 Page 5 of 6 Page 6 of 6
Stretch and float objects in the Page Footer
There's one gotcha with this new feature. If you're calling a method or UDF in the Detail band to build a variable or memo field that you intend to print in the Page Footer, you could get bit. A common example of this is to build a variable that contains footnotes. For each record that has a footnote associated with it, you can add the text to a character variable along with a carriage return/line feed (CHR(10) + CHR(13)). In the Page Footer, you can print the variable and have the object stretch with overflow.
Before printing a particular Detail band, the Report Writer checks to see whether there's enough room left to print this Detail band and the Page Footer, taking into account any stretching objects in the Page Footer. If it determines there's enough room for both, it processes the Detail band. Herein lays the problem. In your Detail band, you happen to call a UDF that adds additional lines to the variable you're about to print in the Page Footer. The Report Writer finishes up the Detail band and moves on to the Page Footer. Only now there's too much information to print in the space left on the page.
This is a real bummer because the preceding example is one of the main reasons we need stretchable fields in the Page Footer. However, in Microsoft's defense, I can understand why this happens and I realize that it's a tough problem to solve. So for now, we just have to accept this limitation.
Include the Page Header and Page Footer in the Summary
In Visual FoxPro 8.0, there are two new check boxes added to the Title/Summary dialog to help overcome these situations. The first check box, Page Header, tells Visual FoxPro whether the Page Header should print along with the Summary band. The Page Footer check box tells Visual FoxPro whether the Page Footer should print along with the Summary band.
The addition of the new check boxes still doesn't correct the bug that occurs when a Summary band isn't marked to start on its own page, yet overflows due to lack of room. Microsoft's response to this bug is that you should check these new check boxes to solve the problem. Although this workaround solves the problem, I still stand by my statement that this behavior is a bug.
Bug fixesSpeaking of bugs, the VFP team has corrected a few bugs in VFP 8.0. Notice I said "few." Many bugs still exist in the Report Writer as documented in my book, The Visual FoxPro Report Writer: Pushing it to the Limit and Beyond.
Edit Bands dialog
No more ghosts
As glad as I am to see this bug fixed, there's a penalty. Now when you zoom a report, it flickers two or three times. The report displays, and then quickly disappears, and then displays again. Oh well, nothing in life is free!
ConclusionIt's nice to see the Visual FoxPro Report Writer finally get some attention. VFP 8.0 has given us some new features, improved upon some old ones, and addressed a few bugs. Microsoft has also announced that the next version of Visual FoxPro, codenamed Europa, will have many more improvements to the Report Writer. Let's all keep our fingers crossed!
To find out more about FoxTalk and Pinnacle Publishing, visit their Web site at http://www.pinpub.com/
Note: This is not a Microsoft Corporation website. Microsoft is not responsible for its content.
This article is reproduced from the November 2003 issue of FoxTalk. Copyright 2003, by Pinnacle Publishing, Inc., unless otherwise noted. All rights are reserved. FoxTalk is an independently produced publication of Pinnacle Publishing, Inc. No part of this article may be used or reproduced in any fashion (except in brief quotations used in critical articles and reviews) without prior consent of Pinnacle Publishing, Inc. To contact Pinnacle Publishing, Inc., please call 1-800-788-1900.