Data Manager to RDL Conversion

This section explains some details on how reports defined in DataManager classes are converted to the Report Definition Language (RDL).

Notice that this mapping is done automatically at runtime . This document gives and overview on how the internal process of converting DataManagers to RDL work.

Overview

As described in the Reports in code section when a report is requested to the modernized application the ReportWatcher service is invoked when all the elements required for creating the report. These elements are (mainly):

  1. Report definitions in the RDL format

  2. Report data using XML and System.Data.DataSet format

The generation of the RDL format is performed at runtime from the definition of a DataManager. This conversion is performed based on the object model of a DataManager. The runtime system takes the definition and converts all of the parts of a DataManager to the RDL format. For example for a DataManager with a label control like this:

    this.name_t = new Mobilize.Web.DmText();
    this.name_t.Band = Mobilize.Web.CaseExtensions.String("detail");
    this.name_t.Alignment = 1;
    this.name_t.Text = "Name:";
    this.name_t.Border = 0;
    this.name_t.Color = "33554432";
    this.name_t.X = 37;
    this.name_t.Y = 4;
    this.name_t.Height = 64;
    this.name_t.Width = 174;
    this.name_t.Name = Mobilize.Web.CaseExtensions.String("name_t");
    this.name_t.Visible = true;
    this.name_t.Font.FontFace = "Tahoma";
    this.name_t.Font.Height = -10;

The conversion generates the following RDL Fragment for DataManager instances created with the previous snippet:


    0.01042in
    0.08333in
    0.39583in
    0.16667in
    true
    
    
        
        
            Name:
            
        
        
        
    
    

Notice that this conversion is performed at runtime. This is done this way to support dynamic operations performed on the DataManager at runtime .

DataManager layout vs RDL File organization

The following diagrams show how different top-level sections of a DataManager are converted to RDL.

Page configuration section:

This section contains properties for page width, height, margins, etc. (left: lines 14-18 in the left source file). These properties are converted to XML elements in RDL in lines 24-29.

Data configuration section

This section contains configuration for report data columns (left: lines 27-30). Theses columns are converted to RDL report Fields in the DataSet section (right: lines 8-12).

This section contains configuration for report header and footers (left: lines 27-30). Theses columns are converted to RDL report Fields in the DataSet section (right: lines 30-31).

Controls and report content

This section contains most of the elements of the report. Controls used inside the report are defined as class properties (left: lines 5-9) and also inside the DataManager constructor as a sequence of control property initialization (left: lines 32-40). These elements are converted to RDL elements inside the report body (right: line 18) .

Dealing with embedded reports

The DataManager to RDL conversion support embedded reports using the RDL Subreport element.

The following code snippet shows an embedded report inside a DataManager:

this.rpt_1 = new DmReport();
this.rpt_1.Band = "detail";
this.rpt_1.Name = "rpt_1";
this.rpt_1.DataObject = "my_subrepo";
this.rpt_1.Nest_Arguments = new string[] { "col1", "col1 + 1" };
this.rpt_1.X = 37;
this.rpt_1.Y = 4;
this.rpt_1.Width = 174;
this.rpt_1.Height = 64;

The DataObject property says which DataManager will be used to render the embedded report. This control is converted to RDL as follows:


  0.39583in
  0.16667in
  rpt_1
    
        
        = Fields!col1.Value 
        
        
        =Code.SumValues( Fields!col1.Value , 1)
        
    

The binding to the new report is performed by the ReportWatcher service. This service uses the ReportViewer.LoadSubReportDefinition to provide the definition of the embedded report .

Label reports

The original platform allowed the creation of a special DataWindow used to print labels. This concept is converted to a DataManager which is converted to a RDL report that tries to emulate the behavior of the original report.

The Tablix SSRS concept is used to emulate the layout of a label DataWindow . The general strategy to create a Tablix having row groups for blocks of labels, a column group is created to show several labels in the same row, with a dummy column at the end for spacing.

Crosstab reports

The CrossTab DataWindow, which presents data in a spreadsheet-like grid. A CrossTab lets users view summary data instead of a long series of rows and columns. The strategy was to use the Tablix SSRS concept to create a report using multiple Tablix elements to generate the matrix-like structure that emulates the same structure as the original DataWindow.

Limitations

There are some limitations to the DataManager to RDL conversion strategy. There are some techniques that were valid on the original platform but that could not be emulated in the target platform.

Here is a list of some of this issues

Position of elements could not be changed at render time

In the original platform the position, height or width of an element could be changed at runtime by evaluating a custom expresion. For example:

this.myLabel.X = "10\t opt_1 + 10"

In this cases the X property of the myLabel control is determined at runtime depending on the evaluation of the opt_1 + 10 expression. This in turn is evaluated for each row. In SSRS and RDL it's not possible to associate an expression to the position, with or height of an element or band.

To support this same behavior it is recommended to examine the original intension of the developer. As an example, the following snippet specify that the height of a label will be zero if the opt_1 = 100 condition is satisfied:

this.myLabel.Height = "10\t IF(opt_1 = 100,0, 10)"

In this case it's better to use the Visible property . This property supports expressions in SSRS.

Evaluation of code inside report expressions

The original platform supports calling global functions inside report expressions. This is not supported in the SSRS/RDL version since the report is being rendered outside of the application process.

In this case the DataManager to RDL conversion generates evaluation of report expressions that required access to original code as part of the data of the report. This allows the evaluation of the original expressions.

For example if a property is assigned as:

this.name_t.Text = "a\tmyglobalfunc(10)";

The generated report definition is going to have an additional field to stored the evaluation of this property:


    name_t__TEXT

The process that generates the data dump for the report data evaluates these expressions for each row of the DataManager. This data dump is passed to the ReportWatcher service to render the report.

Evaluation of code and render time properties

The original platform allowed the evaluation of functions which value could only be determined at render time. For example the Page() function which returns the current page of the report. Uses of this function are converted to the RDL equivalent Globals!PageNumber . However the evaluation of this property could not be combined with expressions evaluated on the server side .For example:

this.name_t.Text = "a\tmyglobalfunc(Page())";

This expression could not be converted to RDL since it requires both evaluating user code and evaluating a render time property.