How to loop rows of dataset in Reporting services rdl custom code - reporting-services

How can I loop through the rows of a dataset in the custom code?
I have a report containing a dataset. I pass the dataset as a parameter to the custom code function. But what then? Where is a reference about the available members etc.?
Here is my dummy sample code so far:
Public Function ShowParameterValues(ByVal ds as DataSet) as object()
Dim codes() As Object
Array.Resize(codes,dc.???.Count)
codes(0)=ds??(field???)(row??)
return codes
End Function
Please note: this will be a very simple script (if it'll work), so I don't want to go into custom assemblies etc.

I think you got your answer at:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a7d59224-0ee5-491e-883b-2e5fcb3edeab/iterate-through-rows-of-dataset-in-reports-custom-code?forum=sqlreportingservices
There were two important pieces of information I was able to grasp from the above link:
First, A dataset in Reporting Services is not the same type of object as an ADO.Net dataset. A report dataset is an internal object managed by the SSRS runtime (it's actually derived from a DataReader object) and not an XML structure containing datatables, etc. and cannot be passed into the report's custom code.
Second, There was a solution posted as to how one can Iterate through rows of dataset in report's custom code by "transforming" the data set into a multivalued parameter (or if several fields are needed, transforming it in multiple multivalued parameters):
The multivalued Report Parameter must have the following characteristics:
Hidden = True, Allow Multiple Values = True
Available Values tab: Choose the desired dataset. Select the searchable id as Value id, and the field you want to expose as Label Field.
Default Values Tab: Get Values from a Query.
Choose the same Dataset as choosen in the available Values Tab.
Value Field the same you choose for value id.
Set the parameter to never refresh (or it will be loading the data from each iteraction of another parameter).
Now, the idea is make this Parameter "searchable". From this point you exposed the Dataset as an array in the Multi valued Parameter.
Now in a custom code insert the following code:
function GetDataSetLabelFromValue( id as integer) as String
dim i as integer
i = 0
for i = 1 to Report.Parameters!YourParameter.Count()
if Report.Parameters!YourParameter.Value(i) = id then
GetDataSetLabelFromValue = Report.YourParameter!ReportParameter1.Label(i)
Exit For
End if
next i
End Function
Were you able to do what you wanted?

Related

SSRS function needs to read field from additional dataset

So in the custom code in SSRS this function is reading a field from a different data set. To be specific the field is "TOTAL_WORK_HOURS".
Public Function CRFtotalhourswobreak(Fields As Microsoft.ReportingServices.ReportProcessing.ReportObjectModel.Fields) As Double
Return Fields!TOTAL_WORK_HOURS.Value - CRFbreakhours(Fields)
End Function
Because that field is in a dataset not being used by the Tablix, the field simply isn't being read. I know this to be true because whenever I replace the field with random number, I do get results.
Is there proper syntax to implement a field that isn't in the main dataset?
you can use
=First(Fields!TOTAL_WORK_HOURS.Value, "DataSet1")

Issues with Passing Multi-value Parameters to a Drill through Report

I have two reports were I pass multi-valued parameters to it's underlining data and both reports work very well independently. The parameter strings are being split using the function dbo.UTILfn_Split. When trying to drill from the main or Summary report into the sub or Detailed report all other parameters field in the report are populated except the multivalued parameter field. The parameter lists or value are listed in the detailed report but not selected and therefore cannot run the report even though the detailed report parameter property is set to allow multiple values. In both reports, the where clause is set "IN" not "=." How do I fix this?
In your Summary Report, when you pass the parameter to the sub or detailled report, the passed value parameter should be like this expression:
=join(parameters!yourMultivaluedParameter.Value,",")
after that, you pass the name of the parameter to the corresponding parameter in the dataset Detailled report.
In your SQL (SP), get the multivalues of the parameter by spliting it with your function
like following, depending of the result of your function, for exemple:
INNER JOIN dbo.SplitFunction( #yourMultivaluedParameter,',') tmp on tmp.yourColumn = ...etc...
Hope it helps...

SSRS Drilling through on dependent grouped parameters

I have been asked to add a group to a drill-through report depending on the parent report's multi-value parameter called Projects.
This group works perfectly on the parent chart however when drilling through into the child other parameters dependent on Projects are not being selected despite appearing in the list.
For instance the project parameter controls the available options for another multi-select Team parameter. When multiple projects are selected you can run the report across multiple teams, when selecting a single project from the grouped report this limits the team filter in the child, despite some of the original parameters from the main report being available in the child none are selected.
When passing the parameters to the drill-through report can I produce a sublist from the parent Team parameter filtered on the grouped Project parameter?
Pseudo-LINQ example:
=Parameters!TeamIds.Where(t => t.ProjectId == Fields!ProjectId.Value)
Alternatively is there any way to pass through the full list of teams to the child report and for the report to select the teams that match the selected project?
Edit
Available values for the Project parameter in both parent and child reports:
select id, header from projects
Available values for the Team parameter in both parent and child reports:
select t.id, t.header from teams t where t.ProjectId = #ProjectId
When running the report we display a lot of data in grouped grids with actions to run another report.
This Drillthrough passes the full list of teams. This stops the child report because some of the teams passed in are not valid values. Then the child report does not automatically run and forces the user to reselect the team.
Despite the Drillthrough implicitly setting the team from the main parameter.
I believe this is breaking due to the child report not being able to handle the multiple team projects originally selected in the main report.
My question is how do I:
a) Filter the team parameter to only include the project I have selected to drillthrough
or
b) Make the child report accept the full list of teams passed into it and only select the appropriate ones from the new filtered team list based on the single Project
Edit 2
Public Function GetTeamsForProject(ByVal ItemWithProjectInHeader as Parameter, ByVal ProjectHeader as String) as Collection
Dim s as new Collection
For i as integer = 0 to ItemWithProjectInHeader.Count-1
if ItemWithProjectInHeader.Label(i).Contains(ProjectHeader)
s.Add(ItemWithProjectInHeader.Value(i))
End If
Next
Return s
End Function
Started trying to put together some code to cherry pick the teams but I can't seem to get the collection return to work, for now i am calling it like
=Code.GetTeamsForProject(Parameters!TeamIds,CSTR(Parameters!ProjectId.Label(0)))
This just returns #Error in the text box i am using.
Hopefully someone could at least spot the 'deliberate' mistake on this.
Thanks
Edit 3
I am also trying something like this
Public Function GetItemsForProject(ByVal ItemWithProjectInHeader as Parameter, ByVal ProjectHeader as String) as Collection
Dim s as new Collection
For i as integer = 0 to ItemWithProjectInHeader.Count-1
if INSTR(1,ItemWithProjectInHeader.Label(i), ProjectHeader,1) > 0
s.Add(ItemWithProjectInHeader.Value(i))
End If
Next
Return s
End Function
and calling it like...
=Code.GetItemsForProject(Parameters!TeamIds,Fields!ProjectId.Value)
As you suggest, It looks like the core problem is that a parameter is being passed into the child report that the child report considers invalid.
Seems like two directions to solve this: one, Filter down what you send pass as the parameter value from the parent, or two, allow all the values that are coming in. Not knowing the structure of the report it seems like the second of these is easier. If you accepted extra teams into the child report will it cause the report to display incorrect values?
That is, if you change the possible values for the Team parameter in the child report to:
select t.id, t.header from teams t
That would certainly limit the usefulness of the child report when used directly, but do users go straight to the child report?
Another option would be to create two parameters in the child report. PassthroughTeams would be a hidden parameter that is passed in by the parent.
Teams would stay as it is, but have some default value (maybe all possible teams)
Then change the core data query of the child report to something like:
SELECT mydata.*
FROM mydata
WHERE mydata.teamId IN (#TeamIds)
AND mydata.teamId IN (#PassthroughTeams)
Finally got a working solution, I added the Project header to the team parameter so that I can use the team's label in the pass through.
Some problems with the original code:
Missing the 'Then' from the ifs
Potential that the instr or contains were missing references so moved to using the startsWith function
Public Function startsWith(str As String, prefix As String) As Boolean
startsWith = Left(str, Len(prefix)) = prefix
End Function
Public Function GetItemsForProject(ByVal ItemWithProjectInHeader as Parameter, ByVal ProjectHeader as String) as Collection
Dim s as new Collection
If ItemWithProjectInHeader.IsMultiValue Then
For i as integer = 0 to ItemWithProjectInHeader.Count-1
If startsWith(ItemWithProjectInHeader.Label(i), ProjectHeader) Or startsWith(ItemWithProjectInHeader.Label(i), "(Not") Then
s.Add(ItemWithProjectInHeader.Value(i))
End If
Next
Else
If startsWith(ItemWithProjectInHeader.Label(0), ProjectHeader) Then
s.Add(ItemWithProjectInHeader.Value(0))
End If
End If
Return s
End Function

Filter a field with concatenated values against a multi-value paramter in SSRS

I have a field called "ContactType" in my SQL dataset. This field has more than one value joined with a "," separator.
Lets say I have two records
Contact Type | RecordId
-------------|----------
A,B,C | Record1
B,C,E | Record2
Now in SSRS I have a multi-value parameter to use as a Contact Type filter. The options will be
A
B
C
D
E
F
When I select A and B from the filter I want to check if A or (OR) B present in the above records. The problem here is that the ContactType field is a single string of text but contains more than one value.
How can I filter the values in the ContactType field based on the array of values in the multi-value parameter?
I think the best way to do this would be to write a simple function using custom code. The custom code editor can be accessed from the Report menu.
Then use a function like this:
Function CheckContactType(ContactTypeList AS String, ContactTypeFilter AS Parameter) As Boolean
Dim contactTypes As String() = ContactTypeList.Split(",")
For i As Integer = 0 To (ContactTypeFilter.Count-1)
If contactTypes.Contains(ContactTypeFilter.Value(i)) Then Return True
Next i
Return False
End Function
Then your filtering expression would be this:
=Code.CheckContactType(Fields!ContactType.Value, Parameters!ContactTypeFilterParameter)
and you would use the = operator against the value expression:
=True
The custom code function is making use of the .NET String.Split() and Array.Contains() methods. These MSDN pages are quite good for learning more about custom code in SSRS reports:
How to: Add Code to a Report (SSRS)
Using Custom Code References in Expressions (Reporting Services)
Using Custom Code in SSRS Reports for Advanced String Operations

Passing parameters to a Dataset from an expression in SSRS

In a report I would like to have the individual static text fields internationalised.
The idea is to have a default word or phrase like "Date and Time" and pass this string to a dataset with static parameters such as Culture_Code.
My question is how do I set the value of the parameter to pass to the dataset BEFORE calling the dataset within each individual expression of each text box?
Example expression;
Parameter!Text_To_Translate.Value = "Date and Time"
=First(Fields!Translated_Text.Value, "Language_Text")
I am using SSRS 2008R2.
if you want to pass the parameter before calling the dataset then you have to pass the parameter in the url of reportserver
http://localhost/reportserver
url format:
http://<localhost/servername>/reportserver/Pages/ReportViewer.aspx?<report_name>&rs:Command=Render&parameter_name=value
here the way you have to pass the value.
If your report layout is such that all of the text fields to be internationalized are in one or two regions, it may be better to set those regions up as data regions and use a separate query (or queries) to populate them, based on your Culture_Code parameter value.
This assumes you are pulling the localized values out of a data source you can connect to - which may be updated or extended over time.