|
Technical answers from the trenches |
|
Creating Quick Reports
| ||||
Posted: 03 May 2001 |
||||
  |
Applies to: Paradox 5.0 and later |
|||
  |
Audience: Everyone |
|||
IntroductionIf you've worked with interactive Paradox for any length of time, you've probably noticed that Table windows let you press Shift+F7 to print a quick (or "instant") report. Unfortunately, you can't do this in Form windows. This article shows how you can add this functionality to your Paradox applications using ObjectPAL. The basic idea involves creating a template report, one containing a blank table frame. When the user triggers your code, it determines the table underlying the active object, adds that to your template report's datamodel, binds the table frame to that table, and then resizes the columns in the tableframe to fit accordingly, as shown in the following code: method doQuickReport()
; -------------------------------------------------------------------------
; Creates a quick report for the table underlying the active object.
; -------------------------------------------------------------------------
var
astrObjs array[] String ; holds objects in a table frame
fmActive Form ; pointer to the calling form
rptQuick Report ; the quick report itself.
siCounter SmallInt ; loop counter
strValue, ; use to hold different values.
strTitle String ; form's title
uiTarget uiObject ; used to resize fields in table frame
endVar
; first, make sure the active object has a tablename property.
try
strValue = active.TableName
onFail
; not data aware
beep()
return
endTry
if strValue = "" then ; (e.g. the object is not bound)
beep()
return
endIf
fmActive.attach()
strTitle = fmActive.getTitle()
; update the template report
if not rptQuick.load( ":priv:quickrpt", winStyleHidden ) then
errorShow( "Can't Print Report",
"Use [>>] for details..." )
else
sleep()
rptQuick.setTitle( strTitle + " Report" )
rptQuick.txtRptTitle.Text = strTitle
rptQuick.dmAddTable( strValue )
rptQuick.tfMaster.tableName = strValue
rptQuick.tfMaster.showAllColumns = TRUE
; reduce the columns to something to grow from
for siCounter from 1 to rptQuick.tfMaster.nCols
rptQuick.tfMaster.CurrentColumn = siCounter
rptQuick.tfMaster.ColumnWidth = 360
endFor
; tell each field object to fit width (and, yes,
; this looks like the only way to do it reliably.)
uiTarget.attach( rptQuick, "tfMaster" )
strValue = uiTarget.getProperty( "firstRow" )
uiTarget.attach( rptQuick, strValue )
uiTarget.enumObjectNames( astrObjs )
for siCounter from 2 to astrObjs.size() ; skip record itself
uiTarget.attach( rptQuick, astrObjs[ siCounter ] )
uiTarget.fitWidth = TRUE;
endFor
rptQuick.DesignModified = FALSE
endIf
endMethod
As you can probably tell, this particular example involves some design assumptions about the template report. Specifically:
You can use this in a variety of ways. For example, you can create the initial set of reports in a database system by adding a little bit of code to save the report to a new name (provided you're not using Runtime, which cannot save changes to a report). You can also use this to create specific types of reports. For example, suppose you've carefully designed a template report ideal for printing to a file. You can also use this approach while respecting any filters, ranges, or other environmental conditions (such a current index). Here's one way to do that: method doQuickReport()
; -------------------------------------------------------------------------
; Creates a quick report for the table underlying the active object.
; -------------------------------------------------------------------------
var
astrObjs array[] String ; holds objects in a table frame
fmActive Form ; pointer to the calling form
rptQuick Report ; the quick report itself.
siCounter SmallInt ; loop counter
strValue, ; use to hold different values.
strTitle String ; form's title
tcActive tCursor ; current data view
uiTarget uiObject ; used to resize fields in table frame
endVar
; first, make sure the active object has a tablename property.
try
tcActive.attach()
onFail
; not data aware
beep()
return
endTry
; save current view into a snapshot.
strValue = ":priv:answer.db"
tcActive.instantiateView( strValue )
tcActive.close()
fmActive.attach()
strTitle = fmActive.getTitle()
; update the template report
if not rptQuick.load( ":priv:quickrpt", winStyleHidden ) then
errorShow( "Can't Print Report",
"Use [>>] for details..." )
else
sleep()
rptQuick.setTitle( strTitle + " Report" )
rptQuick.txtRptTitle.Text = strTitle
rptQuick.dmAddTable( strValue )
rptQuick.tfMaster.tableName = strValue
rptQuick.tfMaster.showAllColumns = TRUE
; reduce the columns to something to grow from
for siCounter from 1 to rptQuick.tfMaster.nCols
rptQuick.tfMaster.CurrentColumn = siCounter
rptQuick.tfMaster.ColumnWidth = 360
endFor
; tell each field object to fit width (and, yes,
; this looks like the only way to do it reliably.)
uiTarget.attach( rptQuick, "tfMaster" )
strValue = uiTarget.getProperty( "firstRow" )
uiTarget.attach( rptQuick, strValue )
uiTarget.enumObjectNames( astrObjs )
for siCounter from 2 to astrObjs.size() ; skip record itself
uiTarget.attach( rptQuick, astrObjs[ siCounter ] )
uiTarget.fitWidth = TRUE;
endFor
rptQuick.DesignModified = FALSE
endIf
endMethodAs you can see, this version isn't vastly different from the previous one. The main changes focus on making a copy of the data being displayed before printing the report. Other approaches are certainly possible. We're often told to work smarter. This technique shows one way you can do so using Paradox. |
|||
|
||||||||
|
Copyright © 2000-2004, techtricks.com; All Rights Reserved. Acknowledgements, Disclaimers, Terms and Conditions. |
||||||||
|
Article last updated on 31 May 2003
|
||
|
|
||
|
[- End -]
|