Grand total for an SSRS calculated field - reporting-services

i have a column in the report in which it stores calculated values depending on a set of iif statements, and calculate subtotals:
=sum(iif(Fields!EDLCode.Value = "X", Fields!Amount.Value, 0)/3 + iif(Fields!EDLCode.Value = XXX, Fields!SubjectAmt.Value, 0) - iif(InStr(Fields!Description1.Value, "YYY"),Fields!SubjectAmt.Value,0))
Question is how to show a grand total for that column in the report? Now it looks like that:

Figured it out. I had to set CDec(0) instead of just 0.
=sum(
iif(Fields!EDLCode.Value = "X", Fields!Amount.Value, CDec(0))/3 +
iif(Fields!EDLCode.Value = XXX, Fields!SubjectAmt.Value, CDec(0)) -
iif(InStr(Fields!Description1.Value, "YYY"),Fields!SubjectAmt.Value,CDec(0)))
This is working now.

There are a couple of problems with your expression
No quotes around XXX
InStr returns a value but you do not do anything with it
I have assume for the InStr function you are checking if "YYY" appears in the string, if not then modify the comparison to suit your needs..
Try this
=SUM(
IIF(Fields!EDLCode.Value = "X", Fields!Amount.Value, 0)/3 +
IIF(Fields!EDLCode.Value = "XXX", Fields!SubjectAmt.Value, 0) -
IIF(InStr(Fields!Description1.Value, "YYY") >0, Fields!SubjectAmt.Value, 0)
)

Related

SSRS - Expression to count the rows for currentdate match or (parameter selected date) with some equivalent other columns

In SSRS Expression, how to count the numbers of rows that present in today or yesterday in dataset with other equivalent condition,
For example
=COUNT(IIF(
DateDiff(DateInterval.Day,Cdate("01/01/1900"),Fields!Opendate.Value) =
DateDiff(DateInterval.Day,Cdate("01/01/1900"), Now()), Fields!Opendate.Value, Nothing))
Using this expression I can check get the total count for today, it's working.
I need to add to check today date with other condition like:
If (today date and Fields!reason.Value = "Other")
It's not working when I add reason value to check :
=COUNT(IIF(
DateDiff(DateInterval.Day, Cdate("01/01/1900"), Fields!Opendate.Value) =
DateDiff(DateInterval.Day, Cdate("01/01/1900"), Now()) -1, Fields!Opendate.Value, Nothing ) **And Fields!reason.Value = "Other"**)
Please guide me
Just add it in your IIF() statement:
=COUNT(IIF(
DateDiff(DateInterval.Day, Cdate("01/01/1900"), Fields!Opendate.Value) =
DateDiff(DateInterval.Day, Cdate("01/01/1900")
And Fields!reason.Value = "Other",
Now()) -1,
Fields!Opendate.Value,
Nothing
)
)

create a set expression for a cell in a table report

I have a report which creates a spreadsheet. one cell could have data from one of three fields depending on a fourth field status or field two being blank..
I was thinking of writing as CASE statement but that does not work in ssrs.
The IIF statement works great for 2 values but how do you write for three values?
In common language it would be "If secondary value ="Yes", use secondary name, If account field value is Null, use Contact field value, otherwise use account field value"
Thanks
You can use nested IIF statements but they quickly get messy. You should use SWITCH which acts a bit like a case statement.
A simple example would be
= SWITCH(
Fields!myFirstField.Value = <10 , "Small",
Fields!myFirstField.Value = <30 , "Medium",
Fields!myFirstField.Value = <80 , "Large",
True , "HUGE",
)
As switch stops at the first true expression there is not need to check ranges of values if you get them in the correct order.
The final "True" expression just acts like an ELSE
If you need to check multiple criteria per condition then you can do that too like this..
= SWITCH(
Fields!myFirstField.Value = <10 AND Fields!mySecondField.Value = 1 , "Small Cat",
Fields!myFirstField.Value = <10 AND Fields!mySecondField.Value = 2 , "Small Dog",
Fields!myFirstField.Value = <30 , "Medium Animal",
Fields!myFirstField.Value = <80 , "Large Animal",
True , "HUGE Animal",
)

SSRS 2012. Replicate grouping results in report in Query Designer

New to SSRS 2012 & struggling.
I have a report - containing a subreport - on client data. When testing with one client (just to make sure everything was OK) it works perfectly.
When the filter's removed, it's timing out (it's actually saying it's been cancelled by the user, which it hasn't).
Obviously the inclusion of the subreport is the problem (as the main report runs fine without it).
My subreport can validly return multiple records per client. The subreport is grouped on ClientId. I then have a calculated field - say HasIP - that concatenates two fields (IC and PC ) to produce either YesYes or YesNo. The tablix is sorted by HasIP by Z to A.
The info in the ClientID footer are what I'm displaying.
ClientID HasIP
22 YesNo - has two records, but since it has a YesYes, I don't want this one
22 YesYes - has two records, but I want the this one
52 YesYes - may only have 1 record, I want this record
76 YesNo - may only have 1 record, I want this record
Theoretically a client can't have more than one instance of HasIP=YesYes & shouldn't have more than 2 records. How can I recreate this effect in Query Designer? Essentially if HasIP=yesyes, use that record, otherwise use the other record
If I can do this, I can then drop the subreport completely, add this dataset to my main report & use Lookup to get the data.
However, the way our report scenario is set up, I'm not permitted to change the query [I have to click Query Designer button in Dataset Properties] & I have no experience in MDX.
SOLVED!!!:
OK - here's what I've come up with.
Assign numeric order to IC and PC values
I concatenated the IC & PC field values together and assigned values and added the ID of the records in the original subreport. I called this field HasIP
=Switch(Fields!IC.Value+Fields!PC.Value="YesYes", 1,
Fields!IC.Value+Fields!PC.Value="YesNo", 2,
Fields!IC.Value+Fields!PC.Value="NoNo", 3) & "-" & Fields!R_Name.Value
This left me with 2-xxxx, 1-yyyy etc.
I then added a filter to my second dataset:
=Left(Fields!HasIP.Value, 1)
to exclude values of "NoNo"
Concatenate HasIP and other fields in Dataset2 (to be used by LookupSet)
In addition also had to convert the text values into code for output (eg Yes = 1, No = 2, Unknown = 3 etc). I did this by creating a calculated field in Dataset2 (in the report, not the query) which included the HasIP. I delimited HasIP from the value by using a dollar sign.
=Fields!HasIP.Value & "$" &
SWITCH(
left(Fields!CoR.Value, 1)="C", 1,
Left(Fields!CoR.Value, 1)="N", 2,
True, ""
)
This left me with 2-xxxx$2, 1-yyyy$1 etc.
Sort the LookupSet results
LookupSet creates an array (and yes, now you know too). I needed to sort this so that the one I'm after is the first value returned. This is achieved by copying and pasting the following into the custom code section of your report. (I've added the code to allow you to sort in reverse if you need it).
Function JoinSorted(m_Array As Object()) As String()
System.Array.Sort(m_Array)
' Array.Reverse(m_Array) 'uncomment this line if you want to sort in reverse
Dim k As Integer = 0
For i As Integer = 0 To m_Array.Length - 1
If i > 0 AndAlso m_Array(i).Equals(m_Array(i - 1)) Then
Continue For
End If
m_Array(k) = m_Array(i)
k += 1
Next
Dim fred As [String]() = New [String](k - 1) {}
System.Array.Copy(m_Array, 0, fred, 0, k)
Return fred
End Function
You call this by using the following in your report expression:
Join(
Code.JoinSorted(
LookupSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!YourField.Value,"Dataset2")
),""
)
So, regardless of how LookupSet wanted to return the array, I always got 1-yyyy$1 first.
Handling LookupSet output on the report - include default for no records
For some LookupSet results in the report, I needed return a default value if there were no records returned. Otherwise I needed to return the assigned value (1, 2, 3 etc). If found two ways to do this.
This checks to see if the array count [yes, by using length] is greater than zero. If so, then using a mid function on the array result to return the 14th character:
=SWITCH(
LookupSet(
Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2"
)
.Length=0,
2,
LookupSet(
Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2")
.Length>0,
1)
OR
This is the same:
=iif(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Main_ID.Value,"Dataset2"
).Length>0,
Mid(
Split(
Join(
Code.JoinSorted(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Main_ID.Value,"Dataset2")
)
,";")
,";").GetValue(0)
, 'start point of mid
InStr(
Join(
Code.JoinSorted(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Main_ID.Value,"Dataset2"
)
)
,";")
,"$")
+1,
1),
"2"
)
Handling LookupSet output on the report - using of MID when length of value varies
In some cases the value I needed to return varied in length, eg 2 or 10. I also needed to return nothing if the LookupSet didn't return any results. I couldn't use "normal" versions of MID like this:
Mid(
Join(Code.JoinSorted(
LookupSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12d.Value,"Dataset2")),
";"),
InStr(
Join(
Code.JoinSorted(
LookupSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12d.Value,"Dataset2")
),
";"),
"$")+1,
(
InStr(
Join(
Code.JoinSorted(
LookupSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12d.Value,"Dataset2")
),
";"),
";")
-
InStr(
Join(
Code.JoinSorted(
LookupSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12d.Value,"Dataset2")
),
";"),
"$")
- 1)
)
as it threw #ERROR due to the use of -1 (at the end) making the string a negative length for some records.
So, here is what I could use:
=
Mid(
Split(
Join(
Code.JoinSorted(
LookupSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12b.Value,"Dataset2")
),
";"),
";").GetValue(0)
,
InStr(
Join(
Code.JoinSorted(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12b.Value,"Dataset2")
),
";"),
"$")
+1,
1)
By doing this, I could get the results I was after in the details & the footer.
I hope this can help someone else.

Append number to front of string with leading 0

How do I correctly replace the first character with 'M'? Suppose you have a PATIENT_ID_NONNUM = 'M001', and we want 1001 as a result.
UPDATE [HIMC_I2B2_LZ-PROD].[dbo].[I2B2_SRC_BIOMETRICS]
SET PATIENT_ID = CONVERT(NUMERIC(22,0),'1' + CONVERT(NVARCHAR(50),PATIENT_ID))
WHERE SUBSTRING(PATIENT_ID_NONNUM, 1, 1) = 'M'
EDIT:
UPDATE [HIMC_I2B2_LZ-PROD].[dbo].[I2B2_SRC_MEDICATION]
SET PATIENT_ID = CONVERT(NUMERIC(22,0),CONVERT(NVARCHAR(50),'1') + CONVERT(NVARCHAR(50),SUBSTRING(PATIENT_ID_NONNUM, 2, LEN(PATIENT_ID_NONNUM))))
WHERE SUBSTRING(PATIENT_ID_NONNUM, 1, 1) = 'M'
I find STUFF() (an often overlooked function) and LEFT() are a little more readable, but others may disagree:
UPDATE [HIMC_I2B2_LZ-PROD].[dbo].[I2B2_SRC_BIOMETRICS]
SET PATIENT_ID = CAST(STUFF(PATIENT_ID_NONNUM, 1, 1, '1') AS NUMERIC(22,0))
WHERE LEFT(PATIENT_ID_NONNUM, 1) = 'M'
I would suggest something like this:
UPDATE [HIMC_I2B2_LZ-PROD].[dbo].[I2B2_SRC_BIOMETRICS]
SET PATIENT_ID = CAST(('1' + SUBSTRING(PATIENT_ID_NONNUM, 2, LEN(PATIENT_ID_NONNUM) - 1)) AS NUMERIC(22,0))
WHERE SUBSTRING(PATIENT_ID_NONNUM, 1, 1) = 'M'
That's going to find all records where the first character is M, and replace the first character with a 1. I haven't tested this, but I believe it should work properly.
I would also suggest not running this type of operation on a production database as a test, which I would assume is what the -PROD stands for in your catalog name.
EDIT: Since it seems important that this query comes out with the PATIENT_ID as a NUMERIC(22,0), I've added the necessary CAST.

Using SSRS expression as a variable

I am trying to use a expression within an expression in SSRS and it's getting really complicated. Is there a way around this?
For example if I have a number of sales and number of contacts I can create the conversion rate by dividing the sales into the contacts ie
=fields!sales.value/fields!contacts.value
What I want to do next is use this to put the sales people into various bands so that those with a conversion rate in thresholds are displayed in bandings.
=iif(fields!sales.value/fields!contacts.value<0.5,"poor","Ok")
This is fine for 2 bandings (ok and poor), but gets more complicated for the 5 bandings I want.
I must be able to define the first variable and then use that within the iif statement?
How do I do this in SSRS 2008?
Thanks in advance.
Better to use Switch which returns the first true condition
=Switch(
fields!sales.value/fields!contacts.value < value1, "very poor",
fields!sales.value/fields!contacts.value < value2, "poor",
...
fields!sales.value/fields!contacts.value < value(n-2), "good",
fields!sales.value/fields!contacts.value < value(n-1), "very good",
True, "excellent"
)
where value1 < value2 < ... < valuen.
The final True is dummy like the use of default in an SQL Case expression
An alternative is using custom vb code you can create a function
Public Function GetRating( ByVal rating As Decimal ) As String
Select Case rating
Case Is < value1
Return "poor"
...
Case Is < valuen
return "very good"
Case Else
Return "excellent"
End Function
Then in the rows use the expression
= Code.GetRating( fields!sales.value/fields!contacts.value )