DataDynamics Active Reports .NET
By Bill Jones

Excellent Product

ActiveReports.Net is an excellent product with outstanding license and demonstration philosophies. Data Dynamics sees ActiveReports as a developer tool, so they license the developer. You are charged for who uses the tool, not for who might view the report. For example, if a developer maintains ten web sites and ships two Windows applications, he buys one copy of the Professional edition for $1,299, not 12 copies. No royalties or Client Access Licenses are required. If your development is limited to Windows applications, you may want to use the Standard edition available for $499 per developer.

Data Dynamics wants to get the word out, so they make fully functional product available for download at no cost ( Granted, all reports generated with unregistered product spray a disclaimer across the report footing, but we have to wonder how many sales are made by developers showing the check signer a really neat report with the caveat "that goes away as soon as we buy the tool".

Once downloaded, the demonstration copy install nicely and integrates itself with Visual Studio.NET under the "Add New Item´┐Ż" context menu associated with the Solution Explorer window. A separate "Report Explorer" window is also provided. The report designer work pretty much as you would expect and offers a fairly shallow learning curve for any competent .NET developer who has ever worked with any other report designer.

ActiveReports.NET does have a few quirks, but we intend to overcome the major issues here. On a recent project implementing our first ActiveReports solution, it took us over 20 hours to figure out HTTPHandlers, when code-behind runs, where to set data sources, what a script is, how to copy a report, where the border properties are hidden and a few other special AR features such as the outstanding XCOPY deployment feature. We present a summary of the lessons learned in the hope you can get to the "good stuff" in an excellent product much more quickly than we did.

HTTP Handlers

The ActiveReports help file, samples and supporting documents spend a lot of time and energy on the use of HTTPHandlers . This technology allows .rpx files to be fired directly from IIS but the code behind is not executed using this scenario. HTTPHandlers require defining several file extensions using IIS Application Configuration and some custom entries to the projects web.config file. Since it seems much more natural for a .Net developer to use the events and capabilities of code behind to control data sources and formatting, this technology holds little attraction for us. We decided to keep it simple so we could use XCOPY deployment. Simple is always better since our hosting resources do not usually allow us to go thrashing around in IIS making changes.

When Code Behind Runs

It is very easy to spend days trying to figure out how to get a report's code behind file to work. In fact, many seasoned veterans end up concluding that the normal breakpoint and code debug features must not be available for AR code behind. But this is not correct. If you can't perform normal debug tasks in the VB.Net file associated with your report, then the code is not being called.

While a VB.Net code behind file is created for each report designed using the Visual Studio.NET IDE, the code in those files only gets fired if you instantiate the report as an object in some .NET calling program. Otherwise, C# scripts associated with a report (.rpx) will execute, but not the code behind.

For example, coding something like this in the web page Page_Load event, where "SampleReport" is an ActiveReport defined in the project will get the report's code behind to fire:

Dim rptMain as ActiveReport
rptMain = New SampleReport()
. . .

Controlling the data source

Once you have the code behind firing, controlling the data source becomes the next objective. One approach is to use a page class variable such as " rptMain " and a sub-routine to set the data source, picking up the connection string from the project's web.config file. Obviously, any connection string stored in a configuration file should be encrypted even though that is not shown in this example.

Private Sub SetDatasource( ByVal LobID As String , _
ByVal PlanYr As String )
Dim myRdr As SqlClient.SqlDataReader
Dim sCn As String = _

If sCn.Length = 0 Then Exit Sub

Dim myParms(2) As SqlParameter

Dim myParmLOB As New SqlParameter
With myParmLOB
.ParameterName = "@LOBID"
.IsNullable = False
.SqlDbType = SqlDbType.Int
.Direction = ParameterDirection.Input
.Value = CType (LobID, Integer )
End With

myParms(0) = myParmLOB
Dim myParmPlanYr As New SqlParameter
With myParmPlanYr
.ParameterName = "@PlanYr"
.IsNullable = False
.SqlDbType = SqlDbType.Int
.Direction = ParameterDirection.Input
.Value = CType (PlanYr, Integer )
End With

myParms(1) = myParmPlanYr

Catch ex As Exception

Exit Sub
End Try

myRdr = SqlHelper.ExecuteReader(sCn, CommandType.StoredProcedure, _
"rpt_LOB", myParms)

rptMain.ShowParameterUI = False
rptMain.DataSource = myRdr

Catch ex As Exception

End Try
End Sub


You can create a custom constructor in the report code behind that allows you to pass in parameters from a web page to set the data source for a sub-report:

Dim sLobID As String = CType (Request.QueryString("LOBID"), String )
Dim sPlanYear As String = CType (Request.QueryString("PLANYEAR"), String )
Dim sCN As String = Me .getDatabasePath


Me .rptMain = New MyReport(sLobID, sPlanYear, sCN)
Me .SetDatasource(sLobID, sPlanYear)
rptMain.Run( False )
. . .

Here's an example of the constructor in the report code behind to receive input parameters:

Public Class MyReport
Inherits ActiveReport

Private m_LOBID As String = "-1"
Private m_PlanYr As String = String .Empty
Private m_CN As String = String .Empty
Private m_Parms(2) As SqlParameter

Public Sub New ( ByVal LobID As String , _
ByVal PlanYr As String , _
ByVal ConnStr As String )
MyBase .New()
m_PlanYr = PlanYr
m_CN = ConnStr
End Sub

You can implement the module variables as properties if you wish, although that is not done in this example.

After importing the System Data classes and the SQLHelper class from the Microsoft Data Access Application Block, the code behind can set the data source for the sub-report using the connection string passed in from the calling web page. Data can then be retrieved with a stored procedure and used to set a sub-report's data source. Since this example displays information in the report header section, we use the Report_Header_Format event to set the data source.

Private Sub ReportHeader_Format( ByVal sender As Object , _
ByVal e As System.EventArgs) _
Handles ReportHeader.Format
'define a sub-report object
Dim srptMySubRpt As New srSubRpt()
Dim myRDR As SqlClient.SqlDataReader
Dim myParmLOB As New SqlParameter
With myParmLOB
. . .
End With

m_Parms(0) = myParmLOB
Dim myParmPlanYr As New SqlParameter
With myParmPlanYr
. . .
End With

m_Parms(1) = myParmPlanYr
' create a datareader object
myRDR = SqlHelper.ExecuteReader(m_CN, CommandType.StoredProcedure, _
"rpt_LOB", m_Parms)
' set the datasource for the sub-report object created here
srptMySubRpt .DataSource = myRDR
' set the corresponding sub-report defined in the MAIN report
' to the instance created here to get the desired data source
Me . srInMain .Report = srptMySubRpt
Catch ex As Exception
' Pass it back up the stack
. . .
End Try
End Sub

This logic can get a bit recursive. If a sub-report contains its own sub-reports, then their constructors can implement similar logic to receive parameters and set data sources.

If you ever wrestled with Crystal Reports trying to get the data source set before the report accesses it and errors out, you will be pleased to note that misbehavior has not been observed with ActiveReports. We created reports in the designer and set an embedded data source to a local data server. When moving those reports onto a web server, the code behind fires and sets a valid data source before any attempt is made to access the now invalid embedded data source.

What is a script

ActiveReports supports scripting. In the report designer, there is an icon of a page with a gear on it that accesses the C# script associated with the report. The script editor is very primitive as it basically a text editor with no debug support. Code behind is so powerful and follows the .Net model so well, scripting seems more of a "backward compatibility" feature than anything else. However, you need to be aware of this feature to understand some of the AR samples.

How to Copy a Report between Projects

You can't just copy an ActiveReports RPX file from one project to another. You have to "load" the RPX and then re-generate the code behind file:

  1. Add a new ActiveReport to the target project giving it the desired name.
  2. From the "Report" menu select "Load Layout" using the RPX file you want to copy as the source or "from" report.
  3. Manually recreate any events in new code behind in the target project by selecting the appropriate event-handlers in the IDE.
  4. Copy the code and events from the source project code behind file into the new code behind file.
  5. Rebuild the project and test. Testing can be simplified if you have previous report samples to use for comparison.

Border Properties

If you expect to be able to set borders on the property page associated with an object, guess again. If you right click an object that supports borders, you will see a context-menu item "Format Borders". There is no corresponding capability on the property page. We hope this oversight gets fixed in a future release.

Font Size

Font size is available on the report designer tool bar, but that setting is limited to the sizes pre-defined in the font file. If you need to scale up or down beyond those values, use the font setting on the objects property page and manually type in the desired number.

XCOPY Deployment

This product becomes a "must have" right after your first successful XCOPY deployment to a web server. After marking the "Copy Local" property true on a couple of ActiveReports DLLs, just copy the "bin" folder, some web files and a configuration file to the server -- and your web site will have reporting capability as advertised. Notice there is no need to install anything special on the web server or to change any IIS configurations. If you are using a hosting service and you need reporting, then you need ActiveReports .NET and you need to instantiate your reports as shown in the code samples above. This same tech­nique should work in a Windows deployment situation although we did not test that in preparing this article.

ActiveReports support

Navigate to and register to access the knowledge base and the forums. The search capability leaves a little to be desired, but the tips, tricks and problem solutions are outstanding. Much of the information consolidated in this document was gained mining the forums.

Four Stars on a Five Star Scale

Again, ActiveReports is an excellent tool. The only reason for not awarding the product five stars is because the ramp up time is unnecessarily steep if you are a first time user. After reading through the tutorials and looking over the samples, the way to get the code behind to fire was still a mystery. Judging from the traffic on the forum, few people get this right on the first try. Once you understand that the HTTPHandlers and scripts are not important if you plan to use an Object Oriented approach, it gets better.

Discovering how to make ActiveReports code behind fire becomes an inference adventure game -- first you immerse yourself in the samples, the help documents and forum messages -- then you began drawing inferences. Inferences such as the fact that the VS.NET debug features are supposed to work when code behind fires.  ActiveReports for .NET has many report export options.  One of the most popular is PDF format.  Here is a sample that demonstrates how to export the report to the browser in PDF format without writing the file to disk: ActiveReports For .NET to PDF Format In Browser.

Since you now know the major quirks and stumbling blocks to getting up and running on ActiveReports, maybe you can rate Data Dynamics ActiveReports.NET as a five star effort after all.

A partner in US Software Developers, Bill specializes in agile development using .NET, VB.Net and C#. He is a seasoned veteran in all phases of software development -- process, classes, data structures, reporting and screen presentation. In his spare time, Bill founded and leads the Enterprise Developers Guild, the .Net User Group in Charlotte NC.

Article Discussion: