Reporting with dBASE Plus:
A Tutorial

Michael Nuwer
October 28, 2002

Session IV
Hiding Report Objects

Goals and Objectives

The goals for this Session are:

Introduction

One of the more powerful aspects of the dBASE reporting tools is that they are completely object orientated. This enables us to change any property of the report before the report prints, and thereby change how the report functions. As Ken Mayer notes:

This gives you a lot of power. I have found in several of my reports and labels that I didn't have to have multiple copies of the same report with minor changes to them like I used to in Crystal Reports -- I can have a single report, and before I render it, I can change just about anything -- as long as I know how to get to the specific control or property I need to change.

A simple example of this flexibility is setting a filter or a range. You might have a form that gets a parameter from the user. When the print button is clicked you might run code similar to this:

   oReport = new myReport()
   oReport.streamSource1.rowset.setRange(someVar)
   oReport.render()

This code creates a new instance of the report class, set the range then render the report. In this Session we are going to look at hiding particular elements of a report in order to modify its appearance.

Detail and Summary Reports

Developers often find that their clients or users often want a report that prints all the details and another one that prints just the summaries. The dBASE reporting tools make this type of thing rather easy. Essentially, a summaries only report is a report with an invisible detail-band. (And if you have headings in the group headerband, these too need to be made invisible.)

Open the report named Hiding1.rep. This report may look familiar, as it is the same as the CalcField1.rep Report. This single report can be controlled so that is renders with all the details displayed or with only the summary information. To do this we will add some new bootstrap code -- that is, code at the very top of the file. This code will be used to instance the report in different ways.

local r
r = new Hiding02Report()
set procedure to program(1) additive
if msgbox("Do you want to show totals only?","Report Type",4)==6    //yes
   // process report for totals only
   r.streamSource1.detailBand.visible = false
   r.StreamSource1.group1.headerBand.KMStandardText1.visible = false
else
   r.streamSource1.detailBand.visible = true
   r.StreamSource1.group1.headerBand.KMStandardText1.visible = true
endif
r.render()
return

Run the report. A message box will appear with a Yes and a No button. If the user clicks the "Yes" button, the code sets the visible property for the detailBand and one text object in the group headerBand to false. The report will then print without the details. However, the aggregate summaries in the group footerBand will print and it will appear as a "summary only" report.

When the user clicks the "No" button in the message box, the standard report is printed. Our code sets the visible property of the two objects true.

In a production application, this type of code might be in your menu or in a form that controls printing choices. If you are using a reportViewer object, like Preview.wfm (which we used in the dBASE application tutorial), you will need to use a params array to set these properties (this topic will be covered in Session VII).

Hiding unwanted headerbands

When a report is based on data from two tables in a one-to-many relationship, there are times when a parent record does not have any child data. One way to deal with this issue is to use a single query where the SQL select statement joins the two tables into a single rowset. Another way is to use a canGetRow in the parent table and return true only if a lookup into the child table finds a record (you should use a second copy of the child table for this procedure). A third technique, which we will use here, is to hide the report's group header, detail and group footer bands when no detail data is available.

Open Hiding2.rep in the report designer. This report selects female dogs from the Dogs.dbf table and lists details about their litters.


An added example in this report is the use of the canGetRow event for selecting the female dogs. The report is adding a female dog to the query only if it's registration number begins with "DRC-G". This is done only to simplify the example for this Tutorial.

If you run this report and scroll through the pages, you will see that a number of the dogs do not have a litter and therefore have no data in the detail band. The goal of this report is to hide those cases where there are no details.

To accomplish this, we will add a second instance of the litters.dbf table to the report. Each time the Master query navigates to a new dog, we will lookup the registration number in this duplicate query. If the dog is not found, we will hide the report components so that they do not print.

Begin by dragging another instance of the litters query onto the report. It will be named Litters2. Set the indexName for this rowset to "DAM" so that we can lookup on that field.

Next add an onNavigate event handler to the Dogs1 rowset. Be careful here. Be sure you do this for dogs1 rowset, not the Litters1 or Litters2 rowset, and not the form onNavigate event.

Then, add the following code to this event handler:

 function rowset_onNavigate(type, nRows)
   local cMasterRecordID, oRow, oSteamSource
   cMasterRecordID = ;
     this.fields["reg_no"].value
   oRow = this.parent.parent.litters2.rowset
   oStreamSource = this.parent.parent.streamsource1
   if oRow.findKey(cMasterRecordID)
      // if found show objects
      oStreamSource.group1.headerband.visible := true
      oStreamSource.group1.footerband.visible := true
      oStreamSource.detailband.visible := true
   else
      // if not found hide objects
      oStreamSource.group1.headerband.visible := false
      oStreamSource.group1.footerband.visible := false
      oStreamSource.detailband.visible := false
   endif
   
   return
 

The code above will lookup each dogs reg_no in the Litters2 rowset. If it is found, the headerband, footerband, and detailband will be set visible, otherwise these bands will be hidden.

You should be able to run this report and the dogs with no litters should not be printed.


Go to next Session
Go back to the tutorial menu

The Legal Stuff: This document is part of the dBASE Reporting Tutorial created by Michael Nuwer. This material is copyright © 2002, by Michael Nuwer. dBASE, dBASE Plus, dBASE SE, and dB2K are copyrighted, trademarked, etc., by dBASE, Inc., the BDE (Borland Database Engine) and BDE Administrator are copyrighted, trademarked and all that by Borland, International. This document may not be posted elsewhere without the explicit permission of the author, who retains all rights to the document.