Bryant Likes's Blog

It's all about WebData

Recent Posts

Tags

News


  • Windows Live Alerts
    View Bryant Likes's profile on LinkedIn

    Me

    The posts on this weblog are provided "as is" with no warranties and confer no rights. The opinions expressed herin are the personal opinions of the individual authors and do not represent the views of Avanade in any way.

Community

Email Notifications

Archives

Writing Custom Code in SQL Server Reporting Services

Writing Custom Code in SQL Server Reporting Services

Someone asked me today how to use a Custom Assembly in Reporting Services. Since I'd never used one before I tried to point them to some useful articles that I found here on MSDN. However, the article didn't seem to help much so I decided to look into it and figure out how to do this since it is an interesting topic.

Let me start by saying that I found the documentation on this to be pretty poor. The docs (which can be found here) do you give enough information to figure it out, but they leave out the information that would make the process as simple as it should be. So that is the goal of this article, to show you how easy it really is to write custom code for SQL Server Reporting Services.

Embedded Code

For our first trick we will write some embedded code. To get started open your browser to this page. On that page under embedded code you will see the following statement.

To use code within a report, you add a code block to the report. This code block can contain multiple methods. Methods in embedded code must be written in Visual Basic .NET and must be instance based.

I'm assuming that "instance based" means the methods don't have to be shared (that's static for you C# coders). However, in my tests I found you can use either instance based or shared methods.

So let's get started and add some embedded code to a report. Fire up Visual Studio and create a new report project and a new report (Right click the project -> Add New Item -> Report). Next click this link for instuctions to add the embedded code to the report.

To add code to a report

  1. On the Report menu, click Report Properties.
  2. Note If the Report menu is not available, click within the report design area.
  3. On the Code tab, in Custom Code, type the code.


So type the code :)

It actually is that easy. So for our example type the following:

Public Function SayHello() as String
  Return "Hello from Embedded Code"
End Function

Next add a textbox to the new report put "=Code.SayHello()" without the quotes in the textbox. You should now be able to preview your report and see "Hello from Embedded Code" on the report. That is as far as we are going to take embedded code (I also found this article which talks a little more about embedded code). At this point you should be able to deploy your report to the server and run it on the server.

Custom Assemblies

The next topic is custom assemblies. This is a much more useful feature since you aren't constrained to writing code in VB.Net on a small dialog in the report designer. You can use Visual Studio and your language of choice. So for our example create a new Visual Studio Class Library project in either C# or VB.Net. Call it MyCustomAssembly. Next rename Class1 to SayHello. To the SayHello class we will add one method which is shown below.

[VB]
Public Shared Function Hello() as String
  Return "Hello from My Custom Assembly!"
End Function

[C#]
public static string Hello()
{
  return "Hello from My Custom Assembly!";
}

Once you're done with the code go ahead and compile the project. Once you've gotten your assembly compiled follow this link for instructions on how to add a reference to your code. Once you've added the reference to your code you will also need to copy the dll file to the C:\Program Files\Microsoft SQL Server\80\Tools\Report Designer folder on your computer. The dll file can be found in your project folder under the bin\debug folder (or bin\release if you compiled a release build).

Note: You only need to add a reference. The Class section will only be used if you're class has instance methods (versus Shared or static methods).

Add another textbox to your report and this time fill it with "=MyCustomAssembly.SayHello.Hello()". You should be able to preview the report and see "Hello from My Custom Assembly" on the report. So you have now used both embedded code and custom assemblies. Before you can deploy the report you need to copy the MyCustomAssembly.dll to the server and put it in the C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin folder on the server. Once you have copied the dll file you should be able to deploy your report to the server.

But what if you want to actually do something interesting like grab values from a database or use a web service? To do that you will need to modify the Code Access Security (CAS) settings for reporting services.

Code Access Security

There is actually a comprehensive article on this topic here. I would recommend you read that article. There is also a good introduction to CAS in general here and here. The goal of this article (the one you're reading) is to give you a quick-and-easy example that can get you started. So we will attempt to read a value from a file and return it.

First create a text file called hello.txt and put it in your c:\temp folder. In the file add the text "Hello from a text file!" and save and close the file. Next add the following method to your SayHello class:

[VB]
Public Shared Function HelloFromFile() as String
  Dim reader as StreamReader = New StreamReader("c:\temp\hello.txt")   Dim hello as String = reader.ReadToEnd()
  reader.Close()
  Return hello
End Function

[C#]
public static string HelloFromFile()
{
  using (StreamReader reader = new StreamReader("c:\\temp\\hello.txt"))
  {
    return reader.ReadToEnd();
  }
}

Note: You will also need to add Imports System.IO in VB and using System.IO in C#.

Next compile you the project. Once the project is compiled you will need to remove the old reference in your report and add the new reference and copy pver the new dll (you will have to close the report project to do this). Add a new textbox to the report and fill it with "=MyCustomAssembly.SayHello.HelloFromFile()". You should be able to preview the report and see the text that you added to the text file.

Next copy the dll and the text file (and put the text file in the c:\temp folder) to the server and deploy the report to the server. When you try to view the report on the server you won't see your message. Instead you should see "#Error".

In order to make this work on the server we need to follow the steps outlined in the CAS article. The first step according to the article is to:

1. Identify the exact permissions that your code needs in order to make the secured call. If this is a method that is part of a .NET Framework library, this information should be included in the method documentation.


Since we are using the StreamReader object we should be able to find this information in the StreamReader documentation but unfortunately I wasn't able to find it (at least I didn't see it). However, I'm going to guess (and I guessed right) it requires the FileIOPermission from the System.Security.Permissions namespace.

Next we need to:

2. Modify the report server policy configuration files in order to grant the custom assembly the required permissions.


So following the example given in the article on CAS we can add the following Xml under the <NamedPermissionSets> node in the rssrvpolicy.config file in the C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer folder.

Note: Be careful when you edit this file. I would highly recommend making a backup copy of the original file before making any changes. This file is an Xml file and you must be sure that what you add is valid Xml.

<PermissionSet
    class="NamedPermissionSet"
    version="1"
    Name="HelloFilePermissionSet"
    Description="A special permission set that grants read access to my hello file.">
  <IPermission
      class="FileIOPermission"
      version="1"
      Read="C:\temp\hello.txt"
  />
  <IPermission
      class="SecurityPermission"
      version="1"
      Flags="Execution, Assertion"
  />
</PermissionSet>

Next we need to add the code group. Again, based on the example in the CAS article we can add the following Xml. We have to put this under the correct CodeGroup node in order for it to work correctly. So you will need to put it under the last code group, but make sure it has the same parent node as the last code group. To do this just insert it before the second to last ending CodeGroup as shown below:

...
      />
      </CodeGroup>
[Insert Here]
    </CodeGroup>
  </CodeGroup>
</PolicyLevel>
...

Here is the code group to add.

<CodeGroup
    class="UnionCodeGroup"
    version="1"
    PermissionSetName="HelloFilePermissionSet"
    Name="MyCustomAssemblyCodeGroup"
    Description="A special code group for my custom assembly.">
  <IMembershipCondition
        class="UrlMembershipCondition"
        version="1"
        Url="C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin\MyCustomAssembly.dll"
  />
</CodeGroup>

Once you've added all this you will still need to complete steps 3 & 4 before the custom assembly will work.

3. Assert the required permissions as part of the method in which the secure call is made. This is required because the custom assembly code that is called by the report server is part of the report expression host assembly which runs with Execution by default. The Execution permission set enables code to run (execute), but not to use protected resources.

4. Mark the custom assembly with the AllowPartiallyTrustedCallersAttribute. This is required because custom assemblies are called from a report expression that is a part of the report expression host assembly, which by default is not granted FullTrust, thus is a 'partially trusted' caller. For more information, see "Using Strong Named Custom Assemblies," earlier in this document.


To complete step 3 you will need to first add using System.Security.Permissions or Imports System.Security.Permissions to your SayHello class. Next you will need to assert the FileIOPermission on the HelloFromFile method as shown below:

[VB]
<FileIOPermissionAttribute(SecurityAction.Assert, Read="c:\temp\hello.txt")> _
Public Shared Function HelloFromFile() as String
...

[C#]
[FileIOPermissionAttribute(SecurityAction.Assert, Read="c:\\temp\\hello.txt")]
public static string HelloFromFile()
...

Next in your assembly attribute file (AssemblyInfo.cs in C# or AssemblyInfo.vb in VB), add the following assembly-level attribute (and add Imports System.Security or using System.Security):

[VB]
<assembly:AllowPartiallyTrustedCallers>

[C#]
[assembly:AllowPartiallyTrustedCallers]

Once you've done this, recompile the assembly and copy it to the server. You should now be able to execute the report and see "Hello from a Text File!" instead of "#Error". If you still see the error need to make sure that you click the refesh button on the report toolbar and you may have to restart the reporting service.

That's it! Hopefully you were able to get everything to work. Now you should have a basic understanding of how to use custom code with reporting services. If you have drop leave a comment and I will try to address it.

Comments

TrackBack said:

# July 16, 2004 12:38 PM

bryantlikes said:

Nice... thanks for taking the time to blog this...
# July 16, 2004 1:03 PM

bryantlikes said:

Bryant is a Genius! Thanx B
# July 19, 2004 10:18 AM

bryantlikes said:

Thanks Bryant - just what I needed to get start.
Microsoft if you're watching - this is what we want in documentation, step by step examples.
# July 20, 2004 2:23 AM

bryantlikes said:

Could you elaborate on instance based classes and the procedures required to make this work.

I ran across this "bad example"
:
Public shared Function AddToCount (ByVal Value As Integer) As String
Count = Count + value
End Function
Shared Count As Integer=0

It was considered a "bad example" because multiple users would be changing the same Count field.

What would be a working "good example" of this using instance based functions and using the Reference Tab and the Class/Instance section in RS?

I have seen many examples using static functions and step by step instructions. I have not found a single example yet of a working instance based custom assembly walk through anywhere. :(

Would appreciate it if you could take a look at this and extend your blog to cover this case step by step.

Thanks for the guidance. I just think the community needs more input on instance based data manipulation with custom assemblies. Instead of static functions.

Once we actually know how to implement a instance based solution we can discuss when and where to use it but I'm still stuck on implementation. :(
# July 20, 2004 1:31 PM

bryantlikes said:

Sidney,

What are you trying to accomplish that requires a stateful object? There are ways you could do this but they would probably have some high overhead.

# July 20, 2004 6:38 PM

bryantlikes said:

Well the question was fairly generic-I simply don't know how to implement an instance based function into RS. I don't know what elements have to line up on the code in the VB to fit with what you select/enter on the RS side.
I've not seen 1 step by step example on connecting the dots between the name of the assemblie/namespace/class name/function name to what you enter in the RS property reference tab.

One specific question i have in mind:
Assume data in Groups
Within a group you have a column of string values-Say states for example
on a group summary line you want a concatenation of the string state values for all rows in the group.
so you might have
ID State
1 AZ
1 AL
1 MO

Summary group footer:
1 AZ, AL, MO

This is a little similar to the "running total" idea but instead of adding values I want to concatenate strings togather.

Any suggestions.

But beyond resolving this need, I need to understand generally how to use instance based functions in RS. So please don't try to answer the need behind the need when I really need to nail down how to design ANY instance based custom assembly and line it up with RS.

Thanks.
# July 21, 2004 8:45 AM

bryantlikes said:

Ok. I've played with this a little and it seems to work fine. I'll post an update.
# July 21, 2004 10:32 AM

TrackBack said:

# July 21, 2004 11:08 AM

bryantlikes said:

I am trying to access a database through a custom assembly and I already have the following in the rssrvpolicy.config file , but I still get the #Error.
<CodeGroup
class="UnionCodeGroup"
version="1"
Name="MySecurityExtensionCodeGroup"
Description="Code Group for Don's test security extension"
PermissionSetName="FullTrust">
<IMembershipCondition
class="UrlMembershipCondition"
version="1"
Url="C:\Program Files\Microsoft SQL Server\MSSQL\Reporting
Services\ReportServer\bin\MyAssembly.dll"
/>
</CodeGroup>
Do I need an associated permission set? And what would that be if I do, I dont know?

And do I need to do step 3 and 4 of your article for my custom assembly if I am only accessing a database from my function.
And If I do, what would step 3 and 4 be?

# July 21, 2004 12:04 PM

TrackBack said:

# July 21, 2004 2:10 PM

bryantlikes said:

To person trying to acccess database:
you need to add a different permission set class than the file/IO one in Bryant's blog or the UrlMembershipCondition in yours.
Try this one:
class =SqlClientPermission

You also need to see books online: Asserting Permissions in Custom Assemblies

From MSFT post on forum:
You need
to assert security permissions inside the custom assembly. Every call that
requires certain permissions (e.g. opening a database connection) will fail
unless the required security permissions for that call (documented in MSDN)
have been asserted.

Example for opening a connection to a SQL Server:

...
SqlClientPermission permission = new
SqlClientPermission(PermissionState.Unrestricted);
try
{
permission.Assert(); // Assert security permission!
SqlConnection con = new SqlConnection("...");
con.Open();
...
}


You might also want to check out these links:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/RSPROG/htm/rsp_prog_rdl_0so6.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconAssert.asp
http://msdn.microsoft.com/library/en-us/RSPROG/htm/rsp_prog_rdl_8wyq.asp

--
This posting is provided "AS IS" with no warranties, and confers no rights.
# July 21, 2004 3:52 PM

bryantlikes said:

Oops Sorry I didn't notice this was answered already. Bryant's responsiveness is out of this world. :)
# July 21, 2004 3:58 PM

bryantlikes said:

Oops Sorry I didn't notice this was answered already. Bryant's responsiveness is out of this world. :)
# July 21, 2004 3:58 PM

TrackBack said:

# July 21, 2004 6:13 PM

bryantlikes said:

I'm a recent college grad doing some asp.net. I'm writing a webpart which I want to access a SQLServer, but I get this error:

"Request for the permission of type System.Data.SqlClient.SqlClientPermission, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed."

I read the Lamont post and added this:

<SecurityClass Name="SqlClientPermission" Description="System.Data.SqlClient.SqlClientPermission, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

and this:

<IPermission class="SqlClientPermission"
version="1"
Unrestricted="true"
/>


to my wss_mediumtrust.config, and minimaltrust files.

However this did not work. I got an error saying:

A Web Part or Web Form Control on this Web Part Page cannot be displayed or imported because it is not registered on this site as safe.

Before I ever made the config file changes, I also made a strongname for my NewWebPart.dll file, and I thought I took care of the "not registered as safe" problem.

Could it be that I should use my own key instead of the b77a5c5....? I tried using the one I have for the .dll file, but that didn't seem to work either.

Does anyone have a solution? I'm a new programmer and I don't understand what I'm doing.
# July 23, 2004 10:40 AM

bryantlikes said:

I am getting the same error Jesse,

The value expression for the textbox ‘xxxxx' contains an error: Request for the permission of type System.Security.Permissions.SecurityPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.

Still looking into it.

Don
# July 23, 2004 12:21 PM

bryantlikes said:

Once I added this code group below along with code group and permission set and assert commands Bryant mentioned I no longer got the System.Permissions.SecurtiyPermission message. Everything seems to work although everything is a little fuzzy as to why?

<CodeGroup
class="UnionCodeGroup"
version"1"
PermissionSetName="FullTrust"
Name="The name of your DLL. This shouldn't be necessary, but it worked for me."
Description="">
<Imembershipcondition
class="ZoneMembershipCondition"
version="1"
Zone="MyComputer"/>
</CodeGroup>
# July 27, 2004 4:31 AM

bryantlikes said:

This is just great Bryant! I was struggling with how to get started with this custom code. Good Job.
# July 31, 2004 5:24 PM

bryantlikes said:

Good Job! Will you please help me regarding the use of custom control in parameter in reporting services, tnx
# August 10, 2004 1:43 AM

bryantlikes said:

Excellent walk through. Thanks Bryant.
Is it possible to pass a parameter to the report, and have the Assembly code adjust a column width based on the parameter value?

Thanks
# August 11, 2004 11:14 AM

bryantlikes said:

how to use Dll's in reporting services
# August 18, 2004 6:26 AM

bryantlikes said:

I have been working on this for a few days and have hit every message board, called ms support and re-written the darn thing at least 20 times. I am still getting the #error in my report manager and have even added strong name. Is there a problem that's not being spoken of?


JamesH.
# August 21, 2004 7:34 PM

bryantlikes said:

Hi,

I'd appriciate if someone could point me to right direction.
I've got my custom assembly working on development computer,
but when I deploy it to production server I'm getting this error:

Error while loading code module: ‘xxxxxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab6b2957da4e38d6’. Details: ?

I copied the assembly to Reporting Services /bin and copied permission set and code group settings to the config file.

What am I missing?

Thanks,
Alex
# August 23, 2004 6:48 PM

bryantlikes said:

Alex,

If you haven't checked yet, you should take a look at:

http://www.microsoft.com/sql/community/newsgroups/dgbrowser/en-us/default.mspx?dg=microsoft.public.sqlserver.reportingsvcs

There are really a lot of good links from MS on there albeit they're redundant. Good luck.

JamesH
# August 23, 2004 7:03 PM

bryantlikes said:

Interestingly enough, it started working after I rebooted production server.

Thanks,
Alex
# August 24, 2004 1:44 PM

bryantlikes said:

Bryant,
Thanks for all the info you posted. I'm working my way through, and I'm now working on the part were you are having us complete steps 3 & 4.

I found something that I'm not sure about, syntactly.

You code is as follows:
<FileIOPermissionAttribute(SecurityAction.Assert, Read="c:\temp\hello.txt")> _
Public Shared Function HelloFromFile() as String

I got an error stating READ is not defined. I did some reading on MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconAssert.asp)
and saw the equals (=) sign is preceded with a colon, as such Read:="c...."

Does this make a difference?

rwiethorn
# September 8, 2004 8:49 AM

bryantlikes said:

Hi Bryant,

Thanks for this wonderful article. Atleast the basic are clear now.

I have a question here. With so many changes that are needed to be made to the config files, is there any way I can do it programatically ( just I can deploy reports using the rs.exe tool and scripts)?
Because we cant expect the end user to make all these changes and (since xml is case sensitive), his whole application will go for a toss even if a small change is left out.

Regards,

Ravindra
# September 13, 2004 3:54 AM

bryantlikes said:

Excellent Job, Bryant
Go Ahead
# September 23, 2004 4:30 AM

bryantlikes said:

Thanks Bryant,
Good work in clearing this up
# September 27, 2004 1:10 PM

bryantlikes said:

I'm not sure what I am missing. I still get #error - where is the error more detailed than this? How would you ever know what the error is since documentation is so bad? I am trying to access SQL Server database.

Here is my code:

<System.Data.SqlClient.SqlClientPermission(Security.Permissions.SecurityAction.Assert, Unrestricted:=True)> _
Public Shared Function GetMdx(ByVal sUserName As String) As String
GetSqlConnection = New SqlClient.SqlConnection
GetSqlConnection.ConnectionString = "Data Source=datasourcehere;User Id=userhere;Password=passwordhere"
GetSqlConnection.Open()
' do query here

End Function

Here are entries in rssrvpolicy.config:

<PermissionSet
class="NamedPermissionSet"
version="1"
Name="SqlClientPermissionSet"
Description="A special permission set that grants access to do SQL Server DB Access.">
<IPermission
class="SqlClientPermission"
version="1"
Unrestricted="true"
/>
<IPermission
class="SecurityPermission"
version="1"
Flags="Execution, Assertion"
/>
</PermissionSet>


<CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="SqlClientPermissionSet"
Name="MyCustomAssemblyCodeGroup"
Description="For my custom assembly">
<IMembershipCondition
class="UrlMembershipCondition"
version="1"
Url="C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin\MyDll.dll"
/>
</CodeGroup>


Still get #error - not sure where to get any further detail.
# October 25, 2004 11:10 AM

bryantlikes said:

This article saved my life. I had serious deadline and knew that I had to use a custom code assembly to acheive the result. It pointed me in right direction and I was able to figure things out from there. The is honestly almost nothing else on the internet (believe me, I looked) that explains precisely how do it. Thanks Bryant!
# October 27, 2004 2:45 PM

bryantlikes said:

Your Article gave me a lot help. I write a custom code to connect to the database and get the right result in my report if I defined the connect string in my custom code directly. But I still struggle with my business objects vb files which using app.config value "Connectstring" to connect to the database which can be get by ConfigurationSettings.AppSettings("ConnectionString") in all business data access objects. I try use the ConfigurationSettings.AppSettings("ConnectionString") in my custom codes to test if I get right connect string but in report there is nothing display and no #error too. But if I use the web application or console application to test costum code in report. All get what I want. I reallize because the web application has the web.config file and console project has app.config they are all same as the business config's connection string. So I wonder if the report project in my solution should have some place to put the *.config file.
# November 1, 2004 12:57 PM

bryantlikes said:

Bryant,
Thanks for all the info you posted. I'm working with an assembly that read the Active Directory, in desing view all work nice!, but when i deploy my project, i recieve an error, my code is:

Public Shared Function GetUserInfo(ByVal inSAM As String, ByVal inType As String) As String
Try
Dim sPath As String = "LDAP://inet.com.sv" '' Dominio donde se buscara
Dim SamAccount As String = Right(inSAM, Len(inSAM) - InStr(inSAM, "\")) ''' Usuario que se buscara
Dim myDirectory As New DirectoryEntry(sPath, "Inet\lopez.carlos", "lc97028") 'pass the user account and password for your Enterprise admin.
Dim mySearcher As New DirectorySearcher(myDirectory)
Dim mySearchResultColl As SearchResultCollection
Dim mySearchResult As SearchResult
Dim myResultPropColl As ResultPropertyCollection
Dim myResultPropValueColl As ResultPropertyValueCollection
'Build LDAP query
mySearcher.Filter = ("(&(objectClass=user)(samaccountname=" & SamAccount & "))")
mySearchResultColl = mySearcher.FindAll()
'I expect only one user from search result
Select Case mySearchResultColl.Count
Case 0
Return "Null"
Exit Function
Case Is > 1
Return "Null"
Exit Function
End Select
'Get the search result from the collection
mySearchResult = mySearchResultColl.Item(0)
'Get the Properites, they contain the usefull info
myResultPropColl = mySearchResult.Properties
'displayname, mail
'Retrieve from the properties collection the display name and email of the user
myResultPropValueColl = myResultPropColl.Item(inType)
Return CStr(myResultPropValueColl.Item(0))
Catch ex As System.Exception
'do some error return here.
Return "Ha ocurrido el siguiente error: " + ex.Message
End Try
End Function

I copied the assembly to Reporting Services /bin and copied permission set and code group settings to the config file.

What am I missing?

Thanks,
Carlos
# November 9, 2004 9:32 AM

bryantlikes said:

Bryant,

I am working on a report, which when opened in the browser should trap the user's window credentials and display his details alone. Impersonation is being for deploying the report on the report server. Therefore the user login info cannot be obtained from SQL server. Is there any alternative way of getting the user login credentials?
# December 12, 2004 8:54 PM

bryantlikes said:

Hi Bryant,

Please forgive me, but im quite new to RS. This might sound kind of simple but ive yet to find how to tile records in a report. i have a need to generated a report which produces pics and associated values in a 2 x 2 or a 2 x 3 format which spill over onto new pages depending on the quantity. all the examples ive seen are straight forward matrices of data with details falling vertically down the table. id like to populate the report left to right and kick down to the next row once the first is filled (max value being at my discretion). any ideas?

thanks ahead of time for all who help.
# December 22, 2004 11:55 AM

bryantlikes said:

how do i set the value of a textbox through custom code? (and can it be done if the textbox is situated in the header?
# December 27, 2004 6:54 PM

bryantlikes said:

Is it possible to use 3rd party controls/assemblies written for use in ASP.NET in Reporting Services? I would like to use the ChartFX for .NET in my reports, instead of the built-in charting functionality.

TIA
# December 28, 2004 12:33 PM

bryantlikes said:

Would you happen to know how to add ActiveX controls onto/into custom SQL Reports? There are many articles that mention this as a possibility, but nothing that I have found will allow me to do so. Even a good link would be welcome.

Thanks,
Jim
# December 30, 2004 4:11 PM

bryantlikes said:

Thanks Bryant.

This example helpfull me to debug my report, because I didn't found in Microsoft documentation that the compiled dll must be copied in the "report designer" folder.
# January 13, 2005 2:33 AM

bryantlikes said:

If anyone has done the same with database, could you please help me. I am really struggling.
# January 26, 2005 10:29 PM

bryantlikes said:

Hi Bryant,

as with the others, fabulous work.

Now to yet another question :)

We are actually trying to call RS methods inside our custom assembly. For a simple example, I am just trying to list the reports. I figure if I can get this working I'll be happy. Question is what permissions do I need to set for the method and in the config file.

any ideas

Many thanks

Matt
# January 31, 2005 12:44 AM

bryantlikes said:

Here is a microsoft kb that also shows how to do this:

http://support.microsoft.com/?kbid=842419
# February 1, 2005 11:14 AM

bryantlikes said:

hello all,

i went through this article and did everytihng that has to be done but when i try to connect to the report manager the report manager does not start up. It gives the following error Unable to communicate with the report server. Please verify the report server is operational. When i restore the rssrvpolicy.config the connection to the server is ok. Can anybody help out. This is really nerve racking.. and mdsn help is awful on this.. my rssrvpolicy.config looks like this

<Permissionset
class = "NamedPermissionset"
version="1"
Name="CustomFunctionPermission"
description="test"
<IPermission
class = "OleDbPermission"
version="1"
Flags="Execution,Assertion"
/>
</Permissionset>

<CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="CustomFunctionPermission"
Name="Test"
Description="Description">
<IMembershipCondition
class = "UrlMembershipcondition"
version="1"
Url="c:\Program Files\Microsoft SQL Server\80\Tools\Report Desinger0x;dll"/>
</CodeGroup>


Trust Microsoft to bring up something that is difficult to work with always.
# February 21, 2005 2:57 PM

bryantlikes said:

Honestly have anybody tried this with a db connection. Whatever i do it always gives me the familiar #Error notification and nothign else. Is there any damn thing that must be done anymore also i dont know. I am running out of my wits can anybody help. If u need i can attach my policyfiles also. Please email to rveluthattil@yahoo.com
# February 22, 2005 1:22 PM

bryantlikes said:

This is the policy file that i am having. the sad part is without doing anything like this it works in the IDE perfectly but when i try to access it using the report manager then i get only #Error. Makes one feel that MS has taken pains to design something that will give only #Error.

<PermissonSet class="NamdPermissionSet"
version="1"
Name="Hopethisworks"
<IPermission class="SqlClientPermission"
version="1"
Unrestricted="true"/>
<IPermission class="SecurityPermission"
version="1"
Unrestricted="true"/>
</PermissionSet>


<CodeGroup class="UnionCodeGroup"
version="1"
PermissionnSetName="Hopethisworks"
Name="Hopethisworkassemblylibrary"
<IMembershipCondition class="UrlMembershipCondition"
version="1"
Url="C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin\Hopethisworks.dll"/>
</CodeGroup>
# February 22, 2005 2:26 PM

bryantlikes said:

Great article Bryant...It has everything I wanted to know.
# February 17, 2006 10:40 AM

kevin said:

I kept on getting the same SecurityPermission error that everyone else is getting.  I ended up going into the web.config and changing trust from "RosettaSrv" to "Full" and now I no longer get any error.
# February 28, 2006 4:08 PM

Adi said:

Hello,
I have successfully implemenetd a report whcih uses Custom Assembly. The problem is when I have a subcription for this report, it fails with the error that
"Failed to load expression host assembly. Details: File or assembly name VaryRSStyleSheet, or one of its dependencies, was not found." where VaryRSStyleSheet is my assembly.

Any help would be highly appreciated.
Thanks
Adi
# April 6, 2006 4:23 PM

Rakesh Mishra said:

Hi
Thanks for this nice information!:)

Could you please tell me if its possible to display a Message box or Alert in RS with custom code? Basically, i want to compare the value of two parameter and based on certain condition i want to display an Alert. e.g. There are two param of a reports; "Start Date" and "End Date". Is it possible to check the date before excuting the reports. I want to check that "Start date" must less than equal to "End Date". How can i do this reqporting server.
# May 5, 2006 10:43 AM

Lucas Almeida said:

Hi friend, great article!

Could you help me to find a solution to my problem?

I want to create just one report and one DataSet, but I need to change the DataSource and/or the Server on DataSet.

How can I do it with Custom Code? Could I replace some DataSet properties by report parameters?

Regards!

# October 24, 2006 12:48 PM

Mallesh said:

Thanks, I got a Good stuff from this article.

Thanks a lot

# November 22, 2006 4:59 AM

Mallesh said:

Hi,

  I have a problem in impleteing a concept in Sql Reports 2000. The problem is :

I have 4 columns in the report and is in a Group. The feilds are Credit amt,Debit amt and balance amt.

In the group I will be getting number of rows.

The calculation part should be

Balance = Balance + ( credit - debit)

ie, In the first row I will be getting the calculation and comming to the second row the first row balance should be added second row and so on till the group is complete.

How to do this issue.

Can any one give me a solution ?

# November 24, 2006 4:55 AM

Remy Marx said:

Bryant,

Found your article on google.  Having gone through all the MSDN articles on custom assemblies (the same ones you mentioned), my assembly still wasn't working.  Your article had actual example code of the Hello World style, the type of super-simple code that doesn't make things too complicated.  It was there that I found I was missing a few things.

Thanks!  Maybe I'll make that deadline now... ;-)

# December 7, 2006 10:20 AM

Amy Bolden said:

I am trying to work my way through through the Custom Assemblies section, but I can't get past this error when I try to preview the report:

Error while loading code module: ‘MyCustomAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’. Details: Could not load file or assembly 'MyCustomAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

I have done everything that this article says, plus I have also followed the steps found in "How to grant permissions to a custom assembly that is referenced in a report in Reporting Services" by Microsoft, but I continue to get the error.

Any suggestions?

Thanks,

# December 11, 2006 7:06 AM

Roman said:

How i use textbox.value in code?

# January 8, 2007 7:29 AM

Flexi said:

Is it Possible to merge a two column in Matrix data region?

# February 7, 2007 5:26 AM

ekkis said:

Bryant,

one of the earlier posts here posed the question of how to create custom aggregators.  I've been googling all over the place but have not found a way to do it.  providing a sum() function but not a concat() function seems to me an eggregious omission on the part of Microsoft... certainly others out there must be feeling my pain.

have you any ideas on how to accomplish this?

1,000 thanks - erick

p.s. would you mind e-mailing me?  e AT arix.com

here's the other poster's question:

> Within a group you have a column of string

> values-Say states for example on a group summary

> line you want a concatenation of the string state

> values for all rows in the group.

> so you might have

> ID State

> 1 AZ

> 1 AL

> 1 MO

>

> Summary group footer:

> 1 AZ, AL, MO

>

> This is a little similar to the "running total"

> idea but instead of adding values I want to

> concatenate strings togather.

# February 16, 2007 11:57 AM

Will said:

I have been asked to create a data entry form and make it available from Reporting Services.  Yes, the request seems rediculous to me too, but I haven't talked them out of it yet.  

Has anyone done something similar?  If so, do you have some code to get me started?

# March 1, 2007 8:56 AM

zeeshan said:

i find the article quite usefull, but i have some query regarding writting custom code. my problem is to change the value of textboxes at run time. if i have "Unit of Measurement" as textbox value it should be displayed as "UOM". and i am working on server side reports. Pls help me how can i change the value of textboxes. how is iterate on textboxex in a server side report. hope you understand my problem.

# March 12, 2007 3:56 AM

John Leonard said:

To everyone trying to access an SQL source instead of just a text file try this link:

http://support.microsoft.com/?kbid=842419

At point 1.l (that's L), add in the SQL Client permissions with grant all aswell.

The .NET config tool will generate the xml code for you but you have to cut & paste it to the RS config.  I think it may matter that you put it in exactly the right place.  For me the permissions it generated was put at the end of the permission sets and the codegroup was just after the first code group.

Hope this helps,

   John

# March 22, 2007 7:44 AM

dkhuon said:

Bryant,

Thanks for your great article.

I have this problem addressing a Global reference(?) in my embedded code:

PUBLIC FUNCTION myUserID() AS String

   DIM LastSeparator

   LastSeparator = User!UserID.LastIndexOf("\")

   RETURN User!UserID.Substring(LastSeparator+1)

END FUNCTION

When I tied a TextBox to it as: =Code.myUserID(),

I got this error:

There is an error on line 2 [BC30469] Reference to a non shared member requires an object reference.

What do I need to do?

Thanks.

# May 3, 2007 6:01 PM

Tianna said:

Hi Bryant:

I enjoyed your article on Writing Custom Code - I felt the same way about there not being enough information about it and I'm still trying to muddle through it and fix errors.  I think I followed everyhing correctly but I keep getting the error: "The Value expression for the Textbox15 contains an error. [BC30469] Reference to a non-shared member requires an object reference."  I have written a custom assembly that basically calculates a percentage and handles dividing by zero since IIf statements cannot handle divide by zero operations.  The code is:

namespace Calculations

{

   public class calcPercentage

{

       public decimal Percentage(decimal decValueOne, decimal decValueTwo)

       {

           decimal decPercentage = 0;

           if (decValueOne == 0 || decValueTwo == 0)

           {

               decPercentage = 0;

           }

           else

           {

               decPercentage = (decValueOne - decValueTwo) / decValueOne;

           }

           return decPercentage;

       }

}

}

In my textbox, I put =Calculations.calcPercentage.Percentage(SUM(Fields!PreviousYTDExpenseAmount.Value, "Template_OutputData_Sales"), SUM(Fields!PreviousYTDExpenseAmount.Value, "Template_OutputData_CGS"))

Could you provide any insight as to what my problem might be?  I have been looking at this so long I could possible be overlooking something simple.  Any help would be greatly appreciated.  Let me know if you need any additinal information.

Thank you!

# May 16, 2007 12:54 PM

Alex said:

dkhuon, you can get around this by passing User!UserID as a parameter into your function. then your custom code can use its local parameter. Something like this

PUBLIC FUNCTION myUserID(UserID as String) AS String

  DIM LastSeparator

  LastSeparator = UserID.LastIndexOf("\")

  RETURN UserID.Substring(LastSeparator+1)

END FUNCTION

=Code.myUserID(User!UserID)

# May 30, 2007 2:26 AM

Frank said:

Hi,

Has anyone solved this problem? It is copy from previous post.

Assume data in Groups

Within a group you have a column of string values-Say states for example

on a group summary line you want a concatenation of the string state values for all rows in the group.

so you might have

ID State

1 AZ

1 AL

1 MO

Summary group footer:

1 AZ, AL, MO

This is a little similar to the "running total" idea but instead of adding values I want to concatenate strings togather.

Any suggestions.

Please email me at franta1346 at yahoo.com

Thanks

# May 30, 2007 4:35 AM

Ali said:

Hi,

I am using custom assembly in reporting services. on development everything is working fine. When i try to upload .rdl files on a separate / different / production machine to check its working it is giving following error

Error while loading code module: ‘reportHelperLib, Version=1.0.2705.22780, Culture=neutral, PublicKeyToken=null’. Details: ? (rsErrorLoadingCodeModule) Get Online HelpError in class instance declaration for class reportHelperLib.rptHelpers: [BC30002] Type 'reportHelperLib.rptHelpers' is not defined. (rsCompilerErrorInClassInstanceDeclaration)

i have gone through many articles but could not solve this problem. i try to add reportHelperLib.dll in gac but invain. i copied reportHelperLib.dll in C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin but still its not working. i have restarted my machine as well but :(

can anyone please tell me what i am missing?

Regards

Ali

# June 5, 2007 7:23 AM

J O said:

I am quite desperate with my custom assembly dll (not in reporting services). After 2 weeks I still do not get it running on my server. On an old server I could, but now it doesnt. If you think you could help me out I can give you a remote rdp login. Please contact me at: www.voice4all.com and then contact tab. Thank you,

J.

# September 14, 2007 1:48 PM

ganesh said:

hi

i have written  custom function in code part in that function we are passing parameter

for ex : code.Get(Parameters!param.Value)

above function iam calling in datasource expression  for generating connection string while previw i can  connect multiple database and view report, after deploying it displays error ...

i hope parameter is not passing to that function

plz help me in this issue

# September 17, 2007 12:03 AM

Shankar said:

Hello Friends,

I have one requirement regarding embedding the HTMl content in sql reporting service, i have a FCK editor value in db, i want to show the values in this report with the specified format in FCK editor.

Thanks.

# October 8, 2007 6:17 AM

rocky said:

bryantlikes said:

how do i set the value of a textbox through custom code? (and can it be done if the textbox is situated in the header?

I have the same question, how can i access report items in custom code, is that possible or not

# October 17, 2007 3:48 AM

Matt said:

these static fields are a bad idea because of two people are running the report at the same time their data will be shared.

# October 18, 2007 9:44 AM

John F said:

I've followed all of these steps, but I keep getting the following message when trying to preview or run in debug:

The Value expression for the textbox ‘textbox1’ contains an error: [BC30456] 'GetDate' is not a member of 'ALMRSFunctions'

However, 'GetDate' is a valid static member of 'ALMRSFunctions'. Also, when I add the namespace in front of the class name, it says it's not defined.

Any suggestions?