I'm using SSRS 2005 to produce a report, and one of the columns in my report is a simple mean calculation. I don't want to divide by zero, so for the textbox value I have put:
=Switch(Fields!Count.Value=0,0,Fields!Count.Value>0,Fields!Sum.Value/Fields!Count.Value)
This still evaluates the second expression.
And so does:
=IIF(Fields!Count.Value=0,0,Fields!Sum.Value/Fields!Count.Value)
I don't want my report to display errors. How can I overcome this issue?
Unfortunately because IIF is actually just a function, all arguments get evaluated before the function gets called (resulting in your divide by zero).
One way of embedding complex logic in an expression is to embed a function in the report. You can write a VB function to return whatever you like in the Code Tab of the Report Properties.
Public Function GetMeanValue(ByVal Sum as Decimal, ByVal Count As Int) As Decimal
'your logic in plain old vb syntax here
End Function
In the Textbox Text expression property:
=Code.GetMeanValue(Fields!Sum.Value, Fields!Count.Value)
When checking for zeros, I always negate the expression like this:
=IIF(Fields!Count.Value<>0,Fields!Sum.Value/Fields!Count.Value,0)
This has the added benefit of avoiding the division in case the Count field is empty/null.
Try this:
=IIf(Fields!Count.Value = 0, 0, Fields!Sum.Value / IIf(Fields!Count.Value = 0, 1, Fields!Count.Value))
Here is solution that has always worked for me:
Avoiding Divide By Zero Errors .
It gets tedious if the report has too many divisions. I prefer some vb code to do the division and handle division by zero. Not sure if too much of vb code would bring down the performance of the report.
Here is how to do it with vb
Replaced he link with archive.org link. Here is the relevant content from that link:
Instead of dropping that calculation into all the textboxes that are
doing division I go under Report >> Report Properties >> Code and
drop in the following code:
Public Shared Function Divide(Num1 as double, Num2 as double) AS
object
IF ISNOTHING(Num2) Or Num2 = 0 Then
Divide = "n/a"
ELSEIF Num1 = 0 THEN
Divide = 0
ELSE
Divide = Num1 / Num2
END IF
End Function
And then in each of the textboxes on the report where I need to do
division, I call the function like this:
=Code.Divide(1, 0)
Related
I'm working in SSRS and have succeeded in creating a 5 tier cascaded parameter set up. Now I'm trying to say that if ALL is selected on tier 2 then filter the dataset differently than of single select.
TO do that I need count of selected and count of all and am trying to write some vb code in ssrs to fix this.
Pasted in this from microsoft
Public Function ShowParameterValues(ByVal parameter as Parameter)
as String
Dim s as String
If parameter.IsMultiValue then
s = "Multivalue: "
For i as integer = 0 to parameter.Count-1
s = s + CStr(parameter.Value(i)) + " "
Next
Else
s = "Single value: " + CStr(parameter.Value)
End If
Return s
End Function
But get error message:
The Value expression for the textrun 'Textbox4.Paragraphs[0].TextRuns[0]' contains an error: [BC30451] 'ShowParameterValues' is not declared. It may be inaccessible due to its protection level.
So 2 questions - 1 how do I declare it and what do I pass in? Options Are
Report.Parameters!Company
Parameters!Company
Parameters!Company.Value
Any help greatly appreciated
Pete
Two things here...
To solve your error, make sure you call the function in the expression like this
=Code.<myFunctionName>(parameters)
So in your case it would probably be
=Code.ShowParameterValues(Parameters!Company)
(you might need to use Parameters!Company.Value, I can't remember)
However, you said you wanted to just know if a single value multiple values have been selected. You can do this without custom code.
=Parameters!Company.Length
Will return the number of selected parameter values.
You can read more about this and other parameter related expressions here
https://learn.microsoft.com/en-us/sql/reporting-services/report-design/built-in-collections-parameters-collection-references-report-builder?view=sql-server-ver16
I am working on SSRS report where user!userid variable coming with 3 pipe delimited values
E.g :
ReportUser |500|100
I split the values using below expression
=(Split(Parameters!QueryString.Value, "|")).GetValue(0)
=(Split(Parameters!QueryString.Value, "|")).GetValue(1)
=(Split(Parameters!QueryString.Value, "|")).GetValue(2)
When the parameter is coming with values above expression works fine. But, when any parameter coming as blank, I am getting below below error during report execution.
index was outside bounds of array for the parameter.
I tried below workarounds with iif expression
=iif((Split(Parameters!QueryString.Value, "|")).GetValue(0)=NOTHING,0,
(Split(Parameters!QueryString.Value, "|")).GetValue(0))
=iif((Split(Parameters!QueryString.Value, "|")).GetValue(0)="",0,
(Split(Parameters!QueryString.Value, "|")).GetValue(0))
Still I am getting the same error. Could someone help how to handle the blank values with this expression?
I had initially though that this would work
This code fails
=SWITCH
(
Split(Parameters!QueryString.Value, "|").Length <3, "",
True, Split(Parameters!QueryString.Value, "|").GetValue(1)
)
As Switch stops evaluating at the first True result but for some reason I still got an Error. I'm not sure why this happens but I got round it by writing a function to do the work.
This does work
I added this code to the Reports Code property (it can probably be made better but I've not done any VB.Net for years)
Public Function GetSplitValue(inputString as String, delim as string, index as Integer) as String
Dim arr() AS String = Split(inputString, delim)
Dim result AS string
TRY
result = arr(index)
CATCH
result = ""
END TRY
RETURN result
End Function
You can then call this in your expression using something like this in your text boxes or whatever you are populating.
=Code.GetSplitValue(Parameters!QueryString.Value,"|",0)
=Code.GetSplitValue(Parameters!QueryString.Value,"|",1)
=Code.GetSplitValue(Parameters!QueryString.Value,"|",2)
If you want something other than an empty string, just edit the code in the CATCH block.
I'm developing a system that shows the total amount paid of a student from the database. For some students that only have a few transactions the function below gives an error Conversion from string "" to type double... but if a student doesn't have any data entry or the values are zero-to-many the code below encounters it. What should I do? Do I need to adjust the code? Please help.
I have here an Function that gets the total items.
Function Totalpaid() As Double
Dim i As Integer
For i = 0 To ((tbl_receipt.Items.Count) - 1)
Totalpaid = (Totalpaid + tbl_receipt.Items(i).SubItems(3).Text)
Next
End Function
You're trying to add two numbers but one of the operands is not a number. You're assuming that the Text of the subitem will be converted a number and added to the running total. At least one of your subitems is blank though. Maybe you consider that to represent zero but it doesn't. It doesn't represent any number at all so the operation fails.
What you should be doing is validating and converting the subitem contents yourself and then providing the system with two Double values to add. If there is no value then you either ignore that subitem or use zero explicitly. Option Strict On will at least force you to perform the conversion but it's still up to you to provide the validation if there's any chance that the data will not be valid.
To me this looks like a problem with your data rather than the code directly. I would recommend sanitising your data before trying to use it in a calculation, i.e.:
Function Totalpaid() As Double
Dim i As Integer
Dim val as Double
For i = 0 To ((tbl_receipt.Items.Count) - 1)
If Double.TryParse(tbl_receipt.Items(i).SubItems(3).Text, val) Then
Totalpaid = (Totalpaid + val)
End If
Next
Return Totalpaid
End Function
The message Conversion from string "" to type double... is saying that your are trying to convert an empty string to a Double which cannot work.
As a side note, when testing your code I did have to include the line Return Totalpaid, I don't know if this was missed when you where writing out the question.
Hopefully I might have the easiest question to answer but so far I couldn't figure it out. I have a RDLC report with following expression.
=Iif(Sum(Fields!OriginalTotal.Value) = 0, 0, (Sum(Fields!WorkingTotal.Value) - Sum(Fields!OriginalTotal.Value))/Sum(Fields!OriginalTotal.Value))
Please note that this field on the report is formatted as percentage with two decimal places.
Problem is whenever the Sum(Fields!OriginalTotal.Value) = 0 condition is true, field prints as "#Error" on the report.
What am I doing wrong here?
Thanks in Advance!
There is a well known problem that ssrs calculates both expressions of "iif". That's why you get Error when trying to divide on 0.
Have a look at the following links:
http://www.reportingservicestips.co.uk/RSTip008.html
SSRS Expression Divide by Zero Error
Instead of Writing expression in SSRS. We can add a function to your report code that handles the divide by zero condition, this makes it a bit easier to implement in multiple cells(code re-usability),
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
We can call this code in a cell as follows,
=Code.Divider(Fields!Dividend.Value, Fields!Divisor.Value)
Thanks
Venky
I had a strange error in a VB6 app this morning and it all stems from the fact that IsNumeric is not working as I expected. Can someone shed some light on why? To me this seems like a bug.
This code displays 4.15877E+62 in a message box:
Dim strMessage As String
strMessage = "0415877D57"
If IsNumeric(strMessage) Then
MsgBox CDbl(strMessage)
Else
MsgBox "not numeric"
End If
I am guessing that the runtime engine is incorrectly thinking that the D is in fact an E?
I think this is a bug though as the exact same code in VB.NET outputs not numeric
Is this a known issue with IsNumeric?
If you check the VB6 docs:
Note Floating-point values can be expressed as mmmEeee or mmmDeee, in which mmm is the mantissa and eee is the exponent (a power of 10). The highest positive value of a Single data type is 3.402823E+38, or 3.4 times 10 to the 38th power; the highest positive value of a Double data type is 1.79769313486232D+308, or about 1.8 times 10 to the 308th power. Using D to separate the mantissa and exponent in a numeric literal causes the value to be treated as a Double data type. Likewise, using E in the same fashion treats the value as a Single data type.
I've been using my own IsNumber function for a long time exactly because of this situation. IsNumeric can also return true for certain money symbols, like this: IsNumeric("$34.20").
My IsNumber function looks like this:
Public Function IsNumber(ByVal Data As String) As Boolean
If Data = "" Then
IsNumber = False
Exit Function
End If
IsNumber = IsNumeric(Data & "e0")
End Function
The idea here is... if there is already an e or d in the data, adding another will cause the data to NOT be numeric using the IsNumeric check. You can easily change this function to only allow for integers by replacing "e0" with ".0e0". Want just positive integers? then use this: IsNumeric("-" & Data & ".0e0")
The only downside of this method is that an empty string normally is not numeric, but when you append "e0" to it, it becomes numeric so you need to add a check for that, like I did in my code.
I suggest making a custom validator. Do you want to allow 0-9 only? What about negatives? Commas? I never cared for Microsoft's implementation, but I understand it.