Scripts in FastReport

General information

Unlike the other report generators, a script in FastReport contains only what you write yourself. In a script, you can:

  • add your variables, methods, and properties to the script's main class;
  • create handlers of report object events;

You cannot: 

  • add new classes to a script, if necessary. A class can be added both before the main ReportScript class and after it.
  • remove, rename or change the visibility of the main class ReportScript;
  • rename the namespace which contains the main class.
  • FastReport adds the list of variables, whose names match the report object names, to the script. It is done before compiling the script and allows you to refer report objects by name;

 When launching the report:

  • expressions from the report are added to the script as functions;
  • the script is compiled, if it is not empty; 
  • variables that were added to the script inexplicitly are initialized;
  • event handlers, which are defined in the script, are bound to the report objects;
  • the report is launched.

Event handlers

Scripts are mostly used for creating object event handlers. To create an event handler, select the required object. On the Properties panel, click on the button to switch to the list of events:

Double click on the required event. FastReport will add an empty event handler to the report code:

private void Text2_BeforePrint(object sender, EventArgs e)
{
   
}

The Report object also has events. There are two ways to select this object:

  • select Report on the Report Tree panel;
  • select Report in the drop-down list on the Properties panel.

To remove an event handler, pick an event on the Properties panel, select an event name and press Delete:

 

Events

Each report object has several events, to which you can assign a handler - a method from the script. For example, you can filter entries in the handler bound to the Data band, i.e. hide or show in the band depending on certain conditions.

Let's take a look at creating a report and the events that are generated at it. As an example, we will use a simple report with one page, one band Data and two objects on the band:

At the start of the report, the StartReport event of the Report object is called. Before generating the page the StartPage event is called. This report is called once for each report template page (not to be confused with the report pages in the web part). In this example, no matter how many pages the report has on the web, the event is called once, since the report template consists of one page.

Next, the Data band rows are generated. The sequence of actions:

  1. the BeforePrint band event is called;
  2. the BeforePrint event of all the band objects are called; 
  3. all the objects are filled with data;
  4. the AfterData event of all the band objects are called;
  5. objects are placed on the band (if there are stretchable objects), the band height is calculated and the band is stretched (if it is stretchable);
  6. the BeforeLayout band event is called;
  7. the AfterLayout event is called; 
  8. if the band does not fit one page, a new page is generated;
  9. the band and all its objects are displayed on the report page in the web part;
  10. the AfterPrint event of all the band objects is called;
  11. the AfterPrint event of the band is called.

Band rows are generated until there are data in the source. After that, the report generation is complete and the FinishPage event of the report page is called and finally, the FinishReport event of the Report object is called.

Thus, using events of different objects, you can control almost every aspect of report generation. To use events correctly, you need to fully understand the process of generating bands. Most of the actions can be performed using only the BeforePrint band event – any changes made to the object will be immediately displayed. But you cannot tell in this event on which page the band will be displayed if it is stretchable because the band height is calculated at step 6. You can do it using the AfterLayout event in step 7 and the AfterPrint event in step 10; if you use the latter, the band will already have been generated and actions with objects will not have an effect. You must clearly understand when each of the events is called and use the most appropriate ones.

Referring to .NET objects

In a script you can refer any .NET objects, which are defined in the following assemblies:

System.dll
System.Drawing.dll
System.Windows.Forms.dll
System.Data.dll
System.Xml.dll

In addition, you can use any objects, defined in FastReport assemblies. If you need to access another assembly, add its name to the list of the report assemblies in Properties - Report - Script - Referenced Assemblies.

For example, if you want to use a function, declared in your application, in a script, add a link to the application assembly (.exe or .dll) to the list of report assemblies. After that, you can refer the function using the namespace of your application. For example, this function is declared in the application:

namespace Demo
{
  public static class MyFunctions
  {
    public static string Func1()
    {
      return "Hello!";
    }
  }
}

You can refer it in the script like this:

string hello = Demo.MyFunctions.Func1();

If you add the using Demo directive to the script, you can make the function reference shorter:

string hello = MyFunctions.Func1();

Referring to report objects

To refer report objects (e.g. Text) use the object name. The following example returns the height of the Text1 object:

float height = Text1.Height;

By default, the report units of measurement are pixels. Keep that in mind when referring to such object properties as Left, Top, Width, Height. To convert pixels to centimeters and back, use the constants, defined in the Units class:

float heightInPixels = Text1.Height;
float heightInCM = heightInPixels / Units.Centimeters;
Text1.Height = Units.Centimeters * 5; // 5cm

Referring to data sources

Unlike FastReport expressions (for more information, check this link), in a script, you cannot use brackets to refer to report data. Instead, the GetColumnValue method of the Report object is used, which returns the field value:

string productName = (string)Report.GetColumnValue("Products.Name");

As you can see, you need to specify the data source name and its fields separated by full stops. A source name can be composite if you refer the data source using relation. For more information, check this link. For example, this way you can address a field of a linked data source:

string categoryName = (string)Report.GetColumnValue("Products.Categories.CategoryName");

To make the work easier, use the Data panel. You can drag data elements to the script from there, while FastReport automatically creates code for referring the element.

To refer the data source itself, use the GetDataSource method of the Report object:

DataSourceBase ds = Report.GetDataSource("Products");

You can find information about the DataSourceBase class methods and properties in FastReport.Net Class Reference Help. Usually, this object is used in a script like this:

// get a link to the data source
DataSourceBase ds = Report.GetDataSource("Products");
// initialize it
ds.Init();
// go through all the entries in the source
while (ds.HasMoreRows)
{
  // get the field value for the current source entry
  string productName = (string)Report.GetColumnValue("Products.Name");
  // perform some actions with it...
  // ...
  // go to the next entry
  ds.Next();
}

Referring to system variables

To refer a system variable, use the GetVariableValue method of the Report object:

DateTime date = (DateTime)Report.GetVariableValue("Date");

The list of system variables is displayed on the Data panel. You can drag variables to the script from there, while FastReport automatically creates code for referring the variable.

Referring to total values

To refer a total value, use the GetTotalValue method of the Report object:

float sales = Report.GetTotalValue("TotalSales");

The list of total values is displayed on the Data panel. You can drag total values to the script from there, while FastReport automatically creates code for referring the total value.

A total value has the FastReport.Variant type. It can be directly used in any expressions because the FastReport.Variant type is automatically cast to any type. For example:

float tax = Report.GetTotalValue("TotalSales") * 0.2f;

You can refer to a total value once it has been calculated. Usually, a total value can be used when generating the band where it is placed.

Referring to report parameters

To refer a report parameter, use the GetParameterValue method of the Report object:

int myParam = (int)Report.GetParameterValue("MyParameter");

Parameters can be nested. In this case, specify the parent parameter name and the child parameter name separated by a full stop:

Report.GetParameterValue("ParentParameter.ChildParameter")

Parameters have a certain data type. It is specified in the DataType property of a parameter. Keep this in mind when referring a parameter. Parameters are displayed on the Data panel. You can drag parameters to the script from there, while  FastReport automatically creates code for referring the parameter.

To change a parameter value, use the SetParameterValue method of the Report object:

Report.SetParameterValue("MyParameter", 10);

Example 1. Changing the display of an object

This example shows how to change the object text depending on its value, using:

  •  the BeforePrint event;
  • reference to a database field from the script. 

Create a simple report:

For the object that displays the product price add the BeforePrint event handler:

private void Text2_BeforePrint(object sender, EventArgs e)
 
{
 
  if (((Decimal)Report.GetColumnValue("Products.UnitPrice")) > 20)
 
    Text2.TextColor = Color.Red;
 
}

To insert the value of the Products.UnitPrice field to the script, drag it from the Data panel. This line will be added to the script:

((Decimal)Report.GetColumnValue("Products.UnitPrice"))

The web page of the report will display all the products with price more than 20 red:

 

Example 2. Calculating total values

This example shows how to calculate a total value, using:

  • the BeforePrint band event;
  • reference to a database field in the script;
  • a local variable, whose value will be displayed in the report. 

Create a report similar to this one:

 

In the script, declare the total variable and add the BeforePrint event handler to the band:

public class ReportScript
{
  private decimal total;
 
  private void Data1_BeforePrint(object sender, EventArgs e)
  {
    total += (Decimal)Report.GetColumnValue("Products.UnitPrice");
  }
}

You can add the Products.UnitPrice table field to the script by dragging it from the Data panel.

The report will look like this: