SSRS Expression in field using IN - reporting-services

I am trying to filter the data returned in a field using multi-value parameters. I need to filter based on 3 conditions:
--Before a Warranty End Date
--AND Service Type on the record must match one of the MULTI-VALUE parameters selected by the user
--AND Order Type on the record must match one of the MULTI-VALUE parameters selected by the user
Currently, this works for the first selection I described above (to sum only those records with a service date <= warranty end date , however, I cannot get the syntax to also check the 2 other fields based on the parameters selected...
Sum(iif(Fields!FirstServiceDate.Value <= Fields!WarrantyEndDate.Value, CDbl(Fields!ExtendedCost.Value), CDbl(0)))
Attached is my layout. Eventually I would like initially display everything to the left of % remaining and allow the user to drill down to see the invoice details
warranty

I don't know what is your reason to use parameter to filter the dataset instead of filter your query directly. However this could be what you are looking for.
Try this:
=Sum(iif(
Fields!FirstServiceDate.Value <= Fields!WarrantyEndDate.Value
AND
Join(Parameters!MultiValSTParam.Value,",").Contains(Fields!ServiceType.Value)
AND
Join(Parameters!MultiValOTParam.Value,",").Contains(Fields!OrderType.Value)
,CDbl(Fields!ExtendedCost.Value)
,CDbl(0)
))
EDIT: Edition based on OP comments.
You should use the parameter to filter the query that is generating your dataset at T-SQL level.
Create #WarrantyEDParam (date type), #ServiceType and #OderType parameters, then use them in your query something similar to this.
select
me.equipment_id,
me.WarrantyEndDate,
me.WarrantyReserveAmnt,
so.invoice_id,
so.service_type,
so.order_type,
so.cost,
so.price
from
master_equipment me
left join sales_order so on me.equipment_id = so.equipment_id
where me.WarrantyEndDate <= #WarrantyEDParam
or so.equipment_id is null --This line was added
and so.service_type in (#ServiceTypeParam)
and so.order_type in (#OrderTypeParam)
Now you will get data filtered directly from the query, so to get the sum of ExtendedCost use:
=Sum(CDbl(Fields!ExtendedCost.Value))

Related

Group projects by Fiscal Year Date expression based on one field value, if field value is null then group projects based on another field value

I am running a report where the projects are grouped by FY based on Fields!EstSubstantial_Completion.Value. Expression below:
=IIf(Month(Fields!EstSubstantial_Completion.Value)=10,
year(Fields!EstSubstantial_Completion.Value)+1,
IIf(Month(Fields!EstSubstantial_Completion.Value)=11,
year(Fields!EstSubstantial_Completion.Value)+1,
IIf(Month(Fields!EstSubstantial_Completion.Value)=12,
year(Fields!EstSubstantial_Completion.Value)+1,
year(Fields!EstSubstantial_Completion.Value))))
The expression is working, but my supervisor would like the projects to first be grouped into a FY based on another date field Fields!Savings_Report_Date.Value first and then if the field is blank (null) reference the Fields!EstSubtantial_Completion.Value field as the date to determine FY grouping.
I am new to SSRS reports so I am unsure if there is a way to write this type of expression.
Thanks!
The easiest way to do this would be to add a calculated field to your dataset.
Go to the dataset properties, then the "Fields" tab, then add a new field, select calculated when prompted.
Give the field a name such as FYCalc and set the expression to
=IIF(Fields!Savings_Report_Date.Value = Nothing, Fields!EstSubtantial_Completion.Value, Fields!Savings_Report_Date.Value)
Now all you need to do is swap out Fields!EstSubtantial_Completion.Value in your current expression and use Fields!FYCalc.Value instead.
Optional :
When you have nested IIF statements, it's often easier to use the SWITCH function instead. It's much easier to read.
=SWITCH(
Month(Fields!FYCalc.Value)=10, year(Fields!FYCalc.Value)+1,
Month(Fields!FYCalc.Value)=11, year(Fields!FYCalc.Value)+1,
Month(Fields!FYCalc.Value)=12, year(Fields!FYCalc.Value)+1,
True, year(Fields!FYCalc.Value)
)
The final True acts like an Else
You could simplify this further like this
=IIF(
Month(Fields!FYCalc.Value) >= 10 and Month(Fields!FYCalc.Value) <= 12, year(Fields!FYCalc.Value)+1,
, year(Fields!FYCalc.Value)
)

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!

query to filter on specific data or no filter if blank

I have a query which filters records based on dates (start date and end date)selected in a previous form. I want the query to filter the specific date range, or output all records if the fields are left blank.
I am unfamiliar with SQL. is there a way to add an if-then statement?
I can use vba if necessary, but would like to use the Access GUI if it is possible.
If you have a parameter, used in WHERE clause (Criteria in query builder) and you want to show all records if parameter is empty, just add this parameter as new column and OR condition where indicate Is Null or, better add a column with expression Nz([MyParam],"") and in Condition area inORrow add""`. Unfortunately in query builder this construction may be quite complicated if you have few parameters, in SQL it looks much simpler, for instance in your case it will be something like this:
WHERE (MyDate >= [paramDateStart] and MyDate <= [paramDateEnd])
OR (Nz([paramDateStart],"")="" AND Nz([paramDateEnd],"") = "")
Sometimes simpler edit SQL and then switch to Design view
You can use these criteria for StartDate and EndDate respectively to compare them to themselves in case one (or both) of the search fields on the form is empty (Null):
>=Nz([Forms]![YourForm]![FromDate], [StartDate])
<=Nz([Forms]![YourForm]![ToDate], [EndDate])

ORA 01797- operator must be followed by any or all

I am testing a condition like this in the where clause of a subquery. But I am getting the error "operator must be followed by any or all" when I execute the SSRS report.
dbase is oracle. And i need to use IN with parameter because the parameter in SSRS report is multivalued. I am using a separate function to generate dates that go in :P_Date.
I need to check if this date is = or < or null . All three conditions need to be tested.
where
trunc(tt.fyh_fecha) IN (:P_Date) OR
trunc(tt.fyh_fecha) <(:P_Date) OR
trunc(tt.fyh_fecha) IS NULL AND
tc.cod_tree = 'blue' AND
tt.color_flower = 'pink'
This doesnt seem directly possible - you are trying to use a parameter containing an array of values against the < operator which only expects one value. Your design doesnt make any logical sense to me either (<= multiple dates?), but anyway ...
I would add a join to a Calendar / Date Dimension table, where I would apply the IN (:P_Date) criteria to get a list of Date values as a deliberate cross join.
Then I would replace:
trunc(tt.fyh_fecha) IN (:P_Date) OR
trunc(tt.fyh_fecha) <(:P_Date) OR
with:
trunc(tt.fyh_fecha) <= Dim_Date.Date_Value

Date field filter is not working in Row Group level filter

I have added a Filter in Row Group-> Group Properties to perform sum of quantity only for those transactions which have done before a certain date.
Whenever I am selecting the 'Cdate' as Expression field from my dataset1, the type is showing as Date/Time but after saving it when I check,I found it as 'Text'. As a result the filter for 'cDate' is not working during report generation.
Note that, I can't filter the data in dataset side or tablix side as I have to show all the column items. This is a matrix report.
OK this is going to be a bit confusing because your dataset contains a field with the same name as one of the built-in expression functions ("CDate" - Convert to Date).
I sometimes run into these datatype issues when using filters and I find the best way to handle it is to force both the filter field and the filter value to be the same data type.
So in your case try setting the Filter expression to:
=CDate(Fields!CDate.Value)
then select the operator as "<=" and set the value using an expression as well:
=CDate(Parameters!MyParameter.value)
and see if that works.
I understand you so that your date field in the dataset is called CDate, try casting it as date, so instead of selecting it in your filter, type the following into the filter
=CDate(Fields!CDate.Value)