We are running into the well-documented problems with localizing our SSRS reports.
Can anyone recommend an alternative? Presume parity (or nearly so) with SSRS' functionality, though a great many of our reports will be simple grids or graphs, with some header/footer text. We want a means by which we can easily identify localizable strings, store them in a database, translate them, and then generate the localized "report definition" at deployment time. The Spanish see Spanish reports, the Italians see Italian reports, etc.
Thanks everyone.
There's a book called "Microsoft SQL Server Reporting Services Recipes" that has a few pages dedicated to how to localize SSRS reports. The only limitation is that parameter prompt text can still only show a single language (as it doesn't allow expressions); if you're accessing reports via a client though then it won't be an issue.
It involves creating a custom assembly in VS that has a main function that does the translation (using localization resource files, in much the same way you'd do it for an application).
Then you override the report's OnInit in custom code to initialise the custom assembly resource manager with the report name (so it knows which set of strings to look up, I suppose), and then instead of using "Name: " text in your report, you can use =Code.my_localizer.GetLocalText("Name")
try to put some parameter on ssrs and create procedure like this:
--TEST
--DECLARE #language int
--SET #language = 2 --1 Italian --2 Spain
--passing language parameter from ssrs report
IF (#language = 1)
SELECT englishNameField1 as italianFieldName1, englishNameField2 as italianFieldName2, englishNameField3 as italianFieldName3
FROM tableName
ELSE
SELECT englishNameField1 as spanishNameField1, englishNameField2 as spanishNameField2, englishNameField3 as spanishNameField3
FROM tableName
WHERE parameterFromSSRS = #language
in report put parameter #language with some expression on UserID (Built-in Fields) to get language(localization)
Related
My team and I are in the process of migrating from Crystal Reports to SQL Server Reporting Services. A handful of our reports involve what my team refer to as "dynamic external images". What this means is that in the report we would have this default blank image object, and then in the Graphic Location setting we would have the following function:
Trim({rpt_StoredProc;1.SignaturePath}) + Trim({rpt_StoredProc;1.SignatureId}) + ".jpg"
This way, we could pass through the directory path and the file name (minus the file extension) via the stored procedure.
I'm now trying to replicate this in SQL Server Reporting Services Report Builder and I'm running into a brick wall.
Your data relating to dynamic external images having been imported in SSRS should be accessible in a table using the data type varbinary(max). This can be accessed and utilised in an SSRS report either as a single field (ie in a header/title) or in matrix a field.
Both usages require you use the toolbox, (view and select toolbox) and left mouse click , drag "image" to your report, image source "database", use the field (select varbinary(max) field) , MIME type try "image/bmp" first, select the size to suit your needs.
and you should be good to go.
Best of luck.
I finally found the answer!
="file://" & First(Fields!SignaturePath.Value, "rpt_StoredProc") & "\" & First(Fields!SignatureId.Value, "rpt_StoredProc") & ".JPG"
I thought I had already tried this and that it didn't work, but I guess not.
Is it possible (if Yes - how) to retrieve data from SSRS dataset that has been published to the ReportServer ?
I have is Azure reporting services setup, and published a DataSource, DataSet, and a report that work perfectly fine.
What I want - is to be able to access that "published DataSet" - like some sort of a XML API ?
Say hit some URL with params from a browser, and get a XML result with Data from that DataSet
The problem you will run into is the rsd (datasetFile) is not much itself but a query and for that reason publishing the proxy services of ReportService2010 will get you the data but you still have to then handle the XML shredding. It is much, much easier to get the data from the dataset through querying the 'ReportServer' IMHO in SQL directly. Rather than making the models from the proxy classes, getting the data from invoking those classes, then you have xml you still have to query to get your data.
Example with word of warning: (This may only work with my example of datasets not other catalog items):
use ReportServer
GO
Select
Path
, Name
, Content
, cast( cast(Content as varbinary(max)) as xml) as ContentAsXML
, cast(
cast(Content as varbinary(max))
as xml)
.query('declare namespace a="http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition";
/a:SharedDataSet/a:DataSet/a:Query/a:CommandText')
.value('.', 'varchar(max)') as QueryStatement
from dbo.Catalog
where type = 8
Based on this guy's writing:
http://bretstateham.com/extracting-ssrs-report-rdl-xml-from-the-reportserver-database/
If you decide you just must use the proxy classes you will have to remember to invoke the namespace and I did an Xdocument method with C# to get the data. Don't have the dataset but I did the Datasource which will be a similar method. You mainly do this method in a foreach loop for each dataset you want. Keep in mind YOUR NAMESPACE for 2008 or 2005 will differ:
private List<string> GetDataSourceRefs(string aSourceLocation)
{
var xdoc = XDocument.Load(aSourceLocation);
// Need a namespace or else the xml elements will not be properly identified. Default below is for 2012 ONLY.
XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition");
return xdoc.Descendants(ns + "DataSource")
.Elements(ns + "DataSourceReference")
.Select(x => x.Value)
.ToList();
}
Use ReportExecution2005 proxy class - you can execute the report and get it in the XML format. I'm not sure but I think you should be able to execute datasets too. You can read more about it here:
Generate reports programmatically using the TFS API and SSRS
Is there a way in SSRS to create a snapshot for a report that uses a shared dataset? We are looking for a way to dynamically set the server and credentials in SSRS, but it seems when the shared dataset is used there is no way to cache a report.
Two things that I think may help you:
You can create a dynamic connection string from parameters you pass in. However you lose intellisense when creating this so generally I use an actual database first to do my dataset then change the connection string later:
A. Create a variable #Server, set it to text:
B. Create a local DataSource, this must be local as you cannot share a data source that is dynamic, to my knowledge as it has no input to go on thus a shared must have set inputs.
C. On the side of 'Connection string:' hit the 'fx' button to get a dynamic connection string. Build a connection string of text with your parameter being an input:
="Data Source=" & Parameters!Server.Value & ";Initial Catalog=(DBName)"
D. You NOW have to set up a dataset to bind to #Server variable or else someone just needs to do plain text to guess at a server. For this reason I usually create a dataset like
select 'Server1' as Server
union
select 'Server2'
union
select 'Server3'
You can handle the cache aspect COMPLETELY from the hosted end and not worry about the report stuff. Just go to a report once deployed and choose 'Manage'>'Snapshot Options'> Set your preferences.
EDIT: You probably want another variable for the database or else you will assume a same database structure all the time.
I have designed a SSRS report having multiple sub-reports. The report is working fine but displaying data for all records.
But my need is to make it context sensitive.
Below is the query for the main report.
SELECT Filterednew_franchisee.new_franchiseeid,
Filterednew_franchisee.new_name,
Filterednew_monthlypayment.new_insurance
FROM Filterednew_franchisee
INNER JOIN Filterednew_monthlypayment
ON Filterednew_franchisee.new_franchiseeid =
Filterednew_monthlypayment.new_franchiseeid
WHERE (Filterednew_monthlypayment.new_yearmonth =
#reportyear + #reportmonth)
AND (Filterednew_franchisee.new_franchiseeid IN
(select new_franchiseeid
from Filterednew_franchisee as CRMAF_Filterednew_franchisee))
Sub-reports are using the fields from the above query as parameter.
Am I missing something ? Is there any other approach that needs to be followed? Is it really possible to design a context sensitive report having multiple sub-reports?
Please help.
Yes, context-sensitive reports are possible. The name Filtered as in Filterednew_franchisee refers to a SQL Server view that is designed for the sake of security roles. To gain access to context-sensitive views, the API takes an arbitrary prefix called CRMAF_ and translates it into a context-sensitive query.
Thankfully, the SDK includes a sample view (which I've copied below).
SELECT
CRMAF_FilteredActivityPointer.activitytypecodename as activitytypecodename,
CRMAF_FilteredActivityPointer.regardingobjectidname as regardingobjectidname,
CRMAF_FilteredActivityPointer.subject as subject,
CRMAF_FilteredAccount.name
FROM FilteredActivityPointer AS CRMAF_FilteredActivityPointer
INNER JOIN FilteredAccount As CRMAF_FilteredAccount on
CRMAF_FilteredAccount.accountid =
CRMAF_FilteredActivityPointer.regardingobjectid
In Reporting Services I would like to add a parameter that contains data from a custom code block. Ideally, I would be able to run the following code (this is a simple testing example):
Function GetPeriods() As String()
Dim values As System.Collections.ArrayList =
New System.Collections.ArrayList()
For i as integer = 1 to 24
values.Add(i)
Next
Return values.ToArray()
End Function
and put the following in the "Text Field" of the parameter:
=Code.GetPeriods()
However, when I run the report, the parameter I apply this to is disabled and empty. Is there a different technique that should be used? Or am I doing something wrong?
If you're using SQL 2008 Reporting Services then you can have a look at this page which introduces the concept of using custom assemblies.
If you're using SQL 2005 Reporting Services then this link is the one you want.
It's a mostly trivial thing, simply compile your code into a class library and follow the instructions provided to allow your report to reference it.
You are returning an array item (an array of strings) into a text field. Instead, try returning a plain string. That should work. If you would still like to return an array list, you must basically bind it to a list control in your RDL. You can definitely do that with dataset extensions. However, I am not sure if there is any other easy way. Check the proprties of the list control and see if it allows you to directly bind to an array list.
You can create the same stored procedure on SQL Server and load parameter values from that procedure.
To access your members/functions implemented in custom code of SSRS report you should set the access modifier to "Public":
Public Function GetPeriods() As String
...
see article Writing Custom Code in SQL Server Reporting Services
I've been trying to do this same thing, set a simple list of parameter values from report code. None of the links in any of these answers shows how to do this and after quite a bit of digging around I don't think it's even possible. Yes it is possible to get the values from a database query, from a web service, or from a custom assembly, but each of these creates a lot of overhead compared to getting the list from a simple function call like =Code.GetValues(), where the function uses a For loop to create the values.
msvcyc is correct in pointing out that the parameter is expecting a string value, but the function is returning an array. I changed the return type to Array as suggested by prashant sable, but the select list is still grayed out, it does not work. And coldice is correct in saying that the access modifier should be Public.
In my digging around I found an article by James Kovac from 2005 that pointed out why this is not possible. The Parameters class has a get method, but no set method. In the VS 2008 object browser for SSRS 2008 the object name has changed, but it still does not contain a set method (see Microsoft.ReportingServices.Interfaces.IParameter.Name or .Value).
My current workaround is to just hard code the list of values, but if your value list needs to be dynamic then your only choices are database queries, web services, or custom assemblies. I think the easiest workaround of these three is to get the values from the database engine, as suggested by oleksiy.t, as long as you can write a query to return the value list you want. Your list of integers, or my list of time intervals, would both be easy queries to write. Otherwise you will need to use one of the other two workarounds.
I checked your code. The only thing that's wrong is your function returns String(). When I changed your method signature to return Array, it worked fine, in my report.
Change the signature to Function GetPeriods() As Array
Everything I've seen requires parameters and their respective settings to be part of the RDL.
That being said, if you're going to "hardcode" the values, you could create a dataset just for the report, perhaps in XML, or if it needs to be programmatically driven, do it in a web service.