テキスト・レポートを印刷するコードの作成

このトピックでは、テキスト・レポート・プログラムおよびハンドラーのサンプルを紹介します。

前提条件

概要

このプログラムは、SQL データベース内の全顧客のリストと、顧客の現在の残高を印刷します。

プログラムの実行中に、以下のイベントが発生します。
  1. CustomerRecord および textReportHandler に基づいて、レポート生成プログラムが変数を作成します。
  2. レポート生成プログラムが、start() 関数をハンドラーから呼び出します。
  3. ハンドラーの start() 関数によって、TextReport ExternalType パーツに基づく変数が作成され、2 つのイベント (onEveryRow および onLastRow) のための関数が指定されます。次に、myReport.startReport() 関数を利用して、レポートの制御がテキスト・レポート・エンジンに渡されます。
  4. myReport.startReport() 関数では、レポートのフォーマットは変更できません。そのため、レポート・エンジンはハンドラーに制御を戻して、ハンドラーはレポート生成プログラムに制御を戻します。
  5. EGL open ステートメントを使用して、レポート生成プログラムが結果セットを作成します。この結果セットには、現行のデータベースにある全顧客のデータが含まれています。
  6. レポート生成プログラムが、結果セットをループします。顧客ごとに、顧客名および残高をハンドラーの output() 関数に送信します。
  7. ハンドラーは、顧客名と残高を、ハンドラー内のすべての関数がアクセスできるレコードに格納し、最新の残高合計を更新します。
  8. 次に、ハンドラーは、outputToReport() 関数を使用して、レポート・エンジンに制御を渡します。
  9. レポート・エンジンは、一定のハウスキーピング・タスクを実行した後に、ハンドラー内の onEveryRow() 関数を呼び出します。
  10. ハンドラー内の onEveryRow() 関数は、顧客名を現行印刷位置に送信してから、ページの 40 番目の列に移動して、その顧客の残高を印刷し、改行文字および用紙送り文字をレポート・ファイルに送信します。
  11. レポート生成プログラムに制御が戻されます。レポート生成プログラムは、処理すべき次の顧客レコードを探します。すべての顧客データの処理が完了すると、生成プログラムはハンドラー内の finish() 関数を呼び出します。
  12. ハンドラー内の finish() 関数は、finishReport() 関数を介して、レポート・エンジンに制御を渡します。
  13. レポート・エンジンが、最終行のイベントの関数を見つけて、onLastRow() をハンドラーから呼び出します。
  14. ハンドラー内の onLastRow() 関数は、ハンドラーによって更新された最新の残高合計を印刷します。
  15. レポート・エンジンがレポート・ファイルを閉じて、ハンドラーに制御を戻します。最後に、生成プログラムに制御が戻されて、生成プログラムが実行単位を終了させます。

顧客レコード

このプログラムでは、以下のレコードを使用して、顧客の SQL データベースにアクセスします。
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

レポート生成プログラム

レポート生成プログラムから、実行が開始されます。
package com.companyb.customer;

program reportGenerator type BasicProgram

myCustomer CustomerRecord;
myHandler textReportHandler{};

   function main()
      myHandler.start();  // 制御をハンドラーに渡す
      
      // 顧客リストをデータベースから取得する
      open myResults scroll for myCustomer;
      forEach (from myResults)  // 結果をループ
         myHandler.output(myCustomer.customerName, myCustomer.customerBalance);
      end // forEach  
      myHandler.finish();  // レポートを終了する
   end
end

汎用ハンドラー

レポート生成プログラムとレポート・エンジンは、共にハンドラーから関数を呼び出します。
package com.companyb.customer;

record reportRecord type BasicRecord 
   customerName STRING;
   customerBalance MONEY;
end

handler textReportHandler type BasicHandler 

myReport TextReport{};   // インスタンスを作成する
currentReportRecord reportRecord;
runningTotal MONEY = 0;
   
   function start()
      myReport.onEveryRowListener = onEveryRow;
      myReport.onLastRowListener = onLastRow;
      
      // 宛先ファイル以外はデフォルトを受け入れる
      myReport.startReport("D:/temp/customerReport.txt",
        null,null,null,null,null,null);
   end
   
   function output(cName STRING in, cBal MONEY in)
      // この情報はメインプログラムの forEach ループから取得する
      currentReportRecord.customerName = cName;
      currentReportRecord.customerBalance = cBal;
      runningTotal = runningTotal + cBal;
      
      // レポート・エンジンに制御を渡す
      // onEveryRow が呼び出される
      myReport.outputToReport();  
   end
           
   function finish()
      // レポート・エンジンに再び制御を渡す
      // onLastRow が呼び出される
      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();  // 1 行スキップする
      myReport.printText("All customers:");
      myReport.column(40);
      myReport.printText(runningTotal);
   end
end 

フィードバック