SSRS 2008r2
I'm trying to perform an aggregate (Sum) on a field within a GROUPing that contains an expression.
The field where I want to SUM to appear is within a different GROUPing.
I've created the following Function within Report Properties
Dim public tot_OT_Hrs As Decimal
Public Function Add_OT_Hrs(ByVal OT_Hrs As Decimal) AS Decimal
tot_OT_Hrs = tot_OT_Hrs + OT_Hrs
return OT_Hrs
End Function
Public Function GetTotal()
return tot_OT_Hrs
End Function
I've added a call to the "Add_OT_Hrs" function in the field where the expression is and this works fine.
=Code.Add_OT_Hrs(
IIF(Sum(Fields!HrsWorked.Value) > Parameters!StdWorkingHrs.Value,
Sum(Fields!HrsWorked.Value) - Parameters!StdWorkingHrs.Value + Sum(Fields!Rate1Hrs.Value)
, Sum(Fields!Rate1Hrs.Value )
)
)
Fields!Rate1Hrs.Value is the field in which the expression resides in and Fields!HrsWorked.Value is an adjacent field
However, the field where I want to total to appear I've added the following
=Code.GetTotal()
All that is returned here is 0 (zero) on every row in the GROUPing. If I initialise the Dim public tot_OT_Hrs As Decimal variable to say 1.2 then 1.2 is returned on every row in the GROUPing. The Add_OT_Hrs function isn't working as expected.
Where am I going wrong?
Thanks in advance.
Looks to me that you are converting in the wrong order and also to the wrong data type. In the code example that you used you were converting the sum to a double which is not the correct data type. There is a notable difference between a double and decimal when using custom functions.
I tested this with a very small dataset as follows
select '1.2'
union all
select '1.8'
Then applied the following custom code
Dim public total as decimal
Public Function AddTotalr(ByVal r AS decimal) AS decimal
total = total + r
return r
End Function
Public Function GetTotalr()
return total
End Function
The order of your explicit conversion is vital. You have to convert the value before you sum the total so that you are working with consistent data types.
=code.addtotalr(sum(cdec(Fields!ID.Value)))
Even with the correct data type the this will produce an error because you are attempting to sum what is, most likely, being interpreted as a character string.
=code.addtotalr(cdec(sum(Fields!ID.Value)))
-----------edit ------------------------
As a test to see what the return on the function is change your function to
Dim public total as decimal
Public Function AddTotalr(ByVal r AS decimal) AS decimal
total = total + r
return total
This should give you a running total of the items processed and the last value in the list should match what your total should be.
I decided to do this in the proc.
It works out quite well now.
Related
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 am using the DateDiff function, but I would like for it to give me 3 decimal places. How should my query be altered to achieve such result? -- I need this done via the query itself not a VBA function.
Date123: DateDiff('d', [startdate], [enddate])
For a line that you can just put into a query, I'd use something like the following.
Format(DateDiff("s",[DateOne],[DateTwo])/60/60/24,"#.###")
Better practice would be to create a function in a module in your db like the following. Then call it through the query. The code is more maintainable, testable and understandable.
Public Function DateDiffInFractions(DateOne As Date, DateTwo As Date) As String
Dim SecondsDiff As Double
SecondsDiff = DateDiff("S", DateOne, DateTwo) / 24 / 60 / 60 'Days/hours/minutes/seconds
DateDiffInFractions = Format(SecondsDiff, "0.000") 'Format to 3 Decimal points. Return string
End Function
I already calculated a row(Add Total row) like Gross profit within Group1(a,b,c,d,e) using Previous and current scope column group values. ex: Gross Profit = a - b.
Gross Profit = Previous(Sum(Fields!Trans_amount.Value)) - Sum(Fields!Trans_amount.Value) in Group1
Now, I want to get values for Net income like Net income = a - b - c in Group1. (OR)
Net income = Gross Profit - c in Group1 (Using Gross Profit textbox values using Reportitems!textbox.value). but, values different. Since Expression got new calculation)
Please help me.
Thanks Advance.
I think you want to get a "running value decreasing total" value in your report. For example, it returns "a-b" first, then "a-b-c", "a-b-c-d", "a-b-c-d-e". Is my understanding correct? In Reporting Services, it doesn't have any built-in function to achieve this goal. I make it by using custom code.
Public Shared Status as String
Public Shared Value as Integer
Public Shared Function GetValue(Item as Integer) as Integer
if Status is nothing then
value=item
status="1"
else
value= value - Item
end if
return Item
End Function
Public Shared Function GetTotal()
return value
End Function
Then call the function in Gross Profit cell:
=Code.GetValue(Sum(Fields!Trans_amount.Value))
To get the Net income, Call the function next to Gross Profit:
=Code.GetTotal()
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 :)