Determine if Any Row Meets Certain Condition in Dataset - reporting-services

I'm creating a report in visual studio, and I have a dataset which returns rows from a stored procedure. Each row has a column with a date in it. I also have another date passed in as a parameter to the report. I would like to go through the rows, and check if any of them have a date that is less than the date parameter. Is there a way to create a boolean variable for the report which gets set based on this logic?
This is what I currently have, but I get an error saying "references outside of a data region must be contained within aggregate functions which specify a dataset scope"
=IIF((Fields!ColumnDate.Value, "Dataset") < Parameters!ParameterDate.Value, "value 1", "value 2)

I was able to find a workaround by using Min to only compare the lowest date with the parameter:
=IIF(Min(Fields!ColumnDate.Value, "Dataset") < Parameters!EndDate.Value, "value 1", "value 2")

Related

Can you set a parameter that references an expression field that is calculated based on another parameter selection?

I am attempting to create a parameter which looks at the values of a field in the report which is calculated based on the entry of another parameter.
Specifically, the first parameter is a number option (30,60 or 90) and the field expression is a DATEADD that adds the parameter value to the value of a date field.
The next parameter I need is to pick dates in the "expression field" that fall into a certain range. i.e. user chooses 30 so the report generates and populates the "Hire Date" + 30.
I want to then only select the records where that new date falls into a specified range i.e. Effective Date 2/1/2020-2/29/2020. I have been looking everywhere, but cannot find an answer and I don't know if it is possible.
Results example
[EffDate Field[\]\[1\]][1]
I think this was what SuperSimmer 44 was referring to that I couldn't understand before.
I added the following parameters:
Wait - which is an integer & has set available values of 30, 60 & 90
From - Date
To - Date
I kept the field "Effective Date" in my report which was the expression =DateAdd("d",Parameters!wait.Value,Fields!HireDate.Value)
I then added a filter to the Dataset that said if the value of the expression =DateAdd("d",Parameters!wait.Value,Fields!HireDate.Value) was between #from & #to then they should include the record in the results. It worked perfectly.
Report Sample
Insert 2 parameters, one called qty to hold available values from a list 30/60/90 or 120 etc
the other called date to hold your from effective date.
Set up a calculated field in your dataset called effectivedate that utilised DateAdd, for example ie: =DateAdd("d",Parameters!qty.Value,Parameters!effectivedate.Value)
Then set a filter on your dataset that utilizes this calculated field.

SSRS lookup missing dataset

I have a dataset which looks like this
Name Spend
"First Aid" 2
"Healing Arts" 0
"Surgeon" NULL
I then have three separate textboxes which will be filled with the value of the column which matches the name.
Example: show value of spend in textbox if value of name equals First Aid
for this I've made following expression
=Lookup(Fields!skill_name.Value, "First Aid", Fields!skill_spend.Value, "Skills")
My problem is however that I get an error saying that skill_name is missing its dataset, which doesn't make sense to me as it is informed in the end of the expression (skills)
I think you may be misunderstanding the purpose of Lookup and how it is used. The purpose of the Lookup function is akin to a JOIN in SQL in some ways. Basically, you would have two datasets that each have a matching field with the other. In that scenario, the expression would match on the skill_name field and lookup the skill_spend value and the expression would look something like the following.
=Lookup(Fields!skill_name.Value, Fields!skill_name.Value, Fields!skill_spend.Value, "Skills")
As the documentation shows, the first reference to skill_name is the field you are referencing from the current dataset. The second reference is to the dataset from which you are attempting to look up a value. The third expression is the field you are looking up and the dataset should be the one you are attempting to look up a value from, not the current dataset scope.
Lookup(source_expression, destination_expression, result_expression, dataset)
From the best I can tell, you have a single dataset but separate textboxes that need the correct spend value. I think the following expression will work.
= IIF(Fields!skill_name.Value = "First Aid", Fields!skill_spend.Value, Nothing)
This expression should get the skill_spend value associated with the row "First Aid" only and leave the textbox blank otherwise.

Dynamically change column names as week number on every weekly run

I want to build a SSRS report that has column as week numbers - 8 weeks for 8 columns starting with current. This report is run every week and current week number is set then. So both column names and their values should change .Is it possible to build something like this in SSRS?
I tried doing this with a dynamic SQL based stored proc in dataset. However for every run I don't even see the columns values updating dynamically
Here's an example :
Also I am trying to avoid these week numbers as row values and then using matrices
My stored proc looks something like this
declare #n tinyint = datepart(wk, getdate())
declare #n1 tinyint = (#n+1), #n2 tinyint =(#n+2), #n3 tinyint =(#n+3), #n4 tinyint =(#n+4), #n5 tinyint =(#n+5), #n6 tinyint =(#n+6)
exec ('Select b.sku, b.['+#n+'], b.['+#n1+'], b.['+#n2+'], b.['+#n3+'], b.['+#n4+'], b.['+#n5+']...
Will appreciate any help in this direction.. many thanks!
When working with SSRS it's generally best to avoid dynamic SQL and pivoting the data in the SQL. Use the SQL to get the raw data you need and then let SSRS do the pivoting and aggregation. This way you take advantage of what they each do best. I know you said you want to avoid matrices, but it is the best way to make the report dynamic.
So you should either return all the data in one dataset and use filters on your matrices OR write two queries and have each one populate a matrix. BTW a matrix is just a table with a column group added, so don't be intimidated by them.
There are 2 ways to do this with a standard tablix.
Calculate the column headers as expressions using concatenation of Wk and some date math to find the correct week number and return the same sort of thing from your query (e.g. columns are current_week, week_minus_1, week_minus_2...)
Return the column headers as additional columns in your query that are the same value for every row (e.g. ColHeader0, ColHeader1...). Your data columns would still be relative weeks (e.g. ValueWeek0, ValueWeek1...). In your report the column header would have an expression like =First(Fields!ColHeader0.Value). This is a more flexible approach since it lets you pick 8 historical weeks instead of only the last 8 weeks if you add a parameter.
EDIT - Clarifications
The reason that you get the blank column Wk48 is approximately that you have created your report looking for that column that won't be there the next time. SSRS looks for exact columns. You should you use relative column names for either of the options I have specified:
exec ('Select b.sku, b.['+#n+'] as Wk0, b.['+#n1+'] as Wk1, b.['+#n2+'] as Wk2, b.['+#n3+'] as Wk3, b.['+#n4+'] as Wk4, b.['+#n5+'] as Wk5...
This will allow you to populate the aliased Wk0 column with the appropriate current week data and still make sure that it can be consistently referenced as the base week by SSRS.
To change the column headers you can:
Independently calculate the week numbers in SSRS in the column header expressions: ="Wk" + CStr(<correct week calculation>).
Return the column headers in the result set and access them in the column header expression:
exec ('Select b.sku, b.['+#n+'] as Wk0, b.['+#n1+'] as Wk1, b.['+#n2+'] as Wk2, b.['+#n3+'] as Wk3, b.['+#n4+'] as Wk4, b.['+#n5+'] as Wk5..., ''Wk'''+#n+' as ColHeader0, ''Wk'''+#n1+' as ColHeader1...
and reference the returned column headers from the SSRS column header expression as =First(Fields!ColHeader0.Value).
Here's a solution that worked for me:
Create parameters (say CurrWk, CurrWk1) ,set as hidden and store 'Default value' and 'Available value' equals to current week number (datepart(wk, now()) and any subsequent week by doing a +1, +2, +3.. etc.
Write a query expression . Click onto fx beside dataset query space and write the select query for your program embedding parameter values in the expression window. For eg ="Select SKU, [" & Parameter!CurrWk.Value & "] as Wk1,
[" & Parameter!CurrWk.Value & "] as Wk1 from Sales_Table"
Before passing this query as a 'command text expression' please ensure this query is working in sql ssms.
Save the expression. Now find 'Fields' tab on the left hand side panel.You need to map the fields manually from the query here. If this is not done, there is a very high chance you seean empty field list and wont be able to access them at all. This may be because ssrs do not store query metadata directly from expressions.
You can avoid part of the issue by having atleast the static fields , for example here SKU listed in the 'Fields' list by first running a sql query with static field(select SKU from Sales_Table ). You can then go back to update dataset- change query to expression and embed the parameterized field names.
Map field names. In this example I chose 'Query Type' fields and set Field names as SKU, CurrentWeek, NextWeek and mapped to source SKU, Wk and Wk1 respectively.
Click on 'Refresh Fields' at the bottom. Now you have a dataset with the complete field list. Use these in charts, tables . Run it every week and note the numbers changing as expected.
In case you are using this dataset in a table, make sure you set headers with Labels of Parameters (for eg here I did =Parameters!CurrWk.Label for col with current week data)
That's it!

Like with IIF and date range not returning results

I am trying to write an Access query (Access 2013) that uses an IIF statement to first check the value of an Option Frame and then, if the value is "1", use a date range or, if the value is anything else, find all records (only values "1" and "2" are available). My query criteria is...
Like IIf([Forms]![MaintenanceDueList]![OptionFrame]=1,>[Forms]![MaintenanceDueList]![FromDateText] And <[Forms]![MaintenanceDueList]![ToDateText],"*")
When my Option Frame Value is set to "2" I get all records returned as expected, but when my Option Frame value is set to "1" I get no results at all, despite there being plenty of records available with dates between the two dates provided in the FromDateText and ToDateText TextBox fields.
This one really has ne stumped, so any help would be gratefully received. Thanks, Mort640.
IIF returns a value but you seem to be trying to return some SQL logic - the true/false parts are evaluated then returned.
You can instead:
WHERE
[Forms]![MaintenanceDueList]![OptionFrame] = 2
OR
XXX > [Forms]![MaintenanceDueList]![FromDateText] And XXX < [Forms]![MaintenanceDueList]![ToDateText]
or to be inclusive of XXX as opposed to greater-than
WHERE
[Forms]![MaintenanceDueList]![OptionFrame] = 2
OR
XXX BETWEEN [Forms]![MaintenanceDueList]![FromDateText] And [Forms]![MaintenanceDueList]![ToDateText]

Show all records/some records based on parameter value

I have stored procedure which returns around 100 rows. One column is Category.
In SSRS, I've created DataSet related to that stored procedure. On Report body I have Tablix, which I relate to DataSet.
Now, I have additional parameter, called FilterColumn, which consist all different categories from dataset, plus one row called "All products".
How to filter tablix based on that parameter to show me whether products from specific categories or all products?
You need to set up a filter similar to the following:
Where the expression is:
=IIf(Parameters!FilterColumn.Value = Fields!Category.Value
or Parameters!FilterColumn.Value = "All products"
, "Include"
, "Exclude")
This matches the row Category based on the parameter value, or, if the value = All products, will include all rows.
As mentioned in the comments and the other answer, this is possible in the SP too, but since it seems to be specifically to demonstrate the functionality this should do the trick at the report level.
I have created some solution and worked for me:
In Expression field, I put first expression:
1. Iif(Parameters!FilterColumn.Value = "All", 1, Fields!Category.Value)
In Value field, I put second expression:
2. Iif(Parameters!FilterColumn.Value = "All", 1, Parameters!FilterColumn.Value)
So, when I choose "All" value in parameter, then first expression will result 1, and second expression will result 1, and i have 1 = 1 which is true for all rows, and I got all rows in table.
When I choose specific category from parameter, then in first expression result will be Fields!Category.Value and in second expression will be Parameters!FilterColumn.Value. Simple, I got Fields!Category.Value = Parameters!FilterColumn.Value, or just give me rows where category is that choosen in parameter.
Pass the Additional Parameter to your store procedure, so you send data that is already sorted to your report. This will avoid multiple Tablix created depending on your parameter selection.