This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
This book is dedicated to the memory of my dear friends, Tom Piper and Ed Rauh. Tom, may you go barefoot through the eternities. Ed, even when you knew you were dying, you kept pressing on. May we learn from your example, and may we always remember you both. —Craig Berntson
v
Our Contract with You, The Reader In which we, the folks who make up Hentzenwerke Publishing, describe what you, the reader, can expect from this book and from us.
Hi there! I’ve been writing professionally (in other words, eventually getting a paycheck for my scribbles) since 1974, and writing about software development since 1992. As an author, I’ve worked with a half-dozen different publishers and corresponded with thousands of readers over the years. As a software developer and all-around geek, I’ve also acquired a library of more than 100 computer and software-related books. Thus, when I donned the publisher’s cap five years ago to produce the 1997 Developer’s Guide, I had some pretty good ideas of what I liked (and didn’t like) from publishers, what readers liked and didn’t like, and what I, as a reader, liked and didn’t like. Now, with our new titles for 2002, we’re entering our fifth season. (For those who are keeping track, the ’97 DevGuide was our first, albeit abbreviated, season, the batch of six “Essentials” for Visual FoxPro 6.0 in 1999 was our second, and, in keeping with the sports analogy, the books we published in 2000 and 2001 comprised our third and fourth.) John Wooden, the famed UCLA basketball coach, posited that teams aren’t consistent; they’re always getting better—or worse. We’d like to get better… One of my goals for this season is to build a closer relationship with you, the reader. In order for us to do this, you’ve got to know what you should expect from us. •
You have the right to expect that your order will be processed quickly and correctly, and that your book will be delivered to you in new condition.
•
You have the right to expect that the content of your book is technically accurate and up-to-date, that the explanations are clear, and that the layout is easy to read and follow without a lot of fluff or nonsense.
•
You have the right to expect access to source code, errata, FAQs, and other information that’s relevant to the book via our Web site.
•
You have the right to expect an electronic version of your printed book to be available via our Web site.
•
You have the right to expect that, if you report errors to us, your report will be responded to promptly, and that the appropriate notice will be included in the errata and/or FAQs for the book.
Naturally, there are some limits that we bump up against. There are humans involved, and they make mistakes. A book of 500 pages contains, on average, 150,000 words and several megabytes of source code. It’s not possible to edit and re-edit multiple times to catch every last
vi misspelling and typo, nor is it possible to test the source code on every permutation of development environment and operating system—and still price the book affordably. Once printed, bindings break, ink gets smeared, signatures get missed during binding. On the delivery side, Web sites go down, packages get lost in the mail. Nonetheless, we’ll make our best effort to correct these problems—once you let us know about them. In return, when you have a question or run into a problem, we ask that you first consult the errata and/or FAQs for your book on our Web site. If you don’t find the answer there, please e-mail us at [email protected] with as much information and detail as possible, including 1) the steps to reproduce the problem, 2) what happened, and 3) what you expected to happen, together with 4) any other relevant information. I’d like to stress that we need you to communicate questions and problems clearly. For example… •
“Your downloads don’t work” isn’t enough information for us to help you. “I get a 404 error when I click on the Download Source Code link on www.hentzenwerke.com/book/downloads.html” is something we can help you with.
•
“The code in Chapter 10 caused an error” again isn’t enough information. “I performed the following steps to run the source code program DisplayTest.PRG in Chapter 10, and I received an error that said ‘Variable m.liCounter not found’” is something we can help you with.
We’ll do our best to get back to you within a couple of days, either with an answer or at least an acknowledgment that we’ve received your inquiry and that we’re working on it. On behalf of the authors, technical editors, copy editors, layout artists, graphical artists, indexers, and all the other folks who have worked to put this book in your hands, I’d like to thank you for purchasing this book, and I hope that it will prove to be a valuable addition to your technical library. Please let us know what you think about this book—we’re looking forward to hearing from you. As Groucho Marx once observed, “Outside of a dog, a book is a man’s best friend. Inside of a dog, it’s too dark to read.” Whil Hentzen Hentzenwerke Publishing April 2003
vii
List of Chapters Chapter 1: Introducing Crystal Reports Chapter 2: Touring Crystal Reports Chapter 3: Creating Your First Report Chapter 4: Accessing Data Chapter 5: Intermediate Reporting Chapter 6: Advanced Reporting Chapter 7: Subreports Chapter 8: Using Formulas Chapter 9: The RDC: Introduction, Printing, and Databases Chapter 10: The RDC: Manipulating Data Chapter 11: The RDC: Formatting the Report Chapter 12: Previewing the Report at Runtime Chapter 13: The Report Designer Control Chapter 14: Exporting Reports Chapter 15: Integrating COM Components Chapter 16: Web Reporting Chapter 17: Crystal Reports .NET Chapter 18: Licensing and Distribution Chapter 19: Crystal Reports Tools
Table of Contents Our Contract with You, The Reader Acknowledgements About the Author How to Download the Files Chapter 1: Introducing Crystal Reports Crystal Reports versions Installing Crystal Reports What’s changed in version 9 What’s missing What’s new Upcoming chapters Summary
Chapter 2: Touring Crystal Reports Report Experts Data page Links page Fields page Grouping page Summaries page Group Sorting page Chart page Record Selection page Template page Blank Reports The Crystal Reports desktop Menus Toolbars Status bar Design page Preview page Report Sections Section Expert Formatting report objects Common page Border page Font page Paragraph page Hyperlink page Resizing and moving objects
x Using the mouse Using the keyboard The Object Size and Position window Guidelines Setting options Application options Report options The report-processing model Pre-pass 1 Pass 1 Pre-pass 2 Pass 2 Pass 3 Summary
Chapter 3: Creating Your First Report Designing the report Sketching the report The report data Your first report, step-by-step Selecting the data source Adding data fields to the report Adding a calculated field Grouping and group totals Formatting the report Adding the page header Charting made easy Summary
Chapter 4: Accessing Data Using the Database Expert Creating a new connection Selecting database objects Linking tables Field definitions files Creating a field definition file Using a field definition file Working with images Images in the database Adding a watermark Limiting records selected The Select Expert Miscellaneous data functions Set Database Location LogOn or Off Server Show SQL Query
xi Perform Grouping on Server Report Bursting Indexes Summary
Chapter 5: Intermediate Reporting Understanding the Crystal Repository Adding objects to the repository Using repository objects in a report Updating objects in the repository Sorting Groups Drill-down Hierarchical groups Summaries Subtotals and grand totals Running totals Cross-tabs Charts Basic charting Advanced charting Maps The Data tab The Type tab The Text tab Summary
Chapter 8: Using Formulas The Formula Editor The General toolbar The Workshop toolbar The Custom Function toolbar The Workshop Tree The Editor toolbar Understanding formulas Comments Data types Variables Fields Operators Functions Custom functions The Formula Extractor The Formula Expert Summary
Chapter 9: The RDC: Introduction, Printing, and Databases Understanding the Report Design Component Getting started with RDC programming Registering the runtime component Working with collections The Application object The Report object The Database object Working with tables Passing stored procedure parameters The DatabaseTable object The ConnectionProperties object Working with the ConnectionProperties object Getting connection property information Working with fields Linking tables Connecting to data—some examples Logging on and off a server database Connecting to ADO Connecting through an ODBC connection Connecting to XML Connecting to file-based data You connected to your data, now what? Summary
Chapter 10: The RDC: Manipulating Data Sorting Working with Groups Summary Fields Running Totals SQL Expressions Formula Fields Parameter Fields Report Alerts Summary
225 225 226 228 231 234 236 237 241 243
Chapter 11: The RDC: Formatting the Report
245
Working with Areas Condition Formulas Working with Sections The ReportObject object TextObject object Field elements LineObject object BoxObject object FieldObject object Picture fields Special variable fields Summary fields BlobFieldObject object Crosstabs GraphObject object The FieldDefinitions collection MapObject object OLEObject OLAPGridObject object The ObjectSummaryFieldDefinitions collection Unbound fields Subreports Summary
Chapter 12: Previewing the Report at Runtime Registering the control Creating a preview form Methods of the Viewer Control Showing the report Retrieving information
Chapter 13: The Report Designer Control Registering the Control Creating a design form Working with the designer Providing Help Using the Designer Control Summary
294 295 297 297 299 301
303 303 304 310 311 312 312
Chapter 14: Exporting Reports
313
Programmatic exports Exporting to files Adobe Acrobat (PDF) Microsoft Word Microsoft Excel Rich Text Format (RTF) HTML XML Comma Separated Values (CSV) Tab-Separated Text Text Report Definition Exporting to an application Exporting to MAPI Exporting to ODBC Summary
Chapter 15: Integrating COM Components Formulas revisited Events Report events Section events Separate image files Report variables Summary
343 343 344 344 352 354 355 356
xv
Chapter 16: Web Reporting
357
Report design revisited Embedded hyperlinks Cascading style sheets Navigation Report Parts Working with ASP Page rendering objects Customizing the Viewer The Report Application Server Customizing the RAS The RAS SDK Summary
357 357 359 360 362 364 366 371 372 379 382 384
Chapter 17: Crystal Reports .NET
385
Windows-based applications Web-based applications The Crystal Reports .NET designer Connecting to ADO .NET XML web services Publishing a web service Consuming a web service The CrystalDecisions namespaces Summary
385 388 392 394 396 396 397 398 399
Chapter 18: Licensing and Distribution Distribution RDC distribution Web reporting .NET distribution Licensing The License Manager Summary
Chapter 19: Crystal Reports Tools Documentation files The Crystal Decisions web site Hot fixes and service packs Utilities Support forums Summary
401 401 401 414 414 414 415 416
417 417 418 419 420 421 421
xvi
xvii
Acknowledgements I remember sitting down at dinner at the hotel restaurant the night before the Great Lakes Great Database Workshop in 2000. Whil Hentzen, sitting next to me, leaned over and said “So, about this book you’re writing.” We had discussed the possibility in passing a few times before that, but nothing concrete. That was when I started thinking I just might be able to do it. But, it still took a year before I started work on the project. Thanks, Whil, for all your efforts, and for publishing the best collection of development books available. Putting this book together has not been easy. I want to thank my coworkers at 3M HIS, Tony Curtis, Cole Gleave, and Erie Walker. Thanks to the people from the Visual FoxPro community that helped in many ways, Cathi Gero, George Tasker, Cathy Pountney, Ted Roche, Doug Dodge, Nancy Folsom, Ken Cluff, Evan Delay, Rick Schummer, and Cindy Winegarden. I’m sure I left out someone, but that doesn’t mean your help wasn’t appreciated. I also need to thank Jaylene Crick and the many support people I worked with at Crystal Decisions. I must not forget the entire Visual FoxPro team at Microsoft. Especially Brad Peterson, Calvin Hsia, Ken Levy, and my good friend John Koziol. These guys have flat out produced the best development tool you can find. I have to thank my Tech Editor, Dan Jurden and my copy editor, Nicole McNeish. I can’t forget Mom and Dad. Finally, I need to thank my boys, Johnathan and Jason. There were many hours and days that I wasn’t there because of this book. Thank you for your understanding.
xviii
xix
About the Authors Craig Berntson Craig has been developing custom and commercial applications for business and government for 20 years. He has developed applications for small business as well as large enterprises. He uses Visual FoxPro, C++, and Crystal Reports as his main development tools. He has written several articles for FoxTalk, some of which are available on the MSDN web site. He has also spoken at many software developer conferences, seminars, and user groups, including Advisor Visual FoxPro DevCon, the Great Lakes Great Database Conference, Essential Fox, and MSDN events. Craig is a Microsoft Certified Solution Developer and has been named a Microsoft Most Valuable Professional every year since 1997 for his support of the Visual FoxPro community. You can often find him online at the Universal Thread (www.universalthread.com). Craig is the President of the Salt Lake City FoxPro User Group where he frequently gives presentations on using Visual FoxPro and other current and emerging technologies. He is currently a Senior Software Engineer at 3M Health Information Systems in Salt Lake City. e-mail: [email protected], Web: www.craigberntson.com
Dan Jurden Dan Jurden is a Senior Application Developer for EPS-Software Corp. located in Houston, Texas. He is a Microsoft Certified Professional. He co-authored the book Creating Visual FoxPro Applications using Visual FoxExpress with BOb Archer, published by Hentzenwerke Publishing. He has also authored articles published in CoDe Magazine and Universal Thread Magazine dealing with SQL Server and other topics. Dan has presented topics at the German DevCon, Essential Fox, SQL Server Live!, and GLGDW conferences. He has been developing Client-Server applications using SQL Server and Crystal Reports for over 6 years. Dan can be reached via email at [email protected].
xx
xxi
How to Download the Files Hentzenwerke Publishing generally provides two sets of files to accompany its books. The first is the source code referenced throughout the text. Note that some books do not have source code; in those cases, a placeholder file is provided in lieu of the source code in order to alert you of the fact. The second is the e-book version (or versions) of the book. Depending on the book, we provide e-books in either the compiled HTML Help (.CHM) format, Adobe Acrobat (.PDF) format, or both. Here’s how to get them.
Both the source code and e-book file(s) are available for download from the Hentzenwerke Web site. In order to obtain them, follow these instructions: 1.
Point your Web browser to www.hentzenwerke.com.
2.
Look for the link that says “Download”
3.
A page describing the download process will appear. This page has two sections:
•
Section 1: If you were issued a username/password directly from Hentzenwerke Publishing, you can enter them into this page.
•
Section 2: If you did not receive a username/password from Hentzenwerke Publishing, don’t worry! Just enter your e-mail alias and look for the question about your book. Note that you’ll need your physical book when you answer the question.
4.
A page that lists the hyperlinks for the appropriate downloads will appear.
Note that the e-book file(s) are covered by the same copyright laws as the printed book. Reproduction and/or distribution of these files is against the law. If you have questions or problems, the fastest way to get a response is to e-mail us at [email protected].
Chapter 1: Introducing Crystal Reports
1
Chapter 1 Introducing Crystal Reports What is Crystal Reports? Who should use it? Why should you use it? When should Crystal Reports be used? How do you use it? These are some of the questions that will be answered in this book.
You have probably heard of Crystal Reports. In fact, you probably use it. Why else would you buy this book? I assume you are also a software developer looking for more information on how to use Crystal Reports in your application. After all, the word “develop” is in the title of this book. You’re about to learn that Crystal Reports is a very powerful and flexible reporting tool. However, before digging into the nitty gritty, I will address a few basic questions in case you are new to Crystal Reports or are investigating it for use in your application. Many years ago, I took a high school journalism class. I don’t remember much from the class, but I do remember one important thing: all good stories answer six questions; who, what, when, where, why, and how. Even though I’m not a journalist today, I think these questions are important to address. I will start with the what. What is Crystal Reports? Simply put, it is a reporting application that creates sophisticated reports from a company called Crystal Decisions. It can pull data from many different data sources and be used stand-alone or embedded in an application. Who should use Crystal Reports? That’s pretty easy. I use Crystal Reports for all my reporting and I think you should too. End users can also use Crystal Reports to pull data from your application, databases, operating system logs, and many other data sources. So, Crystal Reports is for both the developer and end user. Why should you use Crystal Reports? Again, a question with an easy answer. I’m not the type of author who learns a product, writes a book about it, and then moves on to the next product. In fact, my development tool, Visual FoxPro, includes a good built-in reporting tool, but I use Crystal Reports because it gives the user a lot of power in their reporting needs. You will soon see how easy it is to add grouping, graphs, and drill down to reports. When should you use Crystal Reports? As I said earlier, I use Crystal Reports exclusively for reports in applications I develop. I could use the Visual FoxPro report designer for simple reports and Crystal Reports for more sophisticated needs, but by using only one reporting tool, my users have a consistent look and feel across all reports. Where should you use Crystal Reports? Again, in every application you develop. Finally, how do you use Crystal Reports? Well, that’s the purpose of this book. You will see how to seamlessly embed Crystal Reports into your applications.
2
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Crystal Reports versions As I was writing this book, Crystal Reports 9 was released. Some chapters were updated to include new material; others were checked to make sure they were still correct for this release. You should be aware that four editions are available: •
Standard—provides basic reporting capabilities for accessing the most common databases.
•
Professional—adds additional database support such as OLAP and XML plus additional report design features like custom templates, repository, and more.
•
Developer—the base developers version. Gives you report design and runtime distribution capabilities. You also get a license for up to five concurrent users for runtimes and development testing.
•
Advanced—adds advanced development and deployment capabilities. Report queuing and caching as well as report creation and modification SDKs.
If you are developing applications, you should be using either the Developer or the Advanced edition, because they are the only ones that give you both the distributable controls and a license to ship them with your application. If you purchase one of the other versions, an upgrade is available from your reseller or directly from Crystal Decisions.
Installing Crystal Reports Installing Crystal Reports is a simple process. The following steps walk you through the installation: 1.
Insert the Crystal Reports CD into your CR ROM drive. If you have enabled Autostart, the startup window (see Figure 1) displays.
Chapter 1: Introducing Crystal Reports
Figure 1. The startup window displays when you insert the Crystal Reports CD. There are several options available on the left side of the startup screen: •
Release Notes—displays information on installation and system requirements.
•
Technical Resources—launches your web browser and navigates to a Crystal Decisions web site where you can get more information about technical resources such as training, technical support, white papers, etc.
•
Services—navigates to a site that provides an overview of training, consulting, and
certification resources available from Crystal Decisions. •
Web Reporting—displays a web site that discusses Crystal Enterprise, a tool for
enterprise reporting needs. •
Crystal Decisions Products—provides an overview of other products from Crystal Decisions, such as Crystal Enterprise, Crystal Analysis, and several analytical applications.
2.
In the lower right corner of the start up window is the install button. Click Install Crystal Reports 9 to launch the installation wizard. The Welcome to the Installation Wizard (see Figure 2) displays.
3
4
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 2. The welcome page of the Installation Wizard starts you on your way to installing Crystal Reports. 3.
Click Next. The license agreement displays (see Figure 3).
Chapter 1: Introducing Crystal Reports
Figure 3. You must accept the License Agreement to proceed with installation. 4.
If you do not agree with the license agreement, just click Next and the Installation Wizard will abort. If you agree with the license, select I accept the License Agreement, and then click Next to display the User Information page (see Figure 4).
5
6
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 4. Enter your personal information in the User Information page. 5.
Enter your name, organization (if you have one), and your CD Key Code from the back of your CD sleeve. Click Next to display the Installation Type page (see Figure 5.)
Chapter 1: Introducing Crystal Reports
7
Figure 5. The Select Installation Type page allows you to select a Typical, Complete, or Custom installation and choose where you want to install Crystal Reports. 6.
I recommend you choose the Custom installation. This allows you to choose which parts of Crystal Reports you want to install such as maps and database drivers. You should also enter the installation path if you don’t want to use the default. Once you do this, click Next to display the Select Features dialog box (see Figure 6).
8
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 6. The Select Features page allows you customize the components and features you want to install. 7.
I made some changes to my installation. For example, I made changes to the Data Access option, selecting only the data sources I’m interested in using. I also selected all options under Export Support and Geographic Mapping. Once you customize your installation, click Next. The Start Installation page displays (see Figure 7).
Chapter 1: Introducing Crystal Reports
Figure 7. The Start Installation dialog box gives you one last chance to confirm your choices before actually starting the installation. 8.
Click Next to begin the installation. The installation progress page displays (see Figure 8).
9
10
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 8. The installation progress displays once you actually begin the installation. 9.
Once the installation is complete, the Registration Wizard launches. (see Figure 9). Click Next to begin the registration process.
Chapter 1: Introducing Crystal Reports
11
Figure 9. The Registration Wizard walks you through the Crystal Reports registration process. 10. If you have a registration number, enter it in the Registration Options dialog box (see Figure 10). If you don’t have one, you can register your copy of Crystal Reports and obtain a number. I wrote the registration number on my Crystal Reports CD sleeve. That way I have it if I need to reinstall the application. If you don’t want to register Crystal Reports at this time, click Register Later.
12
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 10. You will be asked to register your copy of Crystal Reports as part of the installation process. 11. If you register Crystal Reports or enter the registration number, press Finish to complete the installation process. If you register Crystal Reports, you get a confirmation showing the registration was successful (see Figure 11).
Figure 11. The registration confirmation displays when you successfully register your copy of Crystal Reports.
Chapter 1: Introducing Crystal Reports
13
12. Your installation is now complete (see Figure 12). Click Finish to close the Installation Wizard.
Figure 12. The setup dialog displays when you complete the installation.
What’s changed in version 9? Crystal Reports 9 includes some exciting new features for developers. You will also discover some features found in previous versions are now missing.
What’s missing? Crystal Decisions removed several developer features in this new release, but don’t worry too much about missing functionality. Many of the same functions are implemented in a different way. Some of the removed capabilities include: •
Compiled reports
•
Crystal Dictionary and Crystal SQL Designer
•
Export to Data Interchange Format (DIF), Lotus 123, and Multi-Byte Character Sets (MBCS)
14
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Developer APIs Cpeaut32.DLL and Crystl32.OCX
•
Database drivers for bound database, Centura SQLBase (Gupta), Essbase, and native Microsoft SQL Server
What’s new? Crystal Reports 9 has many exciting new features for developers, including: •
Enhanced designer. I found report creation to be much easier with Crystal Reports 9.
•
SQL commands. These replace and enhance Crystal SQL Designer.
•
Unicode support.
•
Crystal repository. Makes it easy to reuse report objects. This is a replacement for the Crystal Dictionary.
•
Custom templates. It’s now easy to create and reuse templates, thus giving a common look to all your reports.
•
Report parts. Makes is easy to deploy reports to hand-held devices
•
Custom functions. You can now use the Crystal Reports formula languages to create your own functions.
•
Formula Workshop. An enhancement of the old Formula Expert
•
Side-by-side installation. Different versions of Crystal Reports can now coexist on the came computer.
•
Improved database support.
•
In-place chart editing. You no longer need to launch the Chart Analyzer to customize a chart.
•
Improved Report Design Control (RDC) for application integration.
•
Report Application Server (RAS) for web reporting and distribution.
•
Enhanced formulas, experts, cross tabs, and wizards.
Upcoming chapters As this book is about using Crystal Reports in application development, the rest of the book is devoted to helping you understand how to use Crystal Reports and embed it in your applications. In Part 1, you learn how to design a report. In Chapter 2, “Touring Crystal Reports,” I discuss the Crystal Reports designer and how to set various options to maximize your productivity. Chapter 3, “Creating Your First Report, Step-by-Step,” walks you through creating a report with drill-down and graphing. Chapter 4, “Accessing Data,” presents a
Chapter 1: Introducing Crystal Reports
15
discussion on accessing the most common types of data. In Chapter 5, “Intermediate Reporting,” I show how to sort and group and add graphs, maps, and cross tabs to a report. Chapter 6, “Advanced Reporting” discusses report parameters, alerts, and embedded OLE objects. Chapter 7, “Subreports,” covers using subreports. Crystal Reports also has its own programming language. Chapter 8, “Using Formulas,” discusses this topic in detail. Part 2, moves into programming reports and shows you how to embed Crystal Reports in your application. Programmatically controlling Crystal Reports begins in Chapter 9, “The RDC: Introduction, Printing, and Databases,” where I first present the Report Design Control. The RDC is a big topic and continues in Chapter 10, “The RDC: Manipulating Data”; Chapter 11, “The RDC: Formatting the Report”; Chapter 12, “Previewing the Report at Runtime”; and Chapter 13, “The Runtime Design Component.” Chapter 14, “Exporting Reports,” explains the different export options and some “gotchas” to watch out for. Chapter 15, “Integrating COM Components with Crystal Reports,” shows you how you to call COM components from inside your application. It also discusses hooking into Crystal Reports events. Chapter 16, “Crystal Reports .NET,” discusses Microsoft’s Visual Studio .NET, which ships with a special version of Crystal Reports. Chapter 17, “Web Reporting,” moves on to Internet concepts and how to put your report on the web. Chapter 18, “Distribution and Licensing,” discusses the issues of shipping your reporting solution and additional licensing requirements you may face. Finally, Chapter 19, “Crystal Reports Tools,” discusses tools that help you with report design and application development.
Summary This chapter showed you how to install Crystal Reports and gave an overview of the rest of the book. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click on “Catalog” and navigate to the page for this book.
16
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 2: Touring Crystal Reports
17
Chapter 2 Touring Crystal Reports Crystal Reports has many features to help you easily create powerful and full-featured reports. This chapter takes you on a tour of the Crystal Reports design environment.
Users have come to expect software to make things easier for them. Toolbars, wizards, menus, and other application tools help you with using the application. Crystal Reports is no different. When you first launch Crystal Reports or create a new report by selecting File | New from the menu or clicking the New button on the standard toolbar, the Crystal Report Gallery dialog box displays. Using the Crystal Report Gallery, you can open an existing report, create a new report using one of the report wizards, called Experts, or create a blank report.
Report Experts The Crystal Report Gallery shows four different report Experts: •
Standard
•
Cross-Tab
•
Mail Label
•
OLAP
These Experts walk you through a series of steps to select the data and format the report. The exact steps depend on the type of report you select. Most of the reports you create using the Report Expert will be standard reports. The Standard Expert is the one I have chosen to discuss here. Once you choose an Expert, click OK.
Data page The Data page is where you select the tables to include in the report. You can select an existing data connection, select items from the Repository, or create a new connection. The Repository is discussed in Chapter 5, “Intermediate Reporting.” Click Database, to display the Data Explorer. You will briefly see the data page in Chapter 3, “Creating Your First Report” and it is discussed more thoroughly in Chapter 4, “Accessing Data.” Once you select the data tables, click Close.
Links page If you choose multiple tables, Crystal Reports prompts you to link the tables using keys. Crystal Reports initially joins the tables of the first fields that exist in both tables. To change the link, click the link line and delete it, then drag the key field from the parent table and put it on the matching field in the child table. See chapter 4, “Accessing Data,” for more about Linking.
18
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Fields page Once you link the tables, use the Fields page to select the fields to appear in the Detail section on the report. You can use drag-and-drop to move a field from one list to the other or select the field and click Add, Add All, Remove, or Remove All. There are several options on this page. The Browse Data option displays the data for the selected field. Find locates a specific field in the Available Fields list. This is useful when you have many fields available.
Grouping page The Grouping page is where you add any grouping to the report. Use Groups to organize data in a logical way and provide totals for the group. You do not have to group fields selected on the Fields page. You can order each field you select for grouping in ascending or descending order. Groups are discussed in detail in Chapter 5, “Intermediate Reporting.”
Summaries page Groups are commonly used to generate a subtotal. That is the purpose of the Summary page. For each field you select for a group, the Total page allows you to select the field to subtotal and the type of calculation. For example, in a numeric field you can generate a sum, average, minimum, maximum, and several other summaries. You can also create a percentage of the grand total and optionally add grand totals to the report. More about Summaries can be found in Chapter 5, “Intermediate Reporting.”
Group Sorting page When you select a Top or Bottom N, the groups matching your criteria are sorted at the beginning of the report. One example of this powerful feature is being able to see the top salespeople or territories or the top selling brands or products.
Chart page Use the Chart page to add a chart to the report. I discuss charts in more detail in Chapter 5, “Intermediate Reporting.”
Record Selection page You can select a subset of the data by using the Select page. This page equates to the Where clause of a SQL Select statement. You may only want to see data for a particular state or date range. This page is where you can set up this option.
Template page Finally, Use the Template page to assign a preset design template to a report. When you select one of the templates, formatting is applied to the report objects. Crystal Reports 9 allows you to add your own custom templates. Chapter 5, “Intermediate Reporting,” discusses this further.
Chapter 2: Touring Crystal Reports
19
Blank reports The Crystal Report Gallery also has an option to create a blank report. When you select this option, you have to create the report from scratch and do all of the formatting yourself. Selecting As a blank report causes the Database Expert to display.
The Crystal Reports desktop When you launch Crystal Reports, you see the application divided into different areas: menus, toolbars, Field Explorer, Repository Explorer, Report Explorer, design surface, and status bar. The design surface further divides into the Design and Preview areas.
Menus The Crystal Reports menus make available most of the functionality of the product. Some features are only available from a context menu or from a dialog box. The menu options are: File •
New… — Creates a new report.
•
Open… — Displays a File Open window to open an existing report.
•
Close — Closes the current report.
•
Save — Saves the current report.
•
Save As… — Saves the current report using a different file name.
•
Save Data with Report — If selected, the data used for a report is saved in the .rpt file. I recommend you turn this option off.
•
Save Subreport As… — Saves the current subreport as a different file.
•
Print Preview — Previews the current report.
•
Print (Preview Sample, Printer) — Prints or exports the current report.
•
Printer Setup… — Displays a Printer Setup window.
•
Page Setup… — Displays a Page Setup window used to change the page margins.
•
Export… — Displays the Export window.
•
Send To (Mail Recipient, Exchange Folder) — Allows you to send a report via email.
•
Options… — Displays the Crystal Reports Options window (see “Setting options”
later in this chapter). •
Report Options… — Sets options for the current report (see “Setting options” later in
this chapter).
20
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Summary Info… — Displays the Document Properties window to enter the author name, a report description, and other information.
•
MRU — The Most Recently Used list of reports.
•
Exit — Exits Crystal Reports.
Edit •
Undo — Undoes the latest changes.
•
Redo — Reapplies the latest undo.
•
Cut — Cuts the selected object and places it on the clipboard.
•
Copy — Copies the selected object and places it on the clipboard.
•
Paste — Pastes the object on the clipboard into a report.
•
Paste Special — Pastes an OLE object on the clipboard into the report and creates a
link back to the owning application. •
Delete — Deletes the currently selected object.
•
Select All — Selects all the objects in a report.
•
Find… — Displays the Find window to locate a particular item in a report.
•
Go To Page — Displays the Go To Page dialog box. You can go to a specified page
or the first or last page in the preview. • •
Edit Report Object… — Displays a window for editing selected report object. Subreport Links… — Displays the Subreport Links window to link the parent report
to the subreport. •
Browse Field Data… — Displays a window showing data from a selected field.
•
Object — This menu item changes to match the selected object. Choose it to edit the
current object. •
Links… — Use to make changes to OLE links.
View •
Design — Sets the current view to the designer.
•
Preview — Sets Preview as the current view. This option is only available when the
preview is selected. •
Other Views — Lists any other views or drill-downs you have displayed. This option is only available when the view exists.
Chapter 2: Touring Crystal Reports •
21
Close Current View — Closes the current active view. You cannot close the Design
view. •
Field Explorer — Toggles the display of the Field Explorer.
•
Report Explorer — Toggles the display of the Report Explorer.
•
Repository Explorer — Toggles the display of the Repository Explorer.
•
Toolbars — Displays the Toolbars window for selecting the toolbars to display and
setting options for them. •
Status Bar — If selected, the status bar displays.
•
Group Tree — When selected, the group tree displays when in preview mode.
•
Zoom… — Displays the Magnification Factor window to increase or decrease the
view of the report. •
Rulers (Design, Preview) — Toggles the display of rulers in Design and Preview
views. •
Guidelines (Design, Preview) — Toggles display of guidelines in Design and Preview
views. •
Grid (Design, Preview) — Toggles display of the grid in Design and Preview views.
•
Tooltips (Design, Preview) — Toggles display of tooltips in Design and Preview
views. Insert •
Text Object — Inserts a text object into a report.
•
Summary… — Inserts a summary object into a report.
•
Field Heading — Inserts a new field heading for the selected field in the Designer.
This option is only available for fields that do not currently have a heading. •
Group… — Inserts a new group into a report.
•
OLAP Grid… — Inserts an OLAP cube into a report.
•
Cross-Tab… — Inserts a cross-tab into a report.
•
Subreport… — Inserts a subreport into a report.
•
Line — Inserts a line object into a report.
•
Box — Inserts a box into a report.
•
Picture… — Inserts a picture into a report.
•
Chart… — Displays the Chart Expert to insert a chart into a report.
22
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Map… — Display the Map Expert to insert a map into a report.
•
OLE Object… — Inserts an OLE object into a report.
•
Template Field Object — Inserts a template field into a report. Template fields are
useful for creating generic reports because they do not bind to any table or field. Chapter 6, “Advanced Reporting,” covers more about Template fields. Format •
Format Field – Displays the Format Editor window for the currently selected report
object. •
Hyperlink – Displays the Hyperlink page of the Format Editor window for the currently selected report object.
•
Use Expert – This option changes based on the object you have selected. If an Expert
is available for the object, this option will launch it. •
Highlighting Expert – Displays the Highlighting Expert window. The Highlighting Expert is discussed in Chapter 5, “Intermediate Reporting.”
•
Line Height… -- Allows you to set the measurements for how text is placed between
two lines on a report. This option is only available when you are not using free-form placement. •
Text Formatting… -- Displays the Text Format dialog box to format selected text.
•
Report Style Expert – Displays the Report Style Expert to format a report according to
a predefined style. •
Move (Backward, To Back, Forward, To Front) – Changes the location of a selected
item along the z-axis. •
Align (Tops, Middles, Bottoms, Baseline, Lefts, Centers, Rights, To Grid) – Aligns the
selected objects with the last item selected. •
Size (Same Height, Same Width, Same Size) – Sets the height and/or width of
selected objects to that of the object you selected last. •
Size and Position – Displays the Object Size and Position window to set the size and
location of a selected object. •
Pivot OLAP Grid – Rotates an OLAP grid.
•
Pivot Cross-Tab – Rotates a cross-tab.
Chapter 2: Touring Crystal Reports
23
Database •
Database Expert… -- Displays the Database Expert.
•
Set Datasource Location — Sets the location of a table.
•
Log On or Off Server — Use to log on or off the database or server.
•
Browse Data — Displays a browse window containing data for a selected field.
•
Set OLAP Cube Location — Sets the location of an OLAP cube.
•
Verify Database — Checks that the database is in the specified location and its structure has not changed.
•
Show SQL Query — Displays the SQL SELECT statement used to gather the data.
•
Perform Grouping on Server — Instructs Crystal Reports to do a GROUP BY on the
server instead of locally. •
Select Distinct Records — Adds a DISCTINCT clause to the SQL SELECT
command. Report • Select Expert — Displays the Select Expert to modify the SQL SELECT statement. •
Selection Formulas (Record, Group) — Displays the Formula Workshop to enter selection criteria formulas. See Chapter 8, “Using Formulas”.
•
Formula Workshop — Displays the Formula Workshop.
•
Alerts (Create or Modify Alerts, Triggered Alerts) — Creates or modifies an existing
alert or displays any triggered alerts. Alerts are discussed in Chapter 6, “Advanced Reporting.” •
Report Bursting Indexes — Displays the Saved Data Indexes window. These are indexes used with saved data to increase the reporting speed.
•
Section Expert — Displays the Section Expert.
•
Group Expert — Displays the Group Expert.
•
Group Sort Expert — Displays the Group Sort Expert.
•
Record Sort Expert — Displays the Record Sort Expert.
•
XML Expert — Displays the XML Expert.
•
Template Expert — Displays the Template Expert.
•
OLAP Report Settings — Displays the OLAP Report settings window. This option is
only available when you are using an OLAP cube.
24
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Hierarchical Grouping Options — Displays the Hierarchical Options window.
•
Refresh Report Data — Reloads the report data.
•
Set Print Date/Time — Allows you to specify the print date and time.
•
Performance Information — Displays the Performance Information window.
Window •
Tile Vertically — Vertically tiles all open reports.
•
Tile Horizontally — Horizontally tiles all open reports.
•
Cascade — Cascades all open reports.
•
Arrange Icons — Arranges all minimized report windows at the bottom of the Crystal
Reports window. •
Close All — Closes all open reports.
•
Open Windows List —Lists each open report window.
Help •
Crystal Reports Help — Opens the main Crystal Reports Help file.
•
Context Help — Activates What’s This? Help.
•
Welcome Dialog — Displays the Welcome to Crystal Reports window.
•
Additional Help Files — Lists additional Help files available on the Crystal
Reports CD. •
Crystal Decisions On the Web — Provides several links to different Crystal Decisions
web sites. •
Web Report Samples — Lists web report sample files.
•
Register / Change Address — Displays the Software Registration Wizard.
•
About Crystal Reports — Displays the About window.
Chapter 2: Touring Crystal Reports
25
Toolbars Crystal Reports has four toolbars: Standard, Formatting, Insert Tools, and Expert Tools. You can float each toolbar or dock to the top, left, bottom, or right edges of the screen. In addition, select View | Toolbars from the menu to display the Toolbars dialog box. This is where you show or hide each toolbar and select using large buttons and tooltips. The Standard toolbar The Standard toolbar (see Figure 1) contains most of the functionality you will use when designing reports. The controls on this toolbar, from left to right, are:
Figure 1. The Standard Toolbar contains most of the functions you need. •
New — Creates a new report.
•
Open — Displays a file open dialog to open an existing report.
•
Save — Saves the current report.
•
Print — Prints the current report.
•
Print Preview — Previews the current report.
•
Export — Exports the current report.
•
Refresh — Reloads the report data.
•
Cut — Cuts the selected object and places it on the clipboard.
•
Copy — Copies the selected object and places it on the clipboard.
•
Paste — Pastes the object on the clipboard into the report.
•
Undo — Undoes the latest changes.
•
Redo — Reapplies the latest undo.
•
Toggle Group Tree — Toggles the display of the Group Tree when previewing.
•
Field Explorer — Toggles the display of the Field Explorer.
•
Report Explorer — Toggles the display of the Report Explorer.
•
Repository Explorer — Toggles the display of the Repository Explorer.
•
Find — Finds the specified report object or data item in preview.
•
Zoom Control — Specifies the zoom percentage.
•
Help — Toggles What’s This? Help.
26
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The Formatting toolbar The Formatting toolbar (see Figure 2) is used to set formatting for a selected object. The controls on this toolbar, from left to right, are:
Figure 2. Use the Formatting toolbar to apply formatting to various report objects. •
Font Face — Changes the font for the selected object.
•
Font Size — Changes the font size of the selected object.
•
Increase Font Size — Increases the font size of the selected object.
•
Decrease Font Size — Decreases the font size of the selected object.
•
Bold — Toggles bold font for the selected object.
•
Italics — Toggles italic font for the selected object.
•
Underline — Toggles underline for the selected object.
•
Align Left — Aligns the text of the object with the left-hand border of the object.
•
Align Center — Aligns the text of the object in the horizontal center of the object.
•
Align Right — Aligns the text of the object with the right-hand border of the object.
•
Justify — Justifies the text of the selected object.
•
Font Color — Displays a color picker to change the text color of the selected object.
•
Outside Borders — Allows you to set any borders you want on the selected object.
•
Suppress — Suppresses the selected object.
•
Lock Format — Toggles the format lock for the current object. When the lock is
active, you cannot change the formatting of the object. •
Lock Size/Position — Toggles the size and position lock for the current object. When
the lock is active, you cannot change the size or position of the object. •
Currency — Toggles printing of the currency symbol for the selected object.
•
Thousands — Toggles printing of the thousands separator for the selected object.
•
Percent — Toggles printing the percent sign for the selected object.
•
Increase Decimals — Increases the number decimal positions for the selected object.
•
Decrease Decimals — Decreases the number of decimal positions for the
selected object.
Chapter 2: Touring Crystal Reports
27
The Insert Tools toolbar The Insert Tools toolbar (see Figure 3) contains functionality that lets you quickly insert a new object into the report. The buttons on the toolbar, from left to right, are:
Figure 3. Use the Insert Tools toolbar to insert new objects. •
Insert Text Object — Adds a new text object to the report.
•
Insert Group — Adds a new group to the report.
•
Insert Summary — Adds a new summary to the report.
•
Insert Cross-tab — Inserts a new cross-tab object.
•
Insert OLAP Grid — Adds an OLAP grid to the report.
•
Insert Subreport — Inserts a subreport.
•
Insert Line — Inserts a line.
•
Insert Box — Adds a box to the report.
•
Insert Picture — Adds a new picture.
•
Insert Chart — Adds a chart to the current report.
•
Insert Map — Inserts a map.
The Expert Tools toolbar The Expert Tools toolbar (see Figure 4) allows you to quickly display a specific Expert. The buttons on this toolbar, from left to right, are:
Figure 4. The Expert Tools toolbar. •
Database Expert — Displays the Database Expert.
•
Group Expert — Displays the Group Expert.
•
Group Sort Expert — Displays the Group Sort Expert.
•
Record Sort Expert — Displays the Record Sort Expert.
28
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Select Expert — Displays the Select Expert.
•
Section Expert — Displays the Section Expert.
•
Formula Workshop — Displays the Formula Workshop.
•
OLAP Report Settings — Displays the OLAP grid settings dialog.
•
Template Expert — Displays the Template Expert.
•
Format — Displays the Format dialog for the currently selected object.
•
Insert Hyperlink — Displays the Hyperlink page of the Format dialog for the currently
selected object. •
Highlighting — Displays the Highlighting Expert for the currently selected report
object.
Status bar The status bar displays (see Figure 5) at the bottom of the Crystal Reports window. You toggle the display of the status bar by selecting View | Status Bar from the menu. The status bar provides useful information. At the left is detailed information about the selected object or the highlighted menu item. Figure 5. The Status bar provides information about the currently selected object. Next it displays the location and size of the selected item. For example, you may see something like 0.2, 0.9 : 3.3 x 0.2. This tells you the current object is at 0.2 inches on the xaxis and 0.9 inches on the y-axis in the current section. The next set of numbers tells you how big the object is, 3.3 inches horizontally by 0.2 inches vertically. The last two pieces of information only show up when previewing the report. First is the number of records processed and finally the percent of record processing that is complete. If you have a large data set to report or if the SELECT statement takes a long time to complete, you will see these numbers change as the data processes.
Design page The Design page (see Figure 6) is where you do all of your work. On the left side is the section identification area. This shows you the name of each section. You can right-click this area to display a shortcut menu with different options for the sections. The rulers are at the top and left of the actual design area. Select View | Rulers from the menu to toggle the display of the rulers. The rest of the design page is the actual report. You place different report objects in the specific sections to create the report. The controls at the top, right are not enabled in the Designer.
Chapter 2: Touring Crystal Reports
29
Figure 6. The Designer is where you do all of your work.
Preview page Select File | Print Preview or click the Print Preview button on the Standard toolbar to display the Preview page (see Figure 7). This is a fairly accurate display of what the printed report will look like. You can also do some report design on the Preview page. At the far left of the Preview is the Group Tree. You click one of the listed items to jump directly to that item in the preview. Select View | Group Tree from the menu to toggle the display of the Group Tree. Next is the section identification area. Just like on the Design tab, right-click to display a shortcut menu for changing section information. Rulers are at the immediate left and top of the actual preview area. You toggle the display of the rulers by selecting View | Rulers from the menu. The controls at the top, right are available in Preview mode. First is the print date and time, followed by the navigation controls to move from page to page in the report. The current page and total number of pages also displays.
30
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 7. The Preview shows what the report will look like when printed. On the left is the Group Tree you can use to navigate quickly to a specific group.
Report Sections Crystal Reports divides the report into several areas: report header, page header, group header, detail, group footer, page footer, and report footer. Each report is limited to one report header, page header, detail, page footer, and report footer area. You can have multiple group header and footer areas. Each area further divides into sections. For example, you can have multiple detail sections or multiple page header sections. When you place fields, text, and other objects on the report, you place them in a section. You can format and control each section individually.
Section Expert You use the Section Expert to change settings for a particular section. For example, you can change the position of a particular section, set its background color, or programmatically control how different items work. Throughout the rest of this chapter, you will see several dialog boxes. I will not explain each option, but only discuss some of the more interesting or confusing items. The first dialog box is the Section Expert (see Figure 8).
Chapter 2: Touring Crystal Reports
31
Figure 8. You use the Section Expert to customize a particular report section. The first item of interest on the Section Expert is the formula button. It looks like an equation with a pencil. When you click a formula button, the Formula Editor displays for you to enter a programmatic expression to control a particular feature. Formulas are discussed in detail in Chapter 8, “Using Formulas.” Once you enter a formula behind a specific button, the color of the equation text on the button changes from blue to red and the pencil stands at an angle, instead of lying down. You will see the formula buttons in several dialog boxes. The Hide (Drill-Down OK) option suppresses the section from displaying in the Group Tree. However, you can still double-click a group on the Preview page to drill down to the detail for the particular item. To hide a section completely in the report, select the Suppress (No Drill-Down) option. Widow/orphan control is accomplished with the Keep Together option. When you select this option, Crystal Reports attempts to print the entire section on one page. Choosing Underlay Following Sections will cause the selected section to print behind sections that follow it. This is useful for adding watermarks to a report. Simply add a new section near the top of the report, place the graphic in the section, and then select this option.
Formatting report objects Crystal Reports provides many formatting capabilities. The easiest way to format an object is using the Formatting toolbar. However, this toolbar only offers a subset of the format capabilities. Use the Format Editor to access all the formatting options. There are several ways to display the Format Editor:
32
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Right-click an object and select Format Field from the shortcut menu.
•
Select Format | Format Field from the menu.
•
Click the Format button on the Supplementary toolbar.
Note that the pages on the Format Editor change depending on the object type and the data type of the field. The example shown here is for a regular field containing character data.
Common page The Common page (see Figure 9) has settings for adjusting the position and size of an object. Check Suppress to hide the object so it doesn’t print. To enable widow and orphan control, select Keep Together. You can also rotate the object either 90 or 270 degrees.
Figure 9. Use the Common page of the Format Editor to specify the location and printing of a particular object.
Chapter 2: Touring Crystal Reports
33
Border page The Border page (see Figure 10) is used to set the borders and background color of the object. The border on each side of an object can be set and you can use a different line type on each. If you set the bottom border, the entire width of the object appears underlined, as opposed to selecting the underline attribute of the font, which only underlines the actual text in the object. Use the Tight Horizontal setting to change the length of the horizontal border. If not selected, the length of the horizontal border is the same for each item; in other words, the length of the actual report object. If you select Tight Horizontal, the length of the border changes for each record and is the same length as the actual text.
Figure 10. Use the Border page of the Format Editor to change border settings for a selected object.
34
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Font page The Font page (see Figure 11) is used to set the font for an object. The only item of interest is Character Spacing Exactly. When you select this option, the width of each character is the number of points you specify. The actual width of the printed font does not change, but rather the spacing between characters changes so the space used by each character is exactly what you specify. For example, if you use a 12-point font and set character spacing to 14 points, each character will be 12 points high and 14 points wide.
Figure 11. You can specify the font settings of a selected object on the Font page of the Format Editor.
Chapter 2: Touring Crystal Reports
35
Paragraph page Paragraph formatting affects the way text prints inside the report object. There are two items of interest on the Paragraph page (see Figure 12). The first is Line Spacing. You can set the line spacing as an exact number of points or as a multiple of the font size. The other interesting item is Text Interpretation. There are three settings; none, RTF Text, and HTML Text. This setting tells Crystal Reports how to interpret data saved in a character or memo field. If you set the option as HTML Text, Crystal Reports interprets the data as HTML. This adds powerful formatting options to the report.
Figure 12. The Paragraph Formatting page of the Format Editor is where you change settings for how text prints inside a selected object.
36
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Hyperlink page Finally, the Hyperlink page (see Figure 13) tells Crystal Reports an object is a hyperlink. When the user clicks the object in the Preview, the hyperlink launches.
Figure 13. You create hyperlinks in the report from the Hyperlink page of the Format Editor.
Resizing and moving objects When you drop report objects onto the designer, it’s quite rare when the object ends up in the exact spot or the exact size you want it. This requires you move and resize the object. You can do this with the mouse, keyboard, the Object Size and Positioning dialog box, or by using guidelines.
Chapter 2: Touring Crystal Reports
37
Using the mouse The mouse is the most obvious way to change the location or size of an object. Simply drag the object to the desired location to move it or grab the handles on the sides of the selected object to resize it.
Using the keyboard The cursor keys on the keyboard provide another method to move or resize an object. Simply press a cursor key and the object moves in the desired direction. Use the Shift key in combination with the cursor key to resize the object.
The Object Size and Position window The Object Size and Position (see Figure 14) dialog box provides precise location and size abilities. Select Format | Size and Position from the menu to display the dialog box. The Xaxis position is relative to the left margin of the report. The Y-axis position is relative to the top of the section.
Figure 14. The Object Size and Position dialog box allows precise placement and sizing of a report object.
Guidelines Guidelines let you align the border of multiple objects and change them all at the same time. Small triangles (see Figure 15) on the rulers indicate the location of the guidelines. Select View | Guidelines Design or View | Guidelines from the menu in Preview view to toggle display of guidelines as dashed horizontal and vertical lines on the Design and Preview pages. When you lock the border of an object to a particular guideline, the border moves when you move the guideline. To add a new guideline, click the ruler where you want the guideline to be. You may have to move or resize the report object to get it to lock to the guideline. To remove a guideline, click the triangle and drag it off the ruler.
38
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 15. Use guidelines to align and move report objects.
Setting options Crystal Reports offers many options that affect how the software functions or affect the current report. Application options affect each report you design while report options affect only the current report.
Application options Application options affect how Crystal Reports functions or looks. Select File | Options from the menu to display the Options dialog box, where you set these options. In my opinion, the settings on the dialog box are not well organized. For example, there are several pages where you can change settings that affect how Crystal Reports works with data. Instead of centralizing these settings, they are spread across several pages. Layout page The first page of the Options dialog box is the Layout page (see Figure 16). The first interesting option is Insert Detail Field Headings. When you select this option, column headings are placed in the page header when you drop a field onto the details section of the report. Free-Form Placement means when you place an object on the report, it does not have to be placed in a grid.
Chapter 2: Touring Crystal Reports
39
Figure 16. Use the Layout page of the Options dialog box to specify default settings for Crystal Reports. Database page The Database page (see Figure 17) affects how Crystal Reports connects to databases and shows database objects. The Use Indexes or Server for Speed option tells Crystal Reports to use any index files that are associated with the database. Checking this option causes the record selection to perform faster.
40
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 17. Use the Database page of the Options dialog box to change settings for how Crystal Reports interacts with different databases. When selected, the Perform Query Asynchronously option tells Crystal Reports to start loading data into the report before the query completes. This allows you to start producing the report more quickly when a large data set is returned. It also lets you cancel an executing query.
Chapter 2: Touring Crystal Reports
41
Editors page There isn’t much of interest on the Editors page (see Figure 18). The settings on this page affect the visual appearance of different items in the Formula Editor.
Figure 18. You change editor settings on the Editors page of the Options dialog box. Data Source Defaults page One of the settings you can change on the Data Source Defaults page (see Figure 19) is the type of native access database files Crystal Reports displays by default. You can set the directory location and the file extensions for both the data and index files.
42
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 19. The Data Source Defaults page of the Options dialog box is where you change settings for native data types and dictionary locations. Reporting Several options are available on the Reporting page (see Figure 20). The most important of these is Save Data With Report. When selected, any data used to design the report saves with the report. This makes the RPT file bigger and requires you to refresh the data each time you run the report. Update Connected Repository Objects When Loading Reports causes any Repository objects used in the report to be updated with the latest object stored in the Repository. The Repository is a new feature in Crystal Reports 9 and is discussed in Chapter 5, “Intermediate Reporting.”
Chapter 2: Touring Crystal Reports
43
Figure 20. Use the Reporting page of the Options dialog box to change default settings for converting data and saving a report file. You can enter Crystal Reports formulas in Crystal or BASIC syntax. You can change the default syntax to use with the Formula Language setting. Formulas are covered in detail in Chapter 8, “Using Formulas.” Fields There isn’t much to say about the Fields page (see Figure 21). When you click one of the buttons, the Format Editor for the particular data type displays.
44
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 21. Selecting a Field format item from the Fields page of the Options dialog box displays the appropriate page of the Format Editor. Use this to change default settings for how a particular data type prints. Fonts The Fonts page (see Figure 22) allows you to select default fonts for the different types of fields. When you select one of the field type buttons, the Font dialog box displays so you can set the default font for the field.
Chapter 2: Touring Crystal Reports
Figure 22. You change default font settings for different items on the Fonts page of the Options dialog box. Smart Tag The Smart Tag options (see Figure 23) are used to define web server and page information when you use Microsoft Office smart tags attached to Crystal Reports objects.
45
46
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 23. Set the Smart Tag options for linking to Microsoft Office XP Smart Tags.
Report options In addition to application-wide settings, you can change how Crystal Reports works with the current report. Select File | Report Options to display the Report Options dialog box (see Figure 24). All the settings in this window are also available in the Options dialog box. Again, I recommend Save Data With Report not be selected. By default, this option is selected.
Chapter 2: Touring Crystal Reports
47
Figure 24. Change settings for the current report in the Report Options dialog box. Report Parts are portions of a report displayed alone without the rest of the report. Using the Report Options dialog box, you can define the name of the home object and the specific records to use in the home object. Chapter 16, “Web Reporting,” discusses Report Parts in more detail.
The report-processing model Before moving on to report design, it’s important to understand how Crystal Reports processes a report. Crystal Reports is a multi-pass report designer. This means the report processes several times. Each pass processes different pieces of information. Crystal Reports actually makes three passes though the report or data.
48
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Pre-pass 1 Before looking at any data, Crystal Reports processes any constant formulas. These are formulas that have the same value throughout the entire reporting process. This pass is also called BeforeReadingRecords.
Pass 1 During the first pass, the following things occur: •
Records are read from the database. The data is stored in memory or temporary tables and is not read again.
•
Formulas that contain references to data fields, but are not used for subtotals or summaries are evaluated. This process is called WhileReadingRecords.
•
Records are sorted and grouped.
•
Subtotals and summaries are calculated.
•
Cross-tabs are generated.
Pre-pass 2 Groups are ordered for Top/Bottom N and Hierarchical grouping.
Pass 2 Page formatting occurs in pass 2. Crystal Reports does page formatting on demand, meaning the page is not formatted until needed. The following things occur in this pass: •
Group selection formulas are calculated.
•
Running totals are calculated.
•
Formulas marked as WhilePrintingRecords are calculated. These are formulas used to calculate subtotals and summaries.
•
Charts and maps are processed.
•
Subreports are processed.
Pass 3 In the final pass, the total page count is calculated.
Summary You should now be familiar with how Crystal Reports is arranged, how to set the many available options, and how a report is processed. In subsequent chapters, you will see many more dialog boxes and settings as you learn more about the report design process.
Chapter 2: Touring Crystal Reports Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
49
50
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 3: Creating Your First Report
51
Chapter 3 Creating Your First Report Creating reports that include drill-down and graphing in Crystal Reports is easier than you might think. This chapter will help you understand the basics of report design with Crystal Reports.
You are finished installing Crystal Reports and are ready to create your first report. You launch the application and see a dialog box asking you to create a report using either the Report Wizard or a Blank Report. WOW, a wizard! It must know a lot about reports. So, you select that option and are led on your way to creating a wonderful report. However, you soon find the Report Wizard doesn’t provide the control you need. It gives you some default settings, many of which you don’t like. It’s also not good at helping with existing reports. Maybe it would have been better to select Blank Report. That is exactly what this chapter is about, creating a report from scratch. You won’t spend a lot of time on formatting and getting the report to look perfect. The Crystal Reports documentation, help files, and other books do a good job with this. However, I think it is important to give you some reporting basics before diving into programmatically controlling Crystal Reports.
Designing the report Before sitting down with Crystal Reports, you should have an idea of what the finished report should look like. This report will be a sales listing by genre and title for the fictional company WebNet Video. I start by listing the report items, sketching the report layout on paper, and then look at the tables you need for the report.
Sketching the report I already gave you some information about the report, sales listing by genre and title. This sounds like a good report title. The title gives you a clue that you need genre and sales information. The report should list each sale, subtotal the quantity ordered and total dollar value by title and genre, and have a grand total for each grouping at the end, along with a pie chart comparing the subtotal sales for each genre. Most reports also include the print date and page number. Finally, the company logo should also be included. Table 1 lists the items to include.
52
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 1. Items needed for the Sales Listing by Genre and Title report. Item
Report Location
Title, “Sales by Genre and Title” Logo Print date Page number Genre Movie title Customer First name Customer Last name Customer city Customer state Quantity purchased Purchase price Extended price (quantity * price) Total by title Total by genre Grand Total Pie chart
Page Header Page Header Page Header Page Header Group 1 Header Group 2 Header Detail Detail Detail Detail Detail Detail Detail Group 2 Footer Group 1 Footer Report Footer Report Footer
Now that all the report elements are listed, it’s time to lay out the different elements. It is easier to sketch the report with each element and its location defined. Figure 1 shows the layout for the report.
Figure 1. Sketching the report layout makes report design easier.
Chapter 3: Creating Your First Report
53
The report data This report will use FoxPro 2.6 DBF files. Crystal Reports can natively read these files, so there is no need to setup ODBC drivers or an OLE DB connection. Chapter 4, “Accessing Data,” presents a detailed discussion of using a variety of data sources with Crystal Reports. Table 2 describes the four data tables you will use in the report. Table 2. Descriptions of the report data tables. Table
Description
Movies
Information for each movie available for purchase Customer information Order header Order detail
Customer OrdHd OrdDet
Your first report, step-by-step Now that you have a good idea of how the report should look, I’ll walk you through the report design process step-by-step. 1.
Launch Crystal Reports.
2.
If the Welcome to Crystal Reports dialog box displays (see Figure 2), select As a Blank Report, click OK, and then skip to step four. If the Welcome dialog box does not display, proceed to step three.
Figure 2. The Welcome to Crystal Reports dialog displays when you launch Crystal Reports if “Show welcome dialog at startup” is selected.
54
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Selecting the data source Now that you have selected the type of report you want to create, the next step is to identify the data sources. Use the Database Expert dialog box (see Figure 3) to select the data sources for your report.
Figure 3. Use the Database Expert to select the data source. 3.
Expand the tree view under Create a Connection, and then under xBase.
4.
Navigate to the file Movies.DBF and click Open in the Open window to select it.
These files, as well as the completed report, are available for download from the Hentzenwerke website. 5.
Back in the Database Expert, double-click Find Database File to select another table.
6.
Now repeat steps four and five for OrdDet.DBF, OrdHd.DBF, and Customer.DBF. Once you select all the files, click Close.
7.
You have selected the tables to use in the report, but Crystal Reports is not yet using the tables. Select customer.dbf in the Available Data Sources list and click the Move button to move it to the Selected Tables list. You can optionally dragand-drop the table.
8.
Repeat step seven for the three other tables.
9.
Click the Links tab on the Database Expert to display the Links page.
Chapter 3: Creating Your First Report
55
10. The Links page (see Figure 4) is where you link the tables together. In our example, the tables are linked properly to create a parent-child relation from Movies to OrdDet. When you do this, the arrows may point backwards, but you get the same linking. Click OK to close the dialog box.
Figure 4. Use the Links page of the Database Expert to connect related tables. 11. You may get a warning (see Figure 5). If you do, click OK to dismiss it.
Figure 5. The Database Warning reminds you about adding additional data components to the report.
Adding data fields to the report Now it’s time to start placing objects on the report. I’ll start with fields from the data tables. Figure 6 shows the Crystal Reports design surface. It is here you’ll do most of your work. Chapter 2, “Touring Crystal Reports,” discusses the designer in more detail, including explanation of the menus, toolbars, toolboxes, and different report bands.
56
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 6. Use the Crystal Reports design surface to create a report. 12. In the Field Explorer (see Figure 7), drill down to the Customer table and drag the field FirstName onto the Details band of the report.
Chapter 3: Creating Your First Report
57
Figure 7. The Field Explorer displays the fields for each table added to the report. 13. Grab the right side of the FirstName field in the Detail band and drag to the left to make the field width shorter. The column label in the Page Header band resizes automatically. 14. Drag the Customer.LastName, Customer.City, Customer.State, OrdDet.Quantity, and OrdDet.UnitPrice fields onto the Details band, resizing each field as needed. Your report should now look like Figure 8.
58
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 8. The Design tab shows the added fields from the data tables.
Adding a calculated field Crystal Reports has very powerful capabilities for calculated fields, called formula fields. I will explain formula fields in detail in chapter 8, “Using Formulas”. For now, enter a simple formula to calculate the total price for each detail line. 15. Add a total field for each detail item. Click “Formula Field,” and then click the New button in the Field Explorer (see Figure 9).
Chapter 3: Creating Your First Report
59
Figure 9. Create a new Formula Field in the Field Explorer. 16. Enter “DetailTotal” for the Name (see Figure 10), and then click Use Editor.
Figure 10. Name the new Formula Field. 17. Use the Formula Editor (see Figure 11) to create and edit formula fields. Chapter 8, “Using Formulas,” explains formulas in detail. For now, enter {orddet.QUANTITY}*{orddet.UNITPRICE} in the lower right of the Formula Editor window.
60
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 11. Use the Formula Editor to create formula fields. 18. Close the Formula Editor and answer Yes when it prompts you to save changes. 19. Drag the DetailTotal field from the Field Explorer onto the Details band of the report. Place this new field to the right of the existing Details band fields.
Grouping and group totals The report layout required grouping by genre and title along with totals for each group. Adding groups and totals is easy in Crystal Reports. 20. Select Insert | Group from the menu. In the Insert Group window (see Figure 12), select Movies.Genre in the top drop-down list for the grouping. Click OK to add the group to the report.
Chapter 3: Creating Your First Report
61
Figure 12. Define a grouping in the Insert Group dialog box. 21. Click Quantity in the Details band. Select Insert | Summary to display the Insert Summary dialog box (see Figure 13). 22. Select “Group #1: movies.GENRE – A” for the Summary Location. Click OK to add the subtotal to Group Footer #1.
62
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 13. Use the Insert Subtotal dialog box to add grouping subtotals to the report. 23. Again, click Quantity on the Details band. Select Insert | Summary. Verify that Summary Location is set to “Grand Total (Report Footer),” and then click OK to add the grand total to Report Footer band (see Figure 14).
Chapter 3: Creating Your First Report
63
Figure 14. Use the Insert Summary dialog box to define grand totals for a report. 24. Add a new group of Movies.Title to the report. Crystal Reports creates Group #2. 25. Add a Quantity subtotal to the Group Footer #2 (Movies.Title). 26. Click the @DetailTotal field in the Details band and add a new subtotal for each group and a grand total in the Report Footer. 27. This is a good place to view the report. Select File | Print Preview (see Figure 15).
64
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 15. The Print Preview shows how the printed report will look. 28. Examine the preview. The Group Tree, just to the left of the report, lists each genre. As you select an item in the Group Tree, Crystal Reports displays the details for that item. In Chapter 12, “Previewing the Report at Runtime,” you will his drill-down capability is available to end users. Note the Quantity subtotals and grand total are formatted incorrectly. They shouldn’t have decimals. Also, the column headings are not correct.
Formatting the report Crystal Reports offers powerful formatting features through the Format Editor. 29. Select the Design tab to go back to the Designer. Right-click the Quantity field in the Group Footer #2 band and select Format Field from the shortcut menu. 30. Select -1,123 for the field format on the Number tab in the Format Editor (see Figure 16). Click OK to save the format.
Chapter 3: Creating Your First Report
65
Figure 16. Select the field format in the Format Editor. 31. Change the format for the Quantity subtotals Group Footer #1 and for the grand total in the Report Footer band. 32. Double-click FIRSTNAME in the Page Header. Delete the text and enter “First Name” for the column heading. Change the column headings for the other fields to “Last Name,” “City,” “State,” “Qty,” “Price,” and “Total.”
66
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Adding the page header The page header prints at the top of each page. You can use text, data, formula fields, or even graphics in any band of the report, including the page header. 33. Drag the splitter bar between the Page Header and Group Header #1 bands down to enlarge the Page Header band. Make it about 1 ½” tall. 34. Drag each column header down so it is at the bottom of the Page Header band. 35. Insert the report title. Select Insert | Text Object from the menu. Drag the new text object so it centers horizontally at the top of the Page Header band. 36. Using the toolbar, set the font to 14-points and bold. 37. Enter the report title “Sales by Genre and Title,” and then resize the text field so the entire report title is visible. 38. In the Field Explorer, drill down in Special Fields, drag “Page N of M” onto the Page Header band, and place it below the report title. 39. Right-click “Page N of M” in the Page Header band and select Format Field from the shortcut menu. 40. On the Common tab of the Format Editor (see Figure 17), set the Horizontal Alignment to “Centered” and click OK to save the format settings.
Chapter 3: Creating Your First Report
67
Figure 17. Use the Common tab of the Format Editor to set common field formatting options. 41. Drag “Print Date” from the Field Explorer and put it below “Page N of M” on the Page Header band. 42. Add the company logo. Select Insert | Picture and choose the file WebNet.JPG. Place the logo in the upper left corner of the Page Header. 43. Now preview the report. Notice the page header fields do not align horizontally. Crystal Reports does not provide an easy way to center text horizontally on a page, but fear not! I’m about to show you how to do it.
68
CrysDev: A Developer’s Guide to Integrating Crystal Reports 44. On the Design tab, resize the report header field (Sales by Genre and Title) so it stretches horizontally across the entire report. Then, use the Format Editor to center the text in the field (for the text object, it’s on the Paragraph tab). Do the same with the page number and print date.
Charting made easy All that is left is to add the graph. Robust charting capabilities are one of the compelling features of Crystal Reports. You can easily add one or more charts from dozens of different types. 45. From the main menu, select Insert | Chart. On the Type tab of the Chart Expert (see Figure 18), set the chart type to Pie.
Figure 18. Choose the chart type in the Chart Expert dialog box. 46. Select the Data tab of the Chart Expert (see Figure 19). Set the Placement “Once per report” in the Footer. Also verify On change of is set to “Movies.Genre” and Show to “Sum of OrdDet.Quantity”.
Chapter 3: Creating Your First Report
Figure 19. Set the location and grouping of the chart on the Data tab. 47. Click OK to insert the chart into the Report Footer (see Figure 20). The graph does not display properly in the Designer. Crystal Reports only inserts a placeholder to show you where the chart will be.
69
70
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 20. The Designer only shows a placeholder for the chart. 48. Switch to the Preview tab and navigate to the last page of the report. Here the graph displays properly (see Figure 21).
Figure 21. Preview mode correctly shows the chart.
Chapter 3: Creating Your First Report
71
49. Double-click the Drama section of the pie. Crystal Reports drills down to the details for Drama (see Figure 22).
Figure 22. Double-click a pie section to drill down to the details for that slice. 50. To print the report, select File | Print | Printer, and then click OK. 51. You can export the report to a variety of different formats, including Word, Excel, and PDF. Select File | Print | Export and choose the format you want. If you select a file, it will prompt you to enter the file name. Chapter 14, “Exporting Reports,” discusses the various export options in detail. 52. Save the report. Select File | Save. Enter the file name “Sales by Genre”. Crystal Reports appends an RPT extension. Congratulations! You just created your first report using Crystal Reports.
Summary This chapter shows you how to create a fairly simple report. I also show you how to easily add graphs, totals, and drill-down capabilities. Some other concepts, such as file linking, formatting, and alignment are also presented. In other chapters, I show you how to give these capabilities to end users using the Crystal Reports runtimes.
72
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
Chapter 4: Accessing Data
73
Chapter 4 Accessing Data The entire purpose of reporting is to make sense of data. Therefore, it is important to know how to access data locked away in the database. In this chapter, you will learn how to pull data from multiple sources.
Crystal Reports has long had a reputation of being able to use just about any data source. If the database has an ODBC driver or an OLE DB Provider, it would almost guarantee that Crystal Reports could extract data for the report. Crystal Reports 9 made several improvements in data access, all of which make data access easier. The Database Expert is completely redesigned. The Visual Linking Expert has been replaced with an easier to use tool. SQL commands and the Crystal Repository replaced the old Crystal Dictionaries and Crystal.
Using the Database Expert The Database Expert (see Figure 1) is used to select the tables for a report. When you create a new report, the Database Expert displays in the first step. You can also select Database | Database Expert from the menu to display the Database Expert. The Database Expert lists data in five different categories as follows: •
Current Connections – Lists database objects already used in a report.
•
Repository – Lists objects stored in the Repository, discussed later in this chapter.
•
Favorites – Lists commonly used database objects.
•
History – Lists recently used database objects.
•
Create a New Connection – Used to create a connection to a new database object.
A database object is a field, view, cursor, stored procedure, or other object in a database usable as a data source for a report field. To add a database object to a report, move it from the Available Data Sources list to the Selected Tables list. Once you select two tables, the Links tab is added to the Database Expert (see the “Linking Tables” section later in this chapter).
74
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 1. Use the Database Expert window to select the tables for a report.
Creating a new connection When you add a new connection, you first need to expand the Create New Connection branch under Available Data Sources (see Figure 2). The data sources listed depend on which data components you installed with Crystal Reports. The steps to add a connection varies with the data source you select. I explain some of the connection options here. You can find a discussion of COM Connectivity in Chapter 15, “Integrating COM Components,” and ADO .NET in Chapter 17, “Crystal Reports .NET.”
Chapter 4: Accessing Data
75
Figure 2. You need to expand the Create New Connection branch to add new tables to a report. Access/Excel (DAO) When you select the Access/Excel (DAO) option a dialog box displays that allows you to enter the file information (see Figure 3). While called Access/Excel (DAO), this option also lets you connect to data other than Access or Excel files. You can select Access, Dbase, Excel, HTML, Lotus, Paradox, and text files or what Crystal Reports calls “direct access data”. This means Crystal Reports can natively access the data without using any external drivers.
76
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 3. Use the Access/Excel (DAO) window to enter information about direct access data sources. If the data source is password protected, make sure you select the Secure Logon check box and enter the log on information. Once you populate the necessary fields, click Finish to return to the Database Expert. ADO .NET (XML) Crystal Reports supports connecting to XML files, but don’t let this option fool you. You do not need ADO .NET (see Chapter 17, “Crystal Reports .NET”, for a complete discussion of Crystal Reports .NET) to connect to XML. Select this option to specify the file location (see Figure 4).
Chapter 4: Accessing Data
77
Figure 4. Use the ADO.NET (XML) dialog box to specify an XML file for the report data source. When you enter the XML File Path, you can use either a file name or a URL. The Visual Studio Data Class fields are explained in Chapter 17, “Crystal Reports .NET.” ODBC (RDO) Crystal Reports relies on an existing Data Source Name (DSN) to connect to a database using ODBC. When you select ODBC as a data source, Crystal Reports displays the ODBC (RDO) dialog box (see Figure 5). You can optionally select a File DSN. Once you select the DSN, Crystal Reports displays a second dialog box for you to enter the logon information for the database. Figure 6 shows this dialog box for the Northwind database in Microsoft SQL Server. Some databases, such as Visual FoxPro, do not support logons. The second page of the dialog box still displays. Just leave the fields empty and Crystal Reports connects to the data. When you enter all the logon information, click Finish to return to the Database Expert.
78
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 5. Use the Data Source Selection page of the ODBC (RDO) dialog box to select an ODBC data source.
Chapter 4: Accessing Data
79
Figure 6. The Connection Information page of the ODBC (RDO) dialog box is where you enter logon information for the database. OLAP Crystal Reports can connect to various OLAP servers and databases, including Microsoft SQL Server OLAP Services (Analysis Services), IBM DB2, Hyperion Essbase, and Crystal Analysis. When you choose to connect to an OLAP server, the Crystal OLAP Connection Browser displays (see Figure 7).
80
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 7. You select an existing OLAP server from the Crystal OLAP Connection Browser dialog box. Choose an OLAP server from the list or click Add Server to display the New Server dialog box (see Figure 8). You first select the Server Type and enter a Caption to display. The remainder of the dialog box changes depending on the server type you select.
Chapter 4: Accessing Data
81
Figure 8. Add a new OLAP server in the New Server dialog box. OLE DB (ADO) OLE DB is a fairly new technology developed by Microsoft as a replacement for ODBC. Where ODBC is designed to connect to relational data, OLE DB can connect to any type of data. OLE DB itself is a low level interface only used directly by C++ programmers. ADO is a COM wrapper around OLE DB that makes the data accessible to other development languages such as Visual FoxPro, Visual Basic, Delphi, and others. When you choose the OLE DB (ADO) source, Crystal Reports displays the OLE DB (ADO) dialog box (see Figure 9).
82
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 9. The first step in using an OLE DB or ADO connection is choosing the OLE DB provider or data link file. In this dialog box, select the OLE DB Provider or data link file to use for connecting to the data. It is possible the data link file contains all the necessary connection information. If it does, click Finish. Otherwise, click Next to go to the next step. The Connection Information panel displays (see Figure 10).
Chapter 4: Accessing Data
83
Figure 10. Enter server and connection information in the Connection Information dialog box. In this dialog box, you enter connection information such as server name, logon username, password, and set the database to use. If you want to use the default values for additional parameters, click Finish. Otherwise, click Next to display the Advanced Information dialog box (see Figure 11).
84
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 11. You change additional OLE DB parameters in the Advanced Information dialog box. To change a particular value, select it in the list, and then click Edit Value. When you have made all the necessary changes, click Finish. xBase Crystal Reports can natively connect to dBase II, dBase III and FoxPro 2.x tables. If you have data in Visual FoxPro tables, you need to either copy the data to a FoxPro 2.x table or connect to it using the Visual FoxPro OLE DB Provider. When you select xBase from the Available Data Sources list in the Database Expert, Crystal Reports displays a File Open dialog box to select the DBF file you want to include. You need to add the tables one at a time until all the necessary tables are added to the Database Expert. More Data Sources If the data source you want to use is not listed in the Database Expert, select More Data Sources. This list shows the data sources you did not select when you installed Crystal Reports.
Chapter 4: Accessing Data
85
Select the data source you want to use. Crystal Reports may launch the Install on Demand feature of Windows Installer to install the required database drivers. SQL Commands Crystal Reports 9.0 introduces the concept of SQL Commands. They are designed to replace the Crystal Query application. SQL Commands are a powerful feature that let you define a SQL Select statement to pull data from a single table or multiple tables. This makes it easy for developers to provide data to users who create their own report. The following steps show you how to add a SQL Command: 1.
Add the desired connection in the Database Expert
2.
Expand the tree for the connection (see Figure 12).
Figure 12. To add a SQL Command, expand your selected database in the Database Expert and select Add Command.
86
CrysDev: A Developer’s Guide to Integrating Crystal Reports 3.
Double-click Add Command to display the Modify Command dialog box (see Figure 13).
Figure 13. Enter the SQL Select statement in the Modify Command dialog box. 4. 5.
Enter the SQL Select statement to create the desired result set. If the statement is complete, proceed to step 12. Otherwise, continue with step 5. If you need to enter a parameter (Figure 13 shows the parameter pCountry), click Create to display the Command Parameter dialog box (see Figure 14).
6.
Enter the Parameter Name.
7.
Enter the Prompting Text.
8.
Select the Value Type.
9.
Enter the Default Value.
10. Click OK to save the parameter information and return to the Modify Command dialog box. 11. Repeat steps 6 through 10 to enter additional parameters as needed. 12. If desired, select Add to Repository. When you do this, the Add Item dialog box displays. (See “Understanding the Crystal Repository” later in this chapter.) 13. Click OK to close the Modify Command dialog box.
Chapter 4: Accessing Data
87
Figure 14. Specify the SQL Select parameters in the Command Parameter dialog box. There is one important note about command parameters. If the parameter is a character data type, you must surround it by single quotes in the SQL Select statement as shown in Figure 13. This is not required for other data types. Parameters fields, explained in detail in Chapter 6, “Advanced Reporting,” are similar to command parameters.
Selecting database objects Now that you selected the database connections for the report, you need to specify the tables to use. To see the available tables, expand the connection under the connection type or Current Connections in the Available Data Sources list in the Database Expert. Drill down under the appropriate node in the list. By default, Crystal Reports shows the tables, views, and stored procedures of the data source, if they are supported (see Figure 15). To add a table to the report, drill down to the desired table, view, or stored procedure and drag it from the Available Data Sources list to the Selected Tables list. You can also select tables from the Favorites and Repository the same way.
88
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 15. Drag the table from the Available Data Sources list to the Selected Tables list in the Database Expert. If you select a stored procedure, Crystal Reports will prompt you to enter a value for any required parameters (see Figure 16). You do not need to enter the parameters at this time. Crystal Reports will prompt the user to enter the values when the report is run.
Chapter 4: Accessing Data
89
Figure 16. Crystal Reports will prompt for required parameters if you select a stored procedure.
Linking Tables Once you add tables to the report, you need to tell Crystal Reports how to link them. This is done on the Links page of the Database Expert. Figure 17 shows four tables being linked. Some fields are indexed, as indicated by the pointers next to the field name. When you look at this in Crystal Reports, the pointers are different colors. Click Index Legend to see definitions of the different colors.
90
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 17. Crystal Reports makes its best guess at linking tables. When Crystal Reports links the tables, it makes its best guess at which fields to use for linking the tables. It does this by comparing field names in the tables. In Figure 17, Crystal Reports guessed Customers.PostalCode should link to Employees.PostalCode. However, the correct link should be Orders.EmployeeID to Employees.EmployeeID (see Figure 18). The following steps show how to make the correct link: 1.
Click the line with the incorrect link to select it. The link displays bold.
2.
Press the Delete key or right-click and select Delete Link from the shortcut menu.
3.
Drag the linking field from the parent table onto the linking field in the child table.
Chapter 4: Accessing Data
91
Figure 18. A view of the Database Expert Links page after correcting the linking information. Crystal Reports assumes the fields to use for linking should be the same value (equal to) and it should perform an inner join. To modify this, right-click the line indicating the link and select Link Options from the shortcut menu. The Link Options dialog box displays (see Figure 19). Make your changes, and then click OK to save them.
Figure 19. Use the Link Options dialog box to modify how tables are linked.
92
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Field definition files Normally, data fields in a report are bound to a field in a specific table. However, you can create unbound reports, and then apply the actual data source at runtime using a field definition file. The advantage of a field definition file is it is easy to change the actual data source at report time. Field definition files are tab separated text files with a TTX extension. Each line of the file represents one column in the data source. You must specify the field, data type (see Table 1), and length for string fields. Table 1. Data Types for Field Definition Files. Data Type Blob Boolean Byte Currency Date Long Memo Number Short String
Creating a field definition file You can create a field definition file using a text editor or you can use the designer in Crystal Reports. 1.
In the Database Expert, expand the Create New Connection node and select Field Definitions Only. The Field Definitions Only dialog box (see Figure 20) displays.
Chapter 4: Accessing Data
93
Figure 20. Use the Field Definitions Only dialog box to specify the TTX file for unbound reports. 2.
Enter either the name of an existing TTX file or click Create File. If you click Create File, the Database Definition Tool (see Figure 21) displays.
94
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 21. Use the Database Definition Tool to specify field information for a TTX file. 3.
Enter the Field Name for the first field in the table.
4.
Enter the Field Type for the second field in the table. If you select String, it will prompt you to enter the field Length.
5.
Optionally enter Sample Data.
6.
Click Add.
7.
Repeat steps three through six for each field in the table.
8.
When you finish, close the dialog box or select File | Save from the menu. It will prompt you to enter the file name if you created a new file, and then return to the Field Definitions Only dialog box.
9.
Click Finish to return to the Database Explorer.
Using a field definition file Once you create the field definition file, you add it to the report just like any other data source. However, you still need to link the report to the actual data. 1.
Open the report. If you preview the report at this time, it uses the sample data you placed in the TTX file.
Chapter 4: Accessing Data 2.
Select Database | Set Datasource Location from the menu. The Set DataSource Location dialog box (see Figure 22) displays.
Figure 22. You change the location of the database in the Set Datasource Location dialog box. 3.
In the top pane, select the specified table from the TTX file.
4.
In the bottom pane, select the actual data source.
5.
Click Update.
6.
Preview the report to verify it is using the actual data.
Working with Images I have seen many questions over the past few years asking how to handle images. Putting a single image on a report is easy, but when each detail record needs a different image, it’s difficult to make it work.
95
96
CrysDev: A Developer’s Guide to Integrating Crystal Reports
There are two methodologies to handling images. One is storing the image in a field in the database. The second, and probably more accepted method, is keeping an image file on disk and storing the filename in the database.
Images in the database Crystal Reports supports Windows Metafiles, Bitmaps (BMP), TIF, JPG, and PNG file formats. It does not support GIF files. I tested images stored in four different data sources: FoxPro, Visual FoxPro, Access, and SQL Server. In a FoxPro or Visual FoxPro table, images are stored in a General field. When using native data connections to a FoxPro table, Crystal Reports does not recognize the general field. The image does not print in the report. However, if you use ODBC or the Visual FoxPro OLE DB Provider, the General field is recognized and the image prints in the report. Access stores images in an OLE Object field. The images print correctly using direct access, ODBC, and ADO. In SQL Server, you store the pictures in an Image file. Using both ODBC and ADO, the images print correctly. separate image files for each record requires you hook into the formatting Using events of Crystal Reports. Chapter 15, “Integrating COM Components,” discusses Event handling in detail.
Adding a watermark Watermarks are images or text that prints behind the report data. Use the following steps as a guide to add a watermark under the detail section of a report. 1.
Right-click the Page Header, to the left of the design area, and select Insert Section Below from the shortcut menu.
2.
Place the graphic or text in the new section.
3.
Select Report | Section Expert from the menu or click the Section Expert button on the Expert Tools toolbar to display the Section Expert (see Figure 23).
Chapter 4: Accessing Data
Figure 23. Use the Section Expert to set options for each report section. 4.
Select the newly added section in the Sections list box.
5.
Select the Underlay Following Sections check box.
6.
Click OK to return to the designer.
7.
Preview the report.
8.
Return to the design tab and stretch the graphic vertically until it is tall enough to underlay they entire Details section.
Limiting records selected When you apply a record selection criteria, Crystal Reports adds a Where clause to the SQL Select statement sent to the database. You can use the Select Expert or Selection Formulas in the Formula Workshop (see Chapter 8, “Using Formulas”). Either way gives the same results.
97
98
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The Select Expert Basically the Select Expert is a wizard that makes it easy to apply a criteria select statement. The following steps walk you through using the Select Expert. 1.
Choose Report | Select Expert from the menu or click the Select Expert button on the Expert Tools toolbar.
2.
If you don’t have any criteria entered, such as the first time you display the Select Expert, the Choose Field dialog box (see Figure 24) displays.
Figure 24. Use the Choose Field dialog box to pick the first field for the Select Expert. 3.
Select the field for the criteria and click OK to return to the Select Expert (see Figure 25).
Chapter 4: Accessing Data
Figure 25. Use the Select Expert to limit the data used in the report. 4.
In the first combo box, choose the comparison for the field.
5.
In the second combo box, choose the value.
6.
Click Show Formula to display the formula Crystal Reports will apply (see Figure 26). You can also enter the same formula in the Formula Workshop.
Figure 26. The Select Expert expanded to show the selection formula.
99
100
CrysDev: A Developer’s Guide to Integrating Crystal Reports 7.
To add additional criteria, click New or click OK to save the criteria and close the Select Expert.
8.
Preview the report to see the filtered data.
Miscellaneous data functions Crystal Reports has a few other data related functions you should know about.
Set Database Location It’s common to use a different data set during development than at runtime. This makes it necessary to change the location of the data and maybe even the type of data access. For example, you may develop a report using direct access FoxPro data, but at runtime you need to access data on SQL Server. To change the location of the data: 1.
Select Database | Set Database Location from the menu. The Set Datasource Location dialog box (see Figure 22) displays.
2.
Choose the table in the Current Data Source list.
3.
Select the new data source or create a new connection in the Replace with list.
4.
Click Update to change the location and convert the database driver Crystal Reports uses.
5.
Click Close to close the Set Datasource Location dialog box.
6.
Select Database | Verify Database from the menu to confirm the new database is the same structure as the old database.
LogOn or Off Server This option does exactly what it says. It logs you on or off a server. If you have a report open, select Database | LogOn or Off Server from the menu. If you do not have a report open, select File | LogOn or Off Server. With either option, the Data Explorer (see Figure 27) displays.
Chapter 4: Accessing Data
101
Figure 27. Use the Data Explorer to log on or off a database server. To log on the server, select the server from the list or create a new connection and click Log On. To log off, select the server and click Log Off.
Show SQL Query This option displays the Show SQL Query dialog box (see Figure 28) showing the SQL Select statement sent to the database. To display the dialog box, select Database | Show SQL Query from the menu.
102
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 28. The Show SQL Query dialog box displays the SQL Select statement sent to the database.
Perform Grouping on Server When selected, this option can provide significant performance increases, particularly when used with client/server databases such as SQL Server and Oracle. If selected, a Group By clause is added to the SQL Select statement sent to the database. To toggle this option, select Database | Perform Grouping on Server from the menu or set this option in either the Options or Report Options dialog box.
Report Bursting Indexes Sometimes you may want to save the data with the report. When you do this, you can improve the reporting performance by adding indexes to the data. Select Report | Report Bursting Indexes from the menu to display the Saved Data Indexes dialog box (see Figure 29).
Chapter 4: Accessing Data
103
Figure 29. Select fields for indexing in the Saved Data Indexes dialog box to increase reporting speed in reports using saved data. Select the fields you want indexed in the Available Fields list. When you finish, click OK.
Summary In this chapter, I showed you how to connect to many commonly used data sources. Crystal Reports can connect to many others, such as NT Event Logs, IIS Logs, Outlook, Lotus Domino servers, and many others. While I didn’t explain many of these data sources, you should have no trouble connecting to them. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
104
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 5: Intermediate Reporting
105
Chapter 5 Intermediate Reporting This chapter shows you how to do some very common reporting needs. These including grouping, totaling, drill-down, graphs, and cross tabs. Also, Crystal Reports 9 adds a new feature called the Repository. You will see how Crystal Reports makes easy work out of something that seems complicated.
In previous chapters, you have seen how to install Crystal Reports, create a report, connect to data, and learned about some important default settings. However, the capabilities you have used up to this point will rarely suffice. You almost always need to be able to do grouping and totaling. Many users also want graphs or maps as part of their report in order to better analyze their data. Sometimes a report requires essentially a view of the data turned 90 degrees, where the columns are turned into rows and rows into columns. Crystal Reports can handle all of these needs and more.
Understanding the Crystal Repository The Crystal Repository is a new feature introduced in Crystal Reports 9. It is used to store text objects, custom functions, images, and SQL Commands commonly used in reports. Putting an object from the repository onto a report is an easy drag-and-drop procedure. When you install Crystal Reports, it installs the repository database. By default it uses an Access database, Repository.MDB. On my system, it was placed in C:\Program Files\Common Files\Crystal Decisions\2.0\bin. A System DSN ODBC connection named Crystal Repository is also set up during installation. Because the repository database is accessed via an ODBC connection, you can use any back end you like. Create the database and tables, create the ODBC connection, and then edit ORMap.INI to point to the new Repository database. Display the Repository Explorer by selecting View | Repository Explorer from the menu or clicking the Repository Explorer button on the Standard toolbar. Figure 1 shows the default items in the Repository Explorer.
Figure 1. Use the Repository Explorer to navigate objects stored in the Crystal Repository.
106
CrysDev: A Developer’s Guide to Integrating Crystal Reports
One use of the repository is the ability to modify objects used across multiple reports. Modify the object in the repository and then open each report to update the object stored in the report. Another use of the repository is sharing objects across users. For example, you can create complex queries and make them accessible to end users creating their own reports.
Adding objects to the repository The steps required to add an object to the repository vary depending on the object. I discuss text objects, images, and SQL Commands here. Custom Functions are discussed in Chapter 8, “Using Formulas.” Text objects and images Text objects and images are added to the repository directly from the report. 1.
Right-click the object on the report or in the Report Explorer.
2.
Select Add to Repository from the shortcut menu. The Add Item dialog box displays (see Figure 2).
Figure 2. Use the Add Item dialog box to specify the name and location of each object you add to the repository.
Chapter 5: Intermediate Reporting 3.
Enter the Name of the object. This is the name the Repository Explorer displays.
4.
Enter the Author.
5.
Enter a Description of the object.
6.
Select the repository folder to hold the object.
7.
Click OK to add the object and return to the report.
107
SQL Commands In Chapter 4 “Accessing Data,” I introduced the concept of SQL Commands. One of the options in the Modify Command dialog box is Add to Repository. When you select this option, Crystal Reports displays the Add Item dialog box when you save the SQL command.
Using repository objects in a report Once you have objects in the repository, you can add them to a report. How you do this depends on the type of object. SQL commands are added through the Database Expert. Custom Functions are added from the Formula Workshop. To add a text or image object, simply drag-and-drop it from the repository onto the report. The object is locked, meaning it is placed on the report in a read-only state. In the case of a text object, you cannot alter the appearance of the text because it uses the properties from the repository. If you need to modify the object on the report, right-click on the object and select Disconnect from Repository from the shortcut menu.
Updating objects in the repository Sometimes it becomes necessary to modify objects stored in the repository. You modify Custom functions in the Formula Workshop and SQL commands in the Database Expert. The following steps explain how to modify a text object: 1.
Right-click the text object in Design view.
2.
Select Disconnect from Repository from the shortcut menu.
3.
Make the desired modifications.
4.
Right-click the object and select Add to Repository. The Add Item dialog box displays (see Figure 2).
5.
Enter the name of the object and select the repository folder.
6.
Click OK to save the object. If you use the same repository name, it will prompt you to update the original object with the changes.
When you update a repository object, it affects all the reports that use the object. However, you must modify those reports before the changes take affect. The objects automatically update when you open the report.
108
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Sorting Sorting puts the data in a specific order. For example, a customer list is often ordered alphabetically. To sort the data, select Report | Record Sort Expert from the Crystal Reports menu or click the Record Sort Expert button on the Expert Tools toolbar and the Record Sort Order dialog box (see Figure 3) opens.
Figure 3. Use the Record Sort Order dialog box to sort data in the report. The left side of this dialog box displays a list of available fields. On the right are the selected fields. Each field you select can be sorted in Ascending or Descending order. The A or D in front of the item indicates the sort direction for the field. When you have selected the fields and sort order, click OK to save your selections. Note that you cannot change the sort direction for group fields. Record sorting does not add any sections to the report, but simply orders the data.
Groups Groups are similar to sorting, in that the data is ordered a specific way. However, grouping adds a group header and footer section to the report and is often used to provide totals for each group. It is not necessary to sort the data before grouping, as grouping sorts by default. You add a group by selecting Insert | Group from the Crystal Reports menu to display the Insert Group dialog box (see Figure 4).
Chapter 5: Intermediate Reporting
109
Figure 4. Use the Common tab of the Insert Group dialog box for creating a group. The Common tab allows you to select the field to group by and its sort order. You can choose from four sort orders: •
Ascending order
•
Descending order
•
Specified order
•
Original order
Ascending and descending orders are self-explanatory. Original order prints the data in the same order it appears in the data. Specified order requires some explanation. Specified order lets you determine how you want the data to display. When you select this option, two new tabs, Specified Order (see Figure 5) and Others, are added to the dialog box (see Figure 6).
110
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 5. Use the Specified Order tab of the Insert Group dialog box to determine which data you want to see on the report. Here’s how this page works. The Named Group: box contains the group data from the table. Select the data you want to see and that item is added to the list. You can change the order of the displayed data. Only the groups you select appear in the report. Once you select one item from the Named Group: box, a fourth tab, Others, is added to the dialog box. The Others tab (shown in Figure 6) lets you determine how to handle the rest of the data. The default is to group them all together in a group called Others. You can also discard them or leave them in their own group.
Chapter 5: Intermediate Reporting
111
Figure 6.The Others tab is where you determine how to handle the unspecified data. The Options tab (see Figure 7) of the Insert Group dialog box is used to select any group options that you want. By default, Crystal Reports uses the field selected for grouping as the name of the group. You can change this by selecting Use a Formula as Group Name and choosing a different field or formula for the group name. Formulas are discussed in Chapter 8, “Using Formulas.”
Figure 7. Use the Options tab to set options for the group.
112
CrysDev: A Developer’s Guide to Integrating Crystal Reports
You can also select Keep Group Together to force the entire group to print on a single page if it is short enough. Finally, if you check Repeat Group Header On Each Page, the group header section prints at the top of each page the group prints on. Once you finish setting the group options, the new sections are added to the report. This is not the end of what you can do with a section. If you right-click the section description, you see a shortcut menu (see Figure 8) with additional options.
Figure 8. The Group shortcut menu displays by right-clicking the group description. At the top of the shortcut menu is the grouping. It is either Group Header or Group Footer and the field you chose to group on. The letter ‘A’ means this is section A of the group header. Select Insert Section Below to add additional sections to the group header or footer. Hide (Drill-Down OK) hides the section from the report, but displays the drill-down list. Drill-down is explained later in this chapter. Once you select this option, the menu prompt changes to Show. Suppress (No Drill-Down) hides the section and does not allow drill-down. When you select this option, the menu item changes to Don’t Suppress. Section Expert displays the Section Expert, discussed in Chapter 2, “Touring Crystal Reports.” Change Group displays the Change Group Options dialog box, which is the same as the Insert Group dialog box (see Figure 4), but with a different caption.
Chapter 5: Intermediate Reporting
113
Show Short Section Names expands and collapses the left area of the designer. So, instead of showing “Group Header #1”, the short section name, “GH1”, displays. This increases the size of the design area. The Insert Line, Delete Last Line, and Arrange Lines work with Guidelines, discussed in Chapter 2, “Touring Crystal Reports.” Fit Section vertically sizes the section to be the same vertical height as the data it contains. Insert Section Below adds a new section below the current one. The new section is part of the same area. Delete Group removes the entire group from the report. If you choose to delete the group, Crystal Reports displays a warning that the operation cannot be undone. Select All Section Objects selects each report object in the section.
Drill-down By default, when you add a new group, it is available for drill-down. Drill-down allows you to double-click a group and zoom into its data. There are two ways to do this. The first is using the Group Tree on the left side of the preview window. When you double-click a group item, the data in the current preview window repositions to show the selected group. The second method allows you to double-click the group in the preview window. A new preview opens containing only the data for the selected group. There are a couple different ways you can suppress group data and drill-down through the group shortcut menu (see Figure 8). First, you Hide the group. When you select this option, the group does not print on the report and the data does not display in the preview window. However, the group data does show in the Group Tree. The second method, Suppress, completely hides the group.
Hierarchical groups Sometimes you need to relate data in a table to another field in the same table. For example, an Employee table may have a field that points to the employee number for the supervisor (a self join). In this case, the supervisor record is the parent and the employee record is the child. Crystal Reports makes it easy to create a report listing the supervisor followed by the employees that report to him. The following steps show you how to create a hierarchical grouping. 1.
Add a group to the report for the child record.
2.
Place any additional data you need into the group header.
3.
Select Report | Hierarchical Grouping Options from the menu. The Hierarchical Options dialog box displays (see Figure 9).
114
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 9. Use the Hierarchical Options dialog box to add hierarchical grouping to the report. 4.
Select the group from the Available Groups list.
5.
Select the Sort Data Hierarchically check box.
6.
Select the Parent ID Field.
7.
Enter the number of inches to indent the child records.
8.
Click OK to save the grouping.
When you preview or print the report, Crystal Reports correctly matches up the data based on the hierarchy link you select.
Summaries Summaries are used to add or summarize a column of data or specified fields in a column in the report. Totaling on a line requires using a formula, which I discuss in Chapter 8, “Using Formulas.” Another type is called running totals, presented later in this chapter.
Subtotals and grand totals Subtotals add the values of a specified column and place the result in a group footer. Grand totals are printed at the end of the report. To add a summary to your report, select Insert | Summary from the Crystal Reports menu or click the Insert Summary button on the Insert Tools menu. The Insert Summary dialog box appears (see Figure 10).
Chapter 5: Intermediate Reporting
115
Figure 10. Use the Insert Summary dialog box to add a subtotal or grand total to a report. The Choose the field name to summarize box is where you select which field you want to summarize. If you select the field in the report before displaying the Insert Summary dialog box, that field displays in the combo box. The Calculate this summary box is where you select the type of summary to make. The items in the list change depending on the data type of the field you select to summarize. For example, you can calculate the average, sum, or variance of numeric data, but can’t for character data. Next, select the summary location. The choices are the footer sections of each group or a grand total at the end of the report. Click Insert Group to display the Insert Group dialog box and add a new group to the report. Depending on the data type of the summarized field and the type of summary you select, the additional options are enabled or disabled. You can show the summary as a percentage of another field or summarize across hierarchies.
116
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Running totals Running totals are different from group and grand totals. A running total is generally placed on a detail line and incremented by the specified value throughout the report. The following steps show you how to add a running total. 1.
Select Running Total Fields in the Field Explorer.
2.
Click New on the Field Explorer to display The Create Running Total Field dialog box (see Figure 11).
Figure 11. Use the Create Running Total Field dialog box to add a running total to a report. 3.
Enter a name for your running total.
4.
Select the field to total.
5.
Select the summary type.
6.
Determine when to evaluate the field. You can have the field calculate for each record, when a specified field changes, when a group changes, or based on a formula.
7.
Determine when to reset the value. You have the same options as Evaluate.
Chapter 5: Intermediate Reporting
117
8.
When you finish setting the options for the running total, click OK. It returns to the Field Explorer.
9.
Drag-and-drop the running total field from the Field Explorer onto the designer.
Crystal Reports automatically calculates the running total when you print or preview the report.
Cross-tabs Cross-tabs are a powerful data analysis tool that allows you to easily summarize data based on two or more fields. Think of it as a spreadsheet, where you have columns and rows of data and the intersection is the summarized data. To add a cross-tab, select Insert | Cross-Tab from the menu or click the Insert Cross-Tab button on the Insert Tools toolbar. The Cross-Tab Expert displays (see Figure 12).
Figure 12. You define a cross-tab using the Cross-Tab Expert. To create the cross-tab, drag the fields from the Available Fields list and place them where you want the field to appear in the report. By default, summarized fields are calculated as the sum of the selected field. In Figure 12, the data is totaled by Orders.Order Date. The column heading is Employee.Last Name. Each intersection of a row and column consists
118
CrysDev: A Developer’s Guide to Integrating Crystal Reports
of two numbers, the sum of the Order Amount and the count of the orders made for each date and employee. On the left side of the Cross-Tab is the list of available fields and formulas. You pick a field or add a formula with the New Formula button. If you edit or create a formula, the Formula Workshop displays. Formulas are explained in Chapter 8, “Using Formulas.” Both the Columns and Rows lists have Group Options buttons. Select a field in the list to enable the button. When you click Group Options, the Cross-Tab Group Options dialog box displays (see Figure 13). The actual options that appear depend on the date type of the selected field.
Figure 13. Use the Cross-Tab Group Options dialog box to set options for the row or column field. When you select a field in the Summarized Fields list, the Change Summary button enables. Click this button to display the Edit Summary dialog box (see Figure 14).
Chapter 5: Intermediate Reporting
119
Figure 14. The Edit Summary dialog box lets you change the summary type for the summarized field. When you finish selecting all the fields and summaries for the cross-tab, select the Style tab of the Cross-Tab Expert (see Figure 15). On this tab you select the formatting to apply to the cross-tab or select Custom from the style list to apply your own formatting once the crosstab is placed on the report.
120
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 15. The Style tab of the Cross-Tab Expert is where you format the look of the cross-tab. The last step is to apply any custom formatting to the cross-tab. You can do this even if you select an existing style. You add the custom formatting on the Customize Style tab of the Cross-Tab Expert (see Figure 16).
Chapter 5: Intermediate Reporting
121
Figure 16. You further customize the formatting of the cross-tab on the Customize Style tab. There are many different settings you can set for each row, column, label, or even the grid lines. Click Format Grid Lines to display the Format Grid Lines dialog box (see Figure 17).
122
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 17. Further customization of the cross-tab can be done in the Format Grid Lines dialog box. When you finish selecting all the fields and formatting for the cross-tab, click OK to close the Cross-Tab Expert. You then place the cross-tab on the report section where you want it to appear. Figure 18 shows a preview of the cross-tab.
Chapter 5: Intermediate Reporting
123
Figure 18. The formatted results of the cross tab.
Charts Presenting data in a graphic format is very important to some users. Crystal Reports uses the term “charts” instead of graphs. I use the two terms interchangeably. Crystal Reports gives you fourteen different graph types to choose from and some can be presented horizontally or vertically, some two-dimensional or three-dimensional. Here’s a list of the available chart types. •
Bar
•
Line
•
Area
•
Pie
•
Doughnut
•
3D Riser
•
3D Surface
•
XY Scatter
•
Radar
•
Bubble
•
Stock
124
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Numeric Axis
•
Gauge
•
Gantt
Basic charting Creating a chart is fairly simple. Note that some of the options change depending on the chart type you select. To create a chart, select Insert | Chart from the menu or click the Insert Chart button on the Insert Tools toolbar. The Chart Expert displays (see Figure 19).
Figure 19. Use the Type tab of the Chart Expert to select the chart type. The Type tab The Type tab of the Chart Expert is where you select the type of chart you want. If your selected chart supports vertical or horizontal alignment, those options are available. If Automatically set chart options is not selected, the Axes and Options tabs are added to the dialog box, depending on the chart type. For example, the Axes tab isn’t available with a pie chart.
Chapter 5: Intermediate Reporting
125
The Data tab On the Data tab (see Figure 20) you set several chart features. First is where to place the chart. You can place it in the header or footer of each group or the report itself. Next, there are four options based on your selection in the Layout grouping. In the Advanced option you set which fields to chart. Options are available for TopN records and you can order the data how you want. You can also change the summary option (for example, average instead of sum) or choose not to summarize the values.
Figure 20. The Layout option on the Data tab determines how you want the chart to appear and what fields to use. The Group button only enables if you have a group subtotal or summary value and is used to set the grouping options for the graph. If you are charting a cross-tab, the Cross-Tab option enables. This option allows you to choose which items in the cross-tab to graph. The Axes tab The Axes tab (see Figure 21) is only available if you clear the Automatically set chart options check box on the Type tab of the Chart Expert. You use the Axes tab to customize the axes and grid lines of the chart. Options let you turn on or off grid lines, set the data values and range, and the number of divisions on the chart.
126
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 21. Use the Axes tab of the Chart Expert to set options for the chart axes. The Options tab The Options tab (see Figure 22) is where you change miscellaneous chart settings. On this tab, you can determine if the chart will be color or black and white. When you set the chart to print black and white, each section prints with a different line or cross hatch pattern.
Chapter 5: Intermediate Reporting
127
Figure 22. On the Options tab of the Chart Expert, you can change several display options for a graph. Crystal Reports gives you the ability to assign a specific color to any data item. Click Format to display the Chart Color Format Expert (see Figure 23).
Figure 23. Customize the colors of individual chart items in the Chart Color Format Expert.
128
CrysDev: A Developer’s Guide to Integrating Crystal Reports
You can also set the data points. The options, depending on chart type, are None, Show label, or Show value. Options are also provided to change the marker shape and size. Finally, you can change the location of the Legend. The Text tab The last tab is the Text tab (see Figure 24). On this tab, you change the text and fonts for the different captions and labels on the chart.
Figure 24. Use the Text tab of the Chart Expert to set the captions and fonts for the graph. Once you have set the chart options, you drop the chart into a report section just like any other field. The Design tab of the Crystal Reports designer shows a representation of the chart. However, when you preview the report, you see the actual chart. While in the preview, you can double-click a section of the chart to drill-down into the detail data behind it.
Advanced charting After you place the chart on the report, you can set additional chart options. Right-click the chart and select Format chart from the shortcut menu. Several options are available, depending on the chart type and formatting selected. Advanced charting is beyond this book. I encourage you to explore these features on your own.
Chapter 5: Intermediate Reporting
129
Maps Maps are closely related to charts, in that they graphically represent data. However, in this case, the graphics represent a geographic breakdown. To add a map to a report, select Insert | Map from the menu or click the Insert Map button on the Insert Tools toolbar. The Map Expert dialog box displays.
The Data tab The first step (see Figure 25) of inserting a map is to choose its placement on the report. The map can be placed at any group break, at the beginning, or at the end of a report. After setting the map placement, you determine how to arrange the data. First, select the Geographic field. This can be a state or country. Next, add the Map values. These are the data points you want to map out. For example, total sales by country.
Figure 25. Use the Data tab of the Map Expert to determine which fields to map.
130
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The Type tab Once you determine the data to map, you pick the map type (see Figure 26). The options available to you depend on the map type you select.
Figure 26. The Type tab of the Map Expert is where you select the type of mapping to chart and the options for each map type.
Chapter 5: Intermediate Reporting
The Text tab The final step of the Map Expert is to set the text you want to display (see Figure 27).
Figure 27. Set the caption and legend options for the map on the Text tab of the Map Expert. Once you have set the map options, the map displays on the report. In design mode, you only see a representation of the map. However, the map displays in the preview (see Figure 28).
131
132
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 28. A preview of the map.
Summary Crystal Reports gives you the ability to reuse report objects through the use of the Repository. Grouping and sorting is quick and easy through the various Expert windows. Summary data can be made on any field and with many different summary options. Finally, Crystal Reports provides powerful, yet easy to use, charting and mapping capabilities. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click on “Catalog” and navigate to the page for this book.
Chapter 6: Advanced Reporting
133
Chapter 6 Advanced Reporting Crystal Reports offers a number of advanced features reports such as parameters, alerts, embedded files, and hierarchical reporting. You won’t use these features all the time, but they offer a lot of power and ease-of-use when you need them.
Now that you have seen how to create reports and learned about powerful capabilities such as mapping and charting, it’s time to look at other features you may not need often, but provide a lot of flexibility to your reports.
Report parameters Many times you will need to pass data not in a database to a report. For example, you may need SQL SELECT criteria, sort order, filters, report titles, etc. This data can be passed via report parameters. You use the parameter just like a regular field or as part of a formula. (Formulas are explained in detail in Chapter 8, “Using Formulas.”) The following steps walk you through creating a parameter: 1.
In the Field Explorer, click Parameter Fields and then click New. The Create Parameter Field dialog box (see Figure 1) displays.
Figure 1. Use the Create Parameter Field dialog box to enter a new parameter.
134
CrysDev: A Developer’s Guide to Integrating Crystal Reports 2.
Enter the Name for the parameter field.
3.
Enter the Prompting text. This displays to the user when the report is run.
4.
Select the Value type. You can choose Boolean, Currency, Date, DateTime, Number, String, or Time.
5.
If the parameter accepts multiple values, set those options. See “Multiple value parameters” later in this chapter.
6.
If you want default values, click Set default values. See “Default values” later in this section.
7.
Click OK to save the parameter settings.
The new parameter appears under Parameter Fields in the Field Explorer. Drag the field from the Field Explorer onto the report. When the report is run, the Enter Parameter Values dialog box displays (see Figure 2).
Figure 2. The Enter Parameter Values dialog box displays when you run the report.
Chapter 6: Advanced Reporting
135
Multiple value parameters Sometimes you may want to enter multiple values for a single parameter. For example, you may want to report sales figures for specific states. To allow multiple values, select Allow multiple values” in the Create Parameter Field dialog box. You then have three options to choose for the parameter: discrete values, range values, or both discrete and range values. The multiple parameters are passed to the report as an array. You use each parameter by referencing the appropriate array element. For example, if you have a parameter called MultipleStates, you reference the second value with: {?MultipleStates}[2]
Chapter 8, “Using Formulas,” discusses formulas and arrays in detail. Discrete values Select discrete values if you need to enter specific values. For example, you may want to report on sales in California, Utah, and Nevada. When you run the report, it prompts you to enter each value (see Figure 3).
Figure 3. You can enter multiple discrete parameter values when you run the report.
136
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Range values Range values are typically used for numeric or date data. For example, you may want to report on sales for a specific date range and only between two amounts. When you run the report, you enter the range of values (see Figure 4).
Figure 4. You enter a range of values in the Enter Parameter Values dialog box. Discrete and range values Finally, you can enter both discrete values and a range of values (see Figure 5).
Chapter 6: Advanced Reporting
137
Figure 5. Enter both a range of values and discrete values when you run the report.
Default values It is often a good idea to supply default values for each parameter. This prompts the user for the best selection or provides a value if the user doesn’t supply one. To enter default values, click Select default values in the Create Parameter Field dialog box (see Figure 1). The Set Default Values dialog box displays (see Figure 6).
138
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 6. You enter default values in the Set Default Values dialog box. Enter values from a table or key them in yourself. In Figure 6, the values California, Nevada, and Utah are from the States table. The value Oregon was entered in the textbox. Using either method, you need to click the mover button to add the item to the default values list. To add a description for each value, highlight the value in the list, and then click Define description to display the Define Description dialog box (See Figure 7).
Figure 7. Enter a description for each parameter value in the Define Description dialog box.
Chapter 6: Advanced Reporting
139
You can also import values from a text file. The file format is one value per line. If you provide a description, it is the second item on the line, separated from the value by a tab. When you import a pick list, the contents is added to the Default Values list. Once you enter the default values, you can set a number of options. The first determines the minimum and maximum length of the value. Next is an Edit mask. If you use an edit mask, the minimum and maximum length prompts are disabled. Table 1 lists the edit mask characters. Entry required means you must enter a value for the parameter when prompted. Table 1. Valid edit mask characters. Character(s)
Entry required?
Description
A a 0 9 # L ? & C .,:;-/
Yes No Yes No No Yes No Yes No No
< > \
No No No
Password
No
Any alphanumeric character Any alphanumeric character Any digit Any digit or space Any digit or space or the plus or minus sign Any letter Any letter Any character or space Any character or space Literals. Character inserted into the parameter at the location specified. Following characters converted to lowercase Following characters converted to uppercase Literal. Following character inserted into the parameter at the location specified. Makes the parameter password masked.
Next you determine what to display in the pick list. The options are Value and description or Description. Finally, you set the sort order and whether it is determined by the value or the description. After you set all the parameter options, click OK to return to the Create Parameter Field dialog box. In Chapter 10, “The RDC: Manipulating Data,” I show you how to use report parameters at runtime.
Report alerts Report alerts notify the user when a specified condition exists. For example, you may have a sale over specific amount and want to notify the user. Chapter 10, “The RDC: Manipulating Data,” shows how to use alerts at runtime. The following steps show you how to set up an alert and use it in the designer. 1.
Once you design your report, select Report | Alerts | Create or Modify Alerts from the menu. The Create Alerts Dialog displays (see Figure 8).
140
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 8. The Create Alerts window is where you add a new alert or select an existing alert to modify. 2.
Click New to display the Create Alert dialog box (see Figure 9).
Figure 9. Use the Create Alert dialog box to name an alert and enter the alert message. 3.
Enter the Name of the alert.
4.
Enter the alert Message. This message displays to the user when the alert is triggered.
Chapter 6: Advanced Reporting 5.
141
Click Condition to open the Formula Workshop (see Figure 10). Formulas are discussed in detail in Chapter 8, “Using Formulas.”
Figure 10. Enter the alert condition in the Formula Workshop. 6.
Click Save and Close to return to the Create Alert dialog box.
7.
Click OK to save the alert and return to the Create Alerts dialog box.
8.
Click Close.
When you run the report, if the condition exists, the alert displays (see Figure 11). Click View Records to add a tab to the designer containing the records that meet the alert criteria.
142
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 11. When the alert condition is met while running the report, the Report Alerts dialog box displays.
OLE objects You have already seen OLE objects in the form of images. However, it is possible to use files from other applications. For example, you can embed a Word document or an Excel spreadsheet in a report. The following steps guide you through adding a document. 1.
Select Insert | OLE Object from the Crystal Reports menu. The Insert Object dialog box appears (see Figure 12).
2.
To add a new object, select the Object Type. When you click OK, the application assigned to the object type launches.
3.
To add an existing object, click Create from File. The Insert Object dialog box changes allowing you to enter the file name (see Figure 13).
4.
You have the option of linking or embedding the object. To link the object, select Link. When an object is linked, any changes to the original document reflect in the report. If you embed the object (clear the Link option), the contents of the original object always prints on the report.
5.
To display only an icon of the object, select Display as Icon.
6.
Click OK to close the Insert Object dialog box.
7.
Drop the object on the report. Figure 14 shows an Excel spreadsheet embedded on a report.
Chapter 6: Advanced Reporting
Figure 12. Add a new OLE Object from the Insert Object dialog box.
Figure 13. Add an existing object from the Insert Object dialog box.
143
144
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 14. When you add an OLE object to a report, its contents display in the Designer. If you double-click the object in the designer, Crystal Reports uses in-place editing to modify the report. For example, if you double-click the Excel spreadsheet in Figure 14, the menus and toolbars would change to those of Excel. When you double-click the object in Preview, the appropriate application launches with the data. Again, using Figure 14, Microsoft Excel launches with the spreadsheet from the report.
Embedded fields In Chapter 2, “Touring Crystal Reports,” I briefly mention the ability to embed RTF and HTML text in a field in the database. I call these embedded fields. The ability to have preformatted text adds a lot of power to Crystal Reports. Once you drop text or a memo field on a report, set the Text Interpretation on the Paragraph tab of the Format Editor (see Figure 15).
Chapter 6: Advanced Reporting
Figure 15. Set Text Interpretation to use embedded HTML or RTF. Crystal Reports only supports the following HTML tags and attributes: html body div tr span font p br
h1 h2 h3 h4 h5 h6 center big
small b i s strike u align face
size color style font-family font-size font-style font-weight
145
146
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Hierarchical reports Sometimes you need to show related data from the same table. For example, you may want a report that lists each supervisor and their employees. This is called a hierarchical report. Crystal Reports treats this as a special type of grouping. The following steps demonstrate how to create a hierarchical report. 1.
Create a new blank report.
2.
In the Database Expert, select the Extreme database that ships with Crystal Reports. This is a Microsoft Access database.
3.
Select the Employee table from the database.
4.
Close the Database Expert.
5.
Create a new group with EmployeeID.
6.
Drag the Employee ID, Last Name, and First Name fields to the Group Header section.
7.
From the menu, select Report | Hierarchical Grouping Options. The Hierarchical Options dialog box displays (see Figure 16).
Figure 16. Use the Hierarchical Options dialog box to create hierarchical groupings. 8.
Select Sort Data Hierarchically.
9.
Select Employee.Supervisor ID as the Parent ID Field.
10. Enter 0.5 for the number of inches for the Group Indent. 11. Click OK to save the hierarchical options.
Chapter 6: Advanced Reporting
147
12. Preview the report (see Figure 17). You should see each supervisor listed with their employees indented underneath.
Figure 17. A preview of the hierarchical grouping report.
Summary Crystal Reports provides a number of advanced features you won’t use all the time, but they are great time savers that offer a lot of power when you need them. From what I have shown in the chapter, you will most likely use report parameters the most because they are useful in record selection criteria, filtering, sorting, grouping, and many other places. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
148
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 7: Subreports
149
Chapter 7 Subreports Some reporting needs are very complex. In fact, they can be so complex a single report doesn’t provide all the information. You can solve this with multiple reports or you can use subreports to make the report seem like one report.
Subreports are one of the most powerful features in Crystal Reports. Basically, a subreport is a report embedded in another report. A subreport is just like a regular report except it is inserted in another report. You use a subreport to: •
Combine unrelated data into a single report.
•
Print the same data in different ways.
•
Combine data not easily related in other ways.
•
Do a one-to-many lookup from non-indexed data.
Crystal Reports supports two types of subreports, linked or unlinked. A linked subreport connects to the data in the parent report. The parent report drives the data in the linked report. In an unlinked report, the data is not connected in any way to the main report. Subreports can also be set to always print or you can have them only print on demand.
Inserting a subreport Subreports are created in two ways. You can use an existing report or create one to embed in the main report. The following steps explain how to add subreport. 1.
Select Insert | Subreport from the Crystal Reports menu or click Insert Subreport on the Insert Tools toolbar. The Insert Subreport dialog box (see Figure 1) displays.
2.
To use an existing file, select Choose a report and enter the file name or click Browse to select the report file.
3.
To create a new subreport, select Create a subreport and enter the subreport name. Click Report Wizard to begin designing the new subreport.
4.
To create an on-demand subreport, select the On-demand subreport check box. Ondemand subreports are discussed later in this chapter.
5.
When you finish selecting all the proper settings, click OK to save them. The Link page is explained in the “Linked subreports” section later in this chapter.
6.
Drop the subreport into any section on a report. The designer adds a new view for the subreport. The subreport displays as a rectangle in the report designer.
150
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 1. You specify the subreport in the Insert Subreport dialog box. When you create a new subreport, a new RPT file is not created. Instead, the subreport exists only in the main report. If you close the tab for the subreport, double-click it in the designer to edit it. If you choose an existing report file, the subreport is embedded in the main report. The reports are not linked, meaning if you make changes to the subreport, they will not be reflected in the original RPT file and vice-versa. I recommend making any changes to the original RPT file and then right-click the subreport in the main report and select Re-import subreport from the shortcut menu to bring the changes into the subreport.
Unlinked subreports The easiest way to add a subreport is to add an unlinked one. An unlinked subreport is independent from the main report. An unlinked subreport can also use a different data set from the main report. Figure 2 shows a sales report by country. However, the report requirements specify including a summary by country at the end of the report. The following steps show you how to add the subreport.
Chapter 7: Subreports
151
Figure 2. A sales report totaled by country. 1.
Select Insert | Subreport from the menu or click the Insert Subreport button on the Insert Tools toolbar.
2.
In the Insert subreport dialog box, select Create a subreport and enter “Sales Summary” for the report name. Because this subreport is added directly to the main report, there is no separate Sales Summary.RPT.
3.
Click the Report Wizard button. The Data page of the Standard Report Creation Wizard displays.
4.
Select the Customer table from the Available Data Sources list (see Figure 3). Click Next to display the Fields page.
152
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 3. Select the table for the subreport on the Data page of the Standard Report Creation Wizard. 5.
Select the fields Customer.Country and Customer.Last Year’s Sales (see Figure 4). Click Next to display the Grouping page.
Chapter 7: Subreports
Figure 4. Select fields for the subreport on the Fields page of the Standard Report Creation Wizard. 6.
On the Grouping Page (see Figure 5), select Customer.Country.
153
154
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 5. Select the grouping field on the Grouping page. 7.
Click Next to display the Summaries page (see Figure 6). You can see Crystal Reports already selected Last Year’s Sales field to be summed.
Chapter 7: Subreports
155
Figure 6. Use the Summaries page of the Standard Report Creation Wizard to create summaries for the subreport. 8.
Even though there are more steps in the Wizard, this is the last step you need to do for this example. Click Finish to return to the Insert Subreport dialog box.
9.
Click OK to close the Insert Subreport window and return to the designer. Drag the subreport into the Report Footer section of the main report (see Figure 7). A new tab, reflecting the subreport, is added to the designer.
156
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 7. A view of the designer after adding the subreport. 10. Preview the report. The subreport has details for each detail in the main report. The spec did not call for this. Perhaps it would have been better to cancel out of the Standard Report Creation Wizard and create the report from scratch. You may want to keep this in mind when you create your own subreports. Because we already created the subreport, it’s now easier to modify it rather than create it from scratch. 11. Select the Sales Summary tab in the designer. 12. Remove all the objects from the Group Header and Report Footer bands and the Print Date from the Report Header. 13. Delete the objects in the Details band. Deleting the objects removes column headings. You can add them back or choose to suppress the Details band. 14. Select Last Year’s Sales in the Group Footer and then remove the top and bottom border. 15. Shrink the height of all the bands to minimize white space. 16. Preview the subreport (see Figure 8). The subreport now prints the correct information.
Chapter 7: Subreports
157
Figure 8. The subreport, after adjusting the formatting.
Linked subreports In a linked subreport, the data for the subreport is linked to the data in the main report. To add a linked subreport, use the Link tab of the Insert Subreport window. When you link a subreport, Crystal Reports automatically does several things: •
Adds a parameter field to the subreport. This parameter field passes values from the main report to the subreport.
•
Adds a record selection formula to the subreport. This formula uses the parameter field to select the data for the subreport.
•
Prints in the subreport only the records that meet the selection formula.
The following steps show how to add a linked subreport. 1.
Create a report based on the Customer table in the Extreme Access database. Place the Customer Name, City, and Country fields in the Details band.
2.
Stretch the details band so there is additional white space below these fields. You can optionally insert a new section in the band. You will put the subreport into this area.
158
CrysDev: A Developer’s Guide to Integrating Crystal Reports 3.
Select Insert | Subreport from the menu or click Insert Subreport on the Insert Tools toolbar. The Insert Subreport dialog box displays.
4.
Verify the Create a subreport check box is selected, and then enter “Sales” for the Report Name.
5.
Click Report Wizard to display the Standard Report Creation Wizard.
6.
Select the Orders table from the Extreme database.
7.
Click Next to display the Fields page.
8.
Select the fields Order.Order ID, Orders.Order Date, Orders.Order Amount.
9.
Click Finish to close the Standard Report Creation Wizard and return to the Insert Subreport dialog box.
10. Click the Link tab to display the page (see Figure 9).
Figure 9. Link the subreport data to the main report using the Link tab of the Insert Subreport dialog box. 11. Select Customer.Customer ID from the Available Fields list. The value of this field passes to the selection criteria formula in the subreport.
Chapter 7: Subreports
159
12. Crystal Reports creates a new parameter to use to pass the value. This is shown under Subreport parameter field to use. If you have additional parameters in the subreport, they are available in the drop-down list. This makes it possible for you to create your own parameter field. 13. Verify the Select data in subreport based on field check box is selected and the linking field for the subreport is selected. 14. Click OK to close the window. 15. Put the subreport into the space in the Details band below the fields. 16. Preview the report (see Figure 10) to see the sales for each customer below their entry. You may want to format the data in the subreport so it prints correctly.
Figure 10. Previewing the linked subreport shows the matching sales information for the customer.
On-demand subreports On-demand subreports do not print until you request them. To make an on-demand subreport, select On-demand subreport in the Insert Subreport dialog box (see Figure 1). I changed the unlinked report from earlier in this chapter to be a linked, on-demand subreport. The link displays as a hyperlink when you preview the report (see Figure 11).
160
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 11. An on-demand subreport displays as a hyperlink in the main report. To display the subreport, click the link. A new Preview tab is added to the designer. You can then print the subreport. One important difference between a regular subreport and an on-demand subreport is the data is not saved in an on-demand report. This means to print or preview the on-demand subreport, you must have a connection to the database because the data is queried at the time you request the report.
Updating subreports When you insert a subreport from an existing RPT file, it places a copy of the report in the main report. This means if you update the subreport file, you may need to update the copy of the file in the main report. It is not necessary to update subreports created in the main report. You can update a subreport a number of ways: •
In the designer, right-click the subreport and select Re-import subreport from the shortcut menu. This immediately updates the subreport.
•
Select Re-import When Opening on the Common tab of the Format Editor dialog box (see Figure 12) of the subreport. This automatically re-imports the subreport whenever it is opened in the editor. This setting only affects a single subreport.
Chapter 7: Subreports
161
Figure 12. Select Re-import When Opening in the Format Editor to automatically reimport the subreport when you open it. •
Finally, you can select Re-import Subreport When Opening Reports on the Reporting tab of the Options dialog box (see Figure 13). This is a global setting and affects all subreports.
162
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 13. Select Re-import Subreport When Opening Reports in the Options dialog box to automatically re-import any subreports when you open a report.
Summary Subreports are one of the most powerful features of Crystal Reports. By using subreports you can print related data in a different format or unrelated data on the same report. Remember, though, it is necessary to re-import updated subreports based on existing report files. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
Chapter 8: Using Formulas
163
Chapter 8 Using Formulas Crystal Reports provides extensive formula capabilities to enhance the calculations, conditions, and functions you use in a report. In this chapter, you will learn how to utilize these formulas.
Throughout this book, I have talked about formulas. Formulas can perform calculations, conditional branching, formatting, record selection, and more. Crystal Reports 9 also introduces a new type of formula, Custom Functions. Crystal Reports provides a very powerful formula language that allows for calculations, comparison, branching, use of built-in functions, and more. There are several places in Crystal Reports where you can enter formulas, but there are two basic types of formulas. The first causes conditional formatting and printing. To enter a formatting formula, click the formula button where ever it is available. Figure 1 shows the Format Editor. The formula button has a picture of a pencil and the text x + 2. Entering a formatting formula causes the picture on the button to change. For example, the Suppress option’s formula button in Figure 1 has a formula behind it.
164
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 1. Click the formula buttons to enter formatting formulas. When you click a formula button, the Formula Workshop opens. The Formula Workshop is discussed later in this chapter. The second way to enter a formula is by using a formula field. To add a formula field, select Formula Fields in the Field Explorer (see Figure 2) and click the New button.
Chapter 8: Using Formulas
165
Figure 2. Use the Field Explorer to add a new formula field. When you add a new formula field, it prompts you to enter the formula name (see Figure 3), and then you must decide if you want to use the Formula Expert or the Formula Editor to enter the formula.
Figure 3. You must enter a formula name before you create a new formula field.
The Formula Editor Most of the time, you will use the Formula Editor (see Figure 4) to enter a formula. The Formula Editor is just one view of the Formula Workshop. The other view is the Formula Expert (discussed later in this chapter).
166
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 4. The Formula Editor view of the Formula Workshop is where you enter most of your formulas. The Formula Editor is divided into several areas: •
At the top is what looks like a single toolbar, but is actually three toolbars; the General toolbar, the Workshop toolbar, and the Custom Function toolbar. These toolbars are available in both the Formula Editor and Formula Expert views.
•
On the left is the Workshop Tree. The Workshop Tree is available in both the Formula Editor and the Formula Expert views. You can dock the Workshop Tree at either the left or right side of the Formula Workshop. You can also have it undocked and floating on the Crystal Reports design surface by dragging it away from the sides.
•
The second toolbar, the Formula Editor toolbar, is only available in the Formula Editor.
•
Next to the Workshop Tree is the Field Tree. From this tree, you select database fields to include in the formula. You can dock the Field Tree or it can float on the design surface.
•
The middle control is the Function Tree. Functions are discussed later in this chapter. You can dock the Function Tree or it can float on the design surface.
•
The Operator Tree on the right lists the various operators available. Operators are discussed later in this chapter. You can also dock the Operator Tree or it can float on the design surface.
Chapter 8: Using Formulas •
167
The last area is the editor itself. This is where you enter the formula or as you make selections from the different trees, you see items entered automatically for you.
This chapter explains each area.
The General toolbar The General toolbar (see Figure 5) has the following functions corresponding to the buttons, from left to right.
Figure 5. The Formula Workshop’s General toolbar groups the general functions. •
Close—closes the current formula after prompting you to save any changes made to the current formula.
•
New—creates a new formula. Alternatively select the arrow next to the new button to add a new Formula, Custom Function, Formatting Formula, Record Selection Formula, or Group Selection Formula.
•
Rename—allows you to rename the selected formula in the Workshop Tree.
•
Delete—deletes the selected formula in the Workshop Tree.
The Workshop toolbar The Workshop toolbar (see Figure 6) has the following functions, from left to right.
Figure 6. The Workshop toolbar affects how the Workshop Tree displays. •
Hide/Show Workshop Tree—toggles display of the Workshop Tree
•
Expand/Collapse node—expands or collapses the selected node in the Workshop Tree.
•
Show formatting formula nodes only—toggles display of items in the Formatting formulas folder with or without formulas attached.
168
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The Custom Function toolbar The Custom Function toolbar (see Figure 7) has the following functions, from left to right.
Figure 7. The Formula Workshop’s Custom Functions toolbar provides quick-add custom functions to the report or repository. •
Toggle properties display—toggles between the Custom Function editor and the Custom Function Properties dialog box. Custom functions are discussed later in this chapter.
•
Add to Repository—adds the custom function to the Repository.
•
Add to Report—adds the custom function to the report.
The Workshop Tree The Workshop Tree (see Figure 8) shows the available formulas and report objects. To edit one of the formulas, expand the formula category in the tree, and then select the formula you want to edit.
Chapter 8: Using Formulas
169
Figure 8. The Workshop Tree contains the formulas and report objects available to the current report.
The Editor toolbar The Editor toolbar (see Figure 9) provides the following functions, from left to right.
Figure 9. A view of the Editor toolbar. •
Save—saves the current formula. It notifies you if any errors are found in the formula and asks if you still want to save. Alternatively press Alt+S to save the formula.
•
Check—validates the current formula. Alternatively press Alt+C to check the formula.
170
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Undo—undoes the last change.
•
Redo—reapplies the last undo.
•
Browse Data—displays data from the currently selected field in the Field Tree.
•
Find or Replace—displays the Find dialog box (see Figure 10) to find and Alternatively replace text.
Figure 10. Use the Find dialog box to find and optionally replace specific items in the Formula Editor. •
Toggle Bookmark—toggles a bookmark on or off on the current line of the editor. Alternatively press Ctrl+F2 to toggle a bookmark.
•
Next Bookmark—moves the insertion point to the beginning of the next bookmarked line. Alternatively press Ctrl+Alt+F2 to move to the next bookmark.
•
Previous Bookmark—moves the insertion point to the beginning of the previous bookmarked line. Alternatively press Shift+F2 to move to the previous bookmark.
•
Clear All Bookmarks—removes all bookmarks in the current formula. Alternatively press Ctrl+Shift+F2.
•
Sort Trees—toggles the sorting of items in the Field, Function, and Operator Trees. Alternatively press Ctrl+O.
•
Field Tree—toggles the display of the Field Tree. Alternatively press Alt+F.
•
Function Tree—toggles the display of the Function Tree. Alternatively press Alt+U.
•
Operator Tree—toggles the display of the Operator Tree. Alternatively press Alt+P.
Chapter 8: Using Formulas
171
•
Syntax—selects the syntax language for the formula. You can choose to use Crystal syntax or Basic syntax. These are explained later in this chapter. Alternatively press Ctrl+T.
•
Comment/Uncomment Selected Text—either adds a comment or removes a comment on the selected text in the editor. Alternatively press Alt+M.
•
Use Expert—changes the Formula Workshop to use the Formula Expert instead of the Formula Editor. Alternatively press Alt+X.
The Field, Function, and Operator Trees are explained later in this chapter.
Understanding formulas Crystal Reports formulas are basically short programs. Two formula languages are supported, Crystal syntax and Basic syntax. Basic syntax closely resembles Visual Basic. While you may be more familiar with Basic, it is important you understand both, as you may have to support reports that use Crystal syntax. It doesn’t matter which formula language you choose, just keep in mind you cannot mix languages in a single formula. You set the default formula language on the Reporting tab of the Options dialog box. As you create formulas, you can directly enter the code into the Formula Editor or select fields, operators, and functions from the available lists. You can also use the Formula Expert to walk you through the formula. Lines using Crystal syntax can terminate with a semicolon, but it is not required. However, I recommend you do so, as it makes the code easier to read. Basic syntax terminates a line with a carriage return.
Comments Comments written using Crystal syntax begin with a double slash (//). You can enter a comment on a line by itself or at the end of a line. // This is a comment “Hello” // This is also a comment
Basic syntax comments use an apostrophe. Just like Crystal syntax, the comment can be on a single line or after a statement at the end of a line. ‘ Here is a Basic syntax comment “Crystal Reports rocks” ‘ Another comment
You can also select any number of lines and click the Comment/Uncomment Selected Text button on the Formula Editor toolbar or press Alt+M to comment the highlight text.
Data Types Crystal Reports formulas support several data types. I organized these into three categories: simple, range, and array.
172
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Simple data types Simple data types are the easiest to use. •
Number—basic numbers like 34 or 4.237.
•
Currency—indicated with a dollar sign. For example, $12.34.
•
String—delimit strings with either single or double quotes in Crystal syntax and double quotes in Basic syntax. For example: “Today is Friday.”
•
Boolean—the two values are True and False.
•
Date—defines a specific date. For example, #12/25/2002#, #25 Dec 2002#, and #December 25, 2002# all designate the same date.
•
Time—specify time using the same delimiters as a date. For example, #8:04 pm# and #20:04# both define the same time.
•
DateTime—you can also mix date and time to create a DateTime. For example, #12/25/2002 8:04 pm# or #25 Dec 2002 20:08#.
Range data types Range data types are a bit difficult to understand and look quite strange when you first see them. You use range types to specify a range of values, for example from 5 To 30. You can use ranges with any simple data type except Boolean. The underscore on a range means to exclude the top or bottom number in the specified range. You specify a range using either Crystal or Basic syntax. The range types are: •
To
•
_To
•
To_
•
_To_
•
UpTo
•
UpTo_
•
UpFrom
•
Is <—this is the same as UpTo_, the preferred type in Crystal syntax. Is < is preferred in Basic syntax.
•
Is <=—the same as UpTo, the preference in Crystal syntax. Is <= is preferred in Basic syntax.
•
Is >—the same as UpFrom_, the preferred statement in Crystal syntax. Is > is preferred in Basic syntax.
Chapter 8: Using Formulas •
173
Is >=—the same as UpFrom, the preference in Crystal syntax. Is >= is preferred in Basic syntax.
Here are some examples: 5 To 90; // All numbers beginning with 5 and ending with 90 5 _To 90; // All numbers beginning with 6 and ending with 90 5 To_ 90; // All numbers beginning with 5 and ending with 89 5 _To_ 90; // All numbers beginning with 6 and ending with 89 UpTo 90; // All numbers up to and including 90 UpTo 90; // All numbers up to, but excluding 90 UpFrom 90; // All numbers higher than and including 90
You can perform operations on a range using the In keyword to determine if certain values are in the range. 5 In 5 To 10; // Returns True because 5 is in the range from 5 to 10 5 In 5 _To 10; // Returns False because 5 is not in the range from 6 to 10
Array data types Crystal Reports support one-dimensional arrays, which can contain any data type. Using Crystal syntax, you define arrays with brackets and separate each element with a comma. For example: [1, 2, 3, 4, 5]; [“Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”]; [#January 1, 2002#, #April 1, 2002#, #July 1, 2002#, #October 1, 2002#];
You reference a particular element of an array by placing the element number in brackets after the array. [5, 10, 15, 20, 25][2]; // Return the second element, which is 10 [5, 10, 15, 20, 25][2 To 4]; // Returns a new array with the second to // fourth elements of the original array, which is [10, 15, 20]
Referening a particualar element is similar to Crystal syntax: (5, 10, 15, 20, 25)(2) ‘Return the second element, which is 10 (5, 10, 15, 20, 25)(2 To 4) ‘Returns a new array with the second to ‘ fourth elements of the original array, which is (10, 15, 20)
174
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Variables Variables can be of any simple, range, or array data type and have three scoping levels: •
Global—visible through the entire report. This is the default scoping level.
•
Local—visible only in the formula where defined.
•
Shared—visible to the report and any subreports.
Before using a variable, you need to declare its scope and type. // Crystal Syntax Local StringVar Name; Shared DateVar Birthday; Local BooleanVar ReturnValue; Global NumberVar Array Numbers; Redim Numbers [6]; ‘Basic Syntax Local Name As StringVar Shared Birthday As DateVar Dim ReturnValue As BooleanVar Global Numbers() As NumberVar Redim Numbers(6)
Note the use of Dim in the Basic syntax declarations. Dim is the same as Local. Once you declare a variable, you can use it in a formula. Using Crystal syntax, you assign a value to a variable with either an = or a :=. Basic syntax uses just the =. // Crystal Syntax Name := “John Smith”; Birthday := #February 22, 1950#; ReturnValue := True; Numbers := [5 To 9]; Numbers[6] := [10]; ‘Basic Syntax Name = “John Smith” Birthday = #February 22, 1950# ReturnValue = True Numbers = (5 To 9) Numbers(6) = 10
Fields There are several, different types of fields you can use in a formula. Each field type has a different syntax, but each field is enclosed in brackets. The syntax is the same for either Crystal or Basic syntax. You can enter the field directly or drag it from the Field Tree (see Figure 11) into the Formula Editor.
Chapter 8: Using Formulas
Figure 11. You can drag fields from the Field Tree into your formula. Database fields don’t have any special characters. {Customer.Customer ID} {Customer.Name} {Orders.Discount}
Parameter fields use a ? character. {?Country} {?Quarter}
Finally, you can refer to other formulas using the @ character. {@My First Formula} {@My Second Formula}
Operators Operators fall into categories like arithmetic (+, -, *, /), comparisons (>, >=. <>), control structures (if, do while), and others. In all, operators fall into 12 categories. •
Arithmetic
•
Conversion
175
176
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Comparisons
•
Strings
•
Ranges
•
Boolean
•
Arrays
•
Pattern
•
Control Structures
•
Other
•
Scope
•
Variable Declarations
You have already seen some of these such as scope and variable declarations. I will explain some of the others in this section and leave others for your own exploration. You can enter an operator directly or drag it from the Operator Tree (see Figure 12) to the Formula Editor.
Figure 12. You can drag an operator from the Operator Tree into your formula.
Chapter 8: Using Formulas
177
Arithmetic operators Use arithmetic operators to do math. The operators, in order of precedence, are: •
Exponents (^)
•
Negation (-)
•
Multiplication, Division, Percent (*, /, %)
•
Integer Division (/)
•
Modulus (Mod)
•
Addition, Subtraction (+, -)
Comparison operators Use comparison operators to compare one value to another. The comparison operators, in order of precedence, are: •
Equal (=)
•
Not Equal (<>)
•
Less Than (<)
•
Less Than or Equal (<=)
•
Greater Than (>)
•
Greater Than or Equal (>=)
Boolean operators Boolean operators change the way comparison operators work. The Boolean operators, in order of precedence, are: •
Not (Not)
•
And (And)
•
Or (Or)
•
Exclusive Or (XOr)
•
Logical Equivalents (Eqv)
•
Logical Implication (Imp)
Logical Equivalents compares two logical values and returns true if both are true or both are false. Here are some examples
178
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Local BooleanVar x; Local BooleanVar y; x := true; y := true; x Eqv y; // Returns true x:= false; x Eqv y; // Returns false y := false x Eqv y; // Returns true
Logical Implication returns also compare two logical values. It returns true if both are true or both are false or the second value in the comparison is true. Local BooleanVar x; Local BooleanVar y; x := true; y := true; x Imp y; // Returns true x := false; x Imp y; // Returns false y := false; x Imp y; // Returns true
Control structures Control structures change the way the formula flows. These include branching and looping operators. If/Then/Else The If statement works like the If statement in other programming languages. This example shows how to use If/Then/Else with Crystal syntax. // Return 60% of the salary if employee is in the sales dept. If {Employee.Dept} = “Sales” Then {Employee.Salary} * 0.6 Else {Employee.Salary} * 1.6; // Return an increment of income based on current value of income Global NumberVar Income If Income >= 50000 Then Income + 5000 ElseIf Incomce >= 100000 Then Income + 10000 Else Income;
Chapter 8: Using Formulas
179
Here’s the same example using Basic syntax: ‘ Return 60% of the salary if employee is in the sales dept. If {Employee.Dept} = “Sales” Then {Employee.Salary} * 0.6 Else {Employee.Salary} * 1.6 End If ‘ Return an increment of income based on current value of income Global NumberVar Income If Income >= 50000 Then Income + 5000 ElseIf Incomce >= 100000 Then Income + 10000 Else Income End If
Select The Select statement is similar to the select, switch, or case statements of other programming languages. The first example shows Crystal syntax: Select {Employee.Income} Case 50000 To_ 100000 : Income + 5000 Case UpFrom 100000 : Income + 10000 Default : Income;
The same example using Basic syntax looks like: Select {Employee.Income} Case 50000 To_ 100000 Income + 5000 Case Is >= 100000 Income + 10000 Case Else Income End Select
For/Do For/Do loops a specified number of times. Using Crystal syntax, you have: Local DateVar Holiday := #July 4#; Local StringVar PrintMessage := “”; For i := 1 To 50 Do ( PrintMessage := PrintMessage + “Happy Independence Day! “ ) ;
180
CrysDev: A Developer’s Guide to Integrating Crystal Reports With Basic syntax, the code looks like:
Local Holiday As DateVar Local PrintMessage As StringVar Holiday = #July 4# PrintMessage = “” For i = 1 To 50 PrintMessage = PrintMessage && “Happy Independence Day! “ Next i
Do/While The Do/While loop runs until a condition evaluates to true. // Crystal syntax Do While i <= strLen And Result = -1 ( Local StringVar c:= intString[i] If NumericText(c) Then Result := i; i := i + 1; ); ‘ Basic syntax Do While i <= strLen And Result = -1 Local c As StringVar c = intString[i] If NumericText(c) Then Result = i End If i = i + 1 Loop
While/Do Crystal Reports formulas support a While/Do command. The While/Do does not exist in Basic syntax. While I <= strLen And Result = -1 Do ( Local StringVar c := inString[i] If NumericText(c) Then Result := i; i := i + 1; ) ;
Chapter 8: Using Formulas
181
Do Until/Loop The Do Until/Loop command only exists in Basic syntax. It continues looping until the condition evaluates to true. Dim i As NumberVar I = 0 Do Until i = 10 i = i + 1 Loop
Do/Loop While The Do/Loop While construct, which only exists in Basic syntax, is similar to the While/Do statement in Crystal syntax. Dim i As NumberVar I = 0 Do i = i + 1 Loop While i <= 10
Do/Loop Until The Do/Loop Until statement also exists only in Basic syntax. Dim i As NumberVar I = 0 Do i = i + 1 Loop Until i = 10
Option loop The Option loop is not really a loop, but it gives you control over how many times a formula performs a loop. By default, a loop performs a maximum of 100,000 times. Using the Option loop in either Crystal or Basic syntax, you can change this maximum. The Option loop must be placed before any other statements in the formula. Here’s an example using Crystal syntax. The Basic syntax looks similar. Option loop 100; Local NumberVar i := 0; Local NumberVar UpperLimit := 500; While I <= UpperLimit Do ( i := i + 1; ) ;
In this example, once the loop executes 100 times, an error message displays, indicating the loop executed more the maximum number of times allowed.
182
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Functions Crystal Reports has several functions you can include in your formulas. These fall into the following categories: •
Math –Value, sine, cosine, Pi, round, square root, and other mathematical functions.
•
Summary—standard deviation, sum, count, median, and other summary functions.
•
Financial—future value, internal rate of return, interest rate, payment, future value, and other financial functions.
•
Strings—functions that operate on strings such as length, trim, uppercase, lowercase, and so on.
•
Date and Time—set current date or time, extract the year, month, day from a specified date, get the month name, and other functions.
•
Date Ranges—perform functions on date ranges such as calculating the dates from the beginning of the month to the current day, dates over 90 days away, dates that fall in a specific quarter, and other functions.
•
Arrays—manipulate arrays and to do things like calculate the sum, variance, average, count, minimum or maximum of the array elements.
•
Ranges—four functions to determine if the range has an upper and lower bound and if those bounds are included in the range.
•
Type Conversion—convert data from one type to another.
•
Programming Shortcuts—choose one value from a list, immediate if (IIF), or a single line switch statement.
•
Evaluation Time—force Crystal Reports to run a formula during a specific report pass. Functions include BeforeReadingRecords, WhileReadingRecords, WhilePrintingRecords, or you evaluate the formula after another formula executes.
•
Print State—evaluate data or get information about the print job. For example, you can get the current page number, total page count, or page n of m. You can also find out if you are on the first or last record, if a field is null, and several other printing conditions.
•
Document Properties—pull information from the report’s Document Properties dialog box.
•
Alerts—provide information about alerts. The three functions in this category are IsAlertEnabled, IsAlertTriggered, and AlertMessage, which returns the message for a specific alert.
•
Additional Functions—additional functions such as picture clauses, soundex, and many others. If you create COM components that provide additional functions, called User Function Libraries or UFLs, they are listed here.
Chapter 8: Using Formulas •
183
Custom Functions—lists any custom functions you add to a report. This node displays only if you add a custom function. Custom functions are discussed later in this chapter.
As the last two items indicate, you can create your own custom functions, discussed later in this chapter. You can also create COM components that display under Additional Functions. These special functions are discussed in Chapter 15, “Integrating COM Components.” To add a function to a formula, enter it directly into the editor or drag it from the Function Tree (see Figure 13).
Figure 13. You can drag functions from the Function Tree into a formula.
Custom Functions Custom functions give you the ability to add your own procedures to formulas. You cannot use custom functions directly in a report. However, you can use custom functions in a formula just like Crystal Report’s built in functions. You create custom functions like other formulas. Most of the operators and functions available for a formula are also available for custom functions. However, there are some differences: •
The function must begin with the word function, followed by a list of parameters enclosed in parentheses.
•
If you don’t provide a parameter list, you must still provide the parentheses.
184
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
You cannot use database fields.
•
You cannot access global or shared variables. However, you can pass them as parameters.
•
You cannot use recursion.
•
The Evaluation Time, Print State, and Document Properties functions along with the functions Rnd, CurrentFieldValue, DefaultAttribute, and GridRowCOlumnValue are not available.
To create a new custom function: 1. Select Report Custom Functions in the Workshop Tree of the Formula Workshop. 2.
Click New on the Formula Workshop’s General toolbar or press Ctrl + N. The Custom Function Name dialog box displays (see Figure 14).
Figure 14. Use the Custom Function Name to provide a name for a new custom function. 3.
Enter the Name for your custom function.
4.
Click Use Editor to create a new formula. The Formula Editor displays. Use Extractor is discussed later in this chapter.
5.
Enter the formula into the editor.
Function (StringVar StateAbbrev) Select StateAbbrev Case "CA": "California" Case "NY" : "New York" Case "TX" : "Texas" Default: StateAbbrev;
6.
Click Save on the Editor toolbar.
The new custom function displays in the Custom Function node of the Function Tree. You can now use it like any other Crystal Reports function as you see here.
Chapter 8: Using Formulas 1.
Create a new formula called FullRegion
2.
In the Formula Editor, expand the Custom Functions node in the Function Tree.
3.
Drag GetState onto the Editor.
4.
Enter the field {Customer.Region} as the parameter.
5.
Save the formula.
The Forumla Extractor When you create a new formula, one of the options is Use Extractor. The Extrator takes an existing formula and converts it to a function. 1.
Open the Formula Workshop.
2.
Select Report Custom Functions in the Workshop Tree.
3.
Click New to add a new custom formula.
4.
Enter the name GetState2.
5.
Click Use Extractor in the Custom Function Name dialog. The Extract Custom Function from Formula dialog box displays (see Figure 15).
Figure 15. Use the Formula Extractor to convert a formula to a custom function.
185
186
CrysDev: A Developer’s Guide to Integrating Crystal Reports 6.
Select the formula to extract in the list on the left side.
7.
You can modify the formula in the Formula Text area or change the order of the parameters.
8.
Click OK to save the changes.
The Formula Expert So far, you have seen how to create a formula using the Formula Editor. Crystal Reports also provides the Formula Expert to help you with a formula that uses a custom function. The following example creates a formula to use the custom function you created earlier in this chapter. 1.
Select Formula Fields in the Field Explorer.
2.
Click the New button on the Field Explorer toolbar and enter Texas as the name of the formula.
3.
Click Use Expert. The Formula Expert displays (see Figure 16).
Figure 16. The Formula Expert helps you create a formula based on an existing custom function. 4.
Expand the Report Custom Functions node in the Custom Function Supplying Logic tree.
Chapter 8: Using Formulas
187
5.
Select GetState2 from the custom function list.
6.
Click the Value field in the Function Arguments and select Enter Constant Value from the drop–down list.
7.
Enter TX as the value.
8.
Click Save. The new formula is ready to use.
To see the code the Formula Expert generates, click Use Editor. The Formula Editor displays (see Figure 17).
Figure 17. View the formula created by the Formula Expert in the Formula Editor.
Summary Crystal Reports formulas and custom functions give you the ability to add more functionality to your report. You can use Crystal or Basic syntax. The programming syntax gives you many of the capabilities of a full programming language such as variable scoping, logical comparisons, branching, and more. You can also convert formulas to custom functions using the Formula Extractor and use the Formula Expert to help you create Formulas. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
188
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 9: The RDC: Introduction, Printing, and Databases
189
Chapter 9 The RDC: Introduction, Printing, and Databases Now that you have seen many of Crystal Reports features, you may want to give end users these capabilities. This chapter begins exploring the runtime features of the Report Designer Component and shows you how to provide powerful reporting tools for your end users.
You are probably wondering when I am going to start discussing how to programmatically control Crystal Reports. After all, this is a book for developers, and developers like code. I do get to some code in this chapter, but before that, it’s necessary to discuss different runtime options. Historically, Crystal Reports has provided several ways to integrate reports into your application. •
Crystal Report Engine API. Introduced with Crystal Reports 3.0, this was the first available integration method. It is very low level and requires you use C API calls.
•
ActiveX Control. Using this method, you drop the Crystal Reports OCX onto a form in your application. It is a 16 and 32-bit OCX and was first introduced in Crystal Reports 4.5. The ActiveX control is simply a wrapper around the Report Engine API. Because of this, not all reporting functionality is exposed. The ActiveX control is not included in Crystal Reports 9.
•
Automation Server. This method, introduced with Crystal Reports 6.0, is also a wrapper around the Crystal Report Engine API. However, Crystal Decisions recommends you use the Report Designer Control.
•
Visual Component Library (VCL). If you are a Borland Delphi developer, you may want to look at this option.
•
Report Designer Component Runtime (RDC). This method is a full 32-bit automation server. It is completely rewritten with all the functionality exposed. I concentrate on the RDC throughout this book.
•
Java Beans controls. Introduced with Crystal Reports 9, they provide the same functionality as the RDC.
•
Crystal Reports .NET. This version of Crystal Reports ships with Microsoft Visual Studio .NET and is based on Microsoft’s .NET platform. It has been completely rewritten in C#. I explore the .NET version in more detail in Chapter 17, “Crystal Reports .NET.”
190
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Understanding the Report Designer Component The Report Designer Component (RDC) consists of five different components you can integrate into your application. You won’t use all five components in a single application, but choose the components to include based on the needs of your application. •
Report Designer – Designed for Visual Basic developers, the designer integrates into the VB 5.0 and 6.0 development environment.
•
Report Viewer – This component is embedded on a form to provide print preview capabilities in your application. It is discussed in detail in Chapter 12, “Previewing the Report at Runtime.”
•
Distributable Report Designer – Add this component to your application to give users the ability to design their own reports. See Chapter 13, “The Report Designer Control,” for a complete discussion of the embeddable designer.
•
Designer Runtime Library – An automation server you use for generating reports at runtime, it allows you to print and export reports. It should be used for client-side applications or on a server. It is contained in the file Craxdrt.dll.
•
Designer Design and Runtime Library – An automation server for printing and exporting reports. Use this library in conjunction with the distributable report designer. Because it is not thread-safe, only use this component on the client. It is contained in the file Craxddrt.dll.
One problem you will find when you start working with the RDC is Crystal Decisions’ documentation is wrong in many areas. To write this book, I used the supplied documentation along with COM object browsers and extensive testing to verify the material I present.
Getting started with RDC programming The RDC object model (Figure 1) consists of a number of objects and collections. This chapter explores the most commonly used objects. Subsequent chapters discuss the remaining objects and collections. Each object has several properties and methods. Some objects have additional events. Events are discussed in Chapter 15, “Integrating COM Components.”
Chapter 9: The RDC: Introduction, Printing, and Databases
191
Figure 1. Crystal Decisions provides the Report Designer Component object model in the Techref.pdf. (Copyright Crystal Decisions.)
192
CrysDev: A Developer’s Guide to Integrating Crystal Reports
some objects, methods, and properties of the RDC requires additional Using licensing from Crystal Decisions. These are mostly areas that allow you to
create a report programmatically. As you experiment with some of the objects, methods, and properties discussed in the next few chapters, you will find some generate the error message “Creation feature not enabled.” A Report Creation API license is needed to use these features or contact Crystal Decisions for information on a 30 day evaluation license. Licensing issues are discussed in more detail in Chapter 18, “Licensing and Distribution.”
Registering the runtime component Start by registering the Crystal Reports runtime with your development tool so Intellisense works. In Visual FoxPro, this is not required, but it makes development easier as all of the properties, events, and methods are shown as you work. In Visual Basic, registering the component not only gives you Intellisense, but it’s necessary so the component is bound to the application. Registering the runtime component in Visual FoxPro The following steps register Craxdrt.dll in the Visual FoxPro Intellisense Manager. 1.
Select Tools | Intellisense Manager from the menu.
2.
Click the Types tab (Figure 2).
Figure 2. Use the Types tab of the Intellisense Manager to enter object and data type information for Intellisense.
Chapter 9: The RDC: Introduction, Printing, and Databases 3.
193
Click Type Libraries to display the Type Library References dialog box (Figure 3).
Figure 3. Use the Type Library References dialog box to select COM libraries for Intellisense. 4.
Select Crystal Reports 9 ActiveX Designer Run Time Library from the Select References list.
5.
Click Done to close the Type Library References dialog box.
6.
Click OK to close the Intellisense Manager.
Now, open a new program window and type: LOCAL oCR AS CRAXDRT.Application oCR.
As soon as you hit the period, you should see a list of objects and methods available to the Crystal Reports runtime object. Registering the runtime component in Visual Basic The following steps register a reference to the runtime component in Visual Basic. 1. 2.
Select Project | References from the menu. In the References dialog box (Figure 4), select Crystal Reports 9 ActiveX Designer Run Time Library.
3.
Click OK to close the References dialog box.
194
CrysDev: A Developer’s Guide to Integrating Crystal Reports As you enter code, VB gives you a list of all the properties and methods available for the object you are working with.
Figure 4. Use the Visual Basic References dialog box to select a COM library for inclusion in a Visual Basic project.
Working with collections The Crystal Reports object model provides a number of collections that hold references to different objects. Collections in Crystal Reports are one-based rather than zero-based. Most collections have the same set of properties, as shown in Table 1. Table 1. Properties common to all RDC collections. Property
Type
Read Only
Description
Count Item Parent
Numeric Object Object
Y Y Y
The number of items in the collection Returns a reference to the object item specified Holds a reference to the parent object of the collection
Chapter 9: The RDC: Introduction, Printing, and Databases
195
In addition, many of the collections have methods to add and delete items. The parameters of the Add method differ for each collection and I will discuss them as I introduce the collection. The Delete method takes the index of the object to delete. For example, this code deletes the second item in the DataTables collection: oDB = oRpt.Database() oDT = oDB.Tables() oDT.Delete(2)
The Add and Delete methods always come in pairs, meaning if there is an Add method, there is an accompanying Delete method too.
The Application object At the top of the object hierarchy is the Application object. The Application object does not have any properties, but it does have several methods. The first thing you do when using the RDC is instantiate the application object. For example: loCRW = CREATEOBJECT(“CrystalRuntime.Application”)
This instantiates the most recent version of Craxdrt.dll. You can add a version number to instantiate a specific version of the server. Use this to ensure the proper version of the automation server is created. For example, to instantiate the 8.5 version, use the following line: loCRW85 = CREATEOBJECT(“CrystalRuntime.Application.8.5)
If you need to create the version 9 server, use this line: loCRW9 = CREATEOBJECT(“CrystalRuntime.Application.9)
Once you create an application object, you need to open a report. Opening and closing a report Crystal Reports gives you the ability to work with existing reports or programmatically create them from scratch. Usually, you open existing reports. Use the OpenReport method for this: loCRW.OpenReport(cRPTFile, [lExclusive]) cRptFile lExclusive
Character Logical
The fully qualified path of the report file. The .rpt extension is required. If True the report file is opened exclusive. Default is True (optional).
The OpenReport method opens the specified report and creates a reference to the report object. The following code shows how to instantiate the RDC, open a report file, and create the report object:
196
CrysDev: A Developer’s Guide to Integrating Crystal Reports
LOCAL loCRW AS CRAXDRT.Application LOCAL loRPT AS CRAXDRT.Report loCRW = CREATEOBJECT(“CrystalRuntime.Application”) loRpt = loCRW.OpenReport(“C:\CR\Sales by Region.RPT”)
Because the second parameter of the OpenReport method is not passed, the report file opens exclusive. time you instantiate the RDC, it increments an internal counter to track Each the number of instances running in memory. This was implemented to limit the number of simultaneous users on a website to five, which is the limitation of The Developer Edition of Crystal Reports. However, you may hit this number on a standard Win32 desktop application if you create multiple instances of the Application object. The solution is to only create the Application object once. You can call the OpenReport method as many times as you want. It is also possible to create a new, blank report. As you will see in this and subsequent chapters, Crystal Reports has a powerful object model that allows you to create a report using only code. loCRW = CREATEOBJECT(“CrystalRuntime.Application”) loRpt = loCRW.NewReport()
The NewReport method does not have any parameters. You save the report using the SaveAs method of the report object. oRPT.SaveAs(cRPTFile, nFormat) cRptFile nFormat
Character Numeric
The fully qualified path of the report file. The .rpt extension is required. The file format to use. cr70FileFormat = 1792 cr80FileFormat = 2048
If the report contains subreports, you get to the subreport with the OpenSubreport method. This method returns a Report object you treat as any other report object. oSubRpt = oRpt.OpenSubreport(cReportName) cReportName
Character
The name of the subreport
Closing a report is simply releasing the reference to the Report object. However, you can’t close a report while it’s processing, so it’s a good idea to check the CanClose method:
Chapter 9: The RDC: Introduction, Printing, and Databases
197
IF loCRW.CanClose() loRpt = NULL ELSE MESSAGEBOX(“Can’t close report while it is printing.”) ENDIF
The CanClose method returns True if the report file can be closed. The method returns false if the RDC is still printing the report. There are no parameters with the CanClose method. Supplying connection information As you learned in Chapter 4, “Accessing Data,” it is possible to connect to several data sources in a single report. To supply the Application object with user credentials, use the LogonServer method. oCRW.LogonServer(cDll, cServer, [cDatabase], [cUserId], [cPassword]) cDll
Character
cServer
Character
cDatabase
Character
cUserId
Character
cPassword
Character
The Crystal Reports DLL used to connect. For example, use Pdsobcd.dll to log on to ODBC databases. Non-SQL database drivers begin with Pdb (Pdb*.dll). SQL database drivers begin with Pds (Pds*.dll). The server to connect to. If you connect to an ODBC data source, this is the DSN. The value is case sensitive. Pass an empty string to keep the current setting. The database name. Pass an empty string to keep the current setting. (Optional) The user ID. Pass an empty string to keep the current setting. (Optional) The password. Pass an empty string to keep the current setting. (Optional)
You can optionally log on with the LogOnServerEx method. Using this method, you provide additional parameters such as connection string. oCRW.LogonServerEx(cDll, cServer, [cDatabase], [cUserId], [cPassword], ; [cServerType], [cConnectString]
198
CrysDev: A Developer’s Guide to Integrating Crystal Reports
cDll
Character
cServer
Character
cDatabase
Character
cUserId
Character
cPassword
Character
cServerType cConnectString
Character Character
The Crystal Reports DLL used to connect. For example, use Pdsobcd.dll to log on to ODBC databases. Non-SQL database drivers begin with Pdb (Pdb*.dll). SQL database drivers begin with Pds (Pds*.dll). The server to connect to. If you connect to an ODBC data source, this is the DSN. The value is case sensitive. Pass an empty string to keep the current setting. The database name. Pass an empty string to keep the current setting. (Optional) The user ID. Pass an empty string to keep the current setting. (Optional) The password. Pass an empty string to keep the current setting. (Optional) The database server type. (Optional) The connection string. (Optional)
Once you log on with either the LogOnServer or LogOnServerEx methods, you stay on until you log off or destroy the Application object. You log off with the LogOffServer method. oCRW.LogoffServer(cDll, cServer, [cDatabase], [cUserId], [cPassword]) cDll
Character
cServer
Character
cDatabase
Character
cUserId
Character
cPassword
Character
The Crystal Reports DLL used to connect. For example, use Pdsobcd.dll to log on to ODBC databases. Non-SQL database drivers begin with Pdb (Pdb*.dll). SQL database drivers begin with Pds (Pds*.dll). The server to connect to. If you connect to an ODBC data source, this is the DSN. The value is case sensitive. You can pass an empty string to keep the current setting. The database name. Pass an empty string to keep the current setting. (Optional) The user ID. Pass an empty string to keep the current setting. (Optional) The password. Pass an empty string to keep the current setting. (Optional)
If each data source uses the same logon information, you use the SetMatchLogonInfo method to tell the Application server to propagate that information to all database logins. oCRW.SetMatchLogonInfo(lSetLogon) lSetLogon
Logical
If True, sets logon information for all databases using the same logon credentials.
Miscellaneous Application object methods You get the version number of the Crystal Reports DLL you are using with the GetVersion method. This method has no parameters. oCRW.GetVersion()
Chapter 9: The RDC: Introduction, Printing, and Databases
199
Here’s an example: loCRW = CREATEOBJECT(“CrystalRuntime.Application”) ? TRANSFORM(loCRW.GetVersion(), “@0”) && Returns OxOOOOO900 for CR 9
The GetVersion method returns the version number in decimal. The TRANSFORM function converts the decimal value to hexadecimal to get the correct version number. Finally, you get information on the license status for the report creation API. This is used for license management purposes. lStatus = oCRW.GetLicenseStatus(nMaxLicences, cLicenseNo) nMaxLicenses cLicenseNo
Numeric Character
The maximum number of licenses The license number used for this instance
The GetLicenseStatus method returns True if the license is active and cLicenseNo is used when you call the method or False if the license is not active and you passed the license number.
The Report object The Report object is the workhorse of the RDC. You have already seen how to create the report object by opening an existing report or creating a new report. This object is used to create other objects, such as databases, areas, export options, and so on. You also use the report object to print and export your report data. Lastly, the report object has several events discussed in Chapter 15, “Integrating COM Components.” Printing the report A report isn’t much good if it can’t be printed, therefore printing is something users do a lot, and it is easy to do. Here is the code: * Instantiate the application object loCRW = CREATEOBJECT("CrystalRuntime.Application") * Open the report and create the report object loRpt = loCRW.OpenReport("Sales by Genre.RPT") * Set the page orientation loRpt.PaperOrientation = 2
&& crLandscape
* Print the report on the default printer loRpt.PrintOut(.F.)
Table 2 lists the report object properties used for printing. Definitions of the constants in the Description column are found in the RDC.h file available from the Hentzenwerke web site.
200
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 2. The report object has several properties that affect the printing of a report. Property
If True, a progress dialog box displays when the report prints.
Character Numeric
Y N
PaperSize
Numeric
N
The name of the printer driver the report uses. Gets or sets the paper orientation. crDefaultPaperOrientation crPortrait = 1 =0 crLandscape = 2 Gets or sets the paper size. Set a custom paper size with the SetUserPaperSize method. crDefaultPaperSize = 0 crPaperEnvelopeC65 = 32 crPaper10x14 = 16 crPaperEnvelopeDL = 27 crPaper11x17 = 17 crPaperEnvelopeItaly = 36 crPaperA3 = 8 crPaperEnvelopeMonarch crPaperA4 = 9 = 37 crPaperA4Small = 10 crPaperPersonal = 38 crPaperA5 = 11 crPaperEsheet = 26 crPaperB4 = 12 crPaperExecutive = 7 crPaperB5 = 13 crPaperFanFoldLegalGerm crPaperCsheet = 24 an = 41 crPaperDsheet = 25 crPaperFanFoldStdGerma crPaperEnvelope10 = 20 n = 40 crPaperEnvelope11 = 21 crPaperFanFoldUS = 39 crPaperEnvelope12 = 22 crPaperFolio = 14 crPaperEnvelope14 = 23 crPaperLedger = 4 crPaperEnvelope9 = 19 crPaperLegal = 5 crPaperEnvelopeB4 = 33 crPaperLetter = 1 crPaperEnvelopeB5 = 34 crPaperLetterSmall = 2 crPaperEnvelopeB6 = 35 crPaperNote = 18 crPaperEnvelopeC3 = 29 crPaperQuarto = 15 crPaperEnvelopeC4 = 30 crPaperStatement = 6 crPaperEnvelopeC5 = 28 crPaperTabloid = 3 crPaperEnvelopeC6 = 31
PaperSource
Numeric
N
PortName
Character
Y
PrintDate PrinterDuplex
DateTime Numeric
N N
PrinterName
Character
Y
PrintingStatus
Object
Y
Gets or sets the paper source. crPRBinAuto = 7 crPRBinLargeFmt = 10 crPRBinCassette = 14 crPRBinLower = 2 crPRBinEnvelope = 5 crPRBinManual = 4 crPRBinEnvManual = 6 crPRBinMiddle = 3 crPRBinFormSource = 15 crPRBinSmallFmt = 9 crPRBinLargeCapacity = crPRBinTractor = 8 11 crPRBinUpper = 1 Gets the printer port the report uses. Empty if using the default printer. Gets or sets the print date. Default is the current date. Gets or sets the printer duplexing option. crPRDPDefault = 0 crPRDPSimplex = 1 crPRDPHorizontal = 3 crPRDPVertical = 2 Gets the printer name the report uses. Empty if using the default printer. Creates a reference to the printing status object. See “PrintingStatus object” later in this chapter.
Chapter 9: The RDC: Introduction, Printing, and Databases
201
The PaperSize property allows for predefined paper sizes. If you are using a custom size, use the SetUserPaperSize method: oRpt.SetUserPaperSize(nLength, nWidth) nLength nWidth
Numeric Numeric
The length of the paper in pixels. The width of the paper in pixels.
The PrintOut method prints the report. The complete syntax is: oRpt.PrintOut([lPrompt], [nCopies], [lCollated], [nStartPage], [nStopPage]) lPrompt
Logical
nCopies lCollated nStartPage nStopPage
Numeric Logical Numeric Numeric
If True, a print dialog box (see Figure 5) displays before the report prints. Default is True. (Optional) The number of copies to print. (Optional) If True the pages are collated. (Optional) The first page to print. Default is page 1. (Optional) The last page to print. Default is the last page of the report. (Optional)
Figure 5. The Print dialog box displays using the PrintOut method of the Report object. You display the Print Setup dialog box (see Figure 6) by calling the PrinterSetup method: oRpt.PrinterSetup(nWindow) nWindow
Numeric
Pass 0 to display the dialog box in the main application window or an hWind handle to display the dialog box in a particular window. An error is generated if you don’t pass a parameter.
202
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 6. The Print Setup dialog box displays when you call the PrinterSetup method of the Report object. You programmatically select a particular printer with the SelectPrinter method: oRpt.SelectPrinter(cDriver, cPrinter, cPort) cDriver cPrinter cPort
Character Character Character
The printer driver for the specified printer The name of the specified printer The port name where the printer is attached
Finally, you cancel printing with the CancelPrinting method: oRpt.CancelPrinting()
This method does not have any parameters. PrintingStatus object The PrintingStatus object provides information about the current print job. You must create a reference to the object before you query its properties. To find out the total number of pages in a report: loPrintingStatus = loRpt.PrintingStatus() ? loPrintingStatus.NumberOfPages
Chapter 9: The RDC: Introduction, Printing, and Databases
203
The PrintingStatus object does not have any methods or events, only properties you can query. Table 3 lists the properties. Table 3. This table contains properties of the PrintingStatus object. Property
Gets the total number of pages. Gets the number of records printed. Gets the number of records read. Gets the number of records selected.
Object
Y
Progress
Numeric
Y
Returns a reference to the parent object. In this case, the report. Returns a value indicating the progress of the print job. crPrintingCancelled = 5 crPrintingHalted = 6 crPrintingCompleted = 3 crPrintingInProgress = 2 crPrintingFailed = 4 crPrintingNotStarted = 1
Formatting the report Crystal Reports gives you the ability to control just about every aspect of formatting. In Chapter 11, “The RDC: Formatting the Report,” you learn how to control each individual object (fields, lines, graphs, etc). To start, I will show you some formatting affecting a report as a whole. Table 4 lists the properties for margins. Table 4. This table contains the formatting properties of the report object. Property
Type
Read Only
Description
BottomMargin LeftMargin RightMargin TopMargin
Numeric Numeric Numeric Numeric
Y Y Y Y
Gets or sets the bottom margin in twips Gets or sets the left margin in twips Gets or sets the right margin in twips Gets or sets the top margin in twips
measurements in Crystal Reports are in twips. A twip is 1/20 of a point or Most 1/1440 of an inch. There are approximately 567 twips in a centimeter. This means a standard 8½ x 11 inch sheet of paper is 12240 x 15840 twips. This example creates a report object and sets a top and bottom margin of 1” and a left and right margin of ½”: loCRW = CREATEOBJECT(“CrystalRuntime.Application”) loRpt = loCRW.OpenReport(“C:\CR\Sales by Genre.RPT”) loRpt.TopMargin = 1440 loRpt.BottomMargin = 1440 loRpt.LeftMargin = 720 loRpt.RightMargin = 720
204
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Miscellaneous Report object properties The report object has several other properties you can use. For example, you can access the settings from the Document Properties dialog box or determine the type of report you are working with. Table 5 lists these other properties. Table 5. This table contains other properties of the Report object. Property
Type
Read Only
Description
Application ApplicationName Areas CanPerformGrouping OnServer CaseInsensitiveSQL Data ConvertDateTimeType
Object Character Object Logical
Y N Y Y
A reference to the Application object. The application name. A reference to the Areas collection. If True, does the report grouping on the server.
Logical
N
If True, SQL data in the report is not case sensitive.
Numeric
N
ConvertNullFieldTo Default
Logical
N
Database EnableAsynchQuery
Object Logical
Y N
EnableGeneratingData ForHiddenObject EnableParameter Prompting EnablePerformQueries Asynchronously EnableSelectDistinct Records ExportOptions FieldMappingType
Logical
N
Determines how DateTime data is converted. Possible values: crConvertDateTimeToDate crKeepDateTimeType = =1 2 crConvertDateTimeTo String = 0 If True, NULL values are converted to the default for the database. This value can only be set when the report is not formatted. A reference to the database object. If True, enables the asynchronous query option. This property is maintained for backwards compatibility. You should use EnablePerformQueriesAsynchronously. If True, generates data for suppressed objects.
Logical
N
If True, displays prompts for parameter fields.
Logical
N
Logical
N
If True, enables the asynchronous query option. This property is the same as EnableAnynchQuery. If True, enables the Select distinct records option.
A reference to the ExportOptions object Determines the type of field mapping used. Possible values: crAutoFieldMapping = 0 crPromptFieldMapping = crEventFieldMapping = 2 1 A reference to the FormulaFieldDefinitions collection. Determines the syntax of formula fields. crBasicSyntaxFormula = crCrystalSyntaxFormula 1 =0 A reference to the GroupNameFieldDefinitions collection. Gets or sets the group selection formula. A reference to the SortFields collection. If True, the report was saved with data. Displays the keywords saved in the Document Properties dialog box.
Chapter 9: The RDC: Introduction, Printing, and Databases
205
Table 5. (Continued) Property
Type
Read Only
Description
Kind
Numeric
Y
LastGetFormulaSyntax
Numeric
Y
NeedUpdatedPages
Logical
Y
NumberOfGroup PageEngine ParameterFields Parent
Numeric Object Object Object
Y Y Y Y
RecordSelection Formula RecordSortFields ReportAlerts ReportAuthor
Character
N
Returns the kind of report. crColumnarReport = 1 crMultiColumnReport = 0 crLabelReport = 2 Returns the formula syntax of the last formula text used. crBasicSyntaxFormula = crCrystalSyntaxFormula 1 =0 If true, the user needs to update pages because the report changed. Returns the number of groups in the report. A reference to the PageEngine object. A reference to the ParameterFieldDefinitions collection. A reference to the parent object. In this case, the Application object. The formula to use for selecting records.
Object Object Character
Y Y N
ReportComments
Character
N
ReportSubject
Character
N
ReportTemplate
Character
N
ReportTitle
Character
N
RunningTotalFields SavePreviewPicture
Object Logical
Y N
Sections SQLExpressionFields
Object Object
Y Y
SummaryFields UseIndexForSpeed
Object Logical
Y N
VerifyOnEveryPrint
Logical
N
A reference to the RecordSortFields collection. A reference to the ReportAlerts collection. The name of the report author. This option is from the Document Properties dialog box. The report comments. Retrieved from the Document Properties dialog box. The report subject. Retrieved from the Document Properties dialog box. The report template. Retrieved from the Document Properties dialog box. Title of the report. Retrieved from the Document Properties dialog box. A reference to the running total fields collection. If True, stores the preview picture with the report. Retrieved from the Document Properties dialog box. A reference to the Sections collection. A reference to the SQLExpressionFieldDefinitions collection. A reference to the SummaryFieldDefinitions collection If True, uses local indeces to speed report production for non-SQL data. If True, checks the database schema saved with the report against the schema of the actual database.
The Report object also has three miscellaneous methods. The first is the AutoSetUnboundFieldSource. This method automatically binds unbound fields in the report to database fields. Unbound fields are most often found in ADO record sets. Here’s the syntax: oRpt.AutoSetUnboundFieldSource(nMatchType, [lBindSubReports]) nMatchType
Numeric
The type of matching to use. Possible values: crBMTName = 0 crBMTNameAndValue = 1
206
CrysDev: A Developer’s Guide to Integrating Crystal Reports
lBindSubReports
Logical
If True, automatically binds data to subreports.
The GetNextRows method returns the specified number of rows from a row set of the Crystal Data Object. oRpt.GetNextRows(nStart, nRowCount) nStart nRowCount
Numeric Numeric
The first row to read The number of rows to read
The last method of the Report object is ReadRecords. This method forces Crystal Reports to read data from the database. It has no parameters. oRpt.ReadRecords()
The Database object When you design your report, Crystal Reports saves the location of the data files or server log on information as part of the report information. Almost certainly, the location will change at runtime, whether it is file or server based data. This requires you change the location in the report. Sometimes you may even generate the data on the fly and save it to a temporary table. The primary object used for accessing data is the Database object. You instantiate the Database object from the report object: oDB = oRpt.Database()
The properties of the Database object are listed in Table 6. I discuss the Database object methods throughout this section. Table 6. This table contains properties of the Database object. Property
Type
Read Only
Description
Links
Object
Y
Parent Tables
Object Object
Y Y
Gets a reference to the Links (relations) collection. See “The Links collection” later in this chapter. Gets a reference to the parent object (the report). Gets a reference to the Tables collection.
Once you have a reference to the Database object, you may need to provide connection and logon information. Earlier in this chapter, you saw how to use log on using the methods of the Application object. Exactly like the Application object the Database object also provides Logon, LogonEx, and Logoff. The Database object has four additional methods; AddADOCommand, AddOLEDBSource, SetDataSource, and Verify. Use the AddADOCommand method to add a new table to an ADO object used as a report data source.
Chapter 9: The RDC: Introduction, Printing, and Databases
207
oDB.AddADOCommand(oConn, oCommand) oConn oCommand
Object Object
A reference to an ADO Connection object A reference to an ADO Command object
To use this method, you must first create and populate both an ADO Connection and Command objects. The AddOLEDBSource method is very similar. You use this method when connecting directly to an OLE DB data source instead of ADO. oDB.AddOLEDBSource(cConnStr, cTable) cConnStr cTable
Character Character
An OLE DB connection string The name of the table to add to the report
Be careful when supplying the database and table names as some database servers are case sensitive. If you create a report using a Field Definition File, you replace the field definition information with the actual data source using the SetDataSource method. oDB.AddOLEDBSource(oData, [nDataType], [nTable]) oData nDataType
Object Numeric
nTable
Numeric
The data for the report. If using ADO, this is an ADO record set. The type of data passed. Currently the only accepted value is 3. (Optional) The table number in the report for the data. Default is table 1. (Optional)
Before you run a report, it’s a good idea to check for changes to the database schema and location. You do this by calling the Verify method. oDB.Verify()
This method has no parameters. If the table schema changes, the report updates automatically. Before calling Verify, you may want to call the CheckDifferencesMethod of the DatabaseTable object (discussed later in this chapter) to determine exactly what changed.
Working with tables With a reference to the Database object and a connection to the data, you drill down to each table in the report. To do this you need to get a reference to the DatabaseTables collection, and then a reference to each DatabaseTable object. The following code shows this, and gets a reference to the first table in the collection: loDB = loRpt.Database() loDT = loDB.Tables() loTable = loDT.Item(1)
208
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The DataTables collection has standard collection properties (see “Working with collections” earlier in this chapter). The Add method adds a new DatabaseTable object or stored procedure to the collection. Here’s the syntax: oDT.Add(cLocation, [cSubLocation], [cConnectionInfo], [nTableType], [cDllName], [cServerName], [cServerType], [cDatabaseName], [cUserId], [cPassword]) cLocation cSubLocation cConnectionInfo nTableType
The location of the database. The sublocation of the database. (Optional) Connection information. (Optional) The table type. (Optional) It is one of these: crStandardDatabase = 1 crSQLDatabase = 2 The name of the Crystal Reports driver DLL to use for accessing the table. (Optional) The name of the server. (Optional) The database server type. (Optional) The database name. (Optional) The User Id for logging on to the server. (Optional) The password for logging on to the server. (Optional)
You can add different types of tables such as FoxPro, Access, SQL Server, or ADO and OLE DB data sources. This example adds the Customers table in the Northwind.mdb to the DataTables collection: loDB = loRpt.Database loTables = loDB.Tables loTables.Add(“C:\CR\Northwind.MDB”, “Customers”)
The AddStoredProcedure method is similar to the Add method. It has an additional parameter to pass initial values for the stored procedure parameters. oTables.AddStoredProcedure(cLocation, [cSubLocation], [cConnectionInfo], [nTableType], [cDllName], [cServerName], [cServerType], [cDatabaseName], [cUserId], [cPassword], [oParamValues]) cLocation cSubLocation cConnectionInfo nTableType
Character Character Character Character Character Object
The location of the database. The sublocation of the database. (Optional) Connection information. (Optional) The table type. (Optional) Its value is one of these: crStandardDatabase = 1 crSQLDatabase = 2 The name of the Crystal Reports driver DLL to use for accessing the table. (Optional) The name of the server. (Optional) The database server type. (Optional) The database name. (Optional) The User Id to use for logging on the server. (Optional) The password for logging on the server. (Optional) A reference to a ParameterValueInfos collection. (Optional)
Chapter 9: The RDC: Introduction, Printing, and Databases
209
Passing stored procedure parameters When you add a new stored procedure with the AddStoredProcedure method, you use a ParameterValueInfo object to hold information about the parameters used by the stored procedure. You start by creating an instance of the ParameterValueInfos collection. oParams = CREATEOBJECT(“CrystalRuntime.ParameterValueInfos”)
This is a standard Crystal Reports collection with Item and Count properties and Add and Delete methods. Each item in the collection is a reference to a ParameterValueInfo object. The Add method takes a single parameter, a ParameterValueInfo object. oParams.Add(oParam) oParam
Object
A reference to a ParameterValueInfo object.
Before you can use a ParameterValueInfo object, you need to create it. oParam = CREATEOBJECT(“CrystalRuntime.ParameterValueInfo”)
This object doesn’t have any methods. Table 7 lists its properties. Table 7. Properties of the ParameterValueInfo object. Property
Type
Read Only
Description
ParameterValues ParameterName
Variant Character
N N
The value of the parameter. The name of the parameter.
The DatabaseTable object After you instantiate the DatabaseTables collection, you work with a particular table using the DatabaseTable object. There is one DatabaseTable object in the DatabaseTables collection for each table in the report. Table 8 lists the properties of the DatabaseTable object. The following example shows how to get a reference to the first table in the DatabaseTables collection. loDB = loRpt.Database loTables = loDB.Tables loTable = loTables.Item(1)
210
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 8. Properties of the DatabaseTable object. Property
The table connection buffer string. A reference to a ConnectionProperties object. The type of database. Possible values: crSQLDatabase = 2 crStandardDatabase = 1 The descriptive table name. Note the misspelling of the property. It is misspelled in the RDC automation server. You need to do the same in your code if you reference this property. The Crystal Reports DLL used for accessing the data. A reference to a DatabaseFieldDefinitions collection. The location of the table. The name of the table. A reference to the parent DatabaseTables collection.
The SetDataSource method provides information about the database to the data driver. oTable.SetDataSource(vData, [nTag]) vData
Variant
nTag
Numeric
The data passed to the data driver. If you use ADO, this must be a recordset. If you are using Crystal Data Objects, then this is a rowset. Currently the only value you can pass is 3, which you must pass for ADO or CDO. (optional)
Use the SetTableLocation method to change the location of a table when using tablebased data such as Access. oTable.SetTableLocation(cFullPath, cTableName, cConnectBuffer) cFullPath cTable cConnectBuffer
Character Character Character
The fully qualified path and filename to the database. The table to use. The connection buffer string.
For example, if you connect to the Customer table in the Extreme sample database, you could use the following code: loDB = loRpt.Database loTables = loDB.Tables loTable = loTables.Item(1) loTable.SetTableLocation(“C:\CR\Xtreme.MDB”, “Customer”, “”)
Chapter 9: The RDC: Introduction, Printing, and Databases
211
The ConnectionProperties object The ConnectionProperties collection holds information about each connection in the report. Each connection in the report is a separate item in the collection. Each item is a reference to a ConnectionProperty object, which is really a property bag. Table 9 lists the properties of the ConnectionProperties collection. RDC Object Model diagram (Figure 1) shows the ConnectionProperties The object comes from the Database object. However, when you examine the object hierarchy in an object browser, you find the ConnectionProperties object comes from the DatabaseTable object.
Table 9. Properties of the ConnectionProperties collection. Property
Type
Read Only
Description
Count Item NameIds
Numeric Object Array
Y Y Y
The numbers of items in the collection. Returns a reference to a ConnectionProperty object. Each array element is the name of each property in the property bag.
You add new a new item to the property bag with the Database object’s Add method. oDB.Add(cName, vValue) cName xValue
Character Varian
The name of the property to add to the property bag. The property value.
The Delete method removes an item oDB.Delete(nIndex) nIndex
Numeric
The index to the item to delete.
Finally, you remove all ConnectionProperty objects with the DeleteAll method. This method has no parameters. oDB.DeleteAll()
Working with the ConnectionProperties object The ConnectionProperty stores information about a connection in a property bag. The properties depend on the Crystal Decisions database DLL and the capabilities of your database
212
CrysDev: A Developer’s Guide to Integrating Crystal Reports
driver. The ConnectionProperty object does not have any methods. Table 10 lists the properties of the Database object. Table 10. This table contains properties of the ConnectionProperties object. Property
Type
Read Only
Description
ChildProperties
Object
Y
Description LocalizedName
Character Character
N N
Name Value
Character Variant
N Maybe
Returns a reference to a child ConnectionProperties collection. The descriptive name of the connection property. The localized name of the connection property. This is used by the Crystal driver. The name of the property. The value of the property. Some properties, such as Password, are read only.
At this point, you may be wondering what properties exist. Well, it depends on what type of database access you use. Table 11 lists the common properties for different access types. You may find other properties depending on your specific database driver. Table 11. Common connection properties in the ConnectionProperties property bag. Connection Type
Property
Type
Description
ODBC/RDO (crdb_odbc.dll)
Connection String
Character
Database Database Type DSN
Character Character Character
FileDSN
Character
Password Trusted_Connection
Character Logical
User ID Data Source
Character Character
The complete connection string. Note that DSN, FileDSN, and Connection String are mutually exclusive. The database name. The type of database file. The Datasource name. Note that DSN, FileDSN, and Connection String are mutually exclusive. The fully qualified path name to a file DSN. Note that DSN, FileDSN, and Connection String are mutually exclusive. The password to log on the database. True if you want to use or the connection is using an NT Authentication. The user name. The file path and database or the server name.
Database Database Type Integrated Security
Character Character Logical
Microsoft Data Link File Password Provider User ID
Character
OLE DB/ADO (crdb_ado.dll)
Character Character Character
The database name. The type of database file. True if you want to use or the connection is using an NT Authentication. The fully qualified file path and name of the data link. The password to log on the database. The OLE DB provider being used. The user name.
Chapter 9: The RDC: Introduction, Printing, and Databases
213
Table 11. (Continued) Connection Type
Property
Type
Description
Access/Excel/ DAO (crdb_dao.dll)
Database Name
Character
The name of the database.
Database Password Database Type Session Password Session UserID System Database Path Database Type
Character Character Character Character Character Character
The password to log on the database. The file type. The password for a System DSN. The user ID for a System DSN. The fully qualified path and filename of the database. The type of file.
Server Password User ID Database Path
Character Character Character Character
The name of the server. The password to log on the database. The user name. The path to the file.
Database Type Password User ID Database Type
Character Character Character Character
The type of file. The password to log on the database. The user name. The type of file.
Field Definition File
Character
The fully qualified path and filename of the file.
Oracle (crdb_oracle.dll)
Native connections (crdb_pr*.dll)
Field Definitions Only (crdb_fielddef.dll)
Getting connection property information The following code shows you how to retrieve information from the property bag and display it on the screen. loCR = CREATEOBJECT("CrystalRuntime.Application") * Use the Employee Sales sample report that ships with Crystal Reports loRpt = loCR.OpenReport("C:\CR\EMPLOYEE SALES.RPT") loDB = loRpt.Database() loTables = loDB.Tables() CLEAR FOR EACH loTable IN loTables ? lotable.location loConnProp = loTable.ConnectionProperties FOR EACH loNameId IN loConnProp.NameIds ? SPACE(5) + loNameId + " = " + loConnProp.Item(loNameId).Value ENDFOR ENDFOR
214
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Working with fields Once you connect to a table, you can work with individual fields. In Chapter 11, “The RDC: Formatting the Report,” I show you how to work with field objects on the report. This section discusses working directly with the data. You begin using fields by getting a reference to the DatabaseFieldDefinitions collection using the Fields method of the DatabaseTable object. loDB = loRpt.Database loTables = loDB.Tables loTable = loTables.Items(1) loFields = loTable.Fields
This example shows how to get a reference to the DatabaseFieldDefinitions collection for the first table in the DatabaseTables collection. The DatabaseFieldDefinitions collection has the standard collections properties (see Table 1) and no methods. There is one item in the collection for each field in the table. Now that you have a reference to the fields collection, you can create the DatabaseField object for each field in the data table. oField = oDT.Fields.Item(1)
The DatabaseField object does not have any methods. Table 12 lists the properties of the DatabaseField object. You can easily step through each field in the data table and get information about it: loTable = loTables.Item(1) loFields = loTable.Fields() FOR EACH loField IN oFields ? loField.DatabaseFieldName ? loField.ValueType ? loField.Value ENDFOR
This example gets a reference to the DatabaseFieldsCollection for table one and then prints the field name, data type, and value for each field in the current row of the table.
Chapter 9: The RDC: Introduction, Printing, and Databases
215
Table 12. Properties of the DatabaseFieldDefinition object Property
Type
Read Only
Description
DatabaseField DisplayName DatabaseField Name Kind
Character
Y
The display name for the field in the database.
Character
Y
The fieldname.
Numeric
Y
Name NextValue NumberOfBytes Parent PreviousValue TableAliasName Value ValueType
Character Variant Numeric Object Variant Character Variant Numeric
Y Y Y Y Y Y Y Y
The kind of field. Values are: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField = 8 crRunningTotalField = 7 crSummaryField = 3 Gets the Crystal formula name for the field. Gets the next value of the field. Gets the number of bytes needed in memory for the field. Gets a reference to the Report object. Gets the previous value of the field. Gets the alias for the table. Gets the current value of the field. Gets the field type. Values are: crBitmapField = 17 crInt32uField = 6 crBlobField = 15 crInt8sField = 1 crBooleanField = 9 crInt8uField = 2 crChartField = 21 crNumberField = 7 crCurrencyField = 8 crOleField = 20 crDateField = 10 crPersistantMemoField = 14 crDateTimeField = 16 crPictureField = 19 crIconField = 18 crStringField = 12 crInt16sField = 3 crTimeField = 11 crInt16uField = 4 crTransientMemoField = 13 crInt32sField = 5 crUnknownField = 22
Linking tables The last item I discuss in this chapter is table linking. This establishes a relation between tables. You start by getting a reference to the TableLinks collection from the Database object: loCRW = CREATEOBJECT(“CrystalRuntime.Application”) loRpt = loCRW.OpenReport(“C:\CR\Sales by Region.RPT”) loDB = loRpt.Database() loLinks = loDB.Links()
The TableLinks collection has the standard collection properties and methods to Add and Delete links. oLinksCol.Add(oSrcTable, cDestTable, cSrcFields, cDestFields, nJoinType, nLookupType, lPartialMatch, nIndex)
216
CrysDev: A Developer’s Guide to Integrating Crystal Reports
oSrcTable
Object
cDestTable
Object
cSrcFields
Object
cDestFields
Object
nJoinType
Numeric
nLookupType
Numeric
lPartialMatch nIndex
Logical Numeric
A reference to a DatabaseTable object for the source table (the table you are linking from). A reference to a DatabaseTable object for the destination table (the table you are linking to). A reference to a DatabaseFields collection, holding only the source fields used to link the tables. A reference to a DatabaseFields collection, holding only the destination fields used to link the tables. The type of join. Possible values: crJTAdvance = 13 crJTLessOrEqual = 11 crJTEqual = 4 crJTLessThan = 9 crJTGreaterOrEqual = 10 crJTNotEqual = 12 crJTGreaterThan = 8 crRightOuter = 6 crJTLeftOuter = 5 The type of lookup to make. Possible values: crLTLookupParallel = 1 crLTLookupSeries = 3 crLTLookupProduct = 2 If True, makes a partial match. Specifies the index number to use.
Delete a link with the Delete method: oLinksCol.Delete(nIndex) nIndex
Numeric
The index number of the TableLink object to delete.
The TableLinks collection references the TableLink object. The TableLink object has no methods, but several properties (see Table 13) to get information about the table links. Table 13. This table shows properties of the TableLink object. Property
Gets a reference to the DatabaseFieldDefinitions collection. Gets a reference to the DatabaseTableObject. Gets the TableLink index used. Gets the join type used. Values are: crJTAdvance = 13 crJTLessThanOrEqual = 11 crJTEqual = 4 crJTLessTHan = 9 crJTGreaterOrEqual = 10 crJTNotEqual = 12 crJTGreaterThan = 8 crRightOuter = 6 crJTLeftOuter = 5 Gets the lookup type used. Values are: crLTLookupParallel = 1 crLTLookupSeries = 3 crLGLookupProduct = 2 Gets a reference to the Database object. Returns True if partial match is enabled. Gets a reference to the DatabaseFieldDefinition object. Gets a reference to the DatabaseTable object.
Chapter 9: The RDC: Introduction, Printing, and Databases
217
Connecting to data – some examples In this section, I show you some examples of connecting to data and changing the location of the database. Some of the information regarding methods, parameters, and properties is repeated here for ease of understanding. These examples do not demonstrate all the ways to connect to your data.
Logging on and off a server database Server databases such as SQL Server and Oracle require you log on with a username and password. The Application and Database objects both provide identical methods to log on and log off the server. oObject.LogonServer(cDLL, cServer, [cDatabase], [cUserId], [cPassword]) cDLL
Character
cServer
Character
cDatabase cUserId cPassword
Character Character Character
Specifies the Crystal Reports DLL file to use when connecting to the database. The Runtime.hlp that ships with Crystal Reports defines the names of the DLLs. The server to log on to. Use a DSN when using an ODBC connection. The database to connect to. (Optional) The User Id. (Optional) The password. (Optional)
Using the Application object to log on to SQL Server with the NorthwindODBC DSN, the code looks like this: oCRW.LogOnServer("p2sodbc.dll", "NorthwindODBC", "Northwind", "sa")
The code is identical using the report object: oRpt.LogOnServer("p2sodbc.dll", "NorthwindODBC", "Northwind", "sa")
The DataTable object provides another method for logging on: oTable.SetLogOnInfo(cServer, [cDatabase], [cUserId], [cPassword]) cServer
Character
cDatabase cUserId cPassword
Character Character Character
The server to log off. Use a DSN when using and ODBC connection. The database to disconnect from (optional) The User Id (optional) The password (optional)
With all these options for logging on to the server, you might be confused about which method to use. Well, it’s really quite simple. Use the Application object to set the log on information for the entire report. This allows the main report and any subreports to use the same logon information. In other words, it’s global in nature. You should use the Report object for a single report. If the main report contains a subreport that pulls data from a different database, you will want to have each report log on separately. Finally, if you need
218
CrysDev: A Developer’s Guide to Integrating Crystal Reports
to log on using a table-by-table basis, use the DataTable option. This is useful if you are pulling data from multiple databases. Finally, the Application object has a very useful method, SetMatchLogonInfo. This method sets up all subsequent log ons for the report to use the first logon information. This is useful when you have a number of subreports that pull data from the same database. The syntax is: oCR.SetMatchLogonInfo(lSetMatch) lSetMatch
Logical
If True, sets the global logon flag.
Connecting to ADO If you are connecting to data through OLE DB and ADO, the Report object provides two different methods you can use. AddADOCommand adds a database to the report through an ADO command. oDB.AddADOCommand(oConnection, oCommand) oConnection
Object
oCommand
Object
The ADO connection object to use. Must be defined in code before Crystal Reports can use it. The ADO command object to use. Must be defined in code before Crystal Reports can use it.
This example creates ADO connection and command objects, and then adds them to a new report. oConn = CREATEOBJECT("ADODb.Connection") WITH oConn .Provider = "SQLOLEDB.1" .ConnectionString = "User ID=sa;Initial Catalog=Northwind;Data Source=(local)" .Open() ENDWITH oCommand = CREATEOBJECT("ADODb.Command") WITH oCommand .ActiveConnection = oConn .CommandText = "SELECT * FROM Customers WHERE Country = 'France'" ENDWITH oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.NewReport() oDB = oRpt.Database() oDB.AddADOCommand(oConn, oCommand)
You can also pass an ADO record set from your program to Crystal Reports, as shown in the following example:
Chapter 9: The RDC: Introduction, Printing, and Databases
LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loDB AS CRAXDRT.Database loTables AS CRAXDRT.DatabaseTables loTable AS CRAXDRT.DatabaseTable loConn AS ADODB.Connection loRS AS ADODB.Recordset
* Handle the ADO stuff loConn = CREATEOBJECT("ADODB.Connection") loConn.ConnectionString = “Provider=VFPOLEDB.1;” ; + “Data Source=C:\eFox\Data\tastrade.dbc;Password=''” loConn.Open() loRS = CREATEOBJECT("ADODB.RecordSet") loRS.Open("Select * FROM Customer", oConn) loCR = CREATEOBJECT("CrystalRuntime.Application") loRpt = loCR.OpenReport("C:\CR\ADO1.RPT") * Create the Database object loDB = loRpt.Database * Get a references to the DatabaseTables collection loTables = loDB.Tables * Get a reference to the DatabaseTable object for table 1 loTable = loTables.Item(1) * Pass the Record Set to Crystal Reports loTable.SetDataSource(oRS) IF loRPt.HasSavedData loRPT.DiscardSavedData() ENDIF loRpt.PrintOut()
Connecting through an ODBC connection This example shows how to change the ODBC DSN name at runtime. LOCAL LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loDB AS CRAXDRT.Database loTables AS CRAXDRT.DatabaseTables loTable AS CRAXDRT.DatabaseTable
loCR = CREATEOBJECT("CrystalRuntime.Application") loRpt = loCR.OpenReport("C:\CR\ODBC1.RPT") * Create the Database object loDB = loRpt.Database() * Get a references to the DatabaseTables collection loTables = oDB.Tables * Get a reference to the DatabaseTable object for table 1 loTable = loTables.Item(1)
219
220
CrysDev: A Developer’s Guide to Integrating Crystal Reports
* Set the location to the new DSN loTables.SetLogOnInfo("ODBCRuntime") IF loRPt.HasSavedData loRPT.DiscardSavedData() ENDIF loRpt.PrintOut()
Connecting to XML Because Crystal Reports accesses XML data through an ODBC connection, connecting to XML data is just like connecting through ODBC.
Connecting to file based data Some database systems, such as FoxPro or Access, store data in a file-based system. At runtime, the data may be in a different location or even have a different filename from what is saved with the report. You use the SetTableLocation method of the DataTable object to define the runtime location of the data. oDT.SetTableLocation (Location, SubLocation, ConnectBuffer)
For example, you may have a report using four different FoxPro tables. At runtime, these are located in the C:\Temp folder. The following code shows how to open the report, set the location, print the report, and cleanup. loCR = CREATEOBJECT(“CrystalRuntime.Application”) loRpt = loCR.OpenReport(“C:\CR\SalesByTerritory.RPT”) loDB = oRpt.Database() loTables = loDB.Tables FOR EACH loTable IN loTables loTable.SetTableLocation(“C:\Temp\” + oTable.Name + “.DBF”) ENDFOR loRpt.PrintOut() loTables = NULL loDB = NULL loRpt = NULL loCR = NULL
You connected to your data, now what? Now that you established a connection to the data, you are ready to either print or manipulate the data in some way. Or are you? There are several questions you should ask right now: •
Am I really connected to the data?
•
Has the table structure changed since the report was created?
•
Is there data saved with the report?
Chapter 9: The RDC: Introduction, Printing, and Databases
221
If you are using SQL Data, it’s a good idea to check the connection for each table in the report using the TestConnectivity method of the DatabaseTable object. This method has no parameters. It returns True if the connection is good. oTable.TestConnectivity()
Once you verify the connection to each table, you should confirm the structure and location of the data are good. Call the Verify method of the Database object. This method has no parameters and returns True if the data passes verification. oDB.Verify()
You could also set the Report’s VerifyOnEveryPrint property as shown in Table 14. Table 14. VerifyOnEveryPrint is a property of the Report object. Property
Type
Read Only
Description
VerifyOnEveryPrint
Logical
N
If True, the report is verified each time it is printed.
If the report fails the verify check, you might want to determine what exactly changed. Use the DatabaseTable object’s CheckDifferences method to do this. You need to check each table in the report. The method returns True if the check fails. oTable.CheckDifferences(hCheck) hCheck
Hex
The check to perform. Returns one of the following hexadecimal codes: crTDOk = 0x00000000 crTDDatabaseOtherChanges = crTDDatabaseNotFound = 0x00001000crDifferencesConsta 0x00000001 nt, [reserved] crTDServerNotFound = where crDifferencesConstant is: 0x00000002 crTDNumberFieldChanged = crTDServerNotOpened = 0x00010000 0x00000004 crTDFieldOtherChanges = crTDAliasChanged = 0x00020000 0x00000008 crTDFieldNameChanged = crTDIndexesChanged = 0x00040000 0x00000010 crTDFieldDescChanged = crTDDriverChanged = 0x00080000 0x00000020 crTDFieldTypeChanged = crTDDictionaryChanged = 0x00100000 0x00000040 crTDFieldSizeChanged = crTDFileTypeChanged = 0x00200000 0x00000080 crTDNativeFieldTypeChanged = crTDRecordSizeChanged = 0x00400000 0x00000100 crTDNativeFieldOffsetChanged = crTDAccessChanged = 0x00800000 0x00000200 crTDNativeFieldSizeChanged = crTDParametersChanged = 0x01000000 0x00000400 crTDFieldDecimalPlacesChange crTDLocationChanged = d = 0x02000000 0x00000800
222
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The final check is to make sure no data saved with the report. In Chapter 2, “Touring Crystal Reports,” I discuss the importance of not saving data with the report. When processing reports, you can’t be sure you always designed the .rpt file or, even if you did, that you did not save the data with the report. Query the HasSavedData property, shown in Table 15, of the Report object to determine this. Table 15. HasSavedData is a property of the Report object. Property
Type
Read Only
Description
HasSavedData
Logical
Y
If True, data has been saved with the report
If HasSavedData is True, you need to discard the data. Call the Report object’s DiscardSavedData method. This is another method with no parameters. oRpt.DiscardSavedData()
The Report object has several miscellaneous properties used for data access. Table 16 lists these properties. Table 16. Miscellaneous data access properties of the Report object. Property
Type
Read Only
Description
CanPerformGroupingOn Server CaseInsensitiveSQLData
Logical
Y
Logical
N
ConvertDateTimeType
Numeric
N
ConvertNullFieldToDefault EnableAsyncQuery EnablePerformQueries Asynchronously EnableSelectDistinct Records FieldMappingType
Logical Logical Logical
N N N
Logical
N
Returns True if the report can perform grouping on the server. Gets or sets the option where SQL data is case insensitive. Determines how to handle DateTime fields. crConvertDateTimeTo crKeepDateTimeType = 2 Date = 1 crConvertDateTImeTo String = 0 Gets or sets the null field conversion setting. If True, sets the asynchronous query option. If True, sets the perform queries asynchronously option. If True, sets the select distinct records option.
Numeric
N
PerformGroupingOn Server RecordSelectionFormula
Logical
N
Character
N
Returns or sets the FieldMappingType. crAutoFieldMapping = 0 crPromptFieldMapping crEventFieldMapping = 2 =1 When True, performs grouping on the server if using a server database. Gets or sets the record select formula.
Chapter 9: The RDC: Introduction, Printing, and Databases
223
Summary This chapter has presented you with the basics of using the RDC. It has also gone into detail about the Application, Report, and Database objects. In the next chapter, I show you how to manipulate the data. Subsequent chapters discuss working with objects on the report, previewing, runtime report design options, exporting, dealing with report events, and more. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
224
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 10: The RDC: Manipulating Data
225
Chapter 10 The RDC: Manipulating Data The last chapter teaches the basics of Crystal Reports integration, as well as printing and accessing data. This chapter shows you how to manipulate the data using different types of fields. You will also learn how to work with report alerts.
Crystal Reports either uses the data directly from your database or through special fields. Crystal Reports creates special fields for different purposes. You have already seen some of these special fields, such as group names, running totals, sorting, formulas, and summary fields.
Sorting Sorting data is probably the most common way to manipulate data. You can sort the data before passing it to Crystal Reports or have the RDC sort the data for you. Typically, you see better performance if you sort the data outside of Crystal Reports. However, this isn’t always possible. Before you work with sort fields, you need to get a reference to the SortFields collection. For information about working with Crystal Reports collections, see Chapter 9, “The RDC: Introduction, Printing, and Databases.” LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oSortFields AS CRAXDRT.SortFields oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oSortFields = oRpt.GroupSortFields()
Sorting and grouping are similar functions, but with different results. Grouping is discussed in more detail later in this chapter. The SortFields collection has standard properties and two methods, Add and Delete. Use the Add method to add a new SortField object to the collection. oSortFields.Add(oField, nSortDirection) oField nSortDirection
Object Numeric
A DatabaseField object from the DatabaseFields collection. The direction to sort the data. Values are: crAscendingOrder = 0 crOriginalOrder = 2 crDescendingOrder = 1 crSpedifiedOrder = 3
The Delete method removes the specified sort field from the collection.
226
CrysDev: A Developer’s Guide to Integrating Crystal Reports
oSortFields.Delete(nIndex) nIndex
Numeric
The index of the SortField to remove from the collection.
Once you get a reference to the SortFields collection, you can work with the SortField object. First, you need to get a reference to the object. oSortField = oSortFields.Index(1)
This code gets a reference to the first SortField object. Table 1 lists the properties of the SortField object. This object has no methods. Table 1. Properties of the SortField object Property
Type
Read Only
Description
Field
Object
N
Parent SortDirection
Object Numeric
Y N
Gets or sets the field to sort. This is a reference to a DatabaseField object. Gets a reference to the Report object. Gets or sets the sort direction. Values are: crAscendingOrder = 0 crOriginalOrder = 2 crDescendingOrder = 1 crSpedifiedOrder = 3
Working with Groups Groups are similar to sorting, although commonly used for subtotals, page breaks, or other formatting. Again, you need a reference to a collection before you can manipulate a specific group field. This collection is the GroupNameFieldDefinitions collection. LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oGroups AS CRAXDRT.GroupNameFieldDefinitions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oGroups = oRpt.GroupNameFields()
The GroupNameFieldDefinitions collection has the standard collection properties and no methods. To add or delete a group, you use the AddGroup or DeleteGroup methods of the Report object. This is because groups are a section on the report. Here is the syntax for the AddGroup method.
The group number to add in relation to existing groups. For example, to insert a new group between existing groups two and three, specify 3 for the nGroupNumber parameter. A reference to a FieldDefinition object. The RDC groups on the specified field. You can also pass the actual field name. The condition for the grouping. Possible values: crGCAnnually = 7 crGCMonthly = 4 crGCAnyValue = 14 crGCNextIsNo = 13 crGCBiweekly = 2 crGCNextIsYes = 12 crGCByAMPM = 18 crGCQuarterly = 5 crGCByHour = 17 crGCSemiAnnually = 6 crGCByMinute = 16 crGCSemiMonthly = 4 crGCBySecond = 15 crGCToNo = 9 crGCDaily = 0 crGCToYes = 8 crGCEveryNo = 11 crGCWeekly = 1 crGCEveryYes = 10 Gets or sets the sort direction. Possible values: crAscendingOrder = 0 crDescendingOrder = 1
The DeleteGroup method is much simpler. Here’s the syntax: oRpt.DeleteGroup(nGroupNumber) nGroupNumber
Numeric
The group number to delete.
The GroupNameFieldDefinition collection holds a reference to each GroupNameFieldDefintion object. To work with a particular object, you need to get a reference. oGroupField = oGroups.Item(1)
The GroupNameFieldDefinition object has several properties you can query to get information about the grouping. Table 2 lists them. Table 2. This table contains properties of the GroupNameFieldDefinition object. Property
Type
Read Only
Description
GroupNameCondition Formula GroupNameFieldName GroupNumber Kind
String
N
The condition formula for the group.
String Numeric Numeric
Y Y Y
Gets the name of the group field. The group number. Gets the type of field. Possible values: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField = crRunningTotalField = 7 8 crSummaryField = 3
228
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 2. (Continued) Property
Type
Read Only
Description
Name
Character
Y
NextValue NumberOfBytes Parent PreviousValue Value ValueType
Variant Numeric Object Variant Variant Numeric
Y Y Y Y Y Y
Gets the formula name in Crystal Reports formula syntax. Gets the next value of the field. Gets the number of bytes the object uses in memory. Gets a reference to the Report object. Gets the previous value of the field. Gets the current value of the field. Gets the data type of the grouping field. Possible values: crBitmapField = 17 crInt8sField = 1 crBlobField = 15 crInt8uField = 2 crBooleanField = 9 crNumberField = 7 crChartField = 21 crOleField = 20 crCurrencyField = 8 crPersistantMemoField = crDateField = 10 14 crDateTimeField = 16 crPictureField = 19 crIconField = 18 crStringField = 12 crInt16sField = 3 crTimeField = 11 crInt16uField = 4 crTransientMemoField = crInt32sField = 5 13 crInt32uField = 6 crUnknownField = 22
Summary Fields Summary fields perform some type of calculation on a specified field. Most often, this calculation is a sum of a field, but it can be a count, minimum, maximum, average, or one of several other statistical calculations. You generally place summary fields in a grouping section or at the end of the report. Similar to previous fields, the SummaryFieldDefinitions collection holds the summary fields. Here’s the code to get the collection. LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oSummFlds AS CRAXDRT.SummaryFieldDefinitions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oSummFlds = oRpt.SummaryFields()
The SummaryFieldDefinitions collection has the standard properties. It has two methods, Add and Delete, that add or delete a SummaryFieldDefinition object. Here’s the syntax for the Add method: oSummFlds.Add(nGroupLevel, oField, nSummaryType, [oField2])
Chapter 10: The RDC: Manipulating Data
nGroupLevel oField
Numeric Object
nSummaryType
Numeric
oField2
Object
229
The group level for the summary. A reference to a FieldDefinition object. The summary calculation is performed on this field. The type of summary calculation to perform. Possible values: crSTAverage = 1 crSTDPercentile = 14 crSTCount = 6 crSTDWeightedAvg = 12 crSTDCorrelation = 10 crSTMaximum = 4 crSTDCovariance = 11 crSTMinimum = 5 crSTDistinctCount = 9 crSTPopStandardDeviation = 8 crSTDMedian = 13 crSTPopVariance = 7 crSTDMode = 17 crSTSampleStandardDeviation = crSTDNthLargest = 15 3 crSTDNthMostFrequent = 18 crSTSampleVariance = 2 crSTDNthSmallest = 16 crSTSum = 0 crSTDPercentage = 19 A reference to a second summary field. Some summary calculations require two fields, particularly when a graph uses the summary.
The Delete method is just like the other delete methods in a collection: oSummFlds.Delete(Index) Index
Numeric
The index of the SummaryFieldDefinition object to delete.
Once you have a reference to the SummaryFieldDefinitions collection, you can work with an individual SummaryFieldDefinition object. You access this object by referencing the Item property of the SummaryFieldDefinitions collection. oSummFld = oSummFlds.Item(1)
Table 3 lists the properties of the SummaryFieldDefinition object. Table 3. This table lists properties of the SummaryFieldDefinition object. Property
Gets the Area object for where the summary is. Returns True if the summary is in a crosstab. Gets the Area object for where the summary is. Gets or set the hierarchical summary type: crHierarchicalSummary crSummaryAcrossHierar None = 0 chy = 1 The type of field being totaled. Possible values: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField = crRunningTotalField = 7 8 crSummaryField = 3 Gets the name of the field definition formula. The next total value. The number of bytes the object uses in memory. Gets a reference to the Report object.
Y Y Y Y
230
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 3. (Continued) Property
Type
Read Only
Description
PreviousValue SecondarySummarized Field SummarizedField SummaryOperation Parameter SummaryType
Variant Object
Y Y
Gets the value of the previous summary field. Gets a reference to the secondary summarized field.
Object Numeric
Y Y
Gets a reference to the summarized field. Gets or sets the summary operation parameter.
Value ValueType
Variant
Numeric
Y
The type of running total being made. Possible values: crSTAverage = 1 crSTDWeightedAvg = crSTCount = 6 12 crSTDCorrelation = 10 crSTMaximum = 4 crSTDCovariance = 11 crSTMinimum = 5 crSTDistinctCount = 9 crSTPopStandardDeviat crSTDMedian = 13 ion = 8 crSTDMode = 17 crSTPopVariance = 7 crSTDNthLargest = 15 crSTSampleStandardDe crSTDNthMostFrequent viation = 3 = 18 crSTSampleVariance = crSTDNthSmallest = 16 2 crSTDPercentage = 19 crSTSum = 0 crSTDPercentile = 14 The current value of the running total. Gets the data type of the running total field. Possible values: crBitmapField = 17 crInt8sField = 1 crBlobField = 15 crInt8uField = 2 crBooleanField = 9 crNumberField = 7 crChartField = 21 crOleField = 20 crCurrencyField = 8 crPersistantMemoField crDateField = 10 = 14 crDateTimeField = 16 crPictureField = 19 crIconField = 18 crStringField = 12 crInt16sField = 3 crTimeField = 11 crInt16uField = 4 crTransientMemoField = crInt32sField = 5 13 crInt32uField = 6 crUnknownField = 22
The SummaryFieldDefinition object also has two methods. The first, SetSummarizedField, is for setting the field to summarize. oSummFld.SetSummarizedField(oField) oField
Object
A reference to a FieldDefinition object. The summary calculation is performed on this field.
The second method is SetSecondarySummarizedField. oSummFld.SetSecondarySummarizedField(oField) oField
Object
A reference to a FieldDefinition object. The summary calculation is performed on this field.
Chapter 10: The RDC: Manipulating Data
231
Running Totals Running totals create specialized summaries and increment counters. You get to running totals through the RunningTotalFieldDefinitions collection. The following code shows how to reference this collection. LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oRTotFlds AS CRAXDRT.RunningTotalFieldDefinitions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oRTotFlds = oRpt.RunningTotalFields()
As you probably already guessed, the RunningTotalFieldDefinitions collection has the standard collection properties and two methods, Add and Delete. Here’s the syntax for the methods: oRTotFields.Add(oField) oField
Object
A reference to a DatabaseField object.
oRTotFields.Delete(nIndex) nIndex
Numeric
The index of the SortField to remove from the collection.
You get a reference to a RunningTotalFieldDefinition object by accessing the Item property of the RunningTotalFieldDefinitions collection. oRTotFld = oRTotFlds.Item(1)
You can optionally use the GetItemByName method. oRTotFields.GetItemByName(cName, @oRTotFld) cName oRTotFld
Character Object
The name of the running total field. A RunningTotalFielDefinition object returned to your application. You need to pass this by reference.
The RunningTotalFieldDefinition object has several properties, listed in Table 4.
232
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 4. Properties of the RunningTotalFieldDefinition object Property
Type
EvaluateCondition
Read Only
Description
Y
EvaluateCondition Field EvaluateCondition Formula EvaluateGroup Number HierarchicalSummary Type
Object
Y
Gets the condition to use for the total. Possible values: crRTEvalNoCondition = 0 crRTEvalOnChangeOf crRTEvalOnChangeOf Group = 2 Field = 1 crRTEvalOnFormula = 3 Gets the field being totaled.
String
Y
Gets or sets the formula to use for the condition.
Numeric
Y
Gets or sets the group number being evaluated.
Y
Kind
Numeric
Y
Name NextValue NumberOfBytes Parent PreviousValue ResetCondition
Character Variant Numeric Object Variant
Y Y Y Y Y Y
ResetConditionField ResetCondition Formula ResetGroupNumber RunningTotalField Name Secondary SummarizedField SummarizedField SummaryOperation Parameter
Object String
Y Y
Numeric Character
Y Y
Gets or sets how to calculate the total across the hierarchy. Possible values: crHierarchicalSummary crSummaryAcross None = 0 Hierarchy = 1 The type of field being totaled. Possible values: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField = 8 crRunningTotalField = 7 crSummaryField = 3 The formula name. The next total value. The number of bytes the object uses in memory. Gets a reference to the Report object. Gets the value of the previous total. Gets the condition to determine when to reset the total. Possible values: crRTEvalNoCondition = 0 crRTEvalOnChangeOf crRtEvalOnChangeOf Group = 2 Field = 0 crRTEvalOnFormula = 3 Gets the field evaluated to determine when to reset Gets or sets the formula for determining when to reset the total Gets or sets the group number where the reset occurs. Gets the name of the running total field.
Object
Y
Gets a reference to the secondary summarized field.
Object Numeric
Y Y
Gets a reference to the summarized field. Gets or sets the summary operation parameter.
Chapter 10: The RDC: Manipulating Data
233
Table 4. (Continued) Property
Type
SummaryType
Value ValueType
Variant
Read Only
Description
Y
The type of running total being made. Possible values: crSTAverage = 1 crSTDPercentile = 14 crSTCount = 6 crSTDWeightedAvg = 12 crSTDCorrelation = 10 crSTMaximum = 4 crSTDCovariance = 11 crSTMinimum = 5 crSTDistinctCount = 9 crSTPopStandard crSTDMedian = 13 Deviation = 8 crSTDMode = 17 crSTPopVariance = 7 crSTDNthLargest = 15 crSTSampleStandard crSTDNthMostFrequent Deviation = 3 = 18 crSTSampleVariance = 2 crSTDNthSmallest = 16 crSTSum = 0 crSTDPercentage = 19 The current value of the running total. Gets the data type of the running total field. Possible values: crBitmapField = 17 crInt8sField = 1 crBlobField = 15 crInt8uField = 2 crBooleanField = 9 crNumberField = 7 crChartField = 21 crOleField = 20 crCurrencyField = 8 crPersistantMemoField = 14 crDateField = 10 crPictureField = 19 crDateTimeField = 16 crStringField = 12 crIconField = 18 crTimeField = 11 crInt16sField = 3 crTransientMemoField = 13 crInt16uField = 4 crUnknownField = 22 crInt32sField = 5 crInt32uField = 6
Y Y
The RunningTotalFieldDefinition object has several methods. The first, SetSummarizedField allows you to specify which field to use for the running total. oRTotField.SetSummarizedField(oField) oField
Object
A reference to a DatabaseField object.
You can also set the secondary summarized field. oRTotField.SetSecondarySummarizedField(oField) oField
Object
A reference to a DatabaseField object.
SetEvaluateConditionField sets the field to use in evaluating the condition. oRTotField.SetEvaluateConditionField(oField) oField
Object
A reference to a DatabaseField object.
234
CrysDev: A Developer’s Guide to Integrating Crystal Reports
You clear the condition with the SetNoEvaluateCondition method, which has no parameters. oRTotField.SetNoEvaluateCondition()
You set the field to use with the reset condition. oRTotField.SetResetConditionField(oField) oField
Object
A reference to a DatabaseField object.
Finally, you clear the reset condition with the SetNoResetCondition method. This method does not have any parameters. oRTotField.SetNoResetConditionField()
SQL Expressions The SQL Expression field is like any other, but it is used to query the database for a specific data set. SQL Expressions were discussed in Chapter 4, “Accessing Data.” It should come as no surprise that access to SQL Expression fields begins with the SQLExpressionFieldDefinitions collection. LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oSQLFlds AS CRAXDRT.SQLExpressionFieldDefinitions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oSQLFlds = oRpt.SQLExpressionFields
This collection has the standard collection properties. You add a new SQL Expression field with the Add method. oSQLFlds.Add(cName, cSQLText) cName cSQLText
Character Character
The name of the SQL Expression field. The SQL text for the database field being added.
The Delete method removes the specified item from the collection. oSQLFlds.Delete(nIndex) nIndex
Niumeric
The index of the SQLExpressionFieldDefinition object to remove.
Once you have a reference to the SQLExpressionFieldDefinitions collection, you can work with an individual SQLExpressionFieldDefinition object by referring to the proper index of the collection.
Chapter 10: The RDC: Manipulating Data
235
oSQLFld = oSQLFlds.Item(1)
You can also use the GetItemByName method. oSQLFlds.GetItemByName(cFldName, @oSQLFld) cFldName oSQLFld
Character Object
The name of the SQL field. A SQLExpressionFieldDefinition object. You need to pass this by reference.
Table 5 lists the properties of the SQLExpressionFieldDefinition object. Table 5. This table show the properties of the SQLExpressionFieldDefinition object. Property
Type
Read Only
Description
Kind
Numeric
Y
Name NextValue NumberOfBytes Parent PreviousValue SQLExpressionFieldName Text Value ValueType
Character Variant Numeric Object Variant Character Character Variant Numeric
Y Y Y N Y Y
The type of field being totaled. Possible values: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField crRunningTotalField = =8 7 crSummaryField = 3 The formula name. The next total value. The number of bytes the object uses in memory Gets a reference to the Report object. Gets the value of the previous total. Gets the name of the SQL Expression field. Gets or sets the SQL expression. The current value of the running total. Gets the data type of the running total field. Possible values: crBitmapField = 17 crInt8sField = 1 crBlobField = 15 crInt8uField = 2 crBooleanField = 9 crNumberField = 7 crChartField = 21 crOleField = 20 crCurrencyField = 8 crPersistantMemoField crDateField = 10 = 14 crDateTimeField = 16 crPictureField = 19 crIconField = 18 crStringField = 12 crInt16sField = 3 crTimeField = 11 crInt16uField = 4 crTransientMemoField crInt32sField = 5 = 13 crInt32uField = 6 crUnknownField = 22
The SQLExpressionFieldDefinition object has one method, Check, used to verify a SQL Command is valid. oSQLFld.Check(@lCondition, @cErrorMsg) lCondition
Logical
cErrorMsg
Character
Returns True if the expression is valid or False if not. Must be passed by reference. The error message to return if lCondition is False. Must be passed by reference.
236
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Formula Fields Chapter 8, “Using Formulas,” introduced Crystal Reports formulas. The RDC also provides a way to get to the formulas programmatically. You start with the FormulaFieldDefinitions collection created from the Report object. LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oFormulas AS CRAXDRT.FormulaFieldDefinitions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oFormulas = oRpt.FormulaFields
This collection has the standard Count, Index, and Parent properties. The collection holds FormulaFieldDefinition objects. Use the collection’s Add method to add a new object. oFormulas.Add(cName, cText) cName cText
Character Character
The name of the Formula field. The formula field text.
The Delete method removes the specified formula. oFormulas.Delete(nIndex) nIndex
Numeric
The index of the formula you want to delete.
You get a reference to an existing FormulaFieldDefinition object in one of two ways. The first uses the Item property of the FormulaFieldDefinitions collection. oFormula = oFormulas.Index(nIndex) nIndex
Numeric
The index number of the formula field.
The second way is the GetItemByName method. oFormulas.GetItemByName(cName, @oFormula) cName oFormula
Character Object
The name of the Formula field. A FormulaFieldDefinition object, passed by reference.
Table 6 lists the properties of the FormulaFieldDefinition object. This object has a single method, Check, for validating a formula.
Returns True if the expression is valid or False if not. Must be passed by reference. The error message to return if lCondition is False. Must be passed by reference.
Table 6. This table lists the properties of the FormulaFieldDefinition object. Property
Type
Read Only
Description
FormulaFieldName Kind
Character Numeric
Y Y
Name
Character
Y
NextValue
Variant
Y
NumberOfBytes Parent PreviousValue
Numeric Object Variant
Y Y Y
Text
Character
N
Value
Variant
Y
ValueType
Numeric
Y
The user friendly name of the formula field. The kind of field. Possible values: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField crRunningTotalField = =8 7 crSummaryField = 3 The formula as expressed in Crystal Reports terms. For example, {@MyFormula}. The next value of the formula field on the report. This property only accessible during report formatting. The amount of memory, in bytes, the formula uses. A reference to the parent Report object The previous value of the formula field on the report. This property only accessible during report formatting. The actual formula. You can use either Crystal syntax or Basic syntax. The current value of the field. This property only accessible during report formatting. The data type of the Value. Possible values: crBitmapField = 17 crInt8sField = 1 crBlobField = 15 crInt8uField = 2 crBooleanField = 9 crNumberField = 7 crChartField = 21 crOleField = 20 crCurrencyField = 8 crPersistantMemoField crDateField = 10 = 14 crDateTimeField = 16 crPictureField = 19 crIconField = 18 crStringField = 12 crInt16sField = 3 crTimeField = 11 crInt16uField = 4 crTransientMemoField crInt32sField = 5 = 13 crInt32uField = 6 crUnknownField = 22
Parameter Fields Parameters, originally discussed in Chapter 6, “Advanced Reporting,” are accessible programmatically through the ParameterFieldDefinitions collection, which contains ParameterFieldDefinition objects. LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oParameterss AS CRAXDRT.ParameterFieldDefinitions
238
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The ParamterFieldDefinitions collection has standard Crystal Reports collection properties and a single method, GetItemByName. This means you can’t programmatically create or delete parameter fields. You get a reference to a particular ParameterFieldDefinition object with the Item property. oParameter = oParameters.Item(1)
Or you can use the GetItemByName method. oParameters.GetItemByName(cName, @oParameter) cName oParameter
Character Object
The name of the Parameter field. A ParameterFieldDefinition object, passed by reference.
Table 7 lists the properties of the ParameterFieldDefinition object. Table 7. This table lists the properties of the ParameterFieldDefinition object. Property
If True, does not allow editing of the parameter. The parameter value kind. Possible values: crDiscreteValue = 0 crDiscreteAndRange crRangeValue = 1 Value = 2 The edit mask for a character parameter. See Table 1 in Chapter 6, “Advanced Reporting,” for a list of valid EditMask values. If True, a Logical parameter group can only have one value set to True. If this property is False, then the group can have multiple True values. Use in conjunction with PlaceInGroup. If True, you can use the multiple parameter values. If True, allows null values for stored procedures. If True, parameter values must be in the specified range. If True, displays only the user friendly parameter name in a pick list. If True, bases the sort order of the pick list on the user friendly name. The logical group number. If True, sets the current value of the parameter. If True, the parameter has a default value. The kind of field. Possible values: crDatabaseField = 1 crParameterField = 6 crFormulaField = 2 crSpecialVarField = 4 crGroupNameField = 5 crSQLExpressionField crRunningTotalField = =8 7 crSummaryField = 3
The maximum allowed value. For character parameters, the maximum length of the string. EnableRangeLimit must be set to True to use this property. The minimum allowed value. For character parameters, the minimum length of the string. EnableRangeLimit must be set to True to use this property. The user friendly name of the parameter. If True, the parameter does not have a value and one needs to be assigned. The next value of the parameter field on the report. This property only accessible during report formatting. The description of the Nth (specified by nIndex) instance of the value the report uses. Gets the number of bytes the object uses in memory The number of current ranges
Numeric
Y
The number of current values
Numeric
Y
The number of default values
Character
Y
ParameterType
Numeric
Y
Parent PickListSortMethod
Object Numeric
Y N
PlaceInGroup
Logical
N
PreviousValue
Variant
Y
Prompt
Character
N
ReportName
Character
Y
Value
Variant
Y
The parameter expressed in Crystal Reports terms. For example, {@MyParameter} The data type of the parameter. Possbile values: crQueryParameter = 1 crStoreProcedure crReportParameter = 0 Parameter = 2 A reference to the Report object The method to use for sort ing the pick list. Possible values: crNoSort = 0 crNumericAscending = 3 crAlphanumeric crNumericDescending = 4 Ascending = 1 crAlphanumeric Descending = 2 If True and a logical parameter is passed, places the parameter in a group. Use in conjunction with EnableExclusiveGroup. The previous value of the parameter field on the report. This property only accessible during report formatting. The prompt to display to the user for entering the parameter. If using subreports, this is the report name containing the parameter. This is empty for a main report. The current value of the parameter field on the report. This property only accessible during report formatting.
240
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The ParameterFieldDefinition object has several methods. The first is AddDefaultValue, which adds a default value for the parameter. If you set MinimumValue or MaximumValue or use EditMask, the value should follow the settings of those properties. oParameter.AddDefaultValue(xValue) xValue
Variant
The value to assign as the default value.
The AddCurrentValue method sets the current value of the parameter. oParameter.AddCurrentValue(xValue) xValue
Variant
The value to assign as the current value
You assign a range with the AddCurrentRange method. oParameter.AddCurrentRange(xLowerVal, xUpperVal, nInclude) xLowerVal xUpperVal nInclude
Variant Variant Numeric
The lower value of the range. The upper value of the range Determines if the lower and upper values should be included or excluded in the range. Possible values: crRangeNotIncludeUpper crRangeIncludeLowerBound = 2 LowerBound = 0 crRangeNoUpperBound = 4 crRangeIncludeUpperBound = 1 crRangeNoLowerBound = 8
If you need to clear the current setting, you use the ClearCurrentValueAndRange method. This method has no parameters. oParameter.ClearCurrentValueAndRange()
Chapter 10: The RDC: Manipulating Data
241
There are several methods for working with the Nth current value, starting with GetNthDefaultValue to return the default value of the Nth item. oParameter.GetNthDefaultValue(nIndex) nIndex
Numeric
The index of the item value to return.
GetNthCurrentValue returns the current value of the specified item. oParameter.GetNthCurrentValue(nIndex) nIndex
Numeric
The index of the item value to return
You get the current values of a range with the GetNthCurrentRange method. oParameter.GetNthCurrentRange(nIndex, @xLowerVal, xUpperVal, nInclude) nIndex xLowerVal xUpperVal nInclude
Numeric Variant Variant Numeric
The index of the item value to return. The lower value of the range, passed by reference. The upper value of the range, passed by reference. Determines if the lower and upper values should be included or excluded in the range, passed by reference. Possible values: crRangeNotIncludeUpper crRangeIncludeLowerBound = 2 LowerBound = 0 crRangeNoUpperBound = 4 crRangeIncludeUpperBound = 1 crRangeNoLowerBound = 8
SetNthDefaultValue sets the default value of the Nth item. oParameter.GetNthCurrentValue(nIndex) nIndex
Numeric
The index of the item value to return.
Finally, you remove the Nth default value with DeleteNthDefaultValue. oParameter.DeleteNthCurrentValue(nIndex) nIndex
Numeric
The index of the item value to delete.
Report alerts When you work with report alerts, you don’t manipulate data. Because you get a reference to the ReportAlerts collection from the Report object, I discuss them here. You first saw report alerts in Chapter 6, “Advanced Reporting.” You learned report alerts display a message to the user when a specified condition exists in the report. An alert is triggered when the report is formatted. You get a reference to the ReportAlerts collection from the ReportAlerts property of the Report object. Here’s the syntax:
242
CrysDev: A Developer’s Guide to Integrating Crystal Reports
oAlerts = oRpt.ReportAlerts
As you can probably guess, the ReportAlerts collection contains ReportAlert objects and has the standard collections properties. Its two methods are Add and Delete. oAlert = oAlerts.Add(cName, cMessage, lEnabled, cFormula, [cFormulaMessage]) cName cMessage lEnabled cFormula cFormulaMessage
Character Character Logical Character Character
The name of the alert. The default message to display. If True, enables the alert. The condition formula that triggers the alert if true. Formula to generate optional text if the alert is triggered. This text displays in place of the DefaultMessage. The formula consists of a character string and a report field and must return a string. (Optional)
oAlert.Delete(nIndex) nIndex
Numeric
The index of the Alert object to delete.
The AlertObject object has no methods. Table 8 lists its properties. Table 8. This table shows the properties of the ReportAlerts object. Property
Type
Read Only
Description
AlertInstances ConditionFormula
Object Character
Y N
DefaultMessage
Character
N
IsEnabled MessageFormula
Logical Character
N N
Name Parent
Character Object
N N
A reference to the AlertInstances collection. The condition formula for the alert. Condition formulas are discussed in more detail in Chapter 11, “The RDC: Formatting the Report.” The default message to display when the alert is triggered. If True, enables the alert. Formula to generate optional text if the alert is triggered. This text displays in place of the DefaultMessage. The formula consists of a character string and a report field and must return a string. The name of the alert. A reference to the parent Report object.
When an alert is triggered, it creates a ReportAlertInstance object and places it in the ReportAlertInstances collection, which has the standard collections properties and no methods. You get a reference to this collection from the AlertInstances property of the ReportAlerts object: oAlertInstances = oAlert.AlertInstances
The ReportAlertInstance object has no methods. Table 9 lists its properties.
Chapter 10: The RDC: Manipulating Data
243
Table 9. This table lists the properties of the ReportAlertInstance object. Property
Type
Read Only
Description
AlertMessage Parent
Character Object
Y Y
The message to display. A reference to the parent ReportAlert object.
Summary This chapter shows you how to manipulate data to get different types of totals or additional data. You also see how to work with report alerts. In the next chapter, I discuss formatting a report. This includes how to change placement or the look of a field on the report. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
244
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 11: The RDC: Formatting the Report
245
Chapter 11 The RDC: Formatting the Report Chapter 9, “The RDC: Introduction, Printing, and Databases,” and Chapter 10, “The RDC: Manipulating Data,” teaches you how to work with the data objects in the report. This chapter moves to the other part of reporting, formatting the report. This includes placement and formatting of the data fields, manipulating sections, and more.
A report consists of more than just data. The data needs to be placed on the report and formatted in some way. In addition to the data, a report consists of pictures, text strings, lines, and many other objects.
Working with Areas Reports divide into different sections, commonly called bands. Crystal Reports calls these Areas. There are five basic Areas in a report: •
Report Header
•
Page Header
•
Details
•
Page Footer
•
Report Footer
You cannot delete these Areas. You can however add and delete groups. Adding a group to a report also adds a Group Header and Footer, which are always together. You cannot have a group without both a header and footer. Each Area further separates into multiple sections. You determine how many sections you need when you design the report. Sections are explained later in this chapter. The first step in working with report formatting is to get a reference to the Areas collection from the Report object. Here’s the code to do this: LOCAL loCR AS CRAXDRT.Application LOCAL loRpt AS CRAXDRT.Report LOCAL loAreas AS CRAXDRT.Areas loCR = CREATEOBJECT("CrystalRuntime.Application") loRpt = loCR.OpenReport("C:\BegCR\Report2.rpt") loAreas = loRpt.Areas()
The Areas collection is a standard Crystal Reports collection described in Chapter 9, “The RDC: Introduction, Printing, and Databases.” The Count property never returns a value less than five and will always be an odd number. The Areas collection has no methods.
246
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Now that you have a reference to the Areas collection, you can work with an individual Area object. Use the Item property of the Areas collection to get this. This code loops through each Area looking for the Details Area. LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loAreas AS CRAXDRT.Areas loArea AS CRAXDRT.Area
loCR = CREATEOBJECT("CrystalRuntime.Application") loRpt = loCR.OpenReport("C:\BegCR\Report2.rpt") loAreas = loRpt.Areas() loArea = NULL lnCount = 1 DO WHILE ISNULL(loArea) IF loAreas.Item(lnCount).Kind = 4 && Details band. See Table 2. loArea = loAreas.Item(lnCount) ELSE lnCount = lnCount + 1 ENDIF ENDDO
You can also use a character code (see Table 1) to reference a particular area. Here’s the code to get the Details Area object LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loAreas AS CRAXDRT.Areas loArea AS CRAXDRT.Area
Table 1. Character parameters for getting an Area object. Area
Character
Report Header Page Header Group Header (where n = the Group number) Details Group Footer (where n = the Group number) Page Footer Report Footer
RH PH GHn D GFn PF RF
The Areas object does not have any methods. If you want to add or delete a group, use the GroupNameFieldsDefinition collection. Table 2 lists the properties of the Areas object.
Chapter 11: The RDC: Formatting the Report
247
Table 2. This table lists the properties of the Area object. Property
Name NewPageAfter NewPageBefore NumberOfTopOrBottomNGroups Parent ParentIdField PrintAtBottomOfPage RepeatGroupHeader ResetPageNumberAfter Sections
Character Logical Logical Numeric Object Object Logical Logical Logical Object
N N N N Y Y N N N Y
The condition formula. Gets or sets the number of times each item in the Details area should print. Gets the height of the Details Area in twips. Gets the width of the Details Area in a multicolumn report in twips. Twips are discussed in Chapter 9, “The RDC: Introduction, Printing, and Databases.” If True, discards other groups. Gets or sets the value of the hierarchical group sorting. Gets or sets the group condition. Possible values: crGCAnnually = 7 crGCNextIsNo = 13 crGCAnyValue = 14 crGCNextIsYes = 12 crGCBiweekly = 2 crGCQuarterly = 5 crGCByAMPM = 18 crGCSemiAnnually = crGCByHour = 17 6 crGCByMinute = 16 crGCSemiMonthly = crGCBySecond = 15 3 crGCDaily = 0 crGCToNo = 9 crGCEveryNp = 11 crGCToYes = 8 crGCEveryYes = 10 crGCWeekly = 1 crGCMonthly = 4 Gets or sets the field used for the group condition. Gets or sets the group indent in twips. Gets the group number. Gets or sets the hide drill down option. Gets the number of horizontal gaps on the page in a multi-column report. Gets the Instance ID field. Gets or sets the keep group together option. Gets or sets the keep Area together option. Gets the kind of Area. Possible values: crDetail = 4 crPageHeader = 2 crGroupFooter = 5 crReportFooter = 8 crGroupHeader = 3 crReportHeader = 1 crPageFooter = 7 Gets or sets the name of the Area. Gets or sets the new page after setting. Gets or sets the new page before setting. Gets or sets the number of top or bottom groups. Gets a reference to the report object. Gets a reference to a FieldDefinition object. Gets or sets the print at bottom of page option. Gets or sets a repeating group header. Gets or sets the reset page number after option. A reference to the Sections collection.
248
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The sort direction of the group. Possible values: crAscendingOrder = crDescendingOrder 0 =1 An array specifiying how to do the grouping. If True, does not print the area. Determines the group sort ‘N’ order. Possible values: crAllGroupsSorted = crBottomNGroups = 1 3 crAllGroupsUnsorted crTopNGroups = 2 =0 crUnknownGroups OrderSort = 10 A SummaryFieldDefinition object that determines the top or bottom ‘N” sort field.
The Area object has two methods, SetInstanceIdField and SetParentIdField, used to set the value of the InstanceIdField and ParentIdField properties. OEMs use these methods and properties to embed Crystal Reports in their applications. If you are an OEM using Crystal Reports, contact Crystal Decisions for more information.
Condition Formulas One property you see for an Area object is ConditionFormula. Introduced in Crystal Reports 9, this new property exists for just about all formatted objects and requires a bit of explanation. So, I decided to present it in its own section. For report objects, such as a BlobFieldObject, FieldObject, GraphObject, and so on, the ConditionField property gives you access to formulas for each of the attribute settings on the Format Editor dialog box. For areas and sections, the ConditionFormula relates to the items in the SectionExpert dialog box. In either case, the ConditionFormula takes a character string to compose the formula. For example, this code forces a new page to print before detail section 1. LOCAL LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loAreas AS CRAXDRT.Areas loArea AS CRAXDRT.Area loSections AS CRAXDRT.Sections
Working with Sections Each Area contains one or more sections, which are contained in the Sections collection. You get a reference to the Sections collection from the Areas object. LOCAL LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loAreas AS CRAXDRT.Areas loArea AS CRAXDRT.Area loSections AS CRAXDRT.Sections
The Sections collection has the standard collections properties along with Add and Delete methods. Here is the syntax for the Add method to add a new section object. oSections.Add([nIndex]) nIndex
Numeric
Specifies the index for the new section object being added. (Optional)
The Delete method removes a section object. There is always at least one section for each Area. oSections.Delete(nIndex) nIndex
Numeric
Specifies the index of the section object being deleted.
Now that you have the Sections collection, you can work with an individual section object. Get a reference to the object from the Item property of the Sections collection. The following code gets a reference to the first section in the collection. oSection = oSections.Item(1)
I’m delaying a discussion of the methods of the Section object until each specific object is disussed throughout this chapter. Table 3 lists the properties of the Section object.
250
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 3. This table contains the properties of the Section object. Property
Type
Read Only
Description
BackColor ConditionFormula CSSClass Height KeepTogether MinimumHeight Name NewPageAfter NewPageBefore Number Parent PrintAtBottomOfPage ReportObjects ResetPageNumberAfter Suppress SuppressIfBlank
Numeric Character Character Numeric Logical Numeric Character Logical Logical Numeric Object Logical Collection Logical Logical Logical
N N N N N Y N N N Y Y N Y N N N
UnderlaySection Width
Logical Numeric
N Y
Gets or sets the background color of the section. The condition formula. The Cascading Style Sheet class. Gets or sets the section height in twips. If True, keeps the section together. Returns the minimum section height in twips. Gets or sets the name of the section. If True, starts a new page after the section prints. If True, starts a new page before the section prints. Returns the index number for the section. Returns a reference to an Area object. If True, the section prints at the bottom of the page. Gets a reference to the report collection. If True, resets the page number after the section prints. If True, suppresses the section. If True, suppresses the section if all contained objects are blank. If True, underlays the section. Returns the width of the section in twips.
It’s in the Section object where individual report objects, such as fields and lines, are found. These objects are members of the ReportObjects collection. The following code shows how to get a reference to this collection: LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loAreas AS CRAXDRT.Areas loArea AS CRAXDRT.Area loSections as CRAXDRT.Sections loSection as CRAXDRT.Section loRepObjs AS CRAXDRT.ReportObjects
The ReportObjects collection has standard properties and no methods. To add or delete an item from this collection, you call the applicable method of the Section object. For example to add a line, call the AddLineObject method. To manipulate the properties of one of the report objects, you access that object from the ReportObjects collection. The following example shows how to add a TextObject to the first section of the Details Area, and then how to manipulate this object.
Chapter 11: The RDC: Formatting the Report LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL LOCAL
251
loCR AS CRAXDRT.Application loRpt AS CRAXDRT.Report loAreas AS CRAXDRT.Areas loArea AS CRAXDRT.Area loSections AS CRAXDRT.Sections loSection AS CRAXDRT.Section loRepObjs AS CRAXDRT.ReportObjects loTextObj AS CRAXDRT.TextObject
loCR = CREATEOBJECT("CrystalRuntime.Application") loRpt = loCR.OpenReport("C:\BegCR\Report2.rpt") loAreas = loRpt.Areas() loArea = loAreas.Item("D") loSections = loArea.Sections() loSection = loSections.Item(1) loRepObjs = loSection.ReportObjects() * Add the text object loSection.AddTextObject("Hello World", 1000, 5) * The new object will be the last one in the collection loTextObj = loRepObjs.Item(loRepObjs.Count) loTextObj.BottomLineStyle = 2 && Double Line loTextObj.TextColor = 16711680 && Make the color blue
Each object type has its own add method. I show you the syntax for each as I present the objects later in this chapter. You delete all objects using the same method, DeleteObject. Here’s the syntax: oSection.DeleteObject(oObject) oObject
Object
A reference to the object to delete.
The ReportObject object As I mention earlier in this chapter, the ReportObjects collection holds each individual object that prints on the report. In this section, you will see how to use each ReportObject. All report objects have properties such as Top, Left, Height, Width for placement, others for the color, and many more. Some have additional methods.
TextObject object A TextObject is not tied to a database field, but is text on the report, such as headers or labels. You add a new TextObject with the AddTextObject method. oSection.AddTextObject(cText, nLeft, nTop, [lFormat]) cText nLeft nTop lFormat
Character Numeric Numeric Logical
The text to display. The left position of the TextObject. The left position of the TextObject. If True, formats the text just as passed. For example, using carriage returns, tabs, and other formatting characters. If False, it ignores any formatting characters in cText. (Optional)
252
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The TextObject has two methods. The first, SetLineSpacing, sets the amount of line spacing for a multi-line TextObject. Here’s the syntax. oTxtObj.SetLineSpacing(nSpacing, nType) nSpacing nType
Numeric Numeric
The amount of spacing. The type of line spacing. Must be one of these values: crExactSpacing = 1 crMultipleSpacing = 2
The second method is SetText. Use this method to change the text of an existing TextObject. oTxtObj.SetText(cText) cText
Character
The new text for the object.
Table 4 lists the properties of the TextObject. Table 4. This table contains the properties of the TextObject object. Property
Logical Numeric Logical Character Character Object Numeric OLEFont Logical Numeric
N N N N N Y N N N N N
KeepTogether Kind
Logical Numeric
N Y
Left LeftIndent LeftLineStyle
Numeric Numeric Numeric
N N N
The background color of the object. The border color. The line style for the bottom border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, the object can grow vertically on the page. The character spacing. If True, the bottom border prints on a page break. The condition formula. The name of the Cascading Style Sheet class. Gets a reference to the FieldElements collection. The amount of space to indent the first line, in twips. The font to use for the object. If True, the object has a drop shadow. The height of the object in twips. The horizontal alignment of the text inside the object. Possbile values: crDefaultAlign = 0 crLeftAlign = 1 crHorCenterAlign = 2 crRightAlign = 3 crJustified = 4 If True, the keep together option is set. The kind of object. For a TextObject, it always returns crTextObject, which equals 2. The left position of the object in twips. Amount of space to indent the object on the left. The line style of the left border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2
Chapter 11: The RDC: Formatting the Report
253
Table 4. (Continued) Property
Type
Read Only
Description
LineSpacing LineSpacingType
Numeric
Y N
MaxNumberOfLines Name Parent RightIndent RightLineStyle
Numeric Character Object Numeric Numeric
N N Y N N
Suppress SuppressIfDuplicated Text
Logical Logical Character
N N Y
TextColor TextRotationAngle
Numeric
N N
Top TopLineStyle
Numeric Numeric
N N
Width
Numeric
N
Returns the amount of line spacing. The type of line spacing to use. Possible values: crExactSpacing = 1 crMultipleSpacing = 0 The maximum number of lines to print for a memo field The object name. Returns a reference to a Section object. The amount of space to indent the object on the right. The line style for the right border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, suppresses the object. If True, suppresses the object if duplicated. Returns the character string to print. If it has embedded fields, use [] to represent the embedded field The text color. The angle to print the text. Possible values: crRotate0 = 0 crRotate270 = 2 crRotate90 = 1 The top location of the object in twips. The line style for the top border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The width of the object in twips.
Field elements Field elements contain information for a field object embedded in a text object. Because you can have multiple field objects in a single text field, the RDC provides a FieldElements collection that contains FieldElement objects. You get the FieldElements collection from the Text object. oFieldElements = oText.FieldElements
This collection has the normal Index, Parent, and Count properties. You add a new FieldElement object with the Add method: oFieldElements.Add(nIndex, oField) nPosition oField
Numeric Object
The index of the position where you want to insert the new field. The FieldElement you are adding.
You remove an object from the collection with the Delete method:
254
CrysDev: A Developer’s Guide to Integrating Crystal Reports
oFieldElements.Delete(nIndex) nIndex
Numeric
The index of the FieldElement object you want to delete.
Table 5 lists the properties for the FieldElement object. This object has a single method, SetLineSpacing, used to set the size and type of the line spacing. oFieldElement.SetLinSpacing(nSpacingSize, nSpacingType) nSpacingSize nSpacingType
Numeric Numeric
The spacing size. The type of line spacing to use. Possible values: crExactSpacing = 1 crMultipleSpacing = 0
Table 5. This table lists the properties of the FieldElementObject object. Property
Type
Read Only
Description
AmPmType
Numeric
N
AmString BooleanOutputType
Character Numeric
N N
CharacterSpacing Color ConditionFormula CurrencyPositionType
Numeric Numeric Character Numeric
N N N N
CurrencySymbol CurrencySymbolType
Character Numeric
N N
The AM/PM option. Possible values: crAmPmAfter = 1 crAmPmBefore = 0 The string to use for AM. Sets how to print a Boolean value. Possible values: crOneOrZero = 4 crYesOrNo = 2 crTorF = 1 crYOrN = 3 crTrueOrFalse = 0 The amount of character spacing. The font color for the object. The condition formula. The currency position. Possible values: crLeadingCurrency crTrailingCurrency InsideNegative = 0 InsideNegative = 2 crLeadingCurrency crLeadingCurrency OutsideNegative = 1 OutsideNegative = 3 The symbol to use for currency. The symbol type to use for currency. Possible values: crCSTFixedSymbol = 1 crCSTNoSymbol = 0 crCSTFloatingSymbol = 2 Determines the calendar type. Possible values: crGregorian crJapaneseCalendar= 3 Calendar = 1 crKoreanCalendar = 5 crGregorianUS crTaiwanese Calendar = 2 Calendar = 4 crHijriCalendar = 6 crThaiCalendar = 7 Determines the type of era to print for a date. Possible values: crLongEra = 1 crShortEra = 0 crNoEra = 2 Sets the first date separator to the specified character. Determines how to print the date. Possible values: crDayMonthYear = 1 crYearMonthDay = 0 crMonthDayYear = 2 Sets the date prefix separator to the specified character. Sets the second date separator to the specified character.
DateCalendarType
N
DateEraType
N
DateFirstSeparator DateOrder
Character
N N
DatePrefixSeparator DateSecondSeparator
Character Character
N N
Chapter 11: The RDC: Formatting the Report
255
Table 5. (Continued) Property
Type
Read Only
Description
DateSuffixSeparator DateWindows DefaultType
Character
N N
Sets the date suffix separator to the specified character. Determines the formatting of a date according to the specific Windows setting. Possible values: crNotUsingWindows crUseWindowsShort Defaults = 2 Date = 1 crUseWindowsLong Date = 0 Determines how to format the day portion of a date. Possible values: crLeadingZeroNumericDay = 1 crNumericDay = 0 crNoDay = 2 The number of decimal places to print for a numeric field. Sets the symbol used for the decimal to the specified character. If True, prints the reverse sign. A FieldDefinition object. Sets amount of indent for the first line. Standard OLE font. Sets the hour and minute separator to the specified character. Determines how to print the hour portion of a time value. Possible values: crNoHour = 2 crNumericHourNo crNumericHour = 0 LeadingZero = 1 Determines how to print the leading day portion of a date. Possible values: crLeadingDayOf crTrailingDayOf Week = 0 Week = 1 Sets the leading day separator to the specified character. Determines the type of leading day. Possible values: crLongLeadingDay = 1 crShortLeadingDay = 0 crNoLeadingDay = 2 The left position of the object in twips. The left indent in twips. Returns the line spacing. Returns the line spacing type. Possible values: crExactSpacing = 1 crMultipleSpacing = 0 The maximum number of lines to print for a memo field. Sets the minute second separator to the specified character. Determines how to print minutes. Possible values: crNoMinute = 2 crNumericMinute crNumericMinute = 0 NoLeadingZero = 1 Determines how to print the month. Possible values: crLeadingZero crNoMonth = 4 NumericMonth = 1 crNumericMonth = 0 crLongMonth = 3 crShortMonth = 2
DayType
N
DecimalPlaces DecimalSymbol
Numeric Character
N N
DisplayReverseSign FieldDefinition FirstLineIndent Font HourMinuteSeparator
Logical Object Numeric OLEFont Character
N N N N N
HourType
N
LeadingDayPosition
N
LeadingDaySeparator LeadingDayType
Character
N N
Left LeftIndent LineSpacing LineSpacingType
Numeric Numeric Numeric
N N Y Y
MaxNumberOfLines MinuteSecondSeparator
Numeric Character
Y Y
MinuteType
Y
MonthType
Y
256
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 5. (Continued) Property
Type
NegativeType
Parent PmString RightIndent RoundingType
Object Character Numeric
SecondType
Read Only
Description
Y
Determines how to print the negative sign on negative numbers. Possible values: crBracketed = 3 crNotNegative = 0 crLeadingMinus = 1 crTrailingNegative = 2 Returns a reference to the TextObject object. Determines the characters to use for PM. The right indent in twips. Determines how to round a number. Possible values: crRoundToMillion = 17 Thousandth = 8 crRoundToHundred crRoundToTen Thousand = 16 Thousandth = 7 crRoundToTen crRoundToHundred Thousand = 15 Thousandth = 6 crRoundTo crRoundToMillionth = 5 Thousand = 14 crRoundToTen crRoundTo Millionth = 4 Hundred = 13 crRoundToHundred crRoundToTen = 12 Millionth = 3 crRoundToUnit = 11 crRoundToBillionth = 2 crRoundToTenth = 10 crRoundToTen crRoundTo Billionth = 1 Hundredth = 9 crRoundTo Determines how to print the seconds part of a time value. Possible values: crNumericNo crNumericSecondNo Second = 2 LeadingZero = 1 crNumericSecond = 0 If True, does not print the object. If True, does not print the object if it was the same value in the previous record. If True, does not print the object if its value is zero. Determines the text format for memo fields. Possible values: crHTMLText = 2 crStandardText = 0 crRTFText = 1 Sets the thousands separator to the specified character. The symbol to use as the thousands separator. Determines if time should be displayed in 12 or 24 hour format. Possible values: cr12Hour = 0 cr24Hour = 1 If True, prints leading zeros on a numeric value. If True, prints only one symbol per page.
If True, uses the system formatting defaults. Determines how to print the year portion of a date field. Possible values: crLongYear = 1 crShortYear = 0 crNoYear = 2 Sets the zero value of a numeric value to this string.
Chapter 11: The RDC: Formatting the Report
257
LineObject object A LineObject is not tied to any database field, but it serves a cosmetic purpose on the report. You add a new LineObject with the AddLineObject method of the Section object. oSection.AddLineObject(nLeft, nTop, nRight, nBottom, [oSection]) nLeft nTop nRight nBottom oSection
Numeric Numeric Numeric Numeric Object
The left position of the LineObject in twips. The top position of the LineObject in twips. The right position of the LineObject in twips. The bottom position of the LineObject in twips. A reference to a Section object. If the line crosses multiple sections, this is the section where the line ends. (Optional)
The LineObject does not have any methods. Table 6 lists its properties. Table 6. This table contains the properties of the LineObject object. Property
Type
Read Only
Description
Bottom ConditionFormula CSSClass EndSection
Numeric Character Character Object
N N N Y
ExtendToBottomOf Section Kind
Logical
Y
Numeric
N
Left LineColor LineStyle
Numeric Numeric
Y N N
LineThickness Name Parent Right Suppress Top
Numeric Character Object Numeric Logical Numeric
N N Y N N N
The bottom location of the line in twips. The condition formula. The name of the Cascading Style Sheet class. Returns a reference to a Section object where the line ends. If True, extends the line to the bottom of the section. The kind of object. For a LineObject, always returns crLineObject, which equals 2. The left position of the object in twips. The color of the line. The style of the line. Possible values: crLSDashLine = 3 crLSSingleLine = 1 crLSDotLine = 4 Thickness of the line in twips. The name of the object. Returns a reference to a Section object. The right location of the object in twips. If True, suppresses the object. The top location of the object in twips.
BoxObject object The BoxObject ties to boxes on the report rather than a database field. You add a new box object with the AddBoxObject method of the Section object.
258
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The left position of the box in twips. The top postion of the box in twips. The right position of the box in twips. The bottom position of the box in twips. The ending section for the box. You can use a section number or character representation. (Optional)
Table 7 lists the properties of the BoxObject. It has no additional methods. Table 7. This table shows the properties of the BoxObject object. Property
Numeric Object Logical Character Numeric Numeric Character Logical
N N N N N N N N
Numeric Logical Numeric
N N Y
Left LineColor LineStyle
Numeric Numeric Numeric
N N N
LineThickness Name Parent Right Suppress Top
Numeric Character Object Numeric Logical Numeric
N N Y N N N
Gets or sets the bottom position in twips. Gets or sets the bottom right section object. If True, closes the box on a page break. The condition formula. Gets or sets the corner ellipse height in twips. Gets or sets the corner ellipse height in twips. The name of the Cascading Style Sheet class. If True, extends the bottom of the box to the bottom of the section Gets or sets the fill color. If True, the box has a drop shadow. Returns the kind of object. For a BoxObject, always returns crBoxObject, which equals 4. Gets or sets the left position. The color of the line that makes the box. The line style for the box. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The thickness of the line in twips. The name of the box object. Returns a reference to a Section object. The right position in twips. If True, does not print the box. The top location in twips.
FieldObject object A FieldObject is a regular field on the report. I discuss these field objects in Chapter 10, “The RDC: Manipulating Data.” Table 8 lists the properties of the FieldObject object. The types of FieldObjects include: •
DatabaseFieldDefinition
•
FormulaFieldDefinition
•
GroupNameFieldDefinition
Chapter 11: The RDC: Formatting the Report •
ParameterFieldDefinition
•
SpecialVarFieldDefinition
•
SummaryFieldDefinition
•
RunningTotalFieldDefinition
•
SQLExpressFieldDefinition
259
You add one of these fields with the AddFieldObject method of the section object. oSection.AddFieldObject(oField, nLeft, nTop) oField nLeft nTop
Object Numeric Numeric
A reference to a field object. The left position of the FieldObject in twips. The top position of the FieldObject in twips.
The SetLineSpacing method sets the line spacing for multiline objects. Here’s the syntax: oFldObj.SetLineSpacing(nSpacing, nSpacingType) nSpacing nSpacingType
Numeric Numeric
The line spacing. The type of line spacing. Possible values: crExactSpacing = 1 crMultipleSpacing = 0
Table 8. This table lists the properties of the FieldObject object. Property
Type
AmPmType
Read Only
Description
N
Sets the AM/PM type. Possible values: crAmPmAfter = 1 crAmPmBefore = 2 The AM string. The backcolor. Determines how to print logical (Boolean) data. Possible values: crOneOrZero = 4 crYesOrNo = 2 crTorF = 1 crYorN = 3 crTrueOrFalse = 0 The color of the border. The line style for the bottom border Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, the field can grow vertically on the page. The character spacing. If True, prints the bottom border on a page break The condition formula. The name of the Cascading Style Sheet class.
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 8. (Continued) Property
Type
CurrencyPositionType
CurrencySymbol CurrencySymbolType
Character
Read Only
Description
N
Determines where to place the currency symbol if the value is negative. Possible values: crLeadingCurrency crTrailingCurrency InsideNegative = 0 InsideNegative = 2 crLeadingCurrency crTrailingCurrency OutsideNegative = 1 OutsideNegative = 3 The character to use for the currency symbol. Determines if the currency symbol should float as the number of printed characters changes. Possible values: crCSTFixedSymbol = 1 crCSTNoSymbol = 0 crCSTFloating Symbol = 2 Determines the calendar type. Possible values: crGregorian crJapaneseCalendar= 3 Calendar = 1 crKoreanCalendar = 5 crGregorianUS crTaiwanese Calendar = 2 Calendar = 4 crHijriCalendar = 6 crThaiCalendar = 7 Determines the type of era to print on a date. Possible values: crLongEra = 1 crShortEra = 0 crNoEra = 2 Sets the first date separator to the specified character Determines how to print the date. Possible values: crDayMonthYear = 1 crYearMonthDay = 0 crMonthDayYear = 2 Sets the date prefix separator to the specified character. Sets the second date separator to the specified character. Sets the date suffix separator to the specified character. Determines the formatting of a date according to the specific Windows setting. Possible values: crNotUsingWindows crUseWindowsShort Defaults = 2 Date = 1 crUseWindowsLong Date = 0 Determines how to format the day portion of a date. Possible values: crLeadingZeroNumeric crNumericDay = 0 Day = 1 crNoDay = 2 The number of decimal places to print for a numeric field. Sets the symbol used for the decimal to the specified character. If True, prints the reverse sign. If True, enables the tight horizontal option. Returns a reference to a field definition object. Sets the indent of the first line Standard OLE font. If True, the object has a drop shadow. The height of the object in twips.
Determines the horizontal alignment of the data in the object. Possible values: crDefaultAlign = 0 crLeftAlign = 1 crHorCenterAlign = 2 crRightAlign = 3 crJustified = 4 Sets the hour and minute separator to the specified character. Determines how to print the hour portion of a time value. Possible values: crNoHour = 2 crNumericHourNo crNumericHour = 0 LeadingZero = 1 If True, enables the keep together option. The kind of object. For a FieldObject, this value will always be crFieldObject, which equals 1. Determines how to print the leading day portion of a date. Possible values: crLeadingDayOf crTrailingDayOf Week = 0 Week = 1 Sets the leading day separator to the specified character. Determines the type of leading day. Possible values: crLongLeadingDay = 1 crShortLeadingDay = 0 crNoLeadingDay = 2 The left position of the object in twips. The left indent in twips. Determines the line style for the left border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 Returns the line spacing. Returns the line spacing type. Possible values: crExactSpacing = 1 crMultipleSpacing = 0 The maximum number of lines to print for a memo field. Sets the minute second separator to the specified character. Determines how to print minutes. Possible values: crNoMinute = 2 crNumericMinute crNumericMinute = 0 NoLeadingZero = 1 Determines how to print the month. Possible values: crLeadingZero crNoMonth = 4 NumericMonth = 1 crNumericMonth = 0 crLongMonth = 3 crShortMonth = 2 The name of the object. Determines how to print the negative sign on negative numbers. Possible values: crBracketed = 3 crNotNegative = 0 crLeadingMinus = 1 crTrailingNegative = 2 Returns the next value of the field. Returns a reference to a section object. Determines the characters to use for PM.
N N
Logical Numeric
LeadingDayPosition
N Y N
LeadingDaySeparator LeadingDayType
Character
N N
Left LeftIndent LeftLineStyle
Numeric Numeric Numeric
N N N
LineSpacing LineSpacingType
Numeric
Y Y
MaxNumberOfLines MinuteSecondSeparator
Numeric Character
Y Y
MinuteType
Y
MonthType
Y
Name NegativeType
Character
Y Y
NextValue Parent PmString
Variant Object Character
Y Y N
262
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 8. (Continued) Property
Type
Read Only
Description
PreviousValue RightIndent RightLineStyle
Variant Numeric Numeric
Y N N
Returns the previous value of the field. The right indent in twips. The line style for the right hand border of the object Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 Determines how to round a number. Possible values: crRoundToMillion = 17 crRoundToThousandth crRoundToHundred =8 Thousand = 16 crRoundToTen crRoundToTen Thousandth = 7 Thousand = 15 crRoundToHundred crRoundTo Thousandth = 6 Thousand = 14 crRoundToMillionth = 5 crRoundTo crRoundToTen Hundred = 13 Millionth = 4 crRoundToTen = 12 crRoundToHundred crRoundToUnit = 11 Millionth = 3 crRoundToTenth = 10 crRoundToBillionth = 2 crRoundToHundredth = 9 crRoundToTen Billionth = 1 Determines how to print the seconds part of a time value. Possible values: crNumericNo crNumericSecondNo Second = 2 LeadingZero = 1 crNumericSecond = 0 If True, the object is not printed. If True, the object is not printed if it was the same value in the previous record. If True, the object is not printed if its value is zero. The color of the text. Determines the text format for memo fields. Possible values: crHTMLText = 2 crStandardText = 0 crRTFText = 1 Determines the rotation angle of the object. Possible values: crRotate0 = 0 crRotate270 = 2 crRotate90 = 1 Sets the thousands separator to the specified character. Determines whether to display time in 12 or 24 hour format. Possible values: cr12Hour = 0 cr24Hour = 1 The symbol to use as the thousands separator. The top location of the object in twips.
RoundingType
N
SecondType
N
Suppress SuppressIfDuplicated
Logical Logical
N N
SuppressIfZero TextColor TextFormat
Logical Numeric
N N N
TextRotationAngle
N
ThousandsSeparator TimeBase
Character
N N
ThousandSymbol Top
Character Numeric
N N
Chapter 11: The RDC: Formatting the Report
263
Table 8. (Continued) Property
Type
Read Only
Description
TopLineStyle
Numeric
N
UseLeadingZero UseOneSymbolPer Page UseSystemDefaults Value Width YearType
Logical Logical
N N
Determines the top line style for the object border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, prints leading zeros on a numeric value. If True, prints only one symbol per page.
Logical Variant Numeric
N Y N Y
Character
Y
ZeroValueString
If True, uses the system formatting defaults. The value of the field in the current record. The width of the object in twips. Determines how to print the year portion of a date field. Possible values: crLongYear = 1 crShortYear = 0 crNoYear = 2 Sets the zero value of a numeric value to this string.
Picture fields You add pictures to your report using the AddPictureObject method of the Section object. Here’s the syntax: oSection.AddPictureObject(cFilePath, nLeft, nTop) cFilePath nLeft nTop
Character Numeric Numeric
A fully qualified path name to the picture file. The left position of the picture object in twips. The top position of the picture object in twips.
A picture object does not have any additional properties or methods. Once it is on a report, you manipulate it as any other field using properties of the FieldObject.
Special variable fields Crystal Reports tracks special variable fields internally, such as report author, page number, print date, and so on. You add a special field with the AddSpecialVarFieldObject method of the Section object.
264
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The type of special variable to add. :Must be one of these values: crSVTDataDate = 4 crSVTPageNofM = 17 crSVTDataTime = 5 crSVTPageNumber = 7 crSVTFileAuthor = 15 crSVTPrintDate = 0 crSVTFileCreationDate = 16 crSVTPrintTime = 1 crSVTFilename = 14 crSVTRecordNumber = 6 crSVTGroupNumber = 8 crSVTRecordSelection = 12 crSVTGroupSelection = 13 crSVTReportComments = 11 crSVTModificationDate = 2 crSVTReportTitle = 10 crSVTModificationTime = 3 crSVTTotalPageCount = 9 The left position of the object in twips. The top position of the object in twips.
Once you add a SpecialVarObject, you treat it like a regular FieldObject. That is, if you want to manipulate the object, it’s just as any other FieldObject. Table 9 lists the properties for this object. Table 9. This table contains the properties of the SpecialVarObject object. Property
Type
Read Only
Description
Kind Name NextValue
Numeric Character Variant
Y Y Y
NumberOfBytes Parent PreviousValue
Numeric Object Variant
Y Y Y
SpecialVarType
Numeric
Y
Value
Variant
Y
The kind of field. Will be a 4 for a SpecialVarField. The name of the field. The value of the next SpecialVarField in the report. Only accessible while the report is formatting. The amount of memory, in bytes, the field uses. A reference to the parent report object. The value of the previous SpecialVarField in the report. Only accessible while the report is formatting. The type of special variable. Possible values: crSVTDataDate = 4 crSVTPageNofM = 17 crSVTDataTime = 5 crSVTPageNumber = 7 crSVTFileAuthor = 15 crSVTPrintDate = 0 crSVTFileCreationDate = crSVTPrintTime = 1 16 crSVTRecordNumber = crSVTFileName = 14 6 crSVTGroupNumber = 8 crSVTRecordSelection = crSVTGroupSelection = 12 13 crSVTComments = 11 crSVTModificationDate = crSVTReportTitle = 11 2 crSVTTotalPageCount = crSVTModificationTime 9 =3 The value of the current SpecialVarField. Only accessible while the report is formatting.
Summary fields Summary fields total data, count records, compute statistics, and other calculations. They were first presented in Chapter 10, “The RDC: Manipulating Data,” as SummaryFieldObjects. You add a summary field to a section with the AddSummaryFieldObject method. oSection.AddSummaryFieldObject(oField, nSummaryType, nLeft, nTop, [oField2]) oField nSummaryType
Object Numeric
nLeft nTop oField2
Numeric Numeric Numeric
A reference to a SummaryFieldObject. The type of summary field to add. :Must be one of these values: crSTAverage = 1 crSTDPercentage = 19 crSTCount = 6 crSTDPercentile = 14 crSTDCorrelation = 10 crSTDWeightedAvg = 12 crSTDCovariance = 11 crSTMaximum = 4 crSTDistinctCount = 9 crSTMinimum = 5 crSTDMedian = 13 crSTPopStandardDeviation = 8 crSTDMode = 17 crSTPopVariance = 7 crSTDNthLargest = 15 crSTSampleStandardDeviation = crSTDNthMostFrequent = 18 3 crSTDNthSmallest = 16 crSTSampleVariance = 2 The left position of the object in twips. The right position of the object in twips. Some calculations require a second value. This is a reference to the second SummaryFieldObject.
There are no properties for a SummaryFieldObject. Once you have one on a section, you treat it just like a FieldObject.
BlobFieldObject object The BlobFieldObject ties to blob fields from a database, most often these are images. You add a BlobFieldObject using the AddBlobFieldObject method of the Section object.
266
CrysDev: A Developer’s Guide to Integrating Crystal Reports
A reference to a field object. The left position of the object in twips. The top position of the object in twips.
The BlobFieldObject does not have additional methods. Table 10 lists its properties. Table 10. This table lists the properties of the BlobFieldObject object. Property
CloseAtPageBreak ConditionFormula CSSClass Field HasDropShadow Height KeepTogether Kind
Logical Character Character Object Logical Numeric Logical Numeric
N N N Y N N N Y
Left LeftCropping LeftLineStyle
Numeric Numeric Numeric
N N N
Name Parent RightCropping RightLineStyle
Character Object Numeric Numeric
N Y N N
Suppress Top TopCropping TopLineStyle
Logical Numeric Numeric Numeric
N N N N
Width XScaling
Numeric Numeric
N N
YScaling
Numeric
N
Sets or gets the background color. Sets or gets the border color. Sets or gets the bottom cropping size in twips. Sets or gets the line style for the bottom line of the field. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, closes the border on a page break. The condition formula. The name of the Cascading Style Sheet class. Returns a reference to a DatabaseField object. If True, the object has a drop shadow. Sets or gets the height of the object in twips. If True, sets the keep together option. Returns a numeric value that indicates the kind of field. For a BlobFieldObject, the value will always be crBlobObject, which equals 9. Gets or sets the left position in twips. Gets or sets the left cropping size in twips. Gets or sets the left border line style. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 Gets or sets the object name. Returns a reference to a Section object. Gets or sets the right cropping size in twips. Gets or sets the right border style. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, suppresses the object. The object’s top position in twips. Gets or sets the top cropping size in twips. Gets or sets the top border style. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 Gets or sets the width of the object in twips. Gets or sets the X-axis scaling factor. If XScaling = 2, then the blob is scaled by 200%, if 0.5, the blob scales by 50%. Gets or sets the Y-axis scaling factor.
Chapter 11: The RDC: Formatting the Report
267
Crosstabs Crosstabs are treated a bit differently than other ReportObjects. The CrosstabObject holds a reference to the CrosstabGroups collection. You add a new CrosstabObject with AddCrossTabObject method of the Section object. oSection.AddCrossTabObject(nLeft, nTop) nLeft nTop
Numeric Numeric
The left position of the CrosstabObject in twips. The top position of the CrosstabObject in twips.
Table 11 lists the properties of the CrosstabObject. It has no methods. Table 11. This table lists the properties of the CrosstabObject object. Property
Logical Numeric Object Character Character Logical
N N Y N N N
Backcolor of the object. Bordercolor of the object. The style of the bottom line. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, closes the border when the page breaks. The color of the grand total column. Returns a reference to the CrosstabGroups collection. The condition formula. The name of the Cascading Style Sheet class. If True, keeps the columns together.
Logical
N
If True, repeats row labels on a new page.
Logical Logical Logical
N N N
If True, enables row margins. If True, makes the grid visible. If True, the grand total column is not visible.
Logical
N
If True, empty columns does not print.
Logical
N
If True, empty rows do not print.
Logical Numeric Logical Numeric
N Y N Y
Left LeftLineStyle
Numeric Numeric
N N
Name Parent
Character Object
N Y
If True, the object has a drop shadow. The height of the object in twips. If True, enables the keep together option. Returns the object kind. For a CrosstabObject, this value will always be crCrosstabObject which equals 8 The left location of the object. The style of the left line around the object. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The name of the object. Returns a reference to a section object.
268
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 11. (Continued) Property
Type
Read Only
Description
RightLineStyle
Numeric
Y
RowGrandTotalColor RowGroups SummaryFields
Numeric Collection Collection
Y N N
Suppress Top TopLineStyle
Logical Numeric Numeric
Y Y Y
Width
Numeric
Y
The style of the right hand border of the object. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The color of the grand total row. Returns a reference to a CrosstabGroups collection. Returns a reference to a SummaryFieldDefinitions collection. If True, the object does not print. The location of the top of the object in twips. The line style for the top border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The width of the object in twips.
CrosstabGroups collection The CrosstabGroups collection holds references to crosstabs stored in the report. Each crosstab is a separate object. You get a reference to a CrosstabGroups collection through either the ColumnGroups or the RowGroups property of the CosstabObject. * Get a reference to the columns loCols = loXTabObj.ColumnGroups * Get a reference to the rows loRows = loXTabObj.RowGroups
This collection has the standard Crystal Reports properties. You add a new CrosstabGroup object through the Add method of either the column groups or the row groups. oCols.Add(oField) oField
Object
A reference to a field object.
You delete a particular object with the Delete method oRows.Delete(nIndex) nIndex
Numeric
The index of the CrosstabObject to delete.
CrosstabGroup object Once you have a reference to a CrosstabGroup object, you can manipulate it. Table 12 lists the properties of this object. It has no methods.
Chapter 11: The RDC: Formatting the Report
269
Table 12. This table contains the properties of the CrosstabGroup object. Property
Type
Read Only
Description
BackColor Condition
Numeric Numeric
N N
EnableSuppressLabel EnableSuppress Subtotal Field Parent SortDirection
Logical Logical
N N
Sets the backcolor. The grouping condition. Possible values: crGCAnnually = 7 crGCMonthly = 4 crGCAnyValue = 14 crGCNextIsNo = 13 crGCBiweekly = 2 crGCNextIsYes = 12 crGCByAMPM = 18 crGCQuarterly = 5 crGCByHour = 17 crGCSemiAnnually = 6 crGCByMinute = 16 crGCSemiMonthly = 3 crGCBySecond = 15 crGCToNo = 9 crGCDaily = 0 crGCToYes = 8 crGCEveryNp = 11 crGCWeekly = 1 crGCEveryYes = 10 If True, the label does not print. If True, the subtotal does not print.
Object Object Numeric
N Y N
Gets or sets a reference to a FieldDefinition object. Returns a reference to a CrosstabObject object. The sort direction. Possible values: crAscendingOrder = 0 crOriginalOrder = 2 crDescendingOrder = 1 crSpedifiedOrder = 3
GraphObject object The GraphObject gives you access to manipulating a graph. You add this object to a section using the AddGraphObject method. oSection.AddGraphObject(nGraphType, nLeft, nTop, [oXTabObj]) nGraphType
Numeric
nLeft nTop oXTabObj
Numeric Numeric Object
The type of graph. Must be one of the these values. crCrossTabGraph = 2 crGroupGraph = 0 crDetailGraph = 1 The left location of the GraphObject in twips. The top location of the GraphObject in twips. A reference to a CrosstabObject. If nDataType = 2, this parameter is required. Otherwise, it should not be passed.
Table 13 lists the properties of the GraphObject. The GraphObject doesn’t have any methods. Table 13. This table shows the properties of the GraphObject object. Property
If True, autoranges the data axis. If True, autoranges the series axis.
270
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 13. (Continued) Property
Type
Read Only
Description
Backcolor BarSize
Numeric
N N
BorderColor BottomLineStyle
Numeric Numeric
N N
CloseAtPageBreak ConditionFields
Logical Collection
N Y
ConditionFormula CrosstabObject
Character Object
N Y
CSSClass Data2AxisDivision Method Data2AxisDivision Number Data2AxisGridline
Character
N N
Numeric
N
Determines the backcolor. Determines the size of the bars on a bar chart. Possible values: cMinimumBarSize = 0 crLargeBarSize = 3 crSmallBarSize = 1 crMaximumBarSize = 4 crAverageBarSize = 2 Color of the border Line style for the bottom line of the border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, the bottom border prints on a pagebreak. Returns a reference to a FieldDefinitions collection for the condition fields. The condition formula. Returns a reference to a CrosstabObject object. Valid only if this is a crosstab chart. The name of the Cascading Style Sheet class. Determines the data2 axis division method. Possible values: crAutomaticDivision = 0 crManualDivision = 1 The data2 axis division number.
Y
Data2AxisNumber Format
Y
DataAxisDivision Method DataAxisDivision Number DataAxisGridline
N Numeric
N Y
Sets or gets the data2 axis gridline type. Possible values: crMajorAndMinor crMinorGridlines = 1 Gridlines = 3 crNoGridlines = 0 crMajorGridlines = 2 Sets or gets the data2 axis number format. Possible values: crCurrencyMillions = 12 crNoDecimal = 0 crCurrencyNo crOneDecimal = 1 Decimal = 3 crPercentNoDecimal = 5 crCurrency crPercentOne Thousands = 11 Decimal = 6 crCurrencyTwo crPercentTwo Decimal = 4 Decimal = 7 crCustomNumber crThousandsNo Format = 8 Decimal = 9 crMillionsNo crTwoDecimal = 2 Decimal = 10 Determines the data axis division method. Possible values: crAutomaticDivision = 0 crManualDivision = 1 The data axis division number. Sets or gets the data axis gridline type. Possible values: crMajorAndMinor crMinorGridlines = 1 Gridlines = 3 crNoGridlines = 0 crMajorGridlines = 2
Chapter 11: The RDC: Formatting the Report
271
Table 13. (Continued) Property
Type
DataAxisNumber Format
Read Only
Description
Y
Logical
N
Sets or gets the data axis number format. Possible values: crCurrencyMillions = 12 crNoDecimal = 0 crCurrencyNo crOneDecimal = 1 Decimal = 3 crPercentNoDecimal = 5 crCurrency crPercentOne Thousands = 11 Decimal = 6 crCurrencyTwo crPercentTwo Decimal = 4 Decimal = 7 crCustomNumber crThousandsNo Format = 8 Decimal = 9 crMillionsNo crTwoDecimal = 2 Decimal = 10 The font used for the data labels. Determines the graph data points on risers. Possible values: crNone = 0 crShowValue = 2 crShowLabel = 1 The font used for the data title. The type of data used in the graph. Possible values: crCrossTabGraph = 2 crGroupGraph = 0 crDetailGraph = 1 Sets the format for the data value number. Possible values: crCurrencyMillions = 12 crNoDecimal = 0 crCurrencyNo crOneDecimal = 1 Decimal = 3 crPercentNoDecimal = 5 crCurrency crPercentOne Thousands = 11 Decimal = 6 crCurrencyTwo crPercentTwo Decimal = 4 Decimal = 7 crCustomNumber crThousandsNo Format = 8 Decimal = 9 crMillionsNo crTwoDecimal = 2 Decimal = 10 If True, enables the auto scale data axis feature.
Logical
N
If True, enables the auto scale data2 axis feature.
Logical
N
If True, enables the auto scale series axis feature.
Logical
N
If True, turns on the enable for each record option.
Logical Logical
N N
If True, prints the legend. If True, enables summarized values.
Character IFontDisp Numeric Numeric
N N N N
Sets or gets the footnote string. The font for the footnote. Sets or gets the graph color. The direction of the graph. Possible values: crHorizontalGraph = 0 crVerticalGraph = 1
If True, sets the footnote by default. If True, set the groups title by default flag.
Logical
N
If True, sets the series title by default flag.
Logical Logical Logical
N N N
If True, sets the subtitle by default flag. Gets or sets the title by default flag. If True, sets the X axis title by default.
Logical
N
If True, sets the Y axis title by default.
Logical
N
If True, sets the Z axis title by default.
Logical Numeric
N Y
Left LeftLineStyle
Numeric Numeric
N N
LegentFont LegendLayout
IFont Numeric
N N
LegendPosition
Numeric
N
MarkerShape
Numeric
N
MarkerSize
Numeric
N
MaxData2AxisValue
Numeric
N
MaxDataAxisValue
Numeric
N
MaxSeriesAxisValue
Numeric
N
MinData2AxisValue
Numeric
N
MinDataAxisValue
Numeric
N
MinSeriesAxisValue
Numeric
N
Gets or sets the keep together flag. The kind of object. For a GraphObject, this value will always be crGraphObject, which equals 7. The left position of the object in twips. The line style for the left border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The font for the legend. Gets or sets the legend layout for a pie chart. Possible values: crAmountLayout = 1 crPercentLayout = 0 crCustomerLayout = 2 The position of the legend in the object. Possible values: crPlaceBottom crPlaceRight = 3 Center = 1 crPlaceTopCenter = 2 crPlaceLeft = 4 crPlaceUpperRight = 0 Determines the shape of the marker. Possible values: crCircleShape = 4 crRectangleShape = 1 crDiamondShape = 5 crTriangleShape = 8 Determines the size of the markers. Possible values: crLargeMarkers = 4 crMediumSmall crMediumLarge Markers = 1 Markers = 3 crSmallMarkers = 0 crMediumMarkers = 2 Determines the maximum value of the data2 axis. If AutoRangeData2Axis is True, this value is ignored. Determines the maximum value of the data axis. If AutoRangeDataAxis is True, this value is ignored. Determines the maximum value of the data series axis. If AutoRangeSeriesAxis is True, this value is ignored. Determines the minimum data2 axis value. If AutoRangeData2Axis is True, this value is ignored. Determines the minimum data axis value. If AutoRangeDataAxis is True, this value is ignored. Determines the minimum series axis value. If AutoRangeSeriesAxis is True, this value is ignored.
274
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 13. (Continued) Property
Type
Read Only
Description
Name Parent PieSize
Character Object
N Y Y
RightLineStyle
Numeric
Y
SeriesAxisDivision Method SeriesAxisDivision Number SeriesAxisNumber Format
Numeric
Y
Numeric
Y
The name of the object. Returns a reference a SectionObject object. The size of the pie chart inside the object. Possible values: crMaximumPieSize = 0 crSmallPieSize = 48 crLargePieSize = 16 crMinimumPieSize = 64 crAveragePieSize = 32 The line style for the right border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The series axis division method. Possible values: crAutomaticDivision = 0 crManualDivision = 1 Gets or sets the series axis division number.
The format for the series axis division number. Possible values: crCurrencyMillions = 12 crNoDecimal = 0 crCurrencyNo crOneDecimal = 1 Decimal = 3 crPercentNoDecimal = 5 crCurrency crPercentOne Thousands = 11 Decimal = 6 crCurrencyTwo crPercentTwo Decimal = 4 Decimal = 7 crCustomNumber crThousandsNo Format = 8 Decimal = 9 crMillionsNo crTwoDecimal = 2 Decimal = 10 crMajorAndMinor crMinorGridlines = 1 Gridlines = 3 crNoGridlines = 0 crMajorGridlines = 2 The font to use for the series label. The title of the series. The font for the series title. Determines how to detach a slice from the pie. Possible values: crLargestSlice = 2 crNoDetachment = 0 crSmallestSlice = 1 The subtitle of the graph. The font to use for the subtitle. Returns a reference to a SummaryFieldDefinitions collection. If True, suppresses the object. The title for the graph. The font to use for the title. The top location of the object in twips. The line style for the top border. Possible values: crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2
Determines the viewing angle crBirdsEyeView = 15 crShorterView = 12 crDistortedStdView = 10 crShortView = 5 crDistortedView = 4 crStandardView = 1 crFewGroupsView = 9 crTallView = 2 crFewSeriesView = 8 crThickGroups crGroupEmphasis View = 11 View = 7 crThickSeriesView = 13 crGroupEyeView = 6 crThickStdView = 14 crMaxView = 16 crTopView = 3 The width of the object in twips. The title for the X axis. The title for the Y2 axis. The title for the Y axis. The title for the Z axis.
N N N N N
The FieldDefinitions Collection The Graph object contains the FieldDefinitions collection. This collection holds one or more FieldObject objects. The objects in this collection are one of the FieldObject types such as: •
DatabaseFieldDefintion
•
FormulaFieldDefinition
•
GroupNameFieldDefintion
•
ParameterFieldDefintion
•
SpecialVarFieldDefintion
•
SummaryFieldDefintion
•
RunningTotalFieldDefintion
•
SQLExpressionFieldDefintion
You get a reference to this collection through the ConditionFields property of the GraphObject. oFieldDefs = oGraph.ConditionFields
This collection has the standard collection properties. You add a new FieldObject to the collection with the Add method. The syntax is: oFieldDefs.Add(oField) oField
Object
The FieldObject to add to the collection.
276
CrysDev: A Developer’s Guide to Integrating Crystal Reports The Delete method removes a FieldObject from the collection. Here’s the syntax:
oFieldDefs.Delete(oField) oField
Object
The FieldObject to remove from the collection.
MapObject object The MapObject represents a map in the Section. The MapObject has no methods. Table 14 lists its properties. Table 14. This table contains the properties of the MapObject object. Property
Logical Character Character Logical Numeric Logical Numeric
N N N N N N Y
Left LeftLineStyle
Numeric Numeric
N N
Name Parent RightLineStyle
Character Object Numeric
N Y N
Suppress Top TopLineStyle
Logical Numeric Numeric
N N N
Width
Numeric
N
The background color of the object. The color of the border. The style of the bottom line of the border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, prints the bottom border at a page break. The condition formula. The name of the Cascading Style Sheet class. If True, the object has a drop shadow. The height of the object in twips. If True, sets the keep together option. The kind of object. For a MapObject, this value will always be crMapObject, which equals 10. The left position of the object in twips. The line style for the left border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The object name. Returns a reference to a Section object. The line style of the right border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, the object is not suppressed. The location of the top of the object in twips. The line style of the top border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The width of the object in twips.
OLEObject An OLEObject is an embedded object such as a picture, a Word document, or an Excel spreadsheet. You reference this embedded object through the OLEObject. Table 15 lists its properties.
Chapter 11: The RDC: Formatting the Report
277
Table 15. This table lists the properties of the OLEObject object. Property
The background color of the object. The border color of the object. The bottom cropping size in twips. The line style of the bottom border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, prints the bottom border on a page break. The condition formula. The name of the Cascading Style Sheet class. The picture to use in the report. You can only change this when the report is being formatted. See Chapter 15, “Integrating COM Components.” If True, the object has a drop shadow. The height of the object in twips. If True, sets the keep together option. The kind of object. For an OLEObject, this will always be crOLEObject, which has a value of 6. The left position of the object in twips. The left cropping size in twips. The line style of the left border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The name of the object. The parent object. In this case, a reference to the Section object. The right cropping size in twips. The line style of the right border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, the object does not print. The top position of the object, in twips. The top cropping size in twip.s The line style of the top border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The width of the object in twips. The scaling factor for the width of the object. You can provide a number from 0.01 to 100. The number you provide is multiplied by 100 to get the scaling percentage. If you provide the number 2, the width scales by 200%. The scaling factor for the height of the object. You can provide a number from 0.01 to 100. The number you provide is multiplied by 100 to get the scaling percentage. If you provide the number 2, the height scales by 200%.
278
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The OLEObject has two methods to work with the location of the linked object. The first, SetOLELocation assigns the location of the object. You can only call this method while the report during formatting. Here’s the syntax: oOLEObj.SetOLELocation(cFilePath) cFilePath
Character
The fully qualified path and filename of the object.
Usr the second method to get the path and filename for the current object. It returns the fully qualified path and filename. cFilePath = oOLEObj.GetLinkSource()
OLAPGridObject object An OLAP grid generally contains rolled up data used for data analysis. The OLAPGridObject represents this data. Table 16 lists the properties of this object. It has no methods. Table 16. This table contains the properties of the OLAPGridObject object. Property
The background color of the object. The border color. The line style of the bottom border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, prints the bottom border on a page break. The condition formula. If True, the object has a drop shadow. The height of the object in twips. If True, sets the keep together option. The kind of object. For an OLAPGridObject this value will always be crOlapGridObject, which equals 11. The left position of the object in twips. The line style of the left border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The name of the object. Returns a reference to a Section object. The line format of the right border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2
Chapter 11: The RDC: Formatting the Report
279
Table 16. (Continued) Property
Type
Read Only
Description
Suppress Top TopLineStyle
Logical Numeric Numeric
N N N
Width
Numeric
N
If True, it suppresses the object. The top position of the object in twips. The line style of the top border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The width of the object in twips.
The ObjectSummaryFieldDefinitions collection Both the CrossTabObject and the GraphObject use the ObjectSummaryFieldDefinitions collection to hold references to SummaryFieldDefintion objects. Here’s the syntax to get the collection from a CrosstabObject: oSummFields = oCrosstab.SummaryFields
Here’s the syntax to get the collection from a GraphObject: oSummFields = oGraph.SummaryFields
This collection has the standard Count, Index, and Parent properties along with Add and Delete methods. Here’s the syntax for each: oSummFields.Add(oSummField) oSummField
Object
A SummaryDefinitionField object.
oSummFields.Delete([nIndex]) nIndex
Numeric
Specifies the index of the SummaryDefinitionField object to delete.
Unbound fields Unbound fields do not tie directly to a table on disk, but are fields in an ADO recordset or some other type of data stored in memory. You add an unbound field to a section with the AddUnboundFieldFieldObject method.
280
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The type of field. Must be one of these values: crBitmapField = 17 crInt32uField = 6 crBlobField = 15 crInt8sField = 1 crBooleanField = 9 crInt8uField = 2 crChartField = 21 crNumberField = 7 crCurrencyField = 8 crOleField = 20 crDateField = 10\ crPersistantMemoField = 14 crDateTimeField = 16 crPictureField = 19 crIconField = 18 crStringField = 12 crInt16sField = 3 crTimeField = 11 crInt16uField = 4 crTransientMemoField = 13 crInt32sField = 5 crUnknownField = 22 The left position of the object in twips. The top position of the object in twips.
Once the UnboundFieldObject is in a section, you use the SetUnboundFieldSource method of the FieldObject to bind a data source to an unbound field. The syntax is: oFldObj.SetUnboundFieldSource(oField) oField
Object
A field in the Crystal Reports field source. For example, {Customer.Phone}.
The UnboundFieldObject does not have its own set of properties. Once you add it to a section, use the properties of the FieldObject to manipulate it.
Subreports If you have subreports in a section, you refer to them through the SubReportObject object. Table 17 lists the properties for this object. It has two methods, OpenSubreport and ReimportSubreport. You add a SubreportObject to a report with the AddSubreportObject method of the section object: oSubRep = oSection.AddSubreportObject(cName, nLeft, nTop) cName nLeft nTop
Character Numeric Numeric
The name of the subreport. The left position of the SubreportObject. The top position of the SubreportObject.
You insert a new subreport based on an existing report file with the ImportSubreport method of the Section object. oSubRep = oSection.ImportSubreport(cFileName, nLeft, nTop) cFilename Left Top
Character Numeric Numeric
The fully qualified path and filename of the report file. The left position of the imported subreport. The top position of the imported subreport.
Both the AddSubreport and ImportSubreport methods return a SubReportObject.
Chapter 11: The RDC: Formatting the Report
281
The OpenSubreport method of the SubreportObject returns a reference to an existing subreport so you can manipulate its properties, events, and methods. Here is the syntax: oReport = oSubRep.OpenSubreport()
Use the second method, ReimportSubreport, to reimport a subreport based on a separate report file on disk. oSubRep.ReimportSubreport(@lSuccess) lSucces
Logical
A flag indicating success or failure of the reimport process. Pass by reference.
Table 17. This table lists the properties of the SubreportObject object. Property
The background color of the object. The border color. The line style of the bottom border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 If True, the subreport can expand vertically if needed. If True, prints the bottom border on a page break. Returns the value for the real-time subreport option. If True, the object has a drop shadow. The height of the object in twips. If True, enables the keep together option. The kind of object. For a subreport, this value will always be 5, crSubreportObject The left location of the object in twips. The line style of the left border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 Gets a reference to the SubreportLinks collection. The name of the object. A reference to the parent Section object. The line style of the right border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The name of the subreport. If True, the object does not print. The top location of the object in twips. The line style of the top border. Possible values crLSDashLine = 3 crLSNoLine = 0 crLSDotLine = 4 crLSSingleLine = 1 crLSDoubleLine = 2 The width of the object in twips.
282
CrysDev: A Developer’s Guide to Integrating Crystal Reports
You can optionally link subreports to data in the main report. If the subreport is linked, the SubreportLinks collection contains link information. You get the SubreportLinks collection from the Links property of the SubreportObject: oSubRepLinks = oSubRep.Links
The SubreportLinks collection has the standard collection properties and methods. Here is the syntax for the Add method: oSubRepLinks.Add(oMainField, oSubField) oMainField oSubField
Object Object
A reference to a FieldDefinitionObject in the main report used for the link. A reference to a FieldDefinitionObject in the subreport used for the link.
Here is the syntax for the Delete method: oSubRepLinks.Delete(nIndex) nIndex
Numeric
The index of the SubReportLink object to delete.
The SubreportLinksObject object has no methods. Table 18 lists its properties. Table 18. This table contains the properties of the SubreportLinksObject object. Property
Type
Read Only
Description
MainReportField
Object
Y
Parent SubreportField
Object Object
Y Y
The FieldDefinitionObject from the main report used for the link. A reference to the parent SubreportObject object. The FieldDefinitionObject from the subreport used for the link.
Summary In the last three chapters, I have shown you how to use one part of the RDC, its primary automation server from the Craxdrt.dll file. In addition to the information presented here, the Section object has additional events discussed in Chapter 15, “Integrating COM Components.” As you have seen, the automation server is very powerful, but it does not provide one key feature most applications have, report preview. That is the topic of the next chapter. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book.
Chapter 12: Previewing the Report at Runtime
283
Chapter 12 Previewing the Report at Runtime Previewing a report is probably what users do most and Crystal Reports provides excellent preview capabilities for your application.
As you have seen in previous chapters, the Crystal Reports Report Design Component (RDC) gives you total control over creating, modifying, printing, and exporting reports in your application. However, you have not seen how to preview the report. Beginning with Crystal Reports 9, Crystal Decisions began shipping two versions of the report viewer. The first is an ActiveX control for COM-based development environments. The second is a Java Bean control for use in Java. This chapter addresses using the ActiveX viewer. You will soon see how to control most aspects of using this control and how it displays. The Viewer Control is also multi-threaded. This means the user can start previewing the report before all the data loads.
Registering the control To use an ActiveX control on your Visual FoxPro form, you need to list it on the ActiveX Form Control toolbar. The following steps walk you through this process. 1.
Select Tools | Options from the menu. The Options dialog box displays (see Figure 1).
2.
Select the Controls tab.
3.
Select ActiveX controls from the option group.
4.
Select Crystal Report Viewer Control 9 from the list. Make sure the box has an X in it.
5.
Click Set As Default so Visual FoxPro remembers the setting.
6.
Click OK to close the Options dialog box.
284
Crystal Reports Application Development
Figure 1. Select Crystal Report Viewer Control in the Options dialog box to make it available.
Creating a preview form With the Crystal Report Viewer Control available to your application, you can create a preview form. One of the unique features of Visual FoxPro is the ability to subclass an ActiveX control. This allows you to add functionality to the control and reuse it in other places. For example, in Chapter 13, “The Report Designer Control,” you see how to use the Embeddable Report Design Control and use the preview control to build full report design capabilities. The following steps walk you through creating the form. 1.
Type “CREATE CLASS” in the Command Window. The New Class dialog box displays (see Figure 2).
Chapter 12: Previewing the Report at Runtime
285
Figure 2. Use the New Class dialog box to define new classes. 2.
Enter CRPreview for the Class Name.
3.
Select OleControl for Based On.
4.
Enter Crystal for the name of the Visual Class Library in the Store In field.
5.
Click OK. The Insert Object dialog box displays (see Figure 3).
Figure 3. Use the Insert Object dialog box to select the ActiveX control to subclass. 6.
Select Insert Control in the Choose option.
7.
Select Crystal Report Viewer Control 9 in the Control Type list, and then click OK. The Class Designer displays.
286
Crystal Reports Application Development 8.
Add two properties to the class. The first, oCrystal holds a reference to the Application object. The second, oReport, references the report object. The Report Viewer control uses the RDC automation server for many of its own services such as printing and exporting.
9.
Add a new method called Setup. Call this method to do all the set up needed by the viewer control when using it on a form.
If you look at the property sheet, you see many properties, events, and methods for the Viewer Control. It may be tempting to change the properties using the property sheet. However, this doesn’t work in Visual FoxPro. You need to set the properties in code. Table 1 lists the properties. Table 1. This table contains the properties of the Viewer Control. Property
Gets the index of the current view tab. If True, displays the background edge. This offsets the report from the edge of the control. If True, displays the border of the viewer. If True, displays the group tree. If True, displays the tabs for different views. If True, displays the toolbar. If True, displays the animation control. If True, displays the Close button. If True, enables drill down. If True, displays the export button. If True, displays the group tree. If True, displays the help button. If True, displays the page navigation controls. If True, enables the popup menu. If True, makes the print button visible. If True, displays the progress control. If True, makes the refresh button visible. If True, makes the Search button visible and enables the search feature. If True, makes the search expert button visible. If True, displays the stop button. If True, the toolbar is functional. If True, makes the zoom drop down control visible. Returns the busy status of the control. A reference to a report object. A reference to the track cursor info object, discussed later in this chapter. Returns the number of view tabs currently available.
The only property that needs additional explanation is the TrackCursorInfo property. This property holds a reference to the TrackCursorInfo object containing information about the
Chapter 12: Previewing the Report at Runtime
287
mouse cursor used for the Viewer control. Using this object, you can get or set the mouse cursor type. Table 2 lists the properties of the TrackCursorInfo object. Table 2. This table lists the properties of the TrackCursorInfo object. Property
Type
Read Only
Description
DetailAreaCursor
Numeric
N
DetailAreaFieldCursor
Numeric
N
GraphCursor
Numeric
N
GroupAreaCursor
Numeric
N
GroupAreaFieldCursor
Numeric
N
Mouse cursor to use for the detail area of the viewer control. Possible values: crAppStartingCursor crIBeamCursor = 3 = 12 crMagnifyCursor = crArrowCursor = 1 99 crCrossCursor = 2 crNoCursor = 10 crDefaultCursor = 0 crWaitCursor = 11 crHelpCursor = 13 Mouse cursor to use for the detail fields of the viewer control. Values are the same as for the DetailAreaCursor. Mouse cursor to use for a graph displayed in the viewer control. Values are the same as for the DetailAreaCursor. Mouse cursor to use for a group header or footer in the viewer control. Values are the same as for the DetailAreaCursor. Mouse cursor to use for a field in a group header or footer in the viewer control. Values are the same as for the DetailAreaCursor.
The TrackCursorInfo object does not have any methods or events. The ReportSource property is the most important property of the Viewer control. You need to set it to a Report Object before you can use the viewer. Do this in the Setup method of the subclassed control. Because this control is dropped on a form or another container, and the control instantiates before the parent container, you can’t use the Init method to accept the necessary parameters. So, add the following code to the Setup method: LPARAMETERS tcReport, toReport, toCrystal WITH This IF PARAMETERS() = 1 * Only the report name was passed in. Create the CR object .oCrystal = CREATEOBJECT("CrystalRuntime.Application") .oReport = .oCrystal.OpenReport(tcReport) ELSE * All the parameters were passed in. Use those references to the CR objects .oCrystal = toCrystal .oReport = toReport ENDIF
The ViewReport method actually loads the data and displays the report. I explain the methods of the Viewer control later in this chapter. It is important to call the Resize method so the control is the same size as the container you drop it on. Here’s the code for the Resize method: WITH This .Top = 0 .Left = 0 IF .Parent.BaseClass = "Page" * The viewer is on the page of a page frame. * Set the height and width the same as the page .Height = .Parent.Parent.PageHeight .Width = .Parent.Parent.PageWidth ELSE * Just use the height and width of the parent .Height = .Parent.Height .Width = .Parent.Width ENDIF ENDWITH
The control is now ready to use. Close the class designer and save changes to the control. Now, with a customized version of the Viewer Control, you need to make it available to the Visual FoxPro form designer. 1.
Select Tools | Options from the VFP menu. The Options dialog box displays.
2.
Select the Controls page (see Figure 4).
Chapter 12: Previewing the Report at Runtime
289
Figure 4. Make the subclassed Viewer control available to the form designer by selecting it on the Controls page of the Options dialog box. 3.
Select Visual class libraries from the option group.
4.
Click Add, select Crystal from the Open dialog box, and then click Open.
5.
Back in the Options dialog box, click Set as Default and then OK. This saves your changes.
Finally, it’s time to create the preview form. 1.
Create a new form and call it CrystalPreview. The Form Designer displays.
2.
Click View Classes on the Form Controls toolbar and select Crystal from the shortcut menu. The Forms Controls toolbar changes to reflect the controls available in the Crystal class library (see Figure 5).
290
Crystal Reports Application Development
Figure 5. Configure the Form Controls toolbar to show the Crystal class library. 3.
Click the CRPreview OLE control button on the Form Controls toolbar and drop it onto the form. The CRPreview control appears as a square. Don’t worry about sizing the control. Form code handles this.
4.
On the Properties sheet, change the name of the control from CRPreview1 to oleCRPreview.
5.
Double-click the form (not the control) and enter the following code into the Init method of the form:
Enter the following code in the Resize method of the form. This causes the viewer control to resize when you resize the form.
This.oleCRPreview.Resize()
7.
Close the form and save the changes.
8.
Time to test the form. You do this from the Command Window. Substitute the report name for one you have available. The preview is shown in Figure 6.
DO FORM CrystalPreview WITH “C:\CR\MyReport.RPT”
Chapter 12: Previewing the Report at Runtime
291
Figure 6. Preview of the finished report. are using a data source that requires you to log on, you need to release IftheyouReport object from the Report Viewer before you can log off. This is because the Report object, not the Viewer Control, holds the data. There are two ways to release the Report object. First, you assign a new report object to the viewer or you destroy the viewer object. There you have it! A Crystal Report viewer for your application. However, there are many methods and events available on the control. The rest of this chapter discusses them.
Methods of the Viewer Control The Crystal Reports Viewer Control has several methods you can call to affect the preview. You call many of the methods from the control’s native toolbar. This gives you the ability to create your own toolbar for the viewer and still give full functionality to the end user.
Showing the report The first method you should call is Refresh. This ensures you have current data loaded into the report before it is shown. The Refresh method has no parameters. ThisForm.oleViewer.Refresh()
292
Crystal Reports Application Development The ViewReport method shows the report. This method has no parameters.
ThisForm.oleViewer.ViewReport()
Once the report is visible, you can change the way the report displays. You can do things such as navigate to a specific page, change the zoom, or drill down to a specific group either on its own tab (called a view) or in the main preview window. It’s also possible to search for specific text. You can also navigate to a relative page in the report. The following method calls show how to do this. None of the methods take parameters. ThisForm.oleViewer.ShowFirstPage() ThisForm.oleViewer.ShowLastPage() ThisForm.oleViewer.ShowPreviousPage() ThisForm.oleViewer.ShowNextPage()
You display a specific page with the ShowNthPage method. Here is the syntax: ShowNthPage(nPage) nPage
Numeric
The page number of the page to show.
The Zoom method zooms in or out of the displayed report. Zoom(nValue) nValue
Numeric
The zoom percentage. For example, 400 zooms the report to 400%. You can also pass 1 to fill the width of the view window or 2 to fit the entire page in the window.
Print a report with the PrintReport method, which has no parameters. Here is an example: ThisForm.oleViewer.PrintReport()
Working with groups Groups are supported in a couple of different ways. You can show a specific group in the current view or add a new view for a group as a drill down. The ShowGroup method displays a group in the current view. ShowGroup(cGroupPath | aGroupPath) cGroupPath
Character
aGroupPath
Array
A colon separated string containing the path to the group. For example, USA:Utah:Salt Lake City An array containing the path for the group.
Instead of navigating to a particular group in the current view, you can add a new view with the AddView method.
Chapter 12: Previewing the Report at Runtime
293
AddView(cGroupPath | aGroupPath) cGroupPath
Character
aGroupPath
Array
A colon separated string containing the path to the group for the new view. For example, USA:Utah:Salt Lake City An array containing the path for the new view.
You activate a particular view with the ActivateView method. The parameter is the view number you want to activate. View one is always the primary view. ActivateView(nView) nView
Numeric
The view number to activate. Each view is a separate tab on the control.
Use CloseView to close a specific view. View one is the Preview itself. If you try to close it, you get an error. CloseView(nView) nVew
Numeric
The view number to close.
You retrieve the name of the view with the GetViewName method. GetViewName(cTab) cTab
Character
The name of the tab containing the view.
Finally, you get the path to the view with the GetViewPath method. GetViewPath method returns an array. GetViewPath([nView]) nView
Numeric
The view number containing the path.
Retrieving information The Crystal Reports Viewer has three methods you can use to retrieve specific information. The first is GetCurrentPageNumber. This method returns the page number displayed in the current view. It does not have any parameters. GetCurrentPageNumber()
You locate specific information in a report with the SearchForText method. If the specified text is found, it is highlighted in the current view. If the text is not found, the message Search could not find any more instances of the specified text after this page displays. The search always begins on the current page, searches forward in a report, and is always specific to the current view. Here’s the syntax:
294
Crystal Reports Application Development
SearchForText(cText) cText
Character
The text to search for.
Finally, SearchByFormula allows you to enter a search formula. For example, you can search for Country = ‘USA’ by using the following formula: {Customer.Country} = ‘USA’
Here’s the syntax: SearchByFormula(cFormula) cFormula
Character
The formula you want to use for the search.
When you pass an empty string to the SeachbyFormula method, the Viewer control displays the Search Expert, where you enter your search criteria (see Figure 7).
Figure 7. The Search Expert displays when you pass an empty string to the SearchbyFormula method.
Events Events occur when something happens with the application. For example, clicking a particular field causes the click event to fire. Unlike methods, you don’t pass parameters to events. Instead, the Crystal Report Viewer Control passes parameters to code you write in event methods. In the event method code, you can run any code you want. You can even cause the default behavior of the event to not occur. All the events have the lDefault parameter. If you set this parameter to False, the default behavior does not occur.
Chapter 12: Previewing the Report at Runtime
295
Report objects events Report object events occur when you click or double-click a field, heading, or label in a report. Doing this creates the EventInfo object. This object contains information about the event and passes as a parameter to the event method. Table 3 lists the EventInfo object properties. Table 3. This table shows the properties of the EventInfo object. Property
Type
Read Only
Description
CanDrillDown Index ParentIndex Text Type
Logical Numeric Numeric Character Numeric
Y Y Y Y Y
If True, you can drill down on the object. The index of the control in a control array. Gets a reference to the object’s parent’s index. The object’s text string. The type of object. Possible values: crBitMap = 103 crLine = 105 crBlob = 104 crOLAPChart = 113 crBox = 106 crOLAPCrosstabFiel crCrosstab = 110 dType = 4 crCrosstabChart = crOLAPDataFieldTyp 108 e=3 crCrosstabMap = crOLAPDimensionFi 115 eldType = 2 crDatabaseFieldTyp crOLAPMap = 117 e=1 crOLEObject = 101 crDetailChart = 109 crOOPSubreport = crDetailMap = 116 112 crDetailSection = crPageFooterSection 202 = 206 crFormulaFieldType crPageHeaderSectio =5 n = 203 crGraphic = 111 crSpecialVarFieldTy crGroupChart = 107 pe = 7 crGroupFooterSectio crSubreport = 102 n = 201 crSummaryFieldType crGroupHeaderSecti =6 on = 200 crText = 100 crGroupMap = 114 crUnknownFieldDefT crGroupNameFieldT ype = 0 ype = 8
The EventInfo object has a single method, GetFields, which returns a Fields Collection. GetFields does not have any parameters. oFields = oEventInfo.GetFields()
The Fields collection holds a collection of field objects and has no methods. Table 4 lists the properties of this collection.
296
Crystal Reports Application Development
Table 4. This table lists the properties of the Fields collection. Property
Type
Read Only
Description
Count Item SelectedFieldIndex
Numeric Numeric Numeric
Y Y Y
The total number of items in the collection. Index of the item in the collection. Index of the item being selected. This is the item number of the clicked field in the viewer.
If the user clicks a field in the viewer, the following code shows how to reference the Field object to get information about the field. oFields = oEventInfo.GetFields() oField = oFields.Item(oFields.SelectedFieldIndex)
The Field object has no methods or events. Table 5 lists its properties. Table 5. This table contains the properties of the Field object. Property
Type
Read Only
Description
FieldType
Numeric
Y
IsRawData Name Value
Logical Character Variant
Y Y Y
The field type. Possible values: crBoolean = 5 crInt8 = 0 crCurrency = 4 crNumber = 3 crDate = 6 crString = 9 crDateTime = 8 crTime = 7 crInt16 = 1 crUnknownFieldType crInt32 = 2 = 255 .T. if the data is raw data. The name of the field. The value of the field.
Getting back to the report object, there are two events that fire. The first is Clicked, which occurs when you click an object. Clicked(nX, nY, oEventInfo, lDefault) nX nY oEventInfo
Numeric Numeric Object
lDefault
Logical
The x coordinate of the object clicked. The y coordinate of the object clicked. An object containing information about the clicked report object. See Table 3 for a list of properties for this object. If True, performs the default action of the event.
The second is DblClicked, which fires when you double-click an object.
Chapter 12: Previewing the Report at Runtime
DblClicked(nX, nY, oEventInfo, lDefault) nX nY oEventInfo
Numeric Numeric Object
lDefault
Logical
The x coordinate of the object that was double-clicked. The y coordinate of the object that was double-clicked. An object containing information about the clicked report object. See Table 3 for a list of properties for this object. If True, performs the default action of the event.
Drill events Drill events fire when you double-click an object to drill down. DrillOnDetail(aValues, nIndex, lDefault) aValues nIndex lDefault
Array Numeric Logical
An array of objects containing details on the fields. The index of the array for the field that was actually clicked If True, performs the drill down.
DrillOnGraph(nPage, nX, nY, lDefault) nPage nX nY lDefault
Numeric Numeric Numeric Boolen
The page number of the report containing the graph. The X coordinate of the graph that received the click. The Y coordinate of the graph that received the click. If True, performs the drill down.
An array containing all the group names for the drilled-down group. The type of drill down. Possible values: LoadingNothing = 0 LoadingQueryInfo = 3 LoadingPages = 1 LoadingTotaller = 4 If True, performs the drill down.
An array containing all the group names for the drilled-down group. The name of the subreport. The title of the subreport. The page containing the subreport. The index of the drilled-down subreport. If True, performs the drill down.
Toolbar objects events Toolbar object events trigger when you click a control on the toolbar. Here are the event methods available. In most cases, the only parameter is lDefault.
297
298
Crystal Reports Application Development
FirstPageButtonClicked(lDefault) lDefault
Logical
If True, displays the first page.
LastPageButtonClicked(lDefault) lDefault
Logical
If True, displays the last page.
NextPageButtonClicked(lDefault) lDefault
Logical
If True, displays the next page.
PrevPageButtonClicked(lDefault) lDefault
Logical
If True, displays the previous page.
GotoPageNClicked(lDefault, nPage) lDefault nPage
Logical Numeric
If True, displays the Nth page. The page number to display
The type of data being loaded into the report. If True, stops the data load process.
HelpButtonClicked()
Note the HelpButtonClicked event does not send any parameters.
Miscellaneous events Finally, there are several other events that don’t fit neatly into other categories. The first is the DownloadStarted event. This event fires when Crystal Reports starts downloading data into a report. DownloadStarted(nLoadType) nLoadType
Numeric
The type of data being loaded into the report. Possible values: LoadingNothing = 0 LoadingQueryInfo = 3 LoadingPages = 1 LoadingTotaller = 4
Once Crystal Reports completes the download, it triggers the DownloadFinished event. DownloadFinished(nLoadType) nLoadType
Numeric
The type of data being loaded into the report. Possible values: LoadingNothing = 0 LoadingQueryInfo = 3 LoadingPages = 1 LoadingTotaller = 4
When the user clicks the Selection Formula button, it fires the SelectionForumulaButtonClicked event. This event is only valid when the viewer is assigned a report source from the RDC. In other words, you will probably never use it. SelectionFormulaButtonClicked(cFormula, lUseDefault) cFormula lUseDefault
Character Logical
The current selection formula. This is replaced if the user selects anything. If True, the default action occurs.
300
Crystal Reports Application Development
The SelectionFormulaBuilt event fires when a new selection formula is applied to a report. SelectionFormulaBuilt(cFormula, lDefault) cFormula lDefault
Character Logical
The selection formula applied to the report. If True, performs the default action.
Clicking a particular group in the group tree triggers the ShowGroup event. ShowGroup(aGroup, lDefault) aGroup lDefault
Array Logical
An array containing the group list. If True, displays the group.
Changing from one view to another causes the ViewChanging event to fire, notifying you that the view is about to change. ViewChanging(nOldView, nNewiew) nOldView nNewView
Numeric Numeric
The number of the old view. The number of the new view.
Once the view changes, the ViewChanged event occurs. ViewChanged(nOldView, nNewView) nOldView nNewView
Numeric Numeric
The number of the old view. The number of the new view.
Changing the Zoom level triggers the ZoomLevelChanged event. ZoomLevelChanged(nLevel) nLevel
Numeric
The new zoom level.
Finally, if an error occurs when you set the Viewer’s ReportSource property or for some reason the report source cannot load, the OnReportSourceError event fires. OnReportSourceError(cMessage, nCode, lDefault) cMessage nCode lDefault
Character Numeric Logical
The text of the error message. The error number. If True, performs the default action.
Chapter 12: Previewing the Report at Runtime
301
Summary This chapter shows you how to create a report preview form and how to control the preview itself. Crystal Reports provides many capabilities for controlling the preview process. You will use the preview control again in Chapter 13, “The Report Designer Control.” Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book
302
Crystal Reports Application Development
Chapter 13: The Report Designer Control
303
Chapter 13 The Report Designer Control Crystal Reports has a component you can embed in your application giving complete design capabilities to your users. One caveat—to distribute this component, you need to obtain additional licensing from Crystal Decisions.
In previous chapters, I show you how to embed a canned report in your application and even how to create and manipulate a report programmatically. You can also give users the ability to design their own reports, either from scratch or by modifying existing reports. This is done with the Report Designer Control. The Report Designer Control is an ActiveX control you drop onto a form or other container in your development tool. The Report Designer Control does not have a preview mode. Typically, you place the designer on a page in a page frame and the preview control is placed on another page. I discuss the Crystal Report Viewer Control in Chapter 12, “Previewing the Report at Runtime.” noted earlier, using the Report Designer Control in an application requires Asadditional licensing from Crystal Decisions. I discuss licensing in detail in Chapter 18, “Licensing and Distribution.”
Registering the Control To use the Runtime Designer Component, you first need to register it in Visual FoxPro. This makes the control available to Visual FoxPro. 1.
Select Tools | Options from the menu. The Options dialog box displays.
2.
Select the Controls tab.
3.
Select ActiveX controls from the option group.
4.
Select Embeddable Crystal 9 Reports Designer Control from the list (see Figure 1). Make sure there is an ‘X’ in the box.
304
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 1. Select the Embeddable Crystal Reports 9 Designer Control in the Options dialog box to make it available. 5.
Click Set As Default so Visual FoxPro remembers the setting.
6.
Click OK to close the Options dialog box.
Creating a design form In Chapter 12, “Previewing the Report at Runtime,” I discuss how to place the Report Viewer Control on a form. Now, you will see how to use the Report Design Control. The steps here are different from those for previewing, because the Report Design Control is placed on a page of a page frame. 1.
Type “CREATE FORM” in the Command Window. The Form Designer displays with a blank form (see Figure 2).
Chapter 13: The Report Designer Control
305
Figure 2. Use the Visual FoxPro Form Designer to create and modify forms for your application. 2.
Select Form | New Property from the menu. The New Property dialog box displays (see Figure 3).
Figure 3. Use the New Property dialog box to add a property to a form or class.
306
CrysDev: A Developer’s Guide to Integrating Crystal Reports 3.
Enter oCrystal in the Name box, and then select Add. This property holds a reference to the Crystal Reports Design Runtime Automation control.
4.
Enter oReport in the Name box, and then select Add. This property holds a reference to the Report object.
5.
Click Close to close the New Property dialog box.
6.
Select Page Frame from the Forms Controls toolbar and drop it on the form.
7.
Ctrl+Click the Page Frame to drill down in the object hierarchy to Page 1.
8.
In the Properties sheet, change the Caption property of Page 1 to Design.
9.
From the ActiveX Controls toolbar, select the Embeddable Crystal Reports 9 Design Control and drop it onto Page 1 of the Page Frame in the Form Designer. The Form Designer should now look like Figure 4.
Figure 4. The Form Designer should look like this after placing the Designer Control on the page.
Chapter 13: The Report Designer Control
307
10. Click Page 2 in the Form Designer. 11. Change the page caption to Preview in the Properties sheet. 12. Select the Crystal Report Viewer Control 9 from the ActiveX Controls toolbar and drop it onto the Preview page of Page Frame in the Form Designer. With the controls on the form, you need to add some code to get them to work. Add the following code to the Init method of the form: LPARAMETERS tcReport WITH This * Maximize the window .WindowState = 2 * Instantiate the COM control .oCrystal = CREATEOBJECT("CrystalDesignRuntime.Application") IF EMPTY(tcReport) * If the report name was not passed, open a new report .oReport = .oCrystal.NewReport() ELSE * If the report name was passed, open it .oReport = .oCrystal.OpenReport(tcReport) ENDIF WITH This.PageFrame1.Page1.oleControl1 * Set the properties for the designer and hook it to the report .ReportObject = ThisForm.oReport .DisplayToolbar = .T. .DisplayFieldView = .T. ENDWITH WITH .PageFrame1.Page2.oleControl1 * Set the properties for the preview control and hook it to the report .EnableExportButton = .T. .EnableProgressControl = .T. .EnableAnimationCtrl = .F. .ReportSource = ThisForm.oReport ENDWITH .Resize() ENDWITH
The one piece of interesting code is: .oCrystal = CREATEOBJECT("CrystalDesignRuntime.Application")
In past chapters, you have seen code such as: .oCrystal = CREATEOBJECT(“CrystalRuntime.Application”)
The difference here is in producing canned reports, you instantiate Craxdrt.dll with CrystalRuntime.Application. Now you are using the Design Control and you need additional
308
CrysDev: A Developer’s Guide to Integrating Crystal Reports
capabilities. This requires you use a different DLL, Craxddrt.dll. This new DLL has the same properties, methods, and events of Craxdrt.dll. In the above code, both the Design and Preview Controls link to the same report. This is necessary to preview the report in the designer. With the code added it instantiates the form and the two ActiveX controls and loads the report. However, if you resize the form, the ActiveX controls don’t resize. The following code goes into the Resize Event method of the form: WITH This * Resize the pageframe and pages. .PageFrame1.Top = .Top + 5 .PageFrame1.Left = .Left + 5 .PageFrame1.Width = .Width - 10 .PageFrame1.Height = .Height - 10 ENDWITH WITH This.PageFrame1 * Resize the Designer, based on the size of the Page Frame .Page1.oleControl1.Top = .Top + 3 .Page1.oleControl1.Left = .Left + 3 .Page1.oleControl1.Width = .Width - 18 .Page1.oleControl1.Height = .Height - 18 ENDWITH WITH This.PageFrame1 * Resize the Preview, based on the size of the Page Frame .Page2.oleControl1.Top = .Top + 3 .Page2.oleControl1.Left = .Left + 3 .Page2.oleControl1.Width = .Width - 18 .Page2.oleControl1.Height = .Height - 18 ENDWITH
Finally, you need some code to refresh the controls on each page. Place this code in the Activate Event method of Page 1: This.Refresh()
And this code in the Activate Event method of Page 2: This.oleControl1.ViewReport()
The form is now complete. Save it with the filename Designer. There are two ways to use the form. To launch the form and display a new, blank report in the designer (see Figure 5), enter the following code in the Command Windows or in a program: DO FORM Designer
Chapter 13: The Report Designer Control
309
Figure 5. The Report Designer Control with a new, blank report. The first time I ran this, I got an error message telling me I didn’t have the proper license to use the report creation API (see Figure 6).
Figure 6. This error message displays in Visual FoxPro when you don’t have proper licensing to use the Report Creation API. Basically, this message is saying you don’t have a license to create a report from scratch. When I contacted Crystal Decisions about this, they sent me a 30 day evaluation license for the Designer control. When I installed the API Keycode they sent me, the designer worked fine. This message indicates a licensing change from previous versions of Crystal Reports. Licensing is discussed in detail in Chapter 18, “Licensing and Distribution.” However, when I pass a file name, the error message does not display. The following code shows how to do this. You must pass a fully qualified file name. Figure 7 shows the designer with a report. DO FORM Designer WITH “C:\CR\ADO1.RPT”
310
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 7. The Report Designer Control with a report. When I found the Designer works when given a report file, I created a blank report using the normal Crystal Reports designer and passed the filename to the designer form. This works fine for creating a blank report. Beware, though, this seems to be a hole in the licensing engine Crystal Decisions may plug.
Working with the designer The Embeddable Report Designer Control has the following properties shown in Table 1. These are available through the Property sheet or programmatically.
Chapter 13: The Report Designer Control
311
Table 1. This table lists the properties of the Designer Control. Property
If True, makes a case-insensitive search of SQL Data. Determines the date/time type to use for reports. Possible values: crConvertDateTimeToDate = 1 crConvertDateTimeToString = 0 crKeepDateTimeType = 2 If True, converts NULL fields to their default values. If True, makes available the list of fields, databases, formulas, parameters, group names, running totals, special, and unbound fields. If True, displays the grid. If True, displays hidden sections. If True, displays rulers. If True, displays the toolbar. If True, enables the Help button on the toolbar and makes help from the menu visible. See “Providing Help” later in this chapter. If True, turns on snap to grid. Determines the size of the grid in inches. The default is 0.083. A reference to the report object. If True, uses ASCII extended characters if they exist in a data file memo field. If True, uses ASCII extended characters if they exist in a data file character field. If True, uses indeces to improve query speed. If True, verifies the database structure every time the report displays or prints.
There is only one method in the Report Design Control. The SaveReport method is used to save the report. The control does not automatically save the report and does not prompt you if you destroy the control without saving. SaveReport(cReport) cReport
Character
The fully qualified filename for the report file.
Providing Help When the EnableHelp property is true, it enables the Help button on the toolbar and makes Help entries on the shortcut menu available. You must provide your own help file because Crystal Decisions does not supply one for distribution. If you do not provide a help file, an error message displays when the user attempts to access help (see Figure 8).
312
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 8. This message displays when EnableHelp is true, but no Help file is specified. The help file you provide must be a Windows Help (.hlp) file. Compiled HTML help files are not supported. You specify the help file with a registry setting. Use the key: HKEY_LOCAL_MACHINE\SOFTWARE\Seagate Software\Report Designer Component.
Set the value of CRDesignerCtHelpPath to the fully qualified filename of your Help file.
Using the Designer Control It is quite easy to use the Designer Control. The toolbar along the top equates to the same buttons in the standard Crystal Reports designer. The left side displays the Field View. From here, the user can right-click an item to display the Database Expert, Formula Expert, Data Explorer, or several other Experts and dialog boxes, just as you saw earlier in this book. You can also right-click a text or field object to change its properties.
Summary The Embeddable Designer Control is a fully featured, distributable designer that gives your users the same powerful design capabilities of the regular Crystal Reports product. However, the limitations on the developer and the additional licensing and royalty requirements may make you think twice about providing users with report design features. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book
Chapter 14: Exporting Reports
313
Chapter 14 Exporting Reports One of the most powerful features of Crystal Reports is its export capability. You can export reports to several different formats or even directly into a database. Exporting is supported in the designer, Viewer Control, and programmatically.
When you view a report in the designer or runtime Viewer Control, you have the ability to export a report. When you select this option, the Export dialog box displays for you to select an export type (see Figure 1).
Figure 1. Use the Export dialog box to select an export type. While the exact formats available depends on the options you selected at installation, you can generally expect to see Acrobat (PDF), Microsoft Word, Excel, several text formats, and ODBC. My installation lists the following: •
Adobe Acrobat (PDF)
•
Crystal Reports (RPT)
•
HTML 3.2
•
HTML 4.0
•
MS Excel 97-2000
•
MS Excel 91-2000 (Data Only)
•
MS Word
•
ODBC
•
Record style (columns no spaces)
314
CrysDev: A Developer’s Guide to Integrating Crystal Reports •
Record style (columns with spaces)
•
Report Definition
•
Rich Text Format
•
Separated Values (CSV)
•
Tab-separated text
•
Text
•
XML
In addition to the Format, you specify the Destination. My installation of Crystal Reports lists the following: •
Application
•
Disk File
•
Exchange Folder
•
Lotus Domino
•
Lotus Domino Mail
•
MAPI
You will most likely export to a disk file. Be aware that while Crystal Reports does a decent job of exporting to the different formats, some are not be ideal. The quality of an export is based on the format you select and the complexity of the report. As a general rule, the more complex the report, the lower the quality of the export. A separate DLL supports each export format and destination. For example, you use Crxf_pdf.dll to export to PDF files. If you don’t distribute this file, end users will not be able to export to PDF files. Complete information on format and destination DLL files is found in Chapter 18, “Licensing and Distribution.”
Programmatic exports The ExportOptions object supports exporting a report programmatically. The following code shows how to instantiate this object: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\CR\CustomerListing.RPT") oExport = oRpt.ExportOptions()
The ExportOptions object has several properties you can use to change how the exported file will look. Table 1 lists these properties.
Chapter 14: Exporting Reports
315
Table 1. This table contains the properties of the ExportOptions object. Property
The name of the destination when exporting to an application. The character used to separate every field when exporting to character delimited formats. The character used to delimit character fields when exporting to character delimited formats. The export DLL Crystal Reports uses internally when it does the export. This is dependent on what you set for DestinationType. The export destination type. Must be one of these values: crEDTApplication = 5 crEDTLotusDomino = 6 crEDTDiskFile = 1 crEDTMicrosoftExchange crEDTEMailMAPI = 2 =4 crEDTEMailVIM = 3 crEDTNoDestination = 0 The fully qualified file name when exporting to a disk file. If exporting to HTML, use HTMLFileName. If exporting to XML, use XMLFileName. The base area group number when exporting to Excel. Use when the area type is group area. The base area type when exporting to Excel. Use this when not using constant column width. Must be one of these values: crDetail = 4 crPageHeader = 2 crGroupFooter = 5 crReportFooter = 8 crGroupHeader = 3 crReportHeader = 1 crPageFooter = 7 The column width. Valid only when exporting to Excel. If True, converts dates to strings. Valid only when exporting to Excel. If True, exports all pages of the report. Valid only when exporting to Excel. The first page number when exporting to Excel. The last page number when exporting to Excel. If True, inserts page breaks into the exported Excel document. If True, places column headings in the exported Excel document. If True, sets each Excel column the same width. If True, makes the exported data tabular. Valid only when exporting to Excel. If True, places worksheet functions to calculate subtotals in the Excel document. The Microsoft Exchange destination type. Valid only when exporting to Exchange. Must be one of these values: crExchangeFolderType = 0 crExchangePostDocMessage = 1011 The path of the Exchange folder. The password to use to logon Exchange. The user profile to use when exporting to Exchange.
316
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Character Character Character Character Character Numeric
N N N N N N
ODBCDataSourceName
Character
N
If True, turns on the column heading option when exporting to Exchange. The format DLL Crystal Reports uses internally when it does the export. This is dependent on what you set for FormatType. The format type. Must be one of these values: crEFTCharSeparated crEFTHTML40 = 32 Values = 7 crEFTLotus123WK1 = crEFTComma 12 SeparatedValues = 5 crEFTLotus123WK3 = crEFTCrystalReport = 1 13 crEFTCrystal crEFTLotusWKS = 11 Report7 = 33 crEFTNoFormat = 0 crEFTData crEFTODBC = 23 Interchange = 2 crEFTPaginatedText = crEFTExact 10 RichText = 35 crEFTPortableDoc crEFTExcel50 = 21 Format = 31 crEFTExcel50 crEFTRecordStyle = 3 Tabluar = 22 crEFTReportDefinition crEFTExcel70 = 27 = 34 crEFTExcel70 crEFTTabSeparated Tabluar = 28 Text = 9 crEFTExcel80 = 29 crEFTTabSeparated crEFTExcel80 Values = 6 Tabular = 30 crEFTText = 8 crEFTExcel97 = 36 crEFTWordforWindows crEFTExplorer = 14 32Extended = 25 crEFTXML = 37 crEFTExplorer 32Standard = 24 If True, generates multiple pages when exporting to HTML. The filename to use when exporting to HTML. If True, places a page navigator on each page of an HTML report. The comments for the Lotus Domino document. The Lotus Domino database for storing the exported report. The Lotus Notes name to use when exporting to Domino. The Blind Carbon Copy list. Valid only when exporting to a VIM e-mail account. The Carbon Copy list for e-mailed reports. The body of the message for e-mailed reports. The subject to use when e-mailing reports. The list of people being sent the e-mail report. The mail user name. The number of lines per page for paginated text exports. The DSN to use for ODBC exports.
The user id to use for the ODBC data source The table to hold the exported data. If the table doesn’t exist, it is created. A reference to the Report object. If True, exports all report pages to the PDF file. This property must be set to False to set the PDFFirstPageNumber and PDFLastPageNumber. The first page to export to the PDF file. The last page to export to the PDF file. If True, exports all report pages to the RTF file. This property must be set to False to set the RTFFirstPageNumber and RTFLastPageNumber. The first page to export to the RTF file. The last page to export to the RTF file. If True, uses the default characters per inch setting. The characters per inch to use. If True, uses the date format used for the report in the exported report. This property is valid for DIF, Record Style, comma, tab, or character delimited export types. If True, exports the XML schema to a separate file from the report data. Saves the schema to either an XSD or a DTD file, depending on the setting in the XML Forma dialog box. The name of the XML file.
The ExportOptions object has the following methods and neither has any parameters. oExport.PromptForExportOptions()
When you call this method, the normal Crystal Reports export dialog boxes display. oExport.Reset()
The Reset method sets all the ExportOption properties to their default values. You actually cause the export to happen by calling the Export method of the Report object orpt.Export(lPrompt) lPrompt
Logical
If True, displays the export dialog box to the user.
318
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Exporting to files The most common type of export is to a disk file. In this section, I show you the dialog boxes that display when exporting to different file types and how to programmatically perform the same export. I don’t attempt to cover all the possible export formats, just the most commonly used file types. For all the examples in this chapter, I chose the Financial Statement sample report that ships with Crystal Reports. On my computer, I found this file in C:\Program Files\Crystal Decisions\Crystal Reports 9\Samples\En\Reports\General Business. I chose this report because it contains many Crystal Reports features such as formulas, totals, subreports, graphics, and charts. After loading the report in the designer, click the Export button on the Standard toolbar and select the proper format and Disk file as the Destination. Each time, the Export Options dialog box displays (see Figure 2). In all the examples, I select all pages.
Figure 2. The Export Options dialog box allows you to select the report pages you want to export. The dialog boxes that display are also used in the regular Crystal Reports application, the runtime Viewer control, and if you call the PromptForExportOptions method of the ExportOptions object.
Adobe Acrobat (PDF) Adobe’s Acrobat is an extremely popular format because it can be viewed on a wide variety of systems. A user only needs the Acrobat viewer, which is available free from the Adobe web site (http://www.adobe.com). Crystal Reports does an excellent job exporting to a PDF file. You do not need an additional PDF distiller as the Crystal Reports export engine handles everything for you. After selecting to export all pages, Crystal Reports displays the standard Windows Save As dialog box where you select a path and enter a filename for the PDF file. Now the exported report displays in the Adobe Acrobat Reader (see Figure 3).
Chapter 14: Exporting Reports
319
Figure 3. The exported PDF report displays in the Adobe Acrobat Reader. Here’s the code to create the same export: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType = 31 && PDF oExport.PDFExportAllPages = .T. oExport.DiskFileName = "D:\Temp\Financial Statement.PDF" oRpt.Export(.F.)
Microsoft Word When you export to Microsoft Word, you get the same dialog boxes as for a PDF file. Earlier versions of Crystal Reports only did a so-so job of exporting to Word, but Crystal Reports 9 improves the export and does a decent job (see Figure 4). The chart is converted to a graphic and placed in the document.
320
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 4. The exported Word document displays in Word’s Print Preview. Here’s the code for the Word export: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType = 14 && MS Word oExport.DiskFileName = "D:\Temp\Financial Statement.DOC" oRpt.Export(.F.)
Microsoft Excel Exporting to Excel has two options, MS Excel 97-2000 and MS Excel 97-2000 (Data only), each with its own set of options and results. MS Excel 97-2000 When you choose this format type, Crystal Reports displays an Excel Format Options dialog box (see Figure 5).
Chapter 14: Exporting Reports
321
Figure 5. The Excel Format Options dialog box displays when exporting to MS Excel 97-2000. I kept all the defaults as shown in Figure 5. Click OK and a Save As dialog box displays. The chart exports as a graphic, but there are a few problems (see Figure 6). As you see, the columns for each quarter did not line up properly. The page break in Crystal Reports causes this, because it did not correspond to the same page break in Excel. Even attempting to adjust the column width in the Excel Format Options dialog box did not change the layout of the export. Another problem is the column totals export as numbers rather than formulas. One possible solution is to use the Excel Data Only export, which I discuss in the next section.
Figure 6. The exported MS Excel 97-2000 report.
322
CrysDev: A Developer’s Guide to Integrating Crystal Reports Here’s the code to produce the same Excel export:
LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType = 29 && Excel 80 oExport.ExcelAreaType = 4 && crDetail oExport.ExcelTabHasColumnHeadings = .T. oExport.ExcelPageBreaks = .F. oExport.ExcelExportAllPages = .T. oExport.DiskFileName = "D:\Temp\Financial Statement.XLS" oRpt.Export(.F.)
MS Excel 97-2000 (Data only) Use this export type when you want to strip all the formatting from a report and only export the data. After you select the export type, an Excel Format Options dialog box displays (see Figure 7).
Figure 7. This Excel Format Options dialog box displays when exporting to MS Excel 97-2000 (Data only). Again, I kept the default settings in the Excel Format Options dialog box. The resulting spreadsheet has no formatting (see Figure 8). The graph again exports as a graphic.
Chapter 14: Exporting Reports
323
Figure 8. The exported MS Excel 97-2000 (Data only) report. Here’s the code to produce this export: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType = 30 && crEFTExcel80Tabular oExport.ExcelConstantColumnWidth = 36.0 oExport.ExcelTabHasColumnHeadings = .T. oExport.ExcelUseWorksheetFunctions = .F. oExport.DiskFileName = "D:\Temp\Financial Statement.XLS" oRpt.Export(.F.)
Rich Text Format (RTF) Rich Text Format (RTF) is a text format that uses markup symbols to indicate fonts, colors, and other formatting similar to HTML. While RTF is supposed to be application neutral, there are different versions of RTF. For example, after exporting the report, I opened the resulting RTF file in both Word and WordPad with very different results (see Figure 9 and Figure 10).
324
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 9. The exported RTF file viewed in Microsoft Word.
Figure 10. The exported RTF file viewed in WordPad.
Chapter 14: Exporting Reports
325
The code to create an RTF file is fairly simple: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType = 35 && crEFTExactRichText oExport.DiskFileName = "D:\Temp\Financial Statement.RTF" oRpt.Export(.F.)
HTML Exporting a report to HTML creates a new set of problems. With a large report, Crystal Reports creates either many files or a large file that could take some time to load in the browser. When you choose to export to HTML, the Select Export File dialog box displays (see Figure 11).
Figure 11. Use the Select Export File dialog box to set options for exporting to HTML.
326
CrysDev: A Developer’s Guide to Integrating Crystal Reports
When you export to HTML, Crystal Reports places all the exported files in the directory specified in the Directory Name field. You choose the drive and parent directory to place the new directory. Use the Base File Name to determine the name of each file exported. I chose CH14. Crystal Reports adds the HTML extension. The file name of each exported file begins with the value you enter. You add a Page Navigator allowing the user to move from page to page in a report. If you select Separate HTML Pages, it generates one HTML file per report page. If you do not select this option, it generates a single HTML file. Any graphics or charts in a report export as PNG files. When I exported a report to an HTML 4.0 file using the options in Figure 11, I ended up with two HTML files, one for each page, and three PNG files, one for each graphic and one for the chart (see Figure 12).
Figure 12. Crystal Reports generates multiple files when exporting a report to HTML. Crystal Reports does a good job of exporting to HTML (see Figure 13). If you View Source of the HTML file, you see the use of Cascading Style Sheet classes and a lot of DIV, SPAN, and TABLE tags.
Chapter 14: Exporting Reports
Figure 13. The resulting HTML page viewed in a browser. Here’s the code to produce the same export: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType= 32 && crEFTHTML40 oExport.HTMLEnableSeparatedPages = .T. && Use multiple pages oExport.HTMLHasPageNavigator = .T. oExport.HTMLFileName = "D:\Temp\html\CH14.HTML" oRpt.Export(.F.)
327
328
CrysDev: A Developer’s Guide to Integrating Crystal Reports
XML Crystal Reports supports exporting to XML that conforms to a standard or custom schema. The standard schema, called the Crystal ML Schema, is found at http://www.crystaldecisions.com/xml/schema.xsd. When you choose to export to XML, the Export to Directory dialog box (see Figure 14) displays.
Figure 14. The Export To Directory dialog box displays when you export to XML. An XML export is similar to an HTML export in that you can create multiple files. However, only one file generates when you use the default export. This file uses the standard Crystal XML Schema. Figure 15 shows the results of the export.
Chapter 14: Exporting Reports
329
Figure 15. The default XML export viewed in Internet Explorer. Here’s the code: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Financial Statement.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.FormatType = 37 && crEFTXML oExport.XMLAllowMultipleFiles = .F. oExport.XMLFileName = "D:\Temp\xml\Financial_Statement.XML" oRpt.Export(.F.)
To customize the schema, launch Crystal Reports and open your report. Select Report | XML Expert from the menu. The XML Expert displays (see Figure 16).
330
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 16. Select the Options tab of the XML Expert to use a custom schema. Select the Custom Format option. If you want to generate an external schema, select either XSD or DTD. If you select XSD, you enter additional text to place in the XML file. Simply selecting these options does not customize anything. They just produce an external schema file instead of using the standard schema. You customize a schema on the Format tab of the XML Expert dialog box (see Figure 17).
Chapter 14: Exporting Reports
331
Figure 17. Use the Format tab of the XML Expert to define a custom schema. On this tab, you suppress any group or band in a report with the Suppress XML Tag option. You can set additional attributes or select the Create button to define new ones (see Figure 18).
332
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 18. Define new attributes in the XML Attribute dialog box. Once you define a custom schema, the export process is the same as before.
Comma Separated Values (CSV) A comma separated values (CSV) file is a text file that contains data. A comma most often separates each field and double quotes contain strings. When you select this option, the Character-Separated Values dialog box displays (see Figure 19). The default values are set to a comma and double quotes for a delimiter.
Figure 19. Use the Character-Separated Values dialog box to set field delimiters when exporting to a CSV file. When you click OK, the Number and Date Format Settings dialog box displays (see Figure 20) to set the type of formatting to use in the file.
Chapter 14: Exporting Reports
333
Figure 20. Set additional options in the Number and Date Format Settings dialog box. Next, a Save As dialog box displays where you set the filename and directory. It uses a default CSV extension. However, I could not export the example report. I got an error dialog box stating Crosstabs and OLAP grids are not supported in this export format. I tried the export again using a simpler sample file, Inventory.rpt. Figure 21 shows the results of the export.
Figure 21. Results of exporting to a CSV file. I found the exported results to be less than satisfactory. Page header and footer information repeats several times and the data and group headers are on lines by themselves. Nonetheless, here’s the code to produce this export: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions
334
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Tab-Separated Text When you export to tab-separated text, only a Save As dialog box prompts you for information. Crystal Reports uses a default TTX extension. Figure 22 shows the resulting file.
Figure 22. Exporting to a tab-delimited file yields somewhat useful results. I found the resulting file more useful than the comma-separated file as report header and footer information did not repeat throughout. Here’s the code: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ;
Text A text report is a text file that contains the report data. You are first prompted to select the number of lines per page in the Lines Per Page dialog box (see Figure 23), and then the number of characters per inch in the Export To Text dialog box (see Figure 24).
Figure 23. You set the number of lines per page when exporting to a text file.
Figure 24. The number of characters per inch is typically set to 10 or 12.
336
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The export of the Financial Statement sample report did not work well at all. The file shows only the data for the first detail line in each group. However, the Inventory sample report works well, with all the data showing up (see Figure 25).
Figure 25. The export to a text file for the Inventory sample report. Here’s the code: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Inventory.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && Disk File oExport.NumberOfLinesPerPage = 60 oExport.UseDefaultCharactersPerInch = .F. oExport.FormatType = 8 && crEFTText oExport.DiskFileName = "D:\Temp\Inventory.TXT" oRpt.Export(.F.)
Chapter 14: Exporting Reports
337
Report Definition A report definition is a text file that describes a report. Basically, it is documentation about the report (see Figure 26). When you choose this export format, Crystal Reports displays a Save As dialog box with the file name having a default .txt extension.
Figure 26. A Report Definition is documentation about a report. Here’s the code to produce the same export file: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Inventory.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 1 && crEDTDiskFile oExport.FormatType = 34 && crEFTReportDefinition oExport.DiskFileName = "D:\Temp\Inventory.TXT" oRpt.Export(.F.)
338
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Exporting to an application Exporting to an application is similar to exporting to a disk file except it creates a temporary file. You don’t specify a file name, as Crystal Reports generates one. The same dialog boxes and programmatic settings apply, except you change the Export Options object DestinationType property. Once the export completes, the target application launches and the exported report displays.
Exporting to MAPI MAPI is a protocol used for handling e-mail. When you export to MAPI, you need to specify a Format and MAPI as the Destination in the Export dialog box (see Figure 1). The exported file is sent as an attachment to the e-mail. I tried both PDF and HTML export with mixed results. The PDF file works well, but only one of the five HTML export files attaches to the e-mail. I use Microsoft Outlook as my e-mail client and connect with a POP3 account. It prompts me to enter a recipient, subject, and message (see Figure 27). After clicking the Send button, a security warning from Outlook notifies me that another application is attempting to send an email. I allow the message to go through. I then check my Inbox and find the e-mail with the attached report.
Figure 27. The Send Mail dialog box displays when you export to MAPI. Here’s the code: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions
Chapter 14: Exporting Reports
339
oCR = CREATEOBJECT("CrystalRuntime.Application") oRpt = oCR.OpenReport("C:\Program Files\Crystal Decisions" ; + "\Crystal Reports 9\Samples\En\Reports\General Business" ; + "\Inventory.RPT") oExport = oRpt.ExportOptions() oExport.DestinationType = 2 && crEDTEMailMAPI oExport.FormatType = 31 && crEFTPortableDocFormat oExport.DiskFileName = "D:\Temp\Inventory.PDF" oExport.MailToList = "[email protected]" oExport.MailSubject = "Test PDF MAPI Export" oExport.MailMessage = "This is a test of the PDF export" oRpt.Export(.F.)
When I run this code, I still get the security warning from Outlook, but the Send Mail dialog box does not display. Also, to specify multiple recipients, separate each address with a semi-colon.
Exporting to ODBC When you export to an ODBC data source, Crystal Reports creates a new table in the selected ODBC data source. The Destination option of the Export dialog box (see Figure 1) is disabled. The ODBC Formats dialog box displays (see Figure 28). You must select from the list of existing DSNs. You cannot create a DSN from inside Crystal Reports.
Figure 28. You must choose an existing DSN to export to ODBC. If you select an ODBC data source that requires authentication, it prompts you to enter the Login Id and Password. Once authenticated, Crystal Reports displays the Enter ODBC Table Name dialog box (see Figure 29). In this dialog box, enter the name of the table to create.
340
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 29. Enter the name of the table to create in the export. In order to export to ODBC, you may have to strip all totals, subtotals, graphics, grouping, and so on from a report. I had some trouble with both the Inventory and Customer profile sample reports. I finally select the Group.rpt sample report and remove the problem fields. A report then exports without problems to the Northwind database of SQL Server (see Figure 30).
Figure 30. Exporting to ODBC creates a new table in the data source. Here’s the code for exporting to ODBC: LOCAL oCR AS CRAXDRT.Application LOCAL oRpt AS CRAXDRT.Report LOCAL oExport AS CRAXDRT.ExportOptions
Summary Crystal Reports supports exporting to several different formats. You can set all the options programmatically or display dialog boxes to the user so they can choose their own settings. The results of the export vary depending on the complexity of the report and the selected export format. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book
342
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Chapter 15: Integrating COM Components
343
Chapter 15 Integrating COM Components By adding custom COM components to your application, you can implement additional functionality of Crystal Reports such as hooking into events and providing custom formula functions.
This chapter discusses using COM with Crystal Reports. Yes, I know when I enter code something like this: oCR = CREATEOBJECT(“CrystalRuntime.Application”)
I am using COM. However, this chapter focuses on creating COM components Crystal Reports uses. There are two places where you can use custom COM components. First, you can add custom functions to Crystal formulas and second, you can hook into events the RDC generates.
Formulas revisited In Chapter 8, “Using Formulas,” you learned Crystal Reports has its own programming language to do additional processing or formatting. You also saw several functions that are provided to do things like rounding, data type conversion, provide date and time, and much more. You can also provide your own custom functions inside a COM component. These custom functions are called User Function Libraries. When you create the COM component, there are a few rules you must follow: •
The component must be a COM DLL.
•
The DLL name must start with the letters CRUFL.
•
You must specify the data type for all parameters and return values.
•
The physical location of the DLL on the disk doesn’t matter, as Crystal Reports finds User Functions Libraries by scanning the registry.
•
Crystal Reports only looks for User Function Libraries when it launches. This means you can’t launch Crystal Reports, create the DLL, and expect it to be available.
I built a simple DLL, called CRUFLDemo, with a single method that adds two numbers and returns the result. Here’s the code: DEFINE CLASS CrystalUFL AS Session OLEPUBLIC FUNCTION Add(Number1 AS Integer, Number2 AS Integer) AS Integer LOCAL Result Result = Number1 + Number2
344
CrysDev: A Developer’s Guide to Integrating Crystal Reports
RETURN Result ENDFUNC ENDDEFINE
After you compile and register the DLL, launch Crystal Reports, open a report, and then add a new Formula Field. In the Formulas list, drill down to Additional Functions | Visual Basic UFLs. It lists your User Function Library (see Figure 1).
Figure 1. You access User Function Libraries in the Formula Workshop. Once Crystal Reports recognizes your UFL, you can use it in formulas just like any builtin function. However, because the function is written with your programming language of choice, you have the full capabilities of the language. This means you can pull data from data sources, do any type of calculation, or access web services. The only limitation is your development tool.
Events The Report and Section objects of the RDC have several events that fire as a report processes. You make use of these events by writing code that hooks into the event handler. When the event fires, your code automatically runs.
Report events The report object has four events. The first, AfterFormatPage, fires after the page is formatted.
Chapter 15: Integrating COM Components
345
AfterFormatPage(nPageNo) nPageNo
Numeric
The page number that triggers the event.
BeforeFormatPage fires before a page is formatted. BeforeFormatPage(nPageNo) nPageNo
Numeric
The page number that triggers the event.
The FieldMapping event triggers if the database changes while being verified. FieldMapping(aReportField, aDatabaseField, lUseDefault aReportField aDatabaseField lUseDefault
Array Array Logical
The report field array to map. The database field array to map. If True, ignores the values passed in aReportField and aDatabaseField and uses the default values.
If there is no data for a report, the NoData event triggers. NoData(lCancel) lCancel
Logical
If True, the report cancels.
Hooking into Report events In order to hook your custom code into the Crystal Reports events, you need to identify them. Visual FoxPro makes this easy: 1.
From the Visual FoxPro menu, select Tools | Object Browser. The Object Browser displays (see Figure 2).
346
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 2. Use the Visual FoxPro Object Browser to examine COM components. 2.
Click the Open Type Library button (left-most button) on the Object Browser toolbar. An Open dialog box displays.
3.
Select the COM Libraries tab (see Figure 3).
Chapter 15: Integrating COM Components
347
Figure 3. Select the COM components you want to examine in the Object Browser on the COM Libraries tab of the Open dialog box. 4.
Scroll down the list to locate “Crystal Report 9 ActiveX Designer Run Time Library.”
5.
Choose this component by selecting the check box next to the item.
6.
Click OK. You return to the Object Browser (see Figure 4).
348
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 4. You return to the Object Browser after selecting the Crystal Reports RDC component. 7.
Expand the listing under CRAXDRT, and then expand again under Interfaces.
8.
Scroll down the list until you reach IReportEvent (see Figure 5).
Chapter 15: Integrating COM Components
349
Figure 5. The Object Browser after locating the Report event interface object. 9.
Drag IReportEvent from the Object Browser and put it in a new program file. Visual FoxPro automatically creates the stub code for you. The code now looks like this:
x=NEWOBJECT("myclass") DEFINE CLASS myclass AS session OLEPUBLIC IMPLEMENTS IReportEvent IN ; "c:\program files\crystal decisions\report designer component\craxdrt9.dll" PROCEDURE IReportEvent_NoData(pCancel AS LOGICAL) AS VOID ; HELPSTRING "Fires this event when there is no data"
350
CrysDev: A Developer’s Guide to Integrating Crystal Reports
* add user code here ENDPROC PROCEDURE IReportEvent_BeforeFormatPage(PageNumber AS Number) AS VOID; HELPSTRING "Fires this event before formatting a page" * add user code here ENDPROC PROCEDURE IReportEvent_AfterFormatPage(PageNumber AS Number) AS VOID ; HELPSTRING "Fires this event after formatting a page" * add user code here ENDPROC PROCEDURE IReportEvent_FieldMapping(reportFieldArray AS VARIANT, ; databaseFieldArray AS VARIANT, useDefault AS LOGICAL) AS VOID ; HELPSTRING "Fires this event if database is changed while verifing database" * add user code here ENDPROC ENDDEFINE
You see the four events listed in the code. Do not remove any of the methods for the events. If you do, you get an error. One of the rules about implementing interfaces is you must have code for each event, even if you don’t use it. Replace the * add user code here with the code you want to run when the event fires. Because you are using your own development tool, you are only limited to what your development tool can do. The last thing you need to do is bind your event handler to the actual component that fires the event. This is done with Visual FoxPro’s EVENTHANDLER function. This function takes two parameters; the first is the component that triggers the event and the second is the name of your event handler. The sample code here uses the Inventory sample report that ships with Crystal Reports. I renamed the event handler code from the default myclass to ReportEventHandler. Here’s the updated code to run the report and handle the events: LOCAL LOCAL LOCAL LOCAL
loEventHandler loCrystal AS CRAXDRT.Application loReport AS CRAXDRT.Report llSuccess
* Instantiate the RDC loCrystal = CREATEOBJECT("CrystalRuntime.Application") * Get the report object loReport = loCrystal.OpenReport("C:\CR\Inventory.RPT") * Instantiate the event handler class loEventHandler = CREATEOBJECT("ReportEventHandler") * Bind the event handler to the events in the section llSuccess = EVENTHANDLER(loReport, loEventHandler) IF llSuccess * If the event binding was successful, print the report
Chapter 15: Integrating COM Components
351
loReport.PrintOut(.F.) * Unbind the event handler EVENTHANDLER(loReport, loEventHandler, .T.) ENDIF * Define the event handler class DEFINE CLASS ReportEventHandler AS session OLEPUBLIC IMPLEMENTS IReportEvent IN ; "c:\program files\crystal decisions\report designer component\craxdrt9.dll" PROCEDURE IReportEvent_NoData(pCancel AS LOGICAL) AS VOID ; HELPSTRING "Fires this event when there is no data" * Write a message to the log STRTOFILE("No Data Event." + CHR(13) + CHR(10), "C:\CR\EventLog.TXT", .T.) ENDPROC PROCEDURE IReportEvent_BeforeFormatPage(PageNumber AS Number) AS VOID ; HELPSTRING "Fires this event before formatting a page" * Write a message to the log STRTOFILE("Before Format Page Event. Page No: " ; + TRANSFORM(PageNumber, "999") + CHR(13) + CHR(10), ; "C:\CR\EventLog.TXT", .T.) ENDPROC PROCEDURE IReportEvent_AfterFormatPage(PageNumber AS Number) AS VOID ; HELPSTRING "Fires this event after formatting a page" * Write a message to the log STRTOFILE("After Format Page Event. Page No: " ; + TRANSFORM(PageNumber, "999") + CHR(13) + CHR(10), ; "C:\CR\EventLog.TXT", .T.) ENDPROC PROCEDURE IReportEvent_FieldMapping(reportFieldArray AS VARIANT, ; databaseFieldArray AS VARIANT, useDefault AS LOGICAL) AS VOID ; HELPSTRING "Fires this event if database is changed while verifing database" * Write a message to the log STRTOFILE("Field Mapping Event.", "C:\CR\EventLog.TXT", .T.) ENDPROC ENDDEFINE
This code writes a message to a log file when each event fires (see Figure 6). Notice I don’t ever make a call to any of the event methods. Crystal Reports does this automatically because the event handler is bound to the Report object.
352
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 6. The log file created by running the sample Report object event handler code.
Section events The section object has a single event, Format, which fires before a section is formatted. In your event handler, you modify the objects in the section being formatted. Format(oFormattingInfo) oFormattingInfo
Object
An object that contains information about the section being formatted.
Table 1 shows the properties of the FormattingInfo object. It has no methods. Table 1. Properties of the FormattingInfo object. Property
Type
Read Only
Description
IsEndOfGroup
Logical
Y
IsRepeatedGroupHeader
Logical
Y
IsStartOfGroup
Logical
Y
If True, places the section being formatted at the end of the group. If True, makes the section being formatted a repeated group header. If True, places the section being formatted at the beginning of the group.
The formatting process is very complicated and each section may actually be formatted more than once. For this reason, you should do calculations, set flags, or other items during formatting. The purpose of this event is to allow you to modify objects in the section being formatted. At any one time, a section may be in one of three modes: •
Formatting Idle—no formatting is happening. This mode indicates you are going between pages or you are going into preview or print mode.
Chapter 15: Integrating COM Components
353
•
Formatting Active—a section and its objects are being formatted. Only one section at a time is in Formatting Active.
•
Formatting Inactive—when one section is being formatted (Format Active) all other sections are in Formatting Inactive mode.
To create event handler code, use the Object Browser discussed earlier in this chapter, with one exception. You need to drag-and-drop the ISectionEvent instead of the IReportEvent (see Figure 7).
Figure 7. The Object Browser showing the selection of the section event.
354
CrysDev: A Developer’s Guide to Integrating Crystal Reports Here’s the stub code that is created:
x=NEWOBJECT("myclass") DEFINE CLASS myclass AS session OLEPUBLIC IMPLEMENTS ISectionEvent IN ; "c:\program files\crystal decisions\report designer component\craxdrt9.dll" PROCEDURE ISectionEvent_format(pFormattingInfo AS VARIANT) AS VOID ; * add user code here ENDPROC ENDDEFINE
Separate image files One common use of the Session event is to print images, changing the image file for each record. Here are the steps to do this: 1.
Create a new blank report.
2.
Add the database field that contains the filename. You can add this to any section. The sample code assumes it is in the detail section.
3.
Add an image. This image is replaced by the one referenced in the field.
4.
Save the report.
The following code changes the image when you print the report using the RDC. * Declare the variables LOCAL loEventHandler LOCAL loCrystal AS CRAXDRT.Application LOCAL loReport AS CRAXDRT.Report LOCAL loSection AS CRAXDRT.Section LOCAL llSuccess * Instantiate the RDC loCrystal = CREATEOBJECT("CrystalRuntime.Application") * Get the report object loReport = loCrystal.OpenReport("C:\CR\FilePic.RPT") * Get a reference to the detail section loSection = loReport.Sections("D") * Instantiate the event handler class loEventHandler = CREATEOBJECT("MyEventClass", loSection) * Bind the event handler to the events in the section llSuccess = EVENTHANDLER(loSection, loEventHandler) IF llSuccess
Chapter 15: Integrating COM Components
355
* If the event binding was successful, print the report loReport.PrintOut(.F.) * Unbind the event handler EVENTHANDLER(loSection, loEventHandler, .T.) ENDIF * Create the event handler class DEFINE CLASS MyEventClass AS Session IMPLEMENTS ISectionEvent IN "CrystalRuntime.Application” oSection = NULL PROCEDURE Init(toSection AS Object) AS Boolean * Save the reference to the section in the class property This.oSection = toSection ENDPROC PROCEDURE ISectionEvent_format(pFormattingInfo AS VARIANT) AS VOID; HELPSTRING "Fires this event before starting to format a section" LOCAL loSection, loFileName, loPicture * Save a referene to the section loSection = This.oSection * Save the reference to the file name field object. * It's the first object in the section loFileName = loSection.ReportObjects(1) * Save a reference to the picture object. * It's the second object in the section loPicture = loSection.ReportObjects(2) loPicture.FormattedPicture = LOADPICTURE(loFileName.Value) ENDPROC ENDDEFINE
Decisions made changes to the internal COM servers in Crystal Reports Crystal 9. In the process of doing this, a bug was introduced that prohibits the above code from running in Visual FoxPro. However, it works in Crystal Reports 8 and 8.5. If you are using VFP, I recommend creating a component in Visual Basic that handles the Section events for you.
Report variables In Chapter 9, “The RDC: Introduction, Printing, and Databases,” I introduced the RDC Report object. There are three methods of the Report object that provide capabilities for using Report variables during the section formatting event. Use report variables to do calculations during formatting. Keep in mind the format event may be called many times so you should not depend on the number of times the event occurs in your calculations.
356
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The first method is AddReportVariable. You can probably guess what this method does. Here’s the syntax: oRpt.AddReportVariable(nVarType, cVarName, [aArraySize], [Reserved]) nVarType
Numeric
cVarName aArraySize Reserved
Character Array Unknown
The data type of the variable. Must be one of these values: crRVBoolean = 2 crRVNumber = 0 crRvCurrency = 1 crRVString = 6 crRvDate = 3 crRVTime = 4 crRvDateTime = 5 The variable name. Reserved. Do not use. Reserved. Do not use.
Once you add the report variable, set its value with the SetReportVariableValue method. oRpt.SetReportVariableValue(cVarName, xValue) cVarName xValue
Character Variant
The variable name. The data type of this value depends on the data type you use when creating the variable with the AddReportVariable method.
Finally, you access the report variable in your event handling code with the GetReportVariableValue method. xValue = oRpt.GetReportVariableValue(cVarName) cVarName
Character
The variable name.
Summary You now know how to provide custom functions for Crystal Reports formulas and hook into Crystal Report events. For the most part, the only limits are the capabilities of your development tools and the databases you connect to. By creating custom functions and event handlers, you can greatly extend the capabilities of Crystal Reports. Updates and corrections to this chapter can be found on Hentzenwerke’s web site, www.hentzenwerke.com. Click “Catalog” and navigate to the page for this book
Chapter 16: Web Reporting
357
Chapter 16 Web Reporting With the Internet growing more prolific everyday, more and more companies are turning to the web-based reporting solutions. Whether you are generating reports on the Internet, Intranet, or Extranet, Crystal Reports offers several web reporting solutions.
In previous chapters, I touched on some of the web-enabled capabilities of Crystal Reports. In Chapter 2, “Touring Crystal Reports,” you briefly saw how to create hyperlink fields. I will discuss these in more detail later in this chapter. Chapter 14, “Exporting Reports,” discussed exporting to HTML and PDF. You could put these files on a web server and view them in a browser. However, Crystal Reports also provides several ways of doing web reporting: •
Integrating the RDC into Active Server Pages—discussed in this chapter.
•
Using the Report Application Server (RAS)—also covered in this chapter.
•
Using Microsoft Visual Studio .NET Web Forms—discussed in Chapter 17, “Crystal Reports .NET.”
•
Using Crystal Enterprise.
Enterprise provides full featured web-based reporting and includes Crystal capabilities like real-time and scheduled reporting, processing across multiple servers, customized user interfaces, and more. The use of Crystal Enterprise is beyond the subject of this book.
Report design revisited There are several features you can include in a report to make navigation and design easier for the web. These are embedded hyperlinks, cascading style sheet support, navigation, and report parts.
Embedded hyperlinks Many of the objects on a report can have hyperlinks defined for them. The user clicks the link, to display the referenced web page. To create a hyperlink: 1.
Right-click the object in the Crystal Reports designer.
2.
Select Format from the shortcut menu. The Format Editor displays.
3.
Select the Hyperlink tab (see Figure 1).
4.
Select the Hyperlink type.
358
CrysDev: A Developer’s Guide to Integrating Crystal Reports 5.
Enter the Hyperlink information. If it is a web site, enter the URL. If it is an e-mail address, enter the correct address. If you link to a file, enter the fully qualified path name.
6.
Click OK to save the changes.
Figure 1. Set the hyperlink properties in the Format Editor dialog box. The Current Website Field Value and Current E-mail Field Value options are only enabled if the referenced field contains the proper link. The DHTML Viewer Only options are used for the Report Application Server, discussed later in this chapter.
Chapter 16: Web Reporting
359
Cascading style sheets Crystal Reports also supports cascading style sheets for most report objects. To assign a CSS class to a report object: 1.
Right-click the object in the Crystal Reports designer.
2.
Select Format from the shortcut menu. The Format Editor displays.
3.
Select the Common tab (see Figure 2).
4.
Enter the Object Name. This is not required, but is recommended.
5.
Enter the CSS Class Name.
6.
Click OK to save the changes.
Figure 2. Set the cascading style sheet class on the Common tab of the Format Editor dialog box.
360
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The cascading style sheet class applies to reports in the Report Application Server, but not those exported to static HTML files.
Navigation Navigation works similar to a hyperlink, except instead of moving to a web page, e-mail, or external file, it links to another object on the report or on a different report. Navigation only works with the Report Application Server DHTML viewer. The following steps show how to link report objects for navigation: 1.
Open the target report.
2.
Select the target object of the report.
3.
Right-click the target object and select Copy from the shortcut menu.
4.
Open the source report.
5.
Select the object the user will click for navigating to the target object.
6.
Right-click the object and select Format from the shortcut menu.
7.
Select the Hyperlink tab.
8.
Click Another Report Object.
9.
In the Select From text box, right-click and select Paste from the shortcut menu (see Figure 3).
Chapter 16: Web Reporting
361
Figure 3. You link to an object on another report by entering data in the Hyperlink information section of the Format Editor dialog box. There are three text fields in the Hyperlink information section of the Format Editor that need explanation. The first is Select From. This specifies the report you want to link to. You need to enter the fully qualified path name for the report. The Object Name is the object on the linked report. Finally, Data Context specifies the location for the link. This could be a specific customer or the first customer starting with the letter C or a specific date. Table 1 lists sample Data Context formulas.
362
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 1. Sample data context formulas. Explanation
Example Formula
Standard XPath-like Strongly-Typed Detail-level information (0 based) Wildcard Cross-Tab
Report Parts Report parts also work with the DHTML viewer of the Report Application Server. However, instead of displaying the entire page of the report, only selected items display in a special viewer called the Report Part Viewer. The following steps demonstrate how to set up Report Parts: 1.
In the report designer, select the target object.
2.
Right-click and select Copy from the shortcut menu.
3.
Select File | Report Options from the menu. The Report Options dialog box displays (see Figure 4).
4.
Right-click in the Object Name field and select Paste from the shortcut menu. The copied information about the target object is entered in the Object Name and Data Context fields. This specifies the initial object that appears in the Report Part Viewer. If you skip this step, the Report Part Viewer just displays a blank page.
5.
To include additional objects in the report part, add the object names to the Object Name field, separating them by a comma. All objects for the Report Part must be in the same section of the report.
6.
Click OK to save changes and close the Report Options dialog box.
Chapter 16: Web Reporting
363
Figure 4. Enter the Initial Report Part Settings in the Report Options dialog box. If you include a chart, map, summary field, or a field in a group header or footer, you can provide drill down in the Report Part. This allows you to control which object is referenced when the user clicks the chart, map, or field. You set this on the Hyperlink tab of the Format Editor (see Figure 5).
364
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 5. Set Report Part drill down on the Hyperlink tab of the Format Editor.
Working with ASP Creating hyperlinks, navigation, Report Parts, and drill downs are not the only way to work with web reporting. You can call the RDC from your ASP pages and use one of several report viewers in your web application to display the results. Crystal Decisions considers this type of integration to be legacy and recommends you now use the Report Application Server, discussed later in this chapter. As you start looking at ASP reporting, you will find no sample files included. However, some support files are needed. They are located in C:\Program Files\Crystal Decisions\Crystal Reports 9\Samples\En\Code\Web\Report Designer Component and listed in Table 2.
Chapter 16: Web Reporting
365
Table 2. A list of ASP reporting support files. File
Removes any instance of the RDC from memory. The HTML viewer uses to setup frames. The start page for the HTML viewer. The shared code to interface the viewer with the RDC. ActiveX viewer for Internet Explorer. ActiveX viewer for Netscape. Java viewer for Internet Explorer. Java viewer for Netscape. Toolbar for the HTML viewer.
As you can see, there are several viewers to use. The HTML Viewer provides the most browser compatibility, but many Crystal Reports features, such as drill down, are not available. These features are available in the Smart Viewers. I show you how to use these in the sample code. When creating ASP web reporting applications, you first create a new Virtual Directory in the IIS Manager. I created one called CrystalRDC. You then copy all the support files and the needed reports into the virtual directory. Your ASP code should do three things: •
Create an Application object.
•
Create a Report object.
•
Create a PageEngine object.
The following code shows the creation of the objects, and then displays (see Figure 6) the Chart.RPT sample report that ships with Crystal Reports. <%language="VBSCRIPT"%> ASP Reporting Example <% ' Instantiate the Application Object Set session("oApp") = server.createobject("CrystalRuntime.Application") ' Open the report Set session("oRpt") = session("oApp").OpenReport("c:\crystalrdc\chart.rpt", 1) ' Turn off Parameter Prompting session("oRpt").EnableParameterPrompting = false ' Create the PageEngine Set session("oPageEngine") = session("oRpt").PageEngine %>
366
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 6. Use the Smart Viewer ActiveX control in your web pages to get full preview and drill-down capabilities. The example I present is fairly simple, but it shows the basics you need to get started with web reporting. You will want to create a more robust application that checks for the existence of the Application object, has error handling, and more. Crystal Decisions has several sample applications you can download from their web site. Search for the file ASPXMPS9.exe.
Page rendering objects Crystal Reports has several objects you can manipulate to change the way reports are rendered in the browser. Generally, you won’t need to do anything with the PageEngine as it automatically handles the creation of the report. The PageEngine object In the “Working with ASP” section, you saw code referring to the PageEngine object. This object is used to render the report for a web browser. It also handles sending pages to the browser. Only one page at a time is sent to the browser. The PageEngine object has several methods and properties, listed in Table 3.
Chapter 16: Web Reporting
367
Table 3. This table lists properties of the PageEngine object. Property
Type
Read Only
Description
ImageOptions
Numeric
N
Parent PlaceHolderOptions
Object Numeric
Y N
ValueFormatOptions
Numeric
N
The image type for the EPF format. Possible values: crDIBImageType = 1 crImageUnknown = 0 crJPEGImageType = 2 A reference to the parent Report object. The EPF place holder options. Possible values: crAllowPlaceHolders = 2 crDelayTotalPageCount Calc = 1 The EPF value format options. Possible values: crAllowComplexField crIncludeFieldValues = 1 Formatting = 4 crIncludeHiddenFields = 2
The first method, CreatePageGenerator, creates a PageGenerator object. Set session("oPageEngine") = session("oRpt").PageEngine Set PageGen = session(“oPageEngine”).CreatePageGenerator(GroupPath, [DrillLevel]) GroupPath
Array
DrillLevel
Unknown
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group. This parameter reserved for future use. Do not use.
The RenderTotallerETF method returns a variant containing ETF data for the group tree. session(“oPageEngine”).RenderTotallerETF(GroupPath, ChildNo, RootLevels, MaxNode, ResultType) GroupPath
Array
ChildNo RootLevels MaxNode ResultType
Numeric Array Numeric Numeric
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group. The starting child number to display. Past root levels. The maximum number of nodes for each group. Specifies if the page is rendered using arrays or strings. Note that it currently only supports arrays (crUISafeArrayType = 8209).
The RenderTotallerHTML method returns a variant that contains HTML data for the group tree.
368
CrysDev: A Developer’s Guide to Integrating Crystal Reports
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group. The starting child number to display. Past root levels. The maximum number of nodes for each group. Specifies if the page is rendered using arrays or strings. Note that it currently only supports arrays (crUISafeArrayType = 8209).
The PageGenerator object The PageGenerator creates page objects to send to the browser. It has several methods and its properties are listed in Table 4. Table 4. This table lists the properties of the PageGenerator object. Property
Type
Read Only
Description
ContainingGroup Name ContainingGroup Path ContainingPage Number DrillDownLevel GroupName GroupPath Pages Parent ReportName XOffset YOffset
Character
Y
The containing group name for out of place subreport views.
Variant
Y
The group path for out of place subreport views.
Numeric
Y
The page number for out of place subreport views.
Unknown Character Variant Object Object Character Numeric Numeric
Y Y Y Y Y Y Y Y
The property is currently not used. The group name for drill down on a graph. The group path. A reference to the Pages collection. A reference to the parent PageEngine object. The report name for drill down on a subreport. The object’s x-offset. The object’s y-offset.
The CreateSubreportPageGenerator method creates a PageGenerator object for subreports. SubPageGen = PageGen.CreateSubreportPageGenerator(GroupPath, [DrillLevel]) GroupPath
Array
DrillLevel
Unknown
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group. This parameter reserved for future use. Do not use.
The DrillOnGraph method creates a PageGenerator object when the user drills down on a graph.
The page number. The X coordinate where the drill down occurs. This value is in twips The Y coordinate where the drill down occurs. This value is in twips.
The DrillOnMap method creates a new PageGenerator object when the user drills down on a map. MapDrillPage = PageGen.DrillOnMap(PageNo, xOffset, yOffset) PageNo XOffset YOffset
Numeric Numeric Numeric
The page number. The X coordinate where the drill down occurs. This value is in twips. The Y coordinate where the drill down occurs. This value is in twips.
The DrillOnSubreport method creates a new PageGenerator object when the user drills down on a subreport. SubRepDrillPage = PageGen.DrillOnSubreport(PageNo, xOffset, yOffset) PageNo XOffset YOffset
Numeric Numeric Numeric
The page number. The X coordinate where the drill down occurs. This value is in twips. The Y coordinate where the drill down occurs. This value is in twips.
The Export method returns an export data stream. cExport = PageGen.Export(nResultType) nResultType
Numeric
The result type. Currently, crUISafeArrayType = 8 is the only supported type.
The FindText method is used to locate a specific text string in the current drill down view. It returns True if the specified text is found. lFound = PageGen.FindText(cText, nDirection, nPageNo) cText nDirection
Character Numeric
nPageNo
Numeric
The text to search for. The direction for the search. Must be one of these values: crForward = 0 crBackward = 1 The page number where the search should begin.
GetPageNumberForGroup returns the page number where the specified group begins nPageNo = PageGen.GetPageNumberForGroup(GroupPath) GroupPath
Array
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group.
370
CrysDev: A Developer’s Guide to Integrating Crystal Reports
The RenderTotallerETF method is used to generate ETF data for the group tree. It returns a variant. vETF = PageGen.RenderTotallerETF(GroupPath, ChildNo, RootLevels, MaxNode, ResultType) GroupPath
Array
ChildNo RootLevels MaxNode ResultType
Numeric Array Numeric Numeric
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group. The starting child number to display. Past root levels. The maximum number of nodes for each group. Specifies if the page is rendered using arrays or strings. Note that it currently only supports arrays (crUISafeArrayType = 8209).
The RenderTotallerHTML method is used to generate HTML data for the group tree. It returns a variant. vHTML = PageGen.RenderTotallerHTML(GroupPath, ChildNo, RootLevels, MaxNode, ResultType) GroupPath
Array
ChildNo RootLevels MaxNode ResultType
Numeric Array Numeric Numeric
A zero-based array that specifies the group path. If the array is empty, it references the entire report. (0, 1) would mean to drill down on the second group in the first group. The starting child number to display. Past root levels. The maximum number of nodes for each group. Specifies if the page is rendered using arrays or strings. Note that it currently only supports arrays (crUISafeArrayType = 8209).
The Pages collection The Pages collection holds Page objects. It is a standard Crystal Reports collection. It has no additional methods or properties. You get a reference to the Pages collection from the Pages property of the PageGenerator object: oPages = PageGen.Pages
The Page object A Page object is a single generated page sent to the browser. It is created by the PageEngine object. It has two methods and Table 5 lists its properties.
Chapter 16: Web Reporting
371
Table 5. This table lists the properties of the Page object. Property
True if the page is the last page of the report. True if the page misses the total page count.
Numeric Object
Y Y
The page number of the generated page. A reference to the parent PageGenerator object.
The RenderEPF method returns the EPF stream for the rendered page. vEPF = Page.RenderEPF(ResultType) ResultType
Numeric
Specifies if the page is rendered using arrays or strings. Note that it currently only supports arrays (crUISafeArrayType = 8209).
The RenderHTML method returns the HTML stream for the rendered page. vHTML = Page.RenderHTML(lDrillDown, nPageStyle, nTbStyle, cURL, ResultType) lDrillDown
Logical
nPageStyle
Numeric
nTbStyle
Numeric
cURL ResultType
Character Numeric
If True, the HTML contains hyperlinks for drilling down to summary data The style of the HTML page to be rendered. Must be one of these values: crFramePageStyle = 2 crToolbarAtTopPage crPlainPageStyle = 0 Style = 3 crToolbarAtBottomPage crToolbarPageStyle = 1 Style = 4 The style of the toolbar. You can XOR these values. Must one of these values: crToolbarRefreshButton = 1 crToolbarSearchBox = 2 The URL to access the report when it is first generated. Specifies if the page is rendered using arrays or strings. Note that it currently only supports arrays (crUISafeArrayType = 8209).
Customizing the Viewer When specifying the viewer to use in the web browser (see Figure 6), you can customize the toolbar features that appear in the viewer. If you look at SmartViewerActiveX.ASP, you see code that specifies the actual ActiveX control.
It lists the parameters with the values set to 1. If you set the values to 0, the specified control does not display.
The Report Application Server For several years, Crystal Decisions sold a high-end, web report server called Crystal Enterprise. Crystal Reports 9 introduces a scaled-down version of Crystal Enterprise, called the Report Application Server, (RAS). Crystal Decisions recommends you use RAS instead of standard RDC integration when creating web reports. This is because RAS gives you the ability to separate report processing across multiple servers and upgrades easily to Crystal Enterprise when you need a more robust report server. RAS is included on a separate CD with Crystal Reports. Once you install it, Crystal Enterprise 9 is added to your Windows Start menu. One new option is found under Tools | RAS Configuration Manager (see Figure 7).
Figure 7. Use the RAS Configuration Manager to set various RAS options.
Chapter 16: Web Reporting
373
The RAS Configuration Manager is where you change how RAS functions. For example, you can change the report directory, temporary files directory, and how to select and display resulting data. Another Windows Start menu option is Crystal Enterprise 9 | Report Application Server Launchpad (see Figure 8). You can also view the launchpad from your browser. Navigate to http://<webserver>/rassamples. The launchpad is a portal to the ePortfolio Lite sample and to several Crystal Decisions web sites.
Figure 8. Use the RAS Launchpad to access a sample application or other websites. Once the RAS Launchpad displays in your browser, click ePortfolio Lite to launch the sample application (see Figure 9). The full ePortfolio sample application ships with Crystal Enterprise.
374
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 9. A view of the ePortfoloio Lite sample application. You will notice several of the options are disabled. These features, such as Alerts, Favorites, Organize, LogOn, and Schedule are not supported on RAS and are only available with Crystal Enterprise. When you click Preferences, a new browser displaying User Preferences launches (see Figure 10). Select Hide advanced Crystal Enterprise features to not show the features unavailable in RAS. You can also choose the browser you want to use; HTML Page Viewer (see Figure 11), HTML Interactive Viewer (see Figure 12), or Report Parts Viewer (see Figure 13). Click OK to close the User Preferences form and save your changes.
Chapter 16: Web Reporting
Figure 10. You set different options on the User Preferences form. To view a report, click View or the report icon next to the report name on the main ePortfolio Lite page. A new browser window opens displaying the selected report (see Figure 11).
375
376
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Figure 11. The Group Data sample report viewed in the HTML Interactive Viewer.
Figure 12. The Group Data sample report viewed in the HTML Page Viewer.
Chapter 16: Web Reporting
377
Figure 13. The Group Data sample report viewed in the Report Parts Viewer. Much of the same functionality available in the standard ActiveX viewer you embed in your Visual FoxPro or Visual Basic form is available here. Drill down is available along with page navigation, export, print, search, and zoom. You can also display an Advanced Search Wizard (see Figure 14) to more precisely find items in the report. The Advanced Search Wizard is only available in the HTML Interactive Viewer.
Figure 14. The Advanced Search Wizard allows refined searching of the report.
378
CrysDev: A Developer’s Guide to Integrating Crystal Reports
When you select export, the Export form displays (see Figure 15). RAS supports exports to Crystal Reports RPT, PDF, Microsoft Word, Excel, and RTF files. Once you click Export, a file download dialog box appears in the browser, allowing you to save the file to any directory.
Figure 15. Use the RAS Export form to select the export type and page range. Printing from RAS is different than printing regular web pages. You can’t simply use the print button in your web browser because only the displayed page of the report will print. To print the entire report, click the Print button on the RAS toolbar to display the Print Report dialog box (see Figure 16). Select the page range and click Print. Again, a File Download dialog box displays. Select Open to display the PDF file, and then print from the Acrobat toolbar.
Chapter 16: Web Reporting
379
Figure 16. Use the Print dialog box to print a report rather than the print button of your web browser.
Customizing the RAS The Report Application Server contains Active Server Pages (ASP) that call Automation servers, called the RAS SDK. The RAS SDK is discussed later in this chapter. The ePortfolio Lite sample application does not take full advantage of the RAS SDK, but rather uses mostly ASP pages. Because of this, the easiest way to learn how to customize RAS is to modify the ePortfolio Lite application. When you install RAS, by default it places the ePortfolio Lite sample in C:\Program Files\Crystal Decisions\Report Application Server 9\Samples. Before you begin, you need to copy these files to a backup location. As part of the installation, a virtual directory is setup in IIS to point to these files. Table 6 lists the ASP files used in ePortfolio Lite. Because I chose the default installation path, these files are located at C:\Program Files\Crystal Decisions\Report Application Server 9\Samples\En\ASP\rPortfolio on my computer.
380
CrysDev: A Developer’s Guide to Integrating Crystal Reports
Table 6. Web server files used by ePortfolio Lite. File
Contains default values for new users. The initial ePortfolio Lite page. This page lists each report and provides a link to display it. The preferences page. Stores localized strings. VB Script functions used in other ASP pages. Default Cascading Style Sheet. Various Java script files used by the ASP pages. Various graphics files used by ePortfolio Lite. The HTML Interactive Viewer. The HTML Page Viewer. The Report Parts Viewer. The ActiveX Viewer. Called automatically to clean up objects remaining in the user’s session when a viewer browser window is closed. The Java plug in viewer. Creates an instance of the object factory (discussed later in this chapter). Launches the appropriate viewer.
As you can see, there aren’t many files required to run RAS, and even fewer you need to modify. The Cascading Style Sheet (CSS) file determines much of the look and feel of the web pages. For example, you can replace all instances of Verdana with Courier New to change the fonts used. Several options on the main ePortfolio Lite page are disabled by default. Each user can change their preferences to not display those options, but it may be easier to not display them in the first place. The following steps explain how to do this. 1.
Edit ReportListing.ASP. This is just a text file, so you can use NotePad or your favorite text editor or web page design tool.
2.
Search for the third instance of the word Alert. You should now be on this line:
<% if m_MainView = "0" then %><% end if %>
3.
At the beginning of the line, enter the start comment symbols. The line should now look like this: