2. CONTENTS
PAGE 3 INTRODUCTION
PAGE 4 WHY USE CUSTOM CODE?
PAGE 4 DIRECT EMBEDDING
PAGE 5 Direct Inputting Code
PAGE 6 Writing a Function
PAGE 8 EXTERNAL ASSEMBLIES
PAGE 9 Building a .Net Assembly
PAGE 1 1 Deploying an Assembly
PAGE 1 2 Using an Assembly in a Report
PAGE 13 SUMMARY
3. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
INTRODUCTION
SQL Server Reporting Services is capable of creating eye-popping This whitepaper will focus on how to overcome the gaps that
visualizations that can be consumed by a variety of business expressions leaves by using custom code. You will also learn
users. The tool has built-in functionality for developers to many other advantages of using custom code like creating
produce reports that users will find not only functional, but also consistency across all reports developed. As you read this paper,
visually appealing. A report developer is tasked with designing you will walk through many examples of using custom code.
these reports using many of the native components like charts, These examples will emphasize the use of custom code, and
gauges, and matrix to name a few. will therefore skip topics like creating data sources, datasets and
basic report toolbox items. It will significantly benefit the reader
Along with these report tools your developers must learn
to have a basic understanding of Visual Basic which all examples
Reporting Services expressions. Expressions are used frequently
will be shown using. The intent of this paper is not to teach
in reports to control content and report appearance. While the
you Visual Basic, but to know show it can be used in Reporting
expression language is powerful, it does have some gaps in
Services and take away some real-world examples you could use
functionality that can leave a developer searching for ways to
at your work. All the reports developed in this whitepaper can
solve complex problems.
be downloaded at PragmaticWorks.com.
www.pragmaticworks.com PAGE 3
4. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
WHY USE CUSTOM CODE?
Reporting Services can often produce several challenges that are If you are looking for consistency with how your developers write
difficult to overcome with the native tools provided to you. A report reports custom code is a great way of accomplishing it. The
developer could easily spend weeks racking their brain trying to best way this can be done is with external assemblies (which
figure out how to manipulate the native tools in Reporting Services will be discussed in detail later in this paper) that can be shared
to fit an end user requirement. Using custom code can make with multiple report developers to standardize how reports are
complex user requirements a lot quicker to solve and require a lot developed. After creating and deploying an assembly, Reporting
less code. Rather than forcing your needs into the native Reporting Services will reference the code externally, giving the developer
Services expression language, you could use custom code to make the ability to manage the code completely separate from the
developing these complex requests simpler. The reason custom reporting tool.
code makes this so much easier, is because it gives you the ability to
couple .Net languages with Reporting Services.
DIRECT EMBEDDING
Embedding custom code is a quick and easy way to add in new language will greatly benefit you. Even without that knowledge,
functionality into Reporting Services that does not exist in the it is fairly easy to find what you’re looking for with a few simple
natively provided tools. This is a quick process as you simply web searches. Another disadvantage is that the embedded code
input your code and preview the report to see how it changed window is lacking a lot of the functionality of Visual Studio. For
the design. You also have the ability to add multiple functions example you do not have intellisense available or even basic code
at once, so if there are several custom functions you would like errors until the report is in preview mode.
to use in a report you can add them simultaneously. Another
benefit often overlooked is that it gives you one consolidated A summary of many of the pros and cons of using embedded
place to edit code. Many times when you use Reporting Services code can be found in Figure 1.
expressions you apply the same expressions value to multiple cells.
If you needed to make a change to those expression values you
would have to open each textbox property individually, but with a Pros Cons
custom code you could have a just altered the embedded code in More than one function can be Must use Visual Basic
embedded
one spot and it would have been applied to all the necessary cells.
Immediately see the results of code No intellisense in the code
without creating a Visual Studio window
While it may sound like embedding custom code in a report has no project
shortcomings, that is far from the truth. The code must be written One place to make changes to code Code Errors are not visible until
in Visual Basic (no C#), so having some previous knowledge of the report preview
Figure 1
www.pragmaticworks.com PAGE 4
5. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
DIRECT INPUTTING CODE
Once you have come to the conclusion that the best
way to solve your business problem is with custom
code you can begin inputting your VB. The embedded
custom code must be inputted on each report you
wish to use the code. So if you have written code
that will help make your report formatting consistent
across your entire report then you must add the code
to every report that will use the code.
When you are ready to input your code you must go
to the Report Properties window. You can find the
Figure 2
Report Properties window two different ways. The first
method is to right-click outside the design surface of
a report and select Report Properties. In Figure 2 you
will see the first method of getting to the properties.
The second method for navigating to the Report
Properties window can be found in the toolbar. From
the toolbar select Report -> Report Properties. If you
do not see the Report menu in the toolbar then first
select somewhere in the background of your report
and it should appear. Sometimes the Report menu is Figure 3
hidden when other windows are active. For example
if you are looking at the properties of a textbox in your
report, then the Report menu in the toolbar is hidden.
Figure 3 shows the second method for getting to the
properties.
Either way you choose to get to the Report Properties
window you will get the same result. After the Report
Properties window opens, select the Code page where
you can enter your custom code (Figure 4).
You will instantly see some of the disadvantages of
using embedded code that were discussed earlier. It
lacks major Visual Studio functionality like intellisense
and code error windows. Next, we will walk through
creating an example of embedded custom code.
Figure 4
www.pragmaticworks.com PAGE 5
6. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
WRITING A FUNCTION
Writing custom code in Reporting Services assumes you have a
little knowledge of Visual Basic. Unfortunately, VB is currently
the only acceptable coding language when embedding code in
a report. This would likely not change in future versions of SQL
Server either, so get comfortable with VB if you choose to embed
you custom code. If you do not know VB this whitepaper does
not intend to teach you the .Net language, but rather show you
how it can be integrated with Reporting Services. So if VB is new
to you use this paper as a reference while you learn how powerful
having the knowledge of Visual Basic can be.
In our first example we will walk through a basic report and show
how to use embed custom code to do something that is possible
with native SSRS expressions, but would require nested logic that
can be much more confusing. I’m starting off with a very simple
report that lists all products and the sales for each, as shown in
Figure 5. This base report and the completed report can be found
on PragmaticWorks.com.
Figure 5
The requirement for this example is to change the background Public Shared Function SetColor(ByVal Value As Integer) As String
color of the Order Quantity column based on the data values. The SetColor = “Green”
users would like:
If Value < 500 Then
Order Quantity less than 500 to show Maroon
Order Quantity less than 1000 to show Yellow SetColor = “Maroon”
Order Quantity less than 2000 to show Orange ElseIf Value < 1000 Then
Order Quantity greater than or equal to 2000 to show Green SetColor = “Yellow”
ElseIf Value < 2000 Then
We could accomplish this using the Reporting Services Expression
SetColor = “Orange”
language with several nested IIF statements, but to make any
changes to the thresholds you would have to alter every cell End If
that applied the formatting. Using a function you can simply go End Function
back to the code window to adjust the custom code and see the
immediate results next time you preview the report. To input the
function, navigate to the Report Properties window and open the
Code page. Use the following code to satisfy the requirement:
www.pragmaticworks.com PAGE 6
7. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
This code will accept a parameter value and compare that value Once these changes are complete click OK and preview the
against each of each condition to determine what color should be report. Your completed report should look similar to Figure 8.
appropriately returned. Your Code page should appear the same
as Figure 6 before you click OK and return back to the report.
Figure 6
With the custom code set, it is now time to actually call the code in
the background property of the cell that we would like to format.
First select the cell that you wish to apply the formatting to and
then open the properties menu (F4). Find the BackgroundColor
property then select expression to make the property value
dynamic. In the Expression window use the following code to call
the custom code and pass in the value from the OrderQuantity
field (shown in Figure 7): Figure 8
=Code.SetColor(SUM(Fields!OrderQuantity.Value))
Figure 7
www.pragmaticworks.com PAGE 7
8. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
EXTERNAL ASSEMBLIES
Creating external assemblies for custom code is really the best Of course there are disadvantages to using external assemblies
long term solution to creating consistency and standards in the also. For example, it can be very tedious to deploy an assembly.
way report development is done. Any custom code is compiled The steps for deploying will be described later on in this
in Visual Studio without the possibility of someone that is less whitepaper, but for now understand that it is much more time
familiar with .Net making changes with embedded code. consuming then using the embedded custom code method
described earlier. External Assemblies will also have restricted
You will notice that statement was less specific in the coding access to the system resources. This means if you anticipate the
language that can be used this time. Previously, as this paper assembly using the file system or accessing outside data that
mentioned in the embedded code section, you could only use VB. there are some configuration settings that must be changed.
With external assemblies you are no longer limited to VB, you are
free to develop your custom code using either VB or C# because A summary of many of the pros and cons of using embedded
the code you develop with external assemblies is done in Visual code can be found in Figure 9.
Studio and not Reporting Services.
External assemblies are also a great way to manage custom code. Pros Cons
You aren’t forced to open the report to make changes to the Can be any .Net language Deployment is a bit tedious
code because the report simply stores a reference to where the Updates to code can be managed from Assemblies will have restricted
outside of SSRS access to system resources
assembly is stored. This is great because you can make change to
Best way to standardize custom code
the assembly and after redeploying it can affect dozens of reports
that use the code reference. Figure 9
www.pragmaticworks.com PAGE 8
9. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
BUILDING A .NET ASSEMBLY
So you have weighed the pros and cons of using embedded
custom code and building an external assembly and have decided
to go with building an assembly. This section will walk you through
creating an assembly, using the same example scenario we used
for embedded code of wanting to format the background color
based on the value of our Order Quantity field.
Open Visual Studio and create a new Class Library project as
shown in Figure 10. Before you hit OK ensure that the project is
created using .Net Framework 2.0 otherwise Reporting Services
will not accept the assembly
Figure 10
Once the project is created rename the Class1.vb file in the
Solution Explorer to ValueFormat.vb. Open the ValueFormat.vb
file if it is not already open. Use the same code from the previous
example and place it between the existing code, as shown in
Figure 11.
Public Class ValueFormat
Public Shared Function SetColor(ByVal Value As
Integer) As String
SetColor = “Green”
If Value < 500 Then
SetColor = “Maroon” Figure 11
ElseIf Value < 1000 Then
SetColor = “Yellow”
ElseIf Value < 2000 Then
SetColor = “Orange”
End If
End Function
End Class
www.pragmaticworks.com PAGE 9
10. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
Figure 12
There are a few more things we must do to handle security for
this assembly once we are ready to register the dll to the Global
Assembly Cache (GAC). The first step is to set the <Assembly:
AllowPartiallyTrustedCallers()> property. Without this declaration
applications like Reporting Services are unable to use the assembly.
To make this change you must navigate to the Solution Explorer
and with the project select click the button to Show All Files as
shown in Figure 12. Once all the project files are visible expand
My Project and open the AssemblyInfo.vb file.
With the AssemblyInfo.vb file open add the Imports System.Security
namespace and the <Assembly: AllowPartiallyTrustedCallers()> Figure 13
declaration as shown in Figure 13.
Once these changes are complete save and close the AssemblyInfo.
vb file. The last change we need to do before this assembly is
complete and ready for deployment is to sign it with a strong
name. A strong name is basically a way of naming or versioning
the dll. Without giving the dll a strong name it cannot be
registered in the GAC.
To give the dll a strong name right-click on the project name in the
Solution Explorer and select Properties. Go to the Signing page
and check Sign the assembly. You must then create a new strong
name key file by selecting <New…> from the dropdown box as
shown in Figure 14.
Figure 14
Name the file StrongName and uncheck protect my file with a
password, then click OK. Once this is complete, Save All and
preform a build of the project. You can build the project by select
the Build menu from the toolbar and then Build ColorFormat.
With the assembly now created you will learn how to properly
deploy it. From here on you are done with Visual Studio.
www.pragmaticworks.com PAGE 10
11. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
DEPLOYING AN ASSEMBLY
To deploy an assembly for Reporting Services use, you must copy the dll you created to the
two different locations listed below:
C:Windowsassembly
C:Program FilesMicrosoft SQL ServerMSRS10_50.MSSQLSERVERReporting Services
ReportServerbin
Navigate to the binDebug folder in the path of the where the Class Library project was
created. In the Debug folder you should see the ColorFormat.dll file. Copy and paste
this file to the C:Program FilesMicrosoft SQL ServerMSRS10_50.MSSQLSERVERReporting
ServicesReportServerbin folder.
Next you will place the dll in the GAC. This cannot be done by copying and pasting the file
though. It must actually be dragged and dropped into the C:Windowsassembly folder.
Once this is complete you will see the dll appear in the GAC as shown in Figure 15.
Figure 15
www.pragmaticworks.com PAGE 11
12. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
USING AN ASSEMBLY IN A REPORT
With the dll creation and deployment completed the assembly Like we did in the embedded code example, you will select the
should now be ready to use. Open the designer for Reporting cell that you wish to apply the formatting to and then open the
Services with the base report that we started with in the properties menu (F4). Find the BackgroundColor property then
first example. Again all these examples can be found on select expression to make the property value dynamic. In the
PragmaticWorks.com with the beginning and completed Expression window use the following code to call the assembly
examples. and pass in the value from the OrderQuantity field (shown in
Figure 17):
Find the Report Properties menu that you learned about in the
first section of this white paper. With the Report Properties Template
menu open select the References page. This is different from the =AssemblyName.ClassName.FunctionName(Parameter)
embedded code example where we just started typing our code
Code for this example
on the Code page. The Reference page is where we will point the
report to any assemblies that we have previously created. Click =ColorFormat.ValueFormat.SetColor(SUM(Fields!OrderQuantity.
Add under Add or Remove assemblies and then select the ellipsis Value))
next to the new entry as shown in Figure 16.
Figure 16 Figure 17
On the Browse tab of the Add Reference window, select the Once the expression is entered click OK and preview the report.
ColorFormat.dll then click OK. Although we have selected the The report should look exactly the same as the embedded code
dll from the C:Program FilesMicrosoft SQL ServerMSRS10_50. example but now this is using an external assembly to control
MSSQLSERVERReporting ServicesReportServerbin folder, it the background color. If you ever needed to modify the color
will actually load the GAC version when the report runs. Also, thresholds you would modify the Class Library project and
notice now that the reference appears on the Reference page redeploy the dll. This is helpful because if the same dll is used
of the Report Properties. Click OK again to return to the report in several reports then you can change the report appearance
designer. without having to open a single rdl report file.
www.pragmaticworks.com PAGE 12
13. PRAGMATIC WORKS White Paper
Extending Reporting Services with Custom Code
SUMMARY
This white paper has covered how to use custom code to extend the functionality of Reporting Services. Using custom code also allows
you to standardize coding practices among developers that may try and accomplish the same goal using multiple methods. While the
direct embedding of custom code is quick and simple to do, it does not scale nearly as well as an external assembly when multiple
reports use the same functions. External assemblies are a little more cumbersome to create and maintain, but it truly is the ideal solution
because you are not limited by .Net language and it can be managed from outside of Reporting Services.
www.pragmaticworks.com PAGE 13