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

Crystal Reports

Crystal Reports VCL Component

 

 

 

 

Subreports

Subreports

 

 

Summary Info

SummaryInfo

Before attempting to use these properties, please read the following section:

Dealing with SubClass Objects

Since the architecture of the VCL has changed substantially from previous releases, here is a brief programming introduction to acquaint you with the changes. As mentioned in the Introduction, the main change in the architecture is the implementation of numerous subclasses.

An example: the Tables object

For example, the Tables subclass now encapsulates all the functionality of what was called Datafiles and DatafilesLocation in the previous releases. This subclass consists of 10 properties and 8 methods. Of the 10 properties, the most essential are these three:

Number

Name

Path

Formerly, the Datafiles property was programmed like this:

Crpe1.Datafiles[0] := 'c:\MyNewPath\MyNewTable.dbf';

The subscript "[0]" represented the table number, 'c:\MyNewPath\' represented the Path, and 'MyNewTable.dbf' represented the table name. With the new VCL, the Tables object would be used instead of the Datafiles stringlist. So the same statement would be coded like this:

Crpe1.Tables.Add(0);

Crpe1.Tables.Path := 'c:\MyNewPath\';

Crpe1.Tables.Name := 'MyNewTable.dbf';

The Add method instructs the Tables object to add an item with table number zero. Instead of this, you could use the Retrieve method, which retrieves all the table information from the report (this is the same as what was formerly called RetrieveDatafiles):

Crpe1.Tables.Retrieve;

After Retrieve has been called, you need to instruct the Tables object to navigate to the item whose properties you want to change. This is necessary because the Tables object only looks at one table at a time. Think of it as something similar to scrolling through the records of a database. There are a number of properties that can be used to navigate through the object: Item, ItemIndex, and Number.

Seagate Crystal Visual Component Library

203

Each object in the Crystal VCL that can contain more than one item, uses an internal Index to maintain which item it is currently looking at, similar to the ItemIndex property of a list box. This Index is updated whenever the Item property is used (LogOnInfo[2], for example), or whenever the key property (if applicable) is assigned a new lookup value. Key properties are things like Formulas.Name, or SortFields.Number; properties that contain a unique value for each item, and which serve as look up properties. They appear as drop-down lists in the Object Inspector.

Number is the key property for the Tables object. Assigning a new value to the Number property will not overwrite the value stored there, but will rather cause the Tables object to try and find that new value, and point to the table that has the value. For example:

Crpe1.Tables.Number := 2;

This will cause the Tables object to look internally for a table with the number 2. If it finds it, the object will now point it's properties to that table and will remain pointing there until it is changed. That is one way of navigating through the tables.

The ItemIndex property can also be used to navigate through the Tables object:

Crpe1.Tables.ItemIndex := 2;

Although in this case, ItemIndex represents the position of the table in the internal Tables list, not necessarily the table number (although if Retrieve is used, these should be the same).

By far the easiest and most natural way of navigating through the Tables object is the default array property, Item. Since this is a default property, it does not need to be specified when making the call, so Tables[2] is the same as Tables.Item[2]. And since the Item property returns a reference to the Tables object, it is possible to add other properties to the end of the subscript:

Crpe1.Tables[2].Path := 'c:\MyNewPath\';

Crpe1.Tables[3].Name := 'MyNewTable.dbf';

While initially this might seem like a lot more work, it actually is much more powerful, especially when dealing with items that have a dozen properties, such as the SectionFormat object. With SectionFormat, the old method involved passing a large string of about a dozen items separated by semicolons. Even if you only wanted to set one property, you still had to pass the whole string. With the new object format, you only need to set the property that you want to change.

Consistent Code

One of the reasons for making the properties into objects is that the coding syntax is more consistent. For example, there are a number of methods associated with the Tables object:

Crpe1.Tables.Retrieve;

Crpe1.Tables.Count;

Crpe1.Tables.Clear;

Seagate Crystal Visual Component Library

204

They are much easier to code and to remember, and more consistent, than the old calls:

Crpe1.RetrieveDatafiles;

Crpe1.GetNDatafiles;

Crpe1.Datafiles.Clear;

And since each object in the new Component uses the same naming convention for the same methods, they are very easy to remember.

Using the Retrieve method

It is important to remember that in the older versions of the Component, most of the properties were derived from modified stringlists and the declaration Crpe1.Datafiles[0] would add a string to the list of subscript 0. The new Component's subclass objects do not work the same way. Instead, there are two methods now used to add an item to the list.

The first, and preferred way, is to use the Retrieve method. This retrieves the table information from the report, and stores it in the Tables object, so that all the necessary table items are already present. You just need to set the object to the desired table and then change the desired properties. This would be coded as:

(* Retrieves tables from report *) Crpe1.Tables.Retrieve;

(* Modifies path of first table *) Crpe1.Tables[0].Path := 'c:\MyNewPath\'; (* Modifies name of first table *) Crpe1.Tables[0].Name := 'MyNewTable.dbf';

For changing the path of more than one table at a time, a simple loop can be constructed. Since the tables property is now an object, it was easy to add methods and properties to it that made it behave like a stringlist. So the Count method and ItemIndex properties were added, as well as the default array property, Item. The Item property allows you to treat the Tables object as if it were a stringlist (Tables[0] is equivalent to Tables.Item[0]):

(* Retrieves tables from report *)

Crpe1.Tables.Retrieve;

for cnt := 0 to (Crpe1.Tables.Count - 1) do begin

(* Modifies path of table *)

Crpe1.Tables[cnt].Path := 'c:\MyNewPath\';

end;

Seagate Crystal Visual Component Library

205

The second way of adding items to the Tables object would be to do it manually by using the Add method. The Retrieve method is not called. Instead it is up to the programmer to know how many tables are in the report, or to know which tables he wants to change. This method would be coded like as:

(* Adds table 0 to Tables object *) Crpe1.Tables.Add(0);

(* Set path of first table *) Crpe1.Tables.Path := 'c:\MyNewPath\'; (* Set name of first table *) Crpe1.Tables.Name := 'MyNewTable.dbf';

In the above example, it is not necessary to include the subscript [n] after the Tables object name. This is because the Tables object has an internal index that keeps track of which Table item it is currently looking at. To be compatible with future revisions of the Component, it would better to use a subscript as follows:

(* Adds table 0 to Tables object *)

Crpe1.Tables.Add(0);

(* Set path of table just added *)

Crpe1.Tables[Crpe1.Tables.Count - 1].Path := 'c:\MyNewPath\';

(* Set name of table just added *)

Crpe1.Tables[Crpe1.Tables.Count - 1].Name := 'MyNewTable.dbf';

Working with subreports

If the report has subreports, the subreports names can be stored in the Seagate Crystal Component by using the Subreports object and its Retrieve method:

Crpe1.Subreports.Retrieve;

When this call is made, a Tables object is set up for each subreport. Subreport tables are handled in exactly the same way as shown above except that you must specify which subreport you are working with before handling the Tables object:

(* Retrieves the subreports *)

Crpe1.Subreports.Retrieve;

(* Sets the Component to subreport 1 *)

Crpe1.Subreports[1];

(* Retrieves the tables for subreport 1 *)

Crpe1.Tables.Retrieve;

It is important to remember, the Subreports object stores the main report information as the first item in the object, so Subreports[0] refers to the main report. Of course, the Subreport object can also be handled manually through it's Add method instead of using the Retrieve method, but in most cases, this will prove to be more difficult to code and to maintain.

Seagate Crystal Visual Component Library

206

Here is a simple code example which illustrates how to fill the Seagate Crystal Component with report information, which can then be edited and sent back to the Print Engine:

Crpe1.ReportName := 'c:\MyCrystalReport.rpt';

Crpe1.Subreports.Retrieve;

Crpe1.Printer.Retrieve;

Crpe1.PrintOptions.Retrieve;

Crpe1.SummaryInfo.Retrieve;

for cnt := 0 to (Crpe1.Subreports.Count - 1) do

begin

Crpe1.Subreports[cnt];

Crpe1.LogOnInfo.Retrieve;

Crpe1.Connect.Retrieve;

(* Do not do SQL Retrieve here because it slows down loading while trying to Logon to the Server. Use the SQL.Retrieve method after filling in the Password property of the Connect or LogOnInfo objects *)

Crpe1.SQL.Params.Retrieve;

Crpe1.Tables.Retrieve;

Crpe1.Selection.Retrieve;

Crpe1.GroupSelection.Retrieve;

Crpe1.Formulas.Retrieve;

Crpe1.ParamFields.Retrieve;

Crpe1.GraphType.Retrieve;

Crpe1.GraphText.Retrieve;

Crpe1.GraphData.Retrieve;

Crpe1.GraphOptions.Retrieve;

Crpe1.SectionFormat.Retrieve;

Crpe1.SectionFormatFormulas.Retrieve;

Crpe1.AreaFormat.Retrieve;

Crpe1.AreaFormatFormulas.Retrieve;

Crpe1.SectionFont.Retrieve;

Crpe1.SectionMinHeight.Retrieve;

Seagate Crystal Visual Component Library

207

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