I've read through the answers and updated my expression and I continue to get #Error in the row that has a 0 for the budget.
All the percentages are being calculated correctly.
=IIF(SUM(Fields!CM_Budget.Value,"Name")=0,0,SUM(Fields!MTD_Actual.Value,"Name")/SUM(Fields!CM_Budget.Value,"Name"))
This is because SSRS always evaluates both expressions.
You have to break your expression in two parts.
=IIF(SUM(Fields!CM_Budget.Value,"Name")=0,0,SUM(Fields!MTD_Actual.Value,"Name"))
/
IIF(SUM(Fields!CM_Budget.Value,"Name")=0,1,SUM(Fields!CM_Budget.Value,"Name"))
An alternative could be using custom code like below
Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
Return Nothing
Else
Return Dividend/Divisor
End If
End Function
Then you can write your expression like:
=Code.Divider(SUM(Fields!MTD_Actual.Value,"Name"),SUM(Fields!CM_Budget.Value,"Name"))
I usually prefer the second way to do it, to make my expressions more readable
Related
I have a report that uses an expression to sort a group but when choosing one value from the parameter it returns an "The sort expression for the grouping 'grp' contains an error: Attempted to divide by zero."
The expression being used is below;
=Choose(Parameters!sort.Value,
Choose(Parameters!set.Value,Fields!IncomeOfficer.Value,Fields! ManagementArea.Value,Fields!RentGroup.Value,Fields!Tenure.Value),
-Sum(Fields!RentCollected.Value,"grp"),
Sum(Fields!RentDue.Value,"grp"),
-Sum(Fields!RentCollected.Value,"grp")/Sum(Fields!RentDue.Value,"grp"))
Any thoughts amendments appreciated.
Thanks
Add a function to your report code to handle divide by zero error:
Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
Return 0
Else
Return Dividend/Divisor
End If
End Function
Then in your expression call the function:
code.Divider( Sum(Fields!RentCollected.Value,"grp")/Sum(Fields!RentDue.Value,"grp") )
How about you simple check if your Sum(Fields!RentDue.Value,"grp") returns 0 or null, if it does you do not need to divide Sum(Fields!RentCollected.Value,"grp")/Sum(Fields!RentDue.Value,"grp")
else just divide.
I have updated expression below.
=Choose(Parameters!sort.Value,
Choose(Parameters!set.Value,Fields!IncomeOfficer.Value,Fields! ManagementArea.Value,Fields!RentGroup.Value,Fields!Tenure.Value),
-Sum(Fields!RentCollected.Value,"grp"),
Sum(Fields!RentDue.Value,"grp"),
-IIF(IsNothing(Sum(Fields!RentDue.Value,"grp")) or Sum(Fields!RentDue.Value,"grp")=0,Sum(Fields!RentCollected.Value,"grp"), Sum(Fields!RentCollected.Value,"grp")/Sum(Fields!RentDue.Value,"grp")))
We need to be able to calculate the median value of a set of figures for a statistical return - specifically the median Answered figures per contract for a date range.
The data is stored in a shared dataset for use in Report Builder, and this shared dataset is used a number of contractual reports so updating it is not an option. The shared dataset being used ensures consistency between contractual reports, so must be used.
There are answers to this already (e.g. Find the median of a calculated field in SSRS 2012 & Use of 'median' function in calculated field in SSRS) but these require either hidden rows/columns or using a calculated field in a graph.
We need an answer that allows us to use shared datasets/stored procedures and calculate the median value in SSRS/Report Builder.
This custom code can be added to the report:
Public Shared Function Median(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim counter As Integer = items.Length
If counter = 0 Then
Return 0
End If
System.Array.Sort(items)
If counter Mod 2 = 1 Then
Return items(CInt((counter / 2) - 0.5))
Else
Dim FirstIndex As Integer = counter \ 2
Dim SecondIndex As Integer = FirstIndex - 1
Dim FirstValue As Integer = items(FirstIndex)
Dim SecondValue As Integer = items(SecondIndex)
Return (FirstValue + SecondValue) / 2
End If
End Function
Which can then be called by using the following =Code.Median(Lookupset(Fields!Contract.Value, Fields!Contract.Value, Fields!Answered.Value, "DS_CallData_LKP"))
In this example the dataset "DS_CallData_LKP" is powering the entire report, but is being referenced back again to get list of values to be sorted for the median. Using a lookupset() instead of the hidden rows/columns method that is seen a lot helps keep the report simple for editing later down the line.
I have a field in SQL Server that contains an comma separated list. Here are 2 examples:
select 'ex1,ex2,ex3' as str union all
select 'ax1,ax2'
In my report, I have to transform all of these values (5 in this case) using a function. In this question I will use Trim, but in actuality we are using another custom made function with the same scope.
I know how I can split every value from the string and recombine them:
=Join(Split(Fields!str.Value,","),", ")
This works great. However, I need to execute a function before I recombine the values. I thought that this would work:
=Join( Trim(Split(Fields!VRN.Value,",")) ,", ")
However, this just gives me an error:
Value of type '1-dimensional array of String' cannot be converted to 'String'. (rsCompilerErrorInExpression)
I can't personally change the function that we use.
How do I use an extra function when dealing with both an split and a join?
You can use custom code to include all the logic (Split->Custom Code->Join).
Make adjustments inside the loop to call your custom function instead of trim
Public Function fixString (ByVal s As String) As String
Dim mystring() As String
mystring = s.Split(",")
For index As Integer = 0 To mystring.Length-1
mystring(index) = Trim(mystring(index))
Next
Return Join(mystring, ",")
End Function
To call the custom code use the following expression
Code.fixString( Fields!VRN.Value )
I have a query that compares a value. Both values are equal. Data types are double. However, the result is always false. Have you encountered the same scenario?
I tried to round off the data before comparing it and I got the correct results. What do you think is the cause of this issue?
This is a well known side effect of floating numbers.
You have several options. Test for a difference or convert to other data type:
Where Abs(Field1 - Field2) < 0.00001 (or whatever value you consider equal)
Where CCur(Field1) = CCur(Field2)
Where CDec(Field1) = CDecCur(Field2)
Confirm that the values are equal for both variables. Double is floating point with 15 decimal precision, I think. If your display is showing your double variables with rounding, they may appear equal but in fact they may not be equal.
I would recommend you to do Round(variable1, 4) and compare it with Round(variable2, 4). Try testing your variables with a test routine like this:
Public Sub SendDoubles()
Dim a As Double
Dim b As Double
a = 10.0000000001
b = 10.000000001
TestDoubles a, b
End Sub
Public Sub TestDoubles(a As Double, b As Double)
MsgBox CStr(a) & vbCrLf & CStr(b)
MsgBox a = b
MsgBox Round(a, 4) = Round(b, 4)
End Sub
Notice that CStr will convert your double to string so that you can visualize both variable's value. The 2nd MsgBox attempts to compare them as-is and the third one compares them with rounding.
I have a table created a report where there should be a field with sum of Avg.
Please find the below image
I am getting the average but i need to sum the average to display A.
Have you tried adding a custom function to the report, as outlined here?
This person wrote this custom function:
Dim Test as double
Public Function Testing(Byval value as Double, ByVal reset as Boolean) as Double
Test = Test + value
Testing = Test
If reset = TRUE Then
Test = 0
End If
End Function
At the footer of the group call Code.Testing([value], False) then call it again outside of the group with code.Testing([value],True) to reset. Worked for me :)