My client wants to be able to show/hide columns in a report based on a Parameter (ReportType). The report columns are static, they will just be controlling which ones are hidden/shown which creates a different "View" of it. Currently there are only 2 views, but we are about to add several more.
At the moment column visibility is controlled by simple expression: =Parameters!ReportType.Value = "SOMEVALUE"
and only 1 report type hides columns so this expression is fine.
Now we're moving into a situation where a column may be hidden in multiple ReportTypes and i want to avoid getting into: IF report type = VAL1 or VAL2 or VAL3 THEN HIDE as it will make it very hard to see for any given ReportType what columns are meant to be shown (as all the logic is in each column visibility expression)
I found a post and used the basic elements of it:
http://sql-bi-dev.blogspot.co.uk/2010/10/displaying-dynamic-columns-in-ssrs.html
What im trying to do is define a Dataset, something like:
SELECT * FROM
(
select 'Rpt Type1' ReportType, 'Units' ColumnName UNION
select 'Rpt Type1' ReportType, 'Price' ColumnName UNION
select 'Rpt Type2' ReportType, 'Units' ColumnName
) ReportColumns
WHERE ReportType = #ReportType
And then in the Column Visibility expression check to see if the column name exists in the dataset. This way visible columns for a report type are defined in a single place and are easy to manage/maintain.
In the post i linked, hes getting the user to select the Column names in a parameter. I want to lookup the Names in my dataset based off the ReportType param thats selected.
Im stuck on getting the column names into a parameter and then using that in the column visibility expression. Any help would be much apreciated :)
Doh, i was pretty much there.
I created a parameter and set its default values to "Get From Query" and selected my dataset and ColumnName field... job done!
Then i was just writing visibility expressions for each column using the code in the article i was following.
Related
I need to export my SSRS report to csv format. Issue I am facing is that few column header names change with country code (parameter) and I want to show the same name in my exported csv. I have gone through other related questions and topic, specifically this one. It suggested that there is a work around by setting data value to null. I have tried this by adding columns and hiding these based on country code, along with setting data value to null for that dataset field. But it did not work. I still get the hidden column in my export, with no values in it.
Can someone confirm that this workaround works or is there any other way apart from creating different reports for each country?
UPDATE: (added report screenshot and description for clarification)
Based on apporoach I have taken,
I need to only show Column 'Town' for Country A and only 'Suburb' for Country B. This is easily done by hiding columns based on Country Parameter( and works fine for EXCEL export), but when exported to CSV, both columns are exported.
UPDATE 2
Found this link which is similar to what I have been trying to figure out and looks like there is no solution which can be achieved using only one report.
According to this post
MSDN Social: Hide CSV columns conditionally in SSRS report
The XML and CSV renderers use the DataElementOutput property to
control visibility. We can select which item we want to hide in the
report, and set the “DataElementOutput” property with value “NoOutput”
to work around the issue.
Alternatively, we can add below expression to control the item’s
visibility. Please refer to the expression below:
=IIF(Globals!RenderFormat.Name="CSV",True,False)
This, incidentally, is the second answer in the thread that you posted. That answer links to the following article which explains how to do exactly what you need
Hide/Show Items Dependant On Export Format
UPDATE
It appears that you cannot programmatically set DataElementOutput for CSVs. However, according to this post SSRS - Programatically controlling the DataElementOutput property
in RS 2005 / 2008, you should be able to get the desired effect by adding a filter on the tablix directly (in addition to the visibility condition):
Filter expression: =(Parameters!DataPeriod.Value = "DAY")
Filter operator: =
Filter value: =true
Thereby, for the cases where the tablix is not visible, you are also filtering out all the data.
You may be able to show/hide country specific columns this way instead.
My approach would be to do this in SQL. I'm not sure how you determine which Countries require the town to be returned and which require the suburb to be returned but here's a couple of approaches that hopefully cover your scenario.
In either case, the idea is to return the town/suburb data in the same column and then an additional column that will contain a a caption that we can use as the column header.
a. Only one of either the town or suburb column in your table is populated. In this case it's pretty simple.
SELECT
Country
, ISNULL(TownOrCity, StreetSuburb) AS TownSuburb
, CASE WHEN TownOrCity IS NULL THEN 'Street-Suburb' ELSE 'Town-City' END AS Caption
FROM myTable
b. You know upfront which Countries require what and you can pass a parameter in to get the correct column. In this example we'll use a parameter called #TS and pass in either a T or and S
SELECT
Country
, CASE #TS WHEN 'T' THEN TownOrCity ELSE StreetSuburb END as TownSuburb
, CASE #TS WHEN 'T' THEN 'Town-City' ELSE 'Street-Suburb' END AS Caption
FROM myTable
Whichever approach we take you will end up with a simple table
Country TownSuburb Caption
Testland TownA Town
Testland TownB Town
Testland TownC Town
In you report, you don;t need to do anything except make the town/suburb column caption an expression something like =FIRST(Fields!Caption.Value)
That's it, the report is now nice and simple and should export without any issues.
UPDATE to method:
--
-- Dump data into a temp table
--
SELECT
Country
, CASE #TS WHEN 'T' THEN TownOrCity ELSE StreetSuburb END as TownSuburb
INTO #t
FROM myTable
--
--rename the column
--
DECLARE #NewColumnname sysname = CASE #TS WHEN 'T' THEN N'Town-City' ELSE N'Street-Suburb' END
EXECUTE tempdb..sp_rename N'tempdb..#t.[TownSuburb]', #NewColumnname, 'COLUMN'
--
-- finally get the result
--
SELECT * FROM #t
Background -- I’m trying to create a report in SSRS using Report Builder 3.0 that contains multiple parameters. The request is when the report is opened, display all rows of data. The end user can then select one or more of the parameters to reduce the results displayed. I can get it to work using something like the following.
Data sets for Parameters where available values are from a query,(dataset type is text)
For fields that are numbers:
SELECT 0 'FACG' UNION ALL SELECT DISTINCT STR(ACG) FROM STG_CSI_SA_CONFIRM
For columns containing text:
SELECT 'Any' 'FunderName' Union All Select DISTINCT NAME FROM STG_CSI_SA_CONFIRM
In the dataset for the report I have this:
WHERE ('Any' IN (#FrName) or Fname.name in (#FrName)) AND ( 'Any' IN (#FACG) OR FLIST.FACG IN (#FACG))
The results are two Parameter boxes, one says 0, one says Any, and the report runs when first opened. End user can then select one or more numbers from FACG or one or more names from FRName.
My question is, how can I adjust the first parameter to show ‘Any’ instead of a zero as the default value? All the values returned would be integers of 7 digits long. When I simply change the 0 to Any I get an error message about converting data types. If I use STR() I can get a list out of SQL server I get a list as I expect. ( Any, 1234567, 1234568 etc.) But I cant get the list to work in SSRS.
Thanks
R
Two way to do this.
1. Make sure the dataset that provides values for your parameters has two columns, an ID column that you will use to actually do the filtering/joins in your dataset and the other column is the label which will be visible to the user. Something like
ID Label
'Any' 0
'1234567' 1234567
'1234568' 1234568
If you main data dataset is a query (not a Stored proc) then you can simply have a parameter dataset as above but without the 'Any' row. Then set you available value to the parameter dataset and the default values to the same parameter dataset. By default all parameters will then be selected.
In your main data dataset the query would be along the lines of
SELECT * FROM myTable WHERE myColumn IN (#myParameterName)
SSRS will turn the selected values from the parameter into a list of comma separated values and inject them into the query for you.
I am not sure if this is possible in Report Builder or not. I want to put a text box in a Report Builder report and then search the database for a specific person and display that in a subreport. Is this possible and, if so, how would you suggest I do it? I have tried researching it online without success.
This part will produce a parameter into which your user can type whatever they want
You need to set up your report to use parameters. You can set these parameters up to require user input either from manual entry or by picking from a pre-defined list.
Assuming you are returning your data using a SQL query, you can then reference these parameters in your dataset script. If for example you had a parameter called FirstName and another called Surname, and you only wanted to return values in your data set that matched both exactly, you would reference these parameters like so:
select PersonID
,FirstName
,Surname
,OtherDetails
from PersonTable
where FirstName = #FirstName
and Surname = #Surname
If you would rather have more of a 'search' type function, you can use the SQL like operator and wildcards, though bear in mind this will have a potentially very detrimental effect on your query performance:
select PersonID
,FirstName
,Surname
,OtherDetails
from PersonTable
where FirstName like '%'+#FirstName+'%'
and Surname like '%'+#Surname+'%'
This part shows you how to change that parameter so it provides a drop down menu. This part is optional.
If you want to provide a list of available options to select from, you can create a parameter that has a list of 'Available Values'. These can either be manually typed in by yourself - hard coding them in to the report design - or you can make them data driven by basing the parameter on a second dataset.
To get that list of people, you would want to return the ID of the person you are looking for as well as the details that are end-user friendly to be visible in the report:
-- select distinct so we have no duplicates
select distinct PersonID as Value -- Value is what is used to the query. This ideally will be a uniquye identifier
,FirstName
+ ' '
+ Surname as Label -- Label is what the user sees. This can be a bit more verbose and detailed
from PersonTable
order by Surname -- Specify how you want the options ordered
,FirstName
If you set this dataset as the source by selecting Get Values From A Query in the parameter options, you will see the drop down list appear when you run the report. Users can then select one, click Run Report and have their selection impact the data that is returned.
I need to be able to set an SSRS parameter to contain multiple values.
In TSQL, I can have a where clause that states:
where Attribute in ('Value1', 'Value', 'Value3')
What I need is in SSRS to have:
where Attribute in (#Attribute)
Where I am getting hung up is how to format the parameter value expression so that SQL sees it as: 'Value1', 'Value', 'Value3'
I have had some luck making the where clause look at only the first value, but I need it to look at all 3. How would I format the expression to do that?
I would just allow it to accept multiple values, and check each value individually, but I need the drop down list to have groups. So, if the user selects GroupA, the where clause uses: IN ('Value1', Value2') and if the user selects GroupB, the where clause uses a different list for the IN.
Hopefully it's just a matter of formatting the expression correctly.
Well, if you didn't have the requirements about groups, this wouldn't be an issue since all you need is to make your parameter a multi-valued one, and on your dataset query do WHERE Attribute in (#Attribute). But taking that requirement into account, the only way I can think of, is to have two multi-valued parameters: #Group and #Attribute. You'll need to make #Attribute not visible and create a dataset to populate it. That dataset would be something like this:
SELECT Attribute
FROM Attributes
WHERE Group IN (#Group)
And create another dataset for your report data:
SELECT <all your data>
FROM YourTable
WHERE Attribute IN (#Attribute)
I'm trying to follow Microsoft's example on how to add an "All" option to a ComboBox in Microsoft Access, but their article does not do an adequate job of providing guidance, aside from specifying the code.
What I'm trying to do is build a form that allows a user to select an option from a ComboBox (the options are generated from records in a table), and then build a report filtered based on the user's selected option. The ComboBox consists of 2 columns: the primary key/ID of the records and their displayable names.
I can't understand the VBA code Microsoft provides enough to figure out what is going on, but I would like the "All" option in my ComboBox to either have a blank primary key/ID, or one that = 0. That isn't the case, as selecting the "All" option when using the form results in the error message "The value you entered isn't valid for this field". This leads me to believe that the "All" text is getting filled into the primary key/ID column instead of the display column. The example instructs me to assign the display column number as the "Tag" property of the ComboBox - and in this case, my display column number is 2. However, this (and pretty much any other value I add) results in the aforementioned error message.
Any idea if Microsoft's example is even applicable to my case, or do I need to adjust their code somehow?
Check the Control Source property of your combo box. Sounds like it may be bound to a field in the form's record source. If you make it an unbound control (nothing in the Control Source property) you should be able to select any item from the combo's Row Source without Access complaining at you.
Say your combo's Row Source is a query like this:
SELECT id, disp_name
FROM YourTable
ORDER BY disp_name;
You can add an "all" row with a UNION query:
SELECT id, disp_name
FROM YourTable
UNION ALL
SELECT TOP 1 0, "**ALL**"
FROM AnyTable
ORDER BY disp_name;
AnyTable can be just that. If you happen to have a table which contains only a single row, use that one ... and you wouldn't even need the TOP 1 part. Just try not to use some ReallyBigTable as AnyTable.
Edit: Actually some ReallyBigTable would be fine if it has a primary key or other unique field which you can use in a WHERE clause to retrieve a single row:
SELECT id, disp_name
FROM YourTable
UNION ALL
SELECT 0, "**ALL**"
FROM ReallyBigTable
WHERE pk_field = 1
ORDER BY disp_name;
UNION ALL will return all combined rows. If you have any duplicate rows, you can thin them out by using just UNION instead of UNION ALL.