# Report Writer User Interfaces

Logic Object Interface |

The Report Writer can interface with an optional user-created object, which supplies additional generic logic for processing reports. Specifically, the user object has properties and methods, as specified in the User Interface Specifications section below, that can be used to set up the execution environment, load variables, specify new system variables, adjust the report format, manipulate data, and reset the environment. The user object may also have additional miscellaneous methods that can be referenced in the report definition.

The user logic object must either reside under the *rpt directory and be named *rpt/userlogic.pvc, or the global variable %RW_UserLogic$ can be pre-loaded with the object name before the Report Writer object (*rpt/pvxreport) is created. The object named in %RW_UserLogic$ will take precedence. If an *rpt/userlogic.pvc logic object exists or one is specified in %RW_UserLogic$, it will be used to process all reports.

## User Interface Specifications

*rpt/userlogic.pvc
The user logic object will be created during the On_Create logic of the *rpt/pvxreport report object and dropped during the On_Delete logic. It must be defined with specific properties and functions, although additional local properties and On_Create/On_Delete logic may be included as desired. The required methods may contain simple stubs if there is no additional logic associated with them.

The user interface must include the following properties and methods:

function Initialize( ) | The *rpt/pvxreport object will invoke this method in its On_Create logic. It is useful for setting up the execution environment for defining or generating a report.
function Reset( ) | The report object will invoke this method in its On_Delete logic. It can be used to reset the execution environment, if desired.
function UpdateReport(Rpt) | This method is invoked as the first step in the *rpt/pvxreport object StartReport( ) method. At this point, a report definition is contained within the report object, and the object handle for *rpt/pvxreport (Rpt) is passed to UpdateReport( ) so it has access to change the definition before the report is generated.
function UpdateData$(Data$,iolist$) | This method is used within the *rpt/pvxreport object ReadData$( ) method immediately after a record is read. If the file being read has an external key, then this method is invoked passing the unparsed key data and the key IOList. The method is also invoked passing unparsed record data and the compiled data IOList. This method can be useful for translating unprintable characters that could exist in the data. Data can be manipulated on the unparsed record level, or on a field by field level by reading the data from the record into the fields (i.e. READ DATA FROM Data$ to IOL=iolist$). This method returns a string value consisting of the manipulated record. If the data was parsed into fields and manipulated, it must be reassembled into a record to be returned; i.e. REC(iolist$).
property UserVariableCount function GetUserVariable$(idx) function GetUserVariableDescription$(idx) function GetUserVariableLength(idx) function GetUserVariableValue$(idx) | The user object contains a series of properties and methods that allow the user to specify user variables that can be appended to the list of standard system variables that are supported by the Report Writer. If any user variables are defined, then they will be included wherever standard system variables may be accessed, such as the Field Selection list of the Report Designer where they can be dragged and dropped on the report layout, or in formula definitions where they can be included as part of the formula. The UserVariableCount property must be set with the number of user variables to be defined, and methods must be defined to return information concerning each variable:
GetUserVariable$(idx) | Returns the variable name
GetUserVariableDescription$(idx) | Returns a short description of the variable
GetUserVariableLength(idx) | Returns the maximum length of its value
GetUserVariableValue$(idx) | Returns its current value as a string (must convert numerics)
The user variable in question is identified by an index (i.e. information concerning the first variable will be returned if the index passed to the method is one, etc.).

## Additional Methods

The developer may include additional methods that can be accessed in the report using UserLogic as the object handle.

Example:

The user could include a method in the user object to format the page number in a particular way:

> function UserPage$(PageNumber$)=msg("PAGE")+PageNumber$

Then, in the report definition, the formula UserLogic'UserPage$(_Page$) could be used in one of the page header cells to format the page number.

Post Report Logic

Another example of an additional method is a Post Report method that would be invoked upon completion of a report. In the case of Post Report methods, the method call is defined as Post Report Logic in the Report Options window (on the Custom Interfaces tab). The arguments that may be passed to this method include report properties, field names and method calls (using the report object handle variable THIS).

Example:

A function, such as the following, could be defined in the user Logic Object:

> function PostReportLogic(rpt,invoice$)
> enter rpt,invoice$
> ! In this case the logic can use the rpt report handle to reference all report properties and methods
> ! Post report logic could be used to email pdf files, notify users that a report is complete, etc.
> return 1

The method would then be defined In the Post Report Logic of the Report Options window (on the Custom Interfaces tab) as:

> Method: PostReportLogic(THIS,INV_NUM$)

Where:

THIS is the report object handle and INV_NUM$ is a field in the report.

(The Post Report Logic method call was added in PxPlus 2022.)

*rpt/rptuserlogic Template

The following template is supplied for the *rpt/userlogic object, constructed with stubs for all required methods.

> ! *rpt/rptuserlogic.pvc - Template for the UserLogic object
> !
> !
> def class "*rpt/rptuserlogic"
> !
> property UserVariableCount
> !
> function Initialize()=1
> function Reset()=1
> function UpdateReport(Rpt)=1
> function UpdateData$(data$,iolist$)=data$
> function GetUserVariable$(idx)=""
> function GetUserVariableDescription$(idx)=""
> function GetUserVariableLength(idx)=0
> function GetUserVariableValue$(idx)=""
> !
> end def

When creating the *rpt/userlogic object, it is recommended that the class definition include a LIKE "*rpt/rptuserlogic" statement. This means that stubs are present for methods that are not required, and the user need only supply properties and methods for which there is additional logic. It also ensures that stubs will be present for new methods that may be required in future enhancements.

Example:

The following is a sample *rpt/userlogic object:

> ! Userlogic.pvc - Sample Report User Logic object
> !
> !
> def class "*rpt/userlogic" create required
> !
> like "*rpt/rptuserlogic"
> !
> property UserVariableCount
> !
> local UserVariableName$
> local UserVariableDescription$
> local UserVariableLength
> local User$
> local TRN_TBL$=$FF3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
> 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636466666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
> 8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D
> 2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF$
> !
> function Initialize()Initialize
> function UpdateReport(Rpt)Update_Report
> function UpdateData$(data$,iolist$)=tbl(data$,TRN_TBL$)
> function GetUserVariable$(idx)Get_User_Variable_Name
> function GetUserVariableDescription$(idx)Get_User_Variable_Description
> function GetUserVariableLength(idx)Get_User_Variable_Length
> function GetUserVariableValue$(idx)Get_User_Variable_Value
> !
> !
> end def
> !
> !
> On_Create:
> UserVariableCount=3 ! Set the number of user variables here
> dim UserVariableName$[1:UserVariableCount];
> UserVariableName$[1]="CompanyName$";
> UserVariableName$[2]="CompanyCode$";
> UserVariableName$[3]="VersionNumber" ! Dimension and load the variable name array
> dim UserVariableDescription$[1:UserVariableCount];
> UserVariableDescription$[1]="Company Name";
> UserVariableDescription$[2]="Company Code";
> UserVariableDescription$[3]="Version Number" ! Dim and load the description array
> dim UserVariableLength[1:UserVariableCount];
> UserVariableLength[1]=40;
> UserVariableLength[2]=3;
> UserVariableLength[3]=4.2
> ! Dimension and load the variable max length array
> ! Initialize other work variables
> if tcb(88) \
> then call "[wdx]*windx.utl;get_val","WHO",User$ \
> else User$=who
> return
> !
> !
> Initialize:
> %ReportDirectory$="R:\rpt\"
> return 1
> !
> Update_Report:
> enter Rpt
> ! Only BigBoss gets to see the individual balances
> if User$="BigBoss" \
> then return 1
> gc=Rpt'GroupCount()
> for gc
> grp=Rpt'GetGroup(gc)
> lc=grp'LineCount()
> for lc
> line=grp'GetLine(lc)
> cc=line'CellCount()
> for cc
> cell=line'GetCell(cc)
> if cell'format$<>"" and pos("BALANCE"=ucs(cell'value$)) \
> then cell'value$="------------",cell'format$=""
> if cell'AlternateCell>0 and cell'AlternateCell'format$<>"" and pos("BALANCE"=ucs(cell'AlternateCell'value$)) \
> then cell'AlternateCell'value$="------------",cell'AlternateCell'format$=""
> next cc
> next lc
> next gc
> return 1
> !
> Get_User_Variable_Name: \
> enter idx
> if idx<1 or idx>UserVariableCount \
> then return "" \
> else return UserVariableName$[idx]
> !
> Get_User_Variable_Description:
> enter idx
> if idx<1 or idx>UserVariableCount \
> then return "" \
> else return UserVariableDescription$[idx]
> !
> Get_User_Variable_Length:
> enter idx
> if idx<1 or idx>UserVariableCount \
> then return 0 \
> else return UserVariableLength[idx]
> !
> Get_User_Variable_Value:
> enter idx
> if idx<1 or idx>UserVariableCount \
> then return ""
> switch idx
> case 1
> v$="ABC Company" ! supply the value of the user variable
> break
> case 2
> v$="ABC"
> break
> case 3
> v$="7.00"
> break
> end switch
> return v$