Partager via


Considerations for Creating New Report Output Types

Visual FoxPro 9's object-assisted reporting mode offers almost unlimited potential for expanding your output horizons using ReportListeners. The Report Output Application offers a convenient mechanism to help you to share your reporting extensions with other users.

This topic provides some guidelines to consider when developing and distributing Report System extension objects.

Design Decisions for Reporting Extensions

  • Determine whether your goal is to provide a new type of output result not available from baseclass behavior, such as Rich Text, or to enhance multiple output formats, in an output-result-independent manner.
    If your goal is to enhance existing output results, your object probably does not need to be a ReportListener, and it is not an Output Type.

    Design this object to be supportable, as a member or helper object, by multiple ReportListeners. It needs to be single-purpose and small, for efficiency. Design a ReportListener to accept enhancements by iterating through a collection of these objects.

    By contrast, if your goal is a new type of output result, it must be a ReportListener-derived object, so it can partner successfully with the Report Engine. It is a good candidate for a chain of responsibility mechanism, as implemented by the ReportListener Base Foundation Class. This mechanism allows you to generate multiple types of output during the same report run.

    Note

    You can use both techniques together. Register your enhancement objects to a single ReportListener, and apply their effects to the output before sending events to Successors. Each Successor can decide which enhancements are applicable to its type of output.

  • Determine your error handling strategy, and publish your object's requirements in this respect.
    ReportListeners partner with the Report Engine in a unique way, because of the way they process user code during a single Visual FoxPro command. They are also potentially partnered with other user code in DataEnvironment methods and user-defined functions (UDFs) embedded in the report or label file.

    There are different ways to handle REPORT FORM commands that do not complete properly. Review Handling Errors During Report Runs for information and suggestions. When you decide on a strategy, make sure the users of your ReportListener class have proper information to provide proper cleanup when errors occur.

  • Place ReportListener-required temporary tables in the special session provided for this purpose.
    The ReportListener object's FRXDataSession Property provides you with the information you need to access the special copy of the report definition file (.frx) during the report run. If your ReportListener needs to do work with additional cursors, use this protected session, rather than the data session containing the data on which the report is based, represented by the ReportListener object's CurrentDataSession Property. This strategy ensures that you leave the user's "real" data session undisturbed, and also ensures cleanup of these temporary files at the conclusion of a report run.

    Warning

    Be sure to switch appropriately between data sessions during the report run, when you want to use the report copy or your other workfiles. For more information, see SET DATASESSION Command.

    Tip

    For an example of objected-assisted reporting that uses additional cursors in FRXDataSession, see Report XML MemberData Extensions.

  • Make a distinction between the ReportListener's OutputType Property and ListenerType Property in your design.
    OutputType gives you the value with which the Report Output Application was invoked, while ListenerType represents the native output-generation mode provided by the baseclass ReportListener.

    A ReportListener-derived class can be registered to handle many different OutputType values in the Report Output Application's registry table, just as the baseclass ReportListener supports different ListenerType values. However, one OutputType can also support different baseclass behavior and native output, by supporting multiple ListenerType values.

See Also

Reference

Considerations for Creating Reports