Anda di halaman 1dari 4

Adding User Function Libraries to Crystal Reports

By Thomas Althammer As explained in previous TeaTalk contributions, Crystal Reports is a powerful system for reporting demands and data analysis. It can be used on its own or be integrated into development projects. Next to the broad available functionality, there are mechanisms to enhance the product with user-defined function libraries that are presented in this article. Crystal Reports comes with a huge list of functions that can be used in formulas. If you open the formula editor by adding a new method to your report, the middle window displayed a categorized list of the available functions. Some of these built-in functions depend on the formula syntax used with Crystal that can be changed in a drop-down list on the top of the editor window.

While Crystal already includes a large selection of useful functions, it also comes with the ability to accept new functions that you define to meet your needs. Both available syntaxes (Crystal syntax and Basic syntax) have a branch with additional functions on the bottom of the middle tree. If you open this branch, there are already quite a few entries available. Additional functions can be added to the tree just like if they were internal Crystal Reports functions. It is similar to using External Functions in Team Developer, with the difference that you do not have to define them in the outline. Crystal detects their presence itself but more on that later! www.iceteagroup.com

At support.crystaldecisions.com you can also download user function libraries (UFL), for example to calculate the number of business days between two dates passed as a parameter. How can I create an UFL? These libraries can be written in several programming languages. Basically, two types of function libraries are supported: dynamic link libraries and COM Automation server. UFLs implemented as dynamic link libraries are usually coded in C and they must include files that are shipped with Crystal Reports. Optionally, these files can be downloaded from Crystal Decisions support site. We are going to look at the automation server part. Such a server can be written with Visual Basic, Delphi, or other tools. However, this article will focus on Visual Basic implementation which should be the easiest approach. Youll be able to adapt that to your programming language as well. How do I set up my project and write functions? There are only a few simple steps to set up your UFL project. The good news is that it is really simple to do and you do not have to include any interface definitions. In order to create a UFL, follow these steps: create a new ActiveX DLL project in Visual Basic add a function named HelloWorld to your class module or copy the following code: Public Function HelloWorld ( ) As String MsgBox Hello World HelloWorld = Success End Function under project, properties enter a meaningful name to the project, lets use CRUFLHW for now (more details on that later); make sure it starts with CRUFL, otherwise it wont work go to <File>, <Make CRUFLHW.DLL> and compile your project into an ActiveX DLL serving as an automation server for Crystal Reports

Deploying it to customers is actually very simple. Copy the file to the Windows or (better) the Crystal directory and register it with regsvr32. How do I use it in Crystal Reports? Lets try it out by opening Crystal Reports and adding the follow these steps to use the new UFL: create a new report based on a database of your choice (for example with an ODBC driver accessing the ISLAND database in the <Insert> menu, pick <Formula> to add a new method; the formula window should appear with the three panes in the middle pane, go to the last branch, expand it, and double-click on HelloWorld save this method as test and exit the window - Voila you just added an UFL to your report!

In order to use this method, you have to reference it at some point. Make sure that the small floating explorer window is visible and drag the test method you just created into the report header area. Now run the report. There should be two things happening: First of all, the MsgBox function we used before in our Visual Basic application displays the Hello World text message when the report is run. Executions stops until you press the OK button. Secondly, the Success text is printed out in the report header as the return value of this function.

How can I use it in my real-life projects? Well, now that we have it, what are we going to do with it? From my experience, there are four areas that enhance and optimize Crystal Reports by using User-Function Libraries. The small and tedious things are those in life, that we usually dislike the most. One of the first things that I added to my UFL was a StrAppend( String1, String2, Separator) function that would append String1 to String2 and add the separator if both strings are not empty. www.iceteagroup.com

No big deal, you might want to say, I can do that easily with Crystal Reports itself. But adding such functions to tens or hundreds of reports can be a hassle and cumbersome to maintain. It is better to extract often re-used functions into such function libraries. The second way to use UFLs is to speed up Crystal Reports. Speed up by adding functions? Yes, indeed! As you might know, Crystal Report depends always on one main query. If you want to add other queries, you have to use sub-reports. These can be slow and complex, requesting time to prepare, execute, and format the outcome. With your own function library, you could simply add a SqlImmediate( SELECT ) function to look up some data quickly and place the result in a text field. One example for that could be the company name or some other data to be shown in the report header. Another issue that has proved to save a lot of processing time is lookup functions. Imagine you have a report which requires an outer join to lookup some optional foreign key data. A catalog or lookup function could work similar to a combo box: all possible entries are retrieved only once from the database and another function returns the foreign keys text by looking up the foreign key value for each row. I have noticed tremendous speed improvements. Furthermore, I was able to do things that werent really possible before (multiple outer joins with SQLBase, for example). The third area of possible use is layout re-use and standardization. Since Crystal Reports 8 it is possible to have text fields display RTF or HTML text. Instead of showing the pure text, CR interprets the code and shows the formatted field instead. This is limited and doesnt work with pictures or other complicated elements, but it is enough to reuse a typical address formatting setting or some report header/footer that should be the same in all reports. The RTF string adds some formatting keywords to the actual data and the address appears in bold, or just the city underlined, etc. I have written a RTF processing function that takes a format index parameter that is evaluated with a SELECT CASE in the UFL. A separate document describes all possible settings with examples and allows staff and customers to adapt reports themselves reusing existing formatting schemes. The fourth enhancement covers functionality that is not available in Crystal Reports. For example, you could add functions to log report execution in a database. Other functionality might allow you to read INI file settings or even Registry values. You could do that to have users customize reports without editing the report files. Imagine you use address formatting with RTF as described above and store the standard format scheme as an INI file setting. Simply add a reference to your documentation and your users will be able to change your reports on the fly! Other enhancements could be sending an eMail, looking up the computer name, and so on. You can do anything. Depending on your project and your demands, you will probably find several small things that you would like to add or have simplified in your projects as well. Just go ahead! Things that do not work You can set up many parameters but only the return value of the function is passed back to Crystal Reports. The parameters can even be arrays they will be converted to Visual Basic arrays on the fly. However, each return value is limited to 254 characters. There are ways to work around this in case you really have to break that limit but it isnt really nice and easy to do that. Additionally, only simple variable types do work: Integer, Long, Single, and Double are converted to Crystals NumberVar, Currency, Date, Boolean, And String have their equivalent in CR as well. Objects or ranges cannot be passed to the COM Automation Server. Watch the naming of your project. It has to start with CRUFL so that Crystal is able to detect it as a function library. There used to be problems when the project name was more than eight characters long. I am not sure what it was but it took me quite some time to figure it out since the help file states that longer names are possible. However, something did not work so simply add three characters to the CRUFL prefix at the most. Function names must be unique. This said, they cannot have the same name as any one of Crystals internal functions, nor can they consist of any reserved keywords in VB. To differentiate native functions and enhanced features taken from a UFL, I started to add a prefix to my self-developed functions. This helps differentiating. Ideally, you can add the same characters as a prefix that you use to complement the UFL project name. But thats only a best practices recommendation.

www.iceteagroup.com

By default, Crystal adds the project name to functions in the function list pane. I did not like it and suppressed that by declaring UFPrefixFunctions as Boolean and setting that variable to FALSE during UFL initialization. How do I debug my project? There are several ways to debug projects. Unfortunately, none will really allow you to step through your code. However, two things do work: The MsgBox approach is neither nice nor really clean, but hey it notifies you in case of an error. Simply add a MsgBox call in your error handling routine that displays all variable contents and a hint of what is going wrong. You could also have a debug version of your CRUFL file with message boxes for internal testing, and a release version that suppresses them. The second approach is declaring a variable named UFErrorText. In case of an error in an UFL function, Crystal usually responds with memory full or a similarly awkward error message. If you assign a value to UFErrorText, the correct error text is displayed by Crystal Reports as a message box. So, whats next? In the next article I explain functions to connect to a database and provide you with catalog lookup functionality. Another article will cover RTF handling and additional features, like reading from an INI file. If you are interested in using UFLs, try them out. They are really simple to use when you watch out for a couple of basic rules. This article should get you started.

Based in Hannover (Germany), Thomas Althammer is a founding member of the Ice Tea Group, LLC. He is specialized in providing software for the health care industry as a developer and product manager. He is working with hospitals, social services, and health care associations. Contact him at thomas@iceteagroup.com.

www.iceteagroup.com

Anda mungkin juga menyukai