Writing code to print a text report

This topic provides a sample text report program and handler.

Prerequisites

Synopsis

The program prints a list of all customers in the SQL database and their current balances.

The following events take place in the course of the program:
  1. The report generator program creates variables that are based on CustomerRecord and textReportHandler.
  2. The report generator calls the start() function from the handler.
  3. The handler start() function creates a variable that is based on the TextReport ExternalType part, and specifies functions for two events: onEveryRow and onLastRow. The function then passes control of the report to the text report engine by means of the myReport.startReport() function.
  4. The myReport.startReport() function does not change any report formatting, so the report engine returns control to the handler, which returns control to the report generator.
  5. The report generator creates a result set using the EGL open statement. This result set contains all customers from the current database.
  6. The report generator loops through the result set. For each customer, it sends the handler output() function a customer name and balance.
  7. The handler stores the customer name and balance in a record that is accessible to all functions in the handler and updates the running balance total.
  8. The handler then passes control to the report engine using the outputToReport() function.
  9. After performing certain housekeeping tasks, the report engine calls the onEveryRow() function in the handler.
  10. The onEveryRow() function in the handler sends the customer name in the current print position, moves to the 40th column of the page, prints the customer balance, and sends a carriage return and form feed to the report file.
  11. Control passes back to the report generator, which seeks the next customer record to process. When it has processed all customers, the generator calls the finish() function in the handler.
  12. The finish() function in the handler passes control to the report engine through the finishReport() function.
  13. The report engine finds a function for the last-row event and calls onLastRow() from the handler.
  14. The onLastRow() function in the handler prints the running total that the handler has been updating.
  15. The report engine closes the report file, and control passes back to the handler, and finally to the generator, which terminates the run unit.

The customer record

The program uses the following record to access the SQL database of customers:
record CustomerRecord type SQLRecord
   {tableNames = [["ADMINISTRATOR.CUSTOMER", "L1"]], 
    keyItems = [customerNumber]}

   customerNumber STRING      {column="C_NUMBER", maxLen=6};
   customerName STRING        {column="C_NAME", isSQLNullable=yes, maxLen=25};
   customerAddr1 STRING       {column="C_ADDR1", isSQLNullable=yes, maxLen=25};
   customerAddr2 STRING       {column="C_ADDR2", isSQLNullable=yes, maxLen=25};
   customerAddr3 STRING       {column="C_ADDR3", isSQLNullable=yes, maxLen=25};
   customerBalance MONEY      {column="C_BALANCE", isSQLNullable=yes};
end

The report generator

Execution begins with the report generator.
package com.companyb.customer;

program reportGenerator type BasicProgram

myCustomer CustomerRecord;
myHandler textReportHandler{};

   function main()
      myHandler.start();  // passes control to handler
      
      // get customer list from database
      open myResults scroll for myCustomer;
      forEach (from myResults)  // loop through results
         myHandler.output(myCustomer.customerName, myCustomer.customerBalance);
      end // forEach  
      myHandler.finish();  // close report
   end
end

The generic handler

Both the report generator and the report engine call functions from the handler.
package com.companyb.customer;

record reportRecord type BasicRecord 
   customerName STRING;
   customerBalance MONEY;
end

handler textReportHandler type BasicHandler 

myReport TextReport{};   // creates instance
currentReportRecord reportRecord;
runningTotal MONEY = 0;
   
   function start()
      myReport.onEveryRowListener = onEveryRow;
      myReport.onLastRowListener = onLastRow;
      
      // accept defaults on everything but destination file
      myReport.startReport("D:/temp/customerReport.txt",
        null,null,null,null,null,null);
   end
   
   function output(cName STRING in, cBal MONEY in)
      // this information comes from the forEach loop in the main program
      currentReportRecord.customerName = cName;
      currentReportRecord.customerBalance = cBal;
      runningTotal = runningTotal + cBal;
      
      // pass control to the report engine
      // onEveryRow is called
      myReport.outputToReport();  
   end
           
   function finish()
      // pass control to the report engine again
      // onLastRow is called
      myReport.finishReport();
   end
   
   function onEveryRow(myEvent TextReportEvent in)
      myReport.printText(currentReportRecord.customerName);
      myReport.column(40);
      myReport.printText(currentReportRecord.customerBalance);
      myReport.println();
   end
   
   function onLastRow(myEvent TextReportEvent in)
      myReport.println();  // skip a line
      myReport.printText("All customers:");
      myReport.column(40);
      myReport.printText(runningTotal);
   end
end 

Feedback