Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
81
Добавлен:
11.05.2015
Размер:
2.11 Mб
Скачать

case WM_COMMAND: switch (wParam)

{

case IDC_PRINTBUTTON:

result = PEPrintReport ( “boxoffic.rpt”, FALSE, TRUE,

“My Report”, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndParent);

if (result != 0) return FALSE;

return TRUE;

}

break;

}

The Custom-Print Link

A more advanced, and more powerful, method of using the Crystal Report Engine is through a Custom-Print Link. Establishing a Custom-Print Link gives you a great deal of control over your reports at runtime. For example, you can:

set or modify the report sort order,

set or modify the record selection and/or group selection formulas,

modify existing report formulas,

set or modify the database location,

capture and evaluate Crystal Report Engine errors,

export a report to a file, e-mail, Exchange or Lotus Notes folder, or ODBC data source,

log on to SQL servers and ODBC data sources,

format report sections,

and much more.

NOTE: The Crystal Report Engine allows you to add a selection formula and sort fields to a report at runtime, even if none existed in the report when it was designed. Report formulas created in the Seagate Crystal Reports Formula Editor, however, must be added when the report is created in Seagate Crystal Reports. A formula can be edited with the Crystal Report Engine, but can not be added to an existing report from the Crystal Report Engine. Design your reports carefully, and keep this in mind when you create your application.

Crystal Report Engine

74

Coding a Custom-Print Link

There are six required steps to coding a Custom-Print Link in your application. Each uses a different REAPI function. These steps are:

Custom-Print Link Step 1: Open the Crystal Report Engine, Page 75 (PEOpenEngine).

Custom-Print Link Step 2: Open a print job, Page 76 (PEOpenPrintJob).

Custom-Print Link Step 3: Set the output destination, Page 76 (PEOutputToPrinter,

PEOutputToWindow, or PEExportTo).

Custom-Print Link Step 4: Start the print job, Page 77 (PEStartPrintJob).

Custom-Print Link Step 5: Close the print job, Page 77 (PEClosePrintJob).

Custom-Print Link Step 6: Close the Crystal Report Engine, Page 77 (PECloseEngine).

In addition to these six steps, you can add several optional tasks any time after Step 2, opening the print job, and before Step 4, starting the print job. These optional tasks include changing selection formulas, editing report formulas, selecting export options, and sorting report fields.

Some REAPI functions can be called at special times to retrieve information about the print job or Crystal Report Engine. For example, PEGetVersion retrieves the current version of the Crystal Report Engine being used and can be called at any time, even without the Crystal Report Engine being open. Another example, PEGetJobStatus, can be called after Step 4 to obtain information about the current status of a job being printed. For more information on all REAPI functions, see Seagate Crystal Report Engine Reference, Volume 2, Chapter 1 or search for functions by name in Developer’s online Help.

NOTE: The steps described here apply to a single print job. It is possible to have more than one print job open at once.

Custom-Print Link Step 1: Open the Crystal Report Engine

Example

PEOpenEngine();

Description

This step starts the Crystal Report Engine and prepares it to accept a print job. The Crystal Report Engine must be open before a print job can be established. You should open the Crystal Report Engine before the user has a chance to try to print a report. For example, if your application uses a dialog box as the user interface to the Crystal Report Engine, open the Crystal Report Engine immediately after the dialog box is created at runtime. Your dialog box can allow the user to establish a print job and make changes to the report while the Crystal Report Engine is already open.

Every time the Crystal Report Engine is opened, it should be closed once your application is finished accessing it (Custom-Print Link Step 6: Close the Crystal Report Engine, Page 77). For example, if you open the Crystal Report Engine when a dialog box is created, close the Crystal Report Engine when that dialog box is destroyed.

Crystal Report Engine

75

Custom-Print Link Step 2: Open a print job

Example

job = PEOpenPrintJob(“BOXOFFIC.RPT”);

Description

When you open a print job, the Crystal Report Engine returns a Job Handle for the print job. This handle is important to identifying the print job in the rest of your code.

To establish a print job, PEOpenPrintJob, Volume 2, Chapter 1, requires the path and name of the report that is to be printed. This argument can be hard-coded into the function call, as in the example above, or you can prompt the user to choose a report for printing and pass a variable argument to the function.

To close a print job, refer to Custom-Print Link Step 5: Close the print job, Page 77. In most cases, you should open the print job immediately before printing and close the print job as soon as the job is finished and the preview window is closed or printing is complete.

Custom-Print Link Step 3: Set the output destination

Example

PEOutputToWindow (job, ReportTitle, CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT, 0, NULL);

Description

The Crystal Report Engine must know where to send the final report. The report can be printed to a printer, displayed in a preview window, exported to a disk file, exported to another database, or exported to an e-mail address. The example above sends the report to the preview window.

Although you can choose any of the several destinations for report output, you must establish a destination for the report to print. You can, however, write code in your application that allows your users to decide on a destination themselves.

NOTE: This step does not actually print the report, it only establishes a destination for the report when printed. The report is actually printed in Step 4 using the PEStartPrintJob function.

The following functions are available to establish a print destination:

PEOutputToWindow, Volume 2, Chapter 1

Printing a report to a window requires no other print destination code other than the function itself.

PEOutputToPrinter, Volume 2, Chapter 1

Printing a report to a printer requires no other print destination code other than the function itself. However, PESelectPrinter, Volume 2, Chapter 1, can be used to select a printer other than the default printer at runtime. The PESelectPrinter function uses the Windows structure DEVMODE, Volume 2, Chapter 1. For more information on this structure, refer to the Windows SDK.

PEExportTo, Volume 2, Chapter 1

The PEExportTo function works with the PEExportOptions Structure (page 95) and several DLLs that control a report’s export destination and format. The information required by PEExportTo can be set in

Crystal Report Engine

76

your code at design time or it can work with options in your application to allow a user to specify export destination and format. If you would like to allow your users to set the destination and format of a report file, but you do not wish to program the interface to do this, use the PEGetExportOptions, Volume 2, Chapter 1 function to have the Crystal Report Engine provide dialog boxes that query the user for export information at runtime.

Custom-Print Link Step 4: Start the print job

Example

PEStartPrintJob(job, TRUE);

Description

This function actually sends the report to the output device indicated in Step 3. Once PEStartPrintJob, Volume 2, Chapter 1, is called, the Crystal Report Engine begins generating the report. The Crystal Report Engine displays a dialog box that indicates the status of the report being generated. If the report is sent to the preview window, the window will appear as soon as PEStartPrintJob is called. The preview window can be closed by a call to PECloseWindow, Volume 2, Chapter 1, by closing the Crystal Report Engine (as in Step 6), or by the user clicking the Close button.

As a general rule, you should avoid making any formatting changes to a print job once you call PEStartPrintJob, especially if the report is being displayed in a preview window (via PEOutputToWindow). Formatting changes made to a report while it is still being generated and displayed in the preview window may produce undesired results, and can cause errors in the Crystal Report Engine.

Custom-Print Link Step 5: Close the print job

Example

PEClosePrintJob(job);

Description

Once the print job has completed, it can be closed using PEClosePrintJob, Volume 2, Chapter 1. If you wish to make more changes to the report and print it again, you can do so before closing the job. However, once your application is finished with a report, it should close the print job to free up memory in the user’s system.

Custom-Print Link Step 6: Close the Crystal Report Engine

Example

PECloseEngine();

Description

This function closes the Crystal Report Engine entirely. No other Crystal Report Engine functions relating to print jobs may be called once the Crystal Report Engine is closed. Therefore, you should keep the Crystal Report Engine open until it is no longer needed in your application. For example, if the Crystal Report Engine is accessed through a dialog box in your application, you should wait to close the Crystal Report Engine until the dialog box is exited and destroyed by Windows.

Crystal Report Engine

77

A Sample Custom-Print Link

The sample code below has been designed to demonstrate four of the six basic steps in establishing a CustomPrint Link using the C programming language. This example is based on the following scenario:

Using Seagate Crystal Reports, you have created a report called ORDER.RPT and saved it to the C:\CRW directory. This report is a listing of customer orders, and it is the only report your application will need to print.

In your application, you have created a Print Report menu command that opens a dialog box. The dialog box allows the user to select whether the report is printed to the printer or sent to a preview window. If the report is to be sent to the preview window, a Boolean variable called ToWindow, declared and initialized in another section of code not seen here, is given the value of TRUE. If the report is to just be sent straight to the printer, ToWindow is given the value FALSE.

In the Print Report dialog box, there is also a Print button that initializes the event procedure to generate and print the report. The Event code section below demonstrates how the Custom-Print Link can be coded in the Print button event procedure of your application.

PEOpenEngine is called when the dialog box is created, and PECloseEngine is called when the dialog box is destroyed. For this reason, these two steps are not included in the Custom-Print Link that appears below.

The topic titled Event code demonstrates the basic custom-print event procedure. This code includes If statements that check to see if an error has occurred during the call to the Crystal Report Engine. When an error occurs, you can easily handle the error in a separate routine or function. The event code below calls the function ReportError whenever an error occurs. ReportError is not a Crystal Report Engine function but is meant simply as an example of how to handle Crystal Report Engine errors. The code for ReportError appears in the section Error code.

Event code

short hJob;

/* print job handle */

BOOL bResult;

 

hJob = PEOpenPrintJob(“C:\\CRW\\ORDER.RPT”); if (!hJob)

{

ReportError(hJob);

return;

}

if (ToWindow)

{

bResult = PEOutputToWindow(hJob,

“My Report”, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, NULL);

}

else

{

bResult = PEOutputToPrinter(hJob, 1);

}

Crystal Report Engine

78

if (!bResult)

{

ReportError(hJob);

PEClosePrintJob(hJob);

return;

}

if (!PEStartPrintJob(hJob, TRUE))

{

ReportError(hJob);

}

PEClosePrintJob(hJob);

return;

Error code

void ReportError(short printJob)

{

 

short

errorCode;

HANDLE

textHandle;

short

textLength;

char

*errorText;

errorCode = PEGetErrorCode(printJob);

PEGetErrorText (

printJob,

 

&textHandle,

 

&textLength);

errorText = (char*)malloc(textLength);

PEGetHandleString(textHandle,

errorText,

textLength);

MessageBox( hWnd, errorText, “Print Job Failed”,

MB_OK | MB_ICONEXCLAMATION);

return;

}

Crystal Report Engine

79

Code Evaluation

Event code

The following is an evaluation of the sample event code that appears above.

short hJob;

/* print job handle */

BOOL bResult;

 

This section declares two local variables that are important to the remainder of the code. The variable hJob will receive the handle to the print job that results from a PEOpenPrintJob call. This handle is required by most Crystal Report Engine functions. bResult will be given a TRUE or FALSE value as the result of several Crystal Report Engine calls. Any time bResult receives a FALSE value, an error has occurred.

hJob = PEOpenPrintJob(“C:\\CRW\\ORDER.RPT”);

This call opens the new print job according to the path and file name of the report that is to be printed. In this example, the report name is hard-coded in the Crystal Report Engine call. A user would have no choice as to which report is printed. This function could also accept a character array or a pointer to a character array as an argument, allowing you to give your users the opportunity to choose a specific report for printing.

PEOpenPrintJob returns a handle to the new print job, hJob. This handle will be used in all of the subsequent Crystal Report Engine calls shown here.

if (!hJob)

{

ReportError(hJob);

return;

}

This if statement verifies whether a valid print job handle was received in the previous line of code. If PEOpenPrintJob returned a value of 0, the print job is invalid and an error is reported. For more information on processing Crystal Report Engine errors, see the Error code section that appears below.

if (ToWindow)

{

bResult = PEOutputToWindow(hJob,

“My Report”, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, NULL);

}

else

{

bResult = PEOutputToPrinter(hJob, 1);

}

ToWindow acts as a Boolean variable that provides information from the user’s decision as to whether this report will be printed to a preview window or to a printer. If ToWindow holds a TRUE value, then the user has decided to print the report to a preview window.

Crystal Report Engine

80

The if else code determines an output destination for the report based on the user’s earlier decision. The PEOutputToWindow function prepares the Crystal Report Engine to create a preview window while PEOutputToPrinter directs the Crystal Report Engine to print the report to the default printer. (The printer used by the Crystal Report Engine can be changed with the PESelectPrinter function.) The variable bResult receives a FALSE value if an error occurs in either function call.

if (!bResult)

{

ReportError(hJob);

PEClosePrintJob(hJob);

return;

}

Once the appropriate destination function is called, you must verify its success and report an error if bResult is FALSE. ReportError is the error handling routine. It is an internal function designed to process any errors that occur during a print job. The function is passed the current value of the hJob handle for use in analyzing errors. Search for Crystal Report Engine Error Codes in Developer’s online Help for information on processing errors.

NOTE: ReportError is not a Crystal Report Engine function, but specific to the code appearing here; it is meant only as an example of how to handle Crystal Report Engine errors.

Since a print job has been opened, you must close it after the error is reported using PEClosePrintJob. See below for more information on this function. Finally, the if statement causes a return after the error has been reported, thus ending the print job session.

if (!PEStartPrintJob(hJob, TRUE))

{

ReportError(hJob);

}

PEStartPrintJob actually sends the print job to the printer or a preview window. If the report is printed to a window, PEStartPrintJob creates and opens the window according to the parameters set in the PEOutputToWindow function. If PEStartPrintJob fails (returns FALSE), an error is reported.

PEClosePrintJob(hJob);

Once the report has printed, this print job can be closed and another one can be started if needed. If the report has been printed to a preview window, PEClosePrintJob does not close the window. The preview window is closed when the Close button is clicked, the PECloseWindow function is called, or the PECloseEngine function is called.

return;

Now that the print job has finished, the event procedure can return, and the application can wait for the next user event to occur.

Error code

void ReportError(short printJob)

{

Crystal Report Engine

81

Crystal Report Engine error processing can be most efficiently handled by a separate internal function, such as the one shown here, that is called during a print job. The Event code that is evaluated above calls the ReportError function whenever a Crystal REAPI function returns an error. The code for the ReportError function appears here as an example of how to access and evaluate Crystal Report Engine errors. The error number returned by PEGetErrorCode can be used to control how your application reacts to different types of Crystal Report Engine errors.

NOTE: The REAPI functions described here, PEGetErrorCode and PEGetErrorText, are specific to REAPI error handling. For complete descriptions of these functions, see Seagate Crystal Report Engine Reference, Volume 2, Chapter 1, or search for the functions by name in Developer’s online Help. The function PEGetHandleString is used to retrieve variable length strings generated by different REAPI functions.

short errorCode; HANDLE textHandle; short textLength; char *errorText;

Completely processing any Crystal Report Engine error requires at least four variables like those above. While only errorCode will be needed to retrieve the Crystal Report Engine error number, the other three variables will all be needed to retrieve the actual error text.

errorCode = PEGetErrorCode(printJob);

PEGetErrorCode returns a number associated with the error that has occurred. For a list of these error codes and their meanings, search for Crystal Report Engine Error Codes in Developer’s online Help or see CRPE Error Codes, Volume 2, Chapter 1.

PEGetErrorText (

printJob,

 

&textHandle,

 

&textLength);

errorText = (char*)malloc(textLength); PEGetHandleString(textHandle,

errorText,

textLength);

The error text must be returned in the form of a handle to a variable length string. The handle is used, along with the PEGetHandleString function to obtain the actual error text and store it in a character array. This is a complicated process, and it should be examined carefully if your code is to work.

MessageBox( hWnd, errorText, “Print Job Failed”,

MB_OK | MB_ICONEXCLAMATION);

Once the error has been obtained, you can display error information to the user. This example simply opens a warning message box to alert the user of the problem. Using the error code and the error text, however, you can control Crystal Report Engine error messages any way that you find appropriate for your application.

return;

}

Once error processing is finished, you can return to processing the print job. If an error has occurred during the print job, however, then the print job should be terminated immediately after the error is processed. Review the evaluation of the event code above for ideas on how to terminate a print job after an error.

Crystal Report Engine

82

Соседние файлы в папке crystal