Extending Reporting Services Whitepaper

13
Extending Reporting Services with Custom Code Written By: Devin Knight [email protected] @Knight_Devin Bidn.com/Blogs/DevinKnight

Transcript of Extending Reporting Services Whitepaper

Page 1: Extending Reporting Services Whitepaper

Extending Reporting Services with Custom Code

Written By: Devin Knight

[email protected]

@Knight_Devin

Bidn.com/Blogs/DevinKnight

Page 2: Extending Reporting Services Whitepaper

PAGE 3 INTRODUCTION

PAGE 4 WHY USE CUSTOM CODE?

PAGE 4 DIRECT EMBEDDING

PAGE 5 Direct Inputting CodePAGE 6 Writing a Function

PAGE 8 EXTERNAL ASSEMBLIES

PAGE 9 Building a .Net AssemblyPAGE 1 1 Deploying an AssemblyPAGE 1 2 Using an Assembly in a Report

PAGE 13 SUMMARY

CONTENTS

Page 3: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 3

INTRODUCTION

SQL Server Reporting Services is capable of creating eye-popping

visualizations that can be consumed by a variety of business

users. The tool has built-in functionality for developers to

produce reports that users will find not only functional, but also

visually appealing. A report developer is tasked with designing

these reports using many of the native components like charts,

gauges, and matrix to name a few.

Along with these report tools your developers must learn

Reporting Services expressions. Expressions are used frequently

in reports to control content and report appearance. While the

expression language is powerful, it does have some gaps in

functionality that can leave a developer searching for ways to

solve complex problems.

This whitepaper will focus on how to overcome the gaps that

expressions leaves by using custom code. You will also learn

many other advantages of using custom code like creating

consistency across all reports developed. As you read this paper,

you will walk through many examples of using custom code.

These examples will emphasize the use of custom code, and

will therefore skip topics like creating data sources, datasets and

basic report toolbox items. It will significantly benefit the reader

to have a basic understanding of Visual Basic which all examples

will be shown using. The intent of this paper is not to teach

you Visual Basic, but to know show it can be used in Reporting

Services and take away some real-world examples you could use

at your work. All the reports developed in this whitepaper can

be downloaded at PragmaticWorks.com.

Page 4: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 4

WHY USE CUSTOM CODE?

Reporting Services can often produce several challenges that are

difficult to overcome with the native tools provided to you. A report

developer could easily spend weeks racking their brain trying to

figure out how to manipulate the native tools in Reporting Services

to fit an end user requirement. Using custom code can make

complex user requirements a lot quicker to solve and require a lot

less code. Rather than forcing your needs into the native Reporting

Services expression language, you could use custom code to make

developing these complex requests simpler. The reason custom

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

functionality into Reporting Services that does not exist in the

natively provided tools. This is a quick process as you simply

input your code and preview the report to see how it changed

the design. You also have the ability to add multiple functions

at once, so if there are several custom functions you would like

to use in a report you can add them simultaneously. Another

benefit often overlooked is that it gives you one consolidated

place to edit code. Many times when you use Reporting Services

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

custom code you could have a just altered the embedded code in

one spot and it would have been applied to all the necessary cells.

While it may sound like embedding custom code in a report has no

shortcomings, that is far from the truth. The code must be written

in Visual Basic (no C#), so having some previous knowledge of the

language will greatly benefit you. Even without that knowledge,

it is fairly easy to find what you’re looking for with a few simple

web searches. Another disadvantage is that the embedded code

window is lacking a lot of the functionality of Visual Studio. For

example you do not have intellisense available or even basic code

errors until the report is in preview mode.

A summary of many of the pros and cons of using embedded

code can be found in Figure 1.

Pros Cons

More than one function can be embedded

Must use Visual Basic

Immediately see the results of code without creating a Visual Studio project

No intellisense in the code window

One place to make changes to code Code Errors are not visible until report preview

Figure 1

If you are looking for consistency with how your developers write

reports custom code is a great way of accomplishing it. The

best way this can be done is with external assemblies (which

will be discussed in detail later in this paper) that can be shared

with multiple report developers to standardize how reports are

developed. After creating and deploying an assembly, Reporting

Services will reference the code externally, giving the developer

the ability to manage the code completely separate from the

reporting tool.

Page 5: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 5

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

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

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 2

Figure 3

Figure 4

Page 6: Extending Reporting Services Whitepaper

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.

The requirement for this example is to change the background

color of the Order Quantity column based on the data values. The

users would like:

Order Quantity less than 500 to show Maroon

Order Quantity less than 1000 to show Yellow

Order Quantity less than 2000 to show Orange

Order Quantity greater than or equal to 2000 to show Green

We could accomplish this using the Reporting Services Expression

language with several nested IIF statements, but to make any

changes to the thresholds you would have to alter every cell

that applied the formatting. Using a function you can simply go

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:

Public Shared Function SetColor(ByVal Value As Integer) As String

SetColor = “Green”

If Value < 500 Then

SetColor = “Maroon”

ElseIf Value < 1000 Then

SetColor = “Yellow”

ElseIf Value < 2000 Then

SetColor = “Orange”

End If

End Function

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 6

Figure 5

Page 7: Extending Reporting Services Whitepaper

This code will accept a parameter value and compare that value

against each of each condition to determine what color should be

appropriately returned. Your Code page should appear the same

as Figure 6 before you click OK and return back to the report.

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):

=Code.SetColor(SUM(Fields!OrderQuantity.Value))

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 7

Figure 6

Figure 7

Figure 8

Once these changes are complete click OK and preview the

report. Your completed report should look similar to Figure 8.

Page 8: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 8

EXTERNAL ASSEMBLIES

Creating external assemblies for custom code is really the best

long term solution to creating consistency and standards in the

way report development is done. Any custom code is compiled

in Visual Studio without the possibility of someone that is less

familiar with .Net making changes with embedded code.

You will notice that statement was less specific in the coding

language that can be used this time. Previously, as this paper

mentioned in the embedded code section, you could only use VB.

With external assemblies you are no longer limited to VB, you are

free to develop your custom code using either VB or C# because

the code you develop with external assemblies is done in Visual

Studio and not Reporting Services.

External assemblies are also a great way to manage custom code.

You aren’t forced to open the report to make changes to the

code because the report simply stores a reference to where the

assembly is stored. This is great because you can make change to

the assembly and after redeploying it can affect dozens of reports

that use the code reference.

Pros Cons

Can be any .Net language Deployment is a bit tedious

Updates to code can be managed from outside of SSRS

Assemblies will have restricted access to system resources

Best way to standardize custom code

Figure 9

Of course there are disadvantages to using external assemblies

also. For example, it can be very tedious to deploy an assembly.

The steps for deploying will be described later on in this

whitepaper, but for now understand that it is much more time

consuming then using the embedded custom code method

described earlier. External Assemblies will also have restricted

access to the system resources. This means if you anticipate the

assembly using the file system or accessing outside data that

there are some configuration settings that must be changed.

A summary of many of the pros and cons of using embedded

code can be found in Figure 9.

Page 9: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 9

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

Figure 11

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”

ElseIf Value < 1000 Then

SetColor = “Yellow”

ElseIf Value < 2000 Then

SetColor = “Orange”

End If

End Function

End Class

Page 10: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 10

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()>

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 12

Figure 13

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.

Page 11: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 11

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:\Windows\assembly

C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\

ReportServer\bin

Navigate to the bin\Debug 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 Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting

Services\ReportServer\bin 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:\Windows\assembly folder.

Once this is complete you will see the dll appear in the GAC as shown in Figure 15.

Figure 15

Page 12: Extending Reporting Services Whitepaper

Figure 16 Figure 17

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 12

USING AN ASSEMBLY IN A REPORT

With the dll creation and deployment completed the assembly

should now be ready to use. Open the designer for Reporting

Services with the base report that we started with in the

first example. Again all these examples can be found on

PragmaticWorks.com with the beginning and completed

examples.

Find the Report Properties menu that you learned about in the

first section of this white paper. With the Report Properties

menu open select the References page. This is different from the

embedded code example where we just started typing our code

on the Code page. The Reference page is where we will point the

report to any assemblies that we have previously created. Click

Add under Add or Remove assemblies and then select the ellipsis

next to the new entry as shown in Figure 16.

On the Browse tab of the Add Reference window, select the

ColorFormat.dll then click OK. Although we have selected the

dll from the C:\Program Files\Microsoft SQL Server\MSRS10_50.

MSSQLSERVER\Reporting Services\ReportServer\bin folder, it

will actually load the GAC version when the report runs. Also,

notice now that the reference appears on the Reference page

of the Report Properties. Click OK again to return to the report

designer.

Once the expression is entered click OK and preview the report.

The report should look exactly the same as the embedded code

example but now this is using an external assembly to control

the background color. If you ever needed to modify the color

thresholds you would modify the Class Library project and

redeploy the dll. This is helpful because if the same dll is used

in several reports then you can change the report appearance

without having to open a single rdl report file.

Like we did in the embedded code example, you will 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 assembly

and pass in the value from the OrderQuantity field (shown in

Figure 17):

Template

=AssemblyName.ClassName.FunctionName(Parameter)

Code for this example

=ColorFormat.ValueFormat.SetColor(SUM(Fields!OrderQuantity.

Value))

Page 13: Extending Reporting Services Whitepaper

PRAGMATIC WORKS White Paper Extending Reporting Services with Custom Code

www.pragmaticworks.com PAGE 13

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.