RDLC expression error - rdlc

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

Related

SSRS - How to make IIF statement ignore invalid values

I am creating a table in SSRS with Business Intelligence 2008. I have a date, as a string, as one of the values used in the table. This value may have a string representing a date, OR it could also be blank. If it has a value, I want the value formatted in a different way. Right now, I have this expression for the cell in which it is displayed:
=IIf(Fields!MyDate.Value = Nothing, "", Format(CDate(Fields!MyDate.Value), "dd-MM-yyyy"))
This works perfectly if the field has a value. However, when the field is blank, the cell is populated with #Error. This would make sense if I just had the Format function, but it seems like the IIf should prevent it from trying to run that with a blank value. I tested it with this expression:
=IIf(Fields!MyDate.Value = Nothing, "No value", "Value")
...and sure enough the blank values entered the correct part of the statement and printed "No Value". I don't understand why the second part of the expression, which isn't used, would cause an error. Is there a way to rewrite this that will not cause an error? Thanks
EDIT: As I mentioned in the comments, I also tried a switch statement like this:
=Switch(Fields!MyDate.Value = Nothing, "", Fields!MyDate.Value <> Nothing, Format(CDate(Fields.MyDate.Value), "dd-MM-yyyy"))
However, this returned #Error for blank values as well.
EDIT Regarding Possible Duplicate: PLEASE do not mark this as a duplicate to the question asking whether IIf short-circuits. I looked there, it asks a different question and does not give an answer that works for what I need.
The problem is that Iif does not short-circuit. One ugly workaround is to use a nested Iif:
=IIf(Fields!MyDate.Value = Nothing, "", _
Format(CDate(Iif(Fields!MyDate.Value = Nothing, Today(),Fields!MyDate.Value)), "dd-MM-yyyy"))
Which is ugly, repetetive, and error-prone.
Another option is to create a custom function that does short-circuit:
Public Function FormatOrBlank (ByVal theDate As DateTime, ByVal format As String)
If String.IsNullOrWhiteSpace(theDate)
Return ""
Else
Return Format(CDate(theDate)), format)
End If
End Function

VS2008 reporting IFF is failing on a simple condition

I have a simple report in VS2008. I have a table which is like this:
I get the results as this:
I have already wasted 2 hours sitting in front of this issue. Moreover, my colleague didn't see any mistake in this either. I am 100% certain I have no formatting on the table. The results in the field value come as a string.
What wrong am I doing in the last column's code?
P.S. I have also tried
=IIF(IsNumeric(Fields!value.Value), Fields!value.Value, Fields!value.Value)
but then the data in the third column is showed as in the first one.
It seems that for some weird reason IIF is trying to parse both True and False parts and failing CDbl() on a string, but I cannot believe this can be possible, because I haven't seen a programming language doing something like this before.
After the comments on my post, I came up with a solution by writing these two functions. These two were both used to display data and overcome the stupidity of uneditable total field.
Public Function cdblf(ByVal s As Object) As Object
If (IsNumeric(s)) Then
Return CDbl(s)
Else : Return Nothing
End If
End Function
Public Function cdbls(ByVal n As Object, ByVal s As Object, ByVal b As Boolean) As Object
If (IsNumeric(n)) Then
Return CDbl(n)
Else :
If(Not IsNothing(s)) Then
If(b) Then
Return CStr(Left(CStr(s), Len(CStr(s)) - 1))
Else : Return Nothing
End If
Else : Return Nothing
End If
End If
End Function
The usage of these functions combined should be like this:
=Code.cdbls(
Sum(Code.cdblf(Fields!value.Value)),
Fields!value.Value,
InScope("matrix1_row_name") and InScope("matrix1_column_name"))
This both solved the fact that I didn't want to sum string values and also there was no need to use IIF anymore.

IsNumeric returns true for strings containing a D character

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.

VB.Net Anding a byte and a double

during some code conversion from another persons VB.net project to C#, i have come across the following code:
Public Sub New(ByVal lbytModuleAddress As Byte, ByVal lbytRelayStateMask As Byte)
Dim lintCounter As Integer
mbytModuleAddress = lbytModuleAddress
For lintCounter = 0 To 7
If lbytRelayStateMask And (2 ^ lintCounter) Then
mblnRelayState(lintCounter) = True
Else
mblnRelayState(lintCounter) = False
End If
Next
End Sub
Now m trying to convert this to C#, but im a little confused as to exactly the meaning of this line:
If lbytRelayStateMask And (2 ^ lintCounter) Then
Could someone please enlighten me? It appears there something going on behind the scenes (that ill have to examine further) however before i do i would just like to clarify the result of this if statement.
Am i correct in saying if either one of the sub-expressions equals zero then its false, otherwise its true? Sorry, im not too up to speed on VB.net.
lbytRelayStateMask And (2 ^ lintCounter) results in BIT number lintCounter, which is on or off. a bit is a boolean value. AND is a bit operation, not the AND in an IF
th author might have written too:
mblnRelayState(lintCounter) = (lbytRelayStateMask And (2 ^ lintCounter))
Yes, I believe you are correct in your analysis.

Lazy evaluation in SSRS

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)