hope someone more experienced can give me answer/solution to my problem.
In a database I have two columns, one to control do we show data and the data to be shown is in the second column.
I have data and expression as below:
ShowPriceOnMatrix | RSP
-------------------------------
0 | 1.48
1 | 10.26 euro -> This one fails with #Error
1 | 4.59
0 | 7.12
=IIF(Fields!ShowPriceOnMatrix.Value = 1, CDbl(Fields!RSP.Value), "")
This expression sometimes gives me #Error.
The problem is that the RSP field was defined as nvarchar and I cant change it now so I'm trying to convert to number and show as. Some users when input price on the filed they also type a text ex. "12.45 euro" or similar. When the expression hits a value with text the whole IIF fails with an #Error even if the first column is stated not to show the price.
The problem with IIF is that it is not skipping the second parameter if the first one evaluates to false - and therefore produces #Error in my case.
I've tried to use
IsNumeric(Cdbl(Fields!RSP.Value))
and
IsError(Cdbl(Fields!RSP.Value))
but both of them give an #Error also. From SSRS explanation for those functions, they should return a Boolean value but somehow I'm getting #Error :)
Just convert the field to numeric using
VAL(Fields!RSP.Value)
Also, you might want to consider using SWITCH instead of IIF. SWITCH stops at the first expression which evaluates to True, whereas IIF will evaluate all expressions regardless of if they will be used or not.
In your case, with a single IIF, SWITCH is not relevant but in cases where nested IIFs are used or situations where you may get a divide by zero error, SWITCH is often easier to read/debug. So something like this where we have a hypothetical situation that we want to test for divide by zero and return zero or if the thing we are dividing by is negative we want to return -1, otherwise do the calc...
=IIF(Fields!MyDivisor.Value = 0, 0, IIF(Fields!MyDivisor.Value <0, -1, Fields!MyNumber.Value/ Fields!MyDivisor.Value))
would become
=SWITCH (
Fields!MyDivisor.Value =0, 0,
Fields!MyDivisor.Value <0, -1,
True, Fields!MyNumber.Value/ Fields!MyDivisor.Value
)
each expression/result pair is evaluated in order until it hits the first True expression, so if MyDivisor was zero it would return 0 and stop, if it was negative, it would return -1 and stop. The final True acts like an else (as True always returns True ! ) so it would only do the calculation if all other expressions returned false.
You can use this expression to extract your numeric values:
=System.Text.RegularExpressions.Regex.Replace(Fields!RSP.Value, "[^0-9,]", "")
But you have to take care of the . in 1.48. With , and the language DE it worked for me. With . it would be:
=System.Text.RegularExpressions.Regex.Replace(Fields!RSP.Value, "[^0-9.]", "")
Related
Hi all, I have an expression in SSRS that calculates the Due date from the Last Fit Test. The data is correct if the Last Fit Test has a date. However, if the Last Fit Test is Null or blank, it gives an error "########" (it supposes to return empty or blank). How can I fix that expression?
=IIF(IsNothing(Fields!LastFitTest.Value) = True,"",DateAdd(DateInterval.Year,1,Fields!LastFitTest.Value))
Try this ...
=IIF(
IsNothing(Fields!LastFitTest.Value),
"",
DateAdd(DateInterval.Year,1,IIF(IsNothing(Fields!LastFitTest.Value), '1900-01-01', Fields!LastFitTest.Value))
)
The problem was the IIF always evaluates both the true and false condition so when you had no value in LastFitTest the false side could not evaluate even though it would never be used.
All we have done here is made the date that get processed in the DateDiff function always return a valid date. The 1st Jan 1900 means nothing, you can put any date you like in there as it will never be used in the final result.
The only other change was to remove the = True. IsNothing returns True/False so you don't have to explicitly say =True.
I have a database which tracks employee QA. I'd like to be able to search by a single Staff Member, a whole team, or a Unit. I have three controls that correspond to those fields and only one can ever have a value at once. In my quesry I'd like to have threee expressions that will limit my results by one of those three fields. I'm adding just one to start and I've hit a problem.
I found this https://www.acuitytraining.co.uk/microsoft-training-courses/access/if-statements/ which seems to do what I want. Here is the code I'm trying.
IIf(IsNull([Forms]![MainMenu]![btnManagersMenu].[Form]![cmbStaffSelect]),
[UserLogin] Like "*",[UserLogin]=[Forms]![MainMenu]![btnManagersMenu].
[Form]![cmbStaffSelect])
Which works fine if the control has a value. (condition is false) If the dropdown has no value (condition is true) I get zero results. I suspect the problem lies with the Like "*" on my UserLogin field. Here is my query wizard and the buildler wizard for the IIF expression
Can anyone see why I'm not getting any results for the dropdown control being empty. To my thinking this should give me an unfiltered list of results. I have double checked my data and there are 137 records that should appear if I'm not limited by the staff selection.
The short version of this is if cmbStaffSelect has a value I want my records limited by that value. If cmbStaffSelect is blank I want to get all records.
Keep in mind that the iif function will always evaluate both the then and else arguments, before returning the appropriate value depending on the value returned when evaluating the supplied test expression.
As such, if either the then or else arguments have the potential to error when evaluated (regardless of the result of the evaluation of the test expression), then the iif expression has the potential to error.
As an alternative, you could use the Nz function to achieve the same result:
[UserLogin] LIKE Nz([Forms]![MainMenu]![btnManagersMenu].[Form]![cmbStaffSelect],"*")
Perhaps your IsNull([Forms]![MainMenu]![btnManagersMenu].[Form]![cmbStaffSelect]) is always returning false because cmbStaffSelect might be equal to empty string?
Try something like this:
IIf(Trim([Forms]![MainMenu]![btnManagersMenu].[Form]![cmbStaffSelect] & "") = "",
[UserLogin] Like "*",[UserLogin]=[Forms]![MainMenu]![btnManagersMenu].
[Form]![cmbStaffSelect])
This checks to see if the cmbStaffSelect is "" ... if cmbStaffSelect is null - it converts it to "" by appending an "" to the null value.
I believe your hunch is exactly correct. If you want your query result to return the * symbol for the UserLogin field; then alter your IIF statement to be: [UserLogin] = "*"
I am hoping someone can help me here. I am using the PMT function to calculate mortgage payments in SSRS. I am using the following Formula
=IIF(Note = "Present",-PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod),Nothing))
The formula works perfectly when Note = Present. However on all other loans it is producing #ERROR. I don't understand why this is happening.
Is there some other error handling that needs to be done to simply leave the cell blank if the note is not present?
I'm not familiar with PMT but it could be that the values passed to PMT are invalid for loans where Note is not "Present". If this is the case then I would use a SWITCH statement instead. SWITCH will stop at the first expression that evaluates to True, whereas IIF evaluates all expressions, even the expression that does not get used!
try this..
=SWITCH(
Note <> "Present", Nothing,
True, -PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod)
)
This way, if note is not "Present" then return nothing and only if it IS "Present" evaluate the PMT function and return its value. The True just acts like an else to save us writing Note = "Present" for the second condition
SSRS will always evaluate both sides of a conditional expression, no matter what the result of the first parameter boolean test. This means that
-PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod)
must be a valid calculation for rows where Note <> "Present" as well or you will get an expressions error. I would suggest that probably some of the other fields aren't populated with appropriate "dummy" values in this scenario.
What is Nothing in your code?
=IF(Note = "Present",-PMT(Rate/12,Term,Balance,0,DueDate.EndOfPeriod),0))
The matrix's odd rows contain strings, representing integer numbers. The even rows contain strings, representing dates in mm/dd/yyyy format. The order is not guaranteed, it could be the other way around if someone changed the category names.
The grand total row has to be added to this matrix, but the following expressions throw an #Error:
=Sum(Iif(IsDate(Fields!Data.Value), 0, CInt(Fields!Data.Value)))
=Sum(Iif(InStr(Fields!Data.Value, "/"), 0, CInt(Fields!Data.Value)))
Converting 0 and field value to some other numeric data types did not work too.
Interesting enough, the expressions partially work for the grand total column, i.e. they calculate the numbers' row total, but #Error on the dates rows.
Protecting the row grand total as follows did not help either:
=Iif(Fields!Results.Value = "# of items", CStr(Sum(CInt(Fields!Data.Value))), "")
What is the correct way to implement data driven conditional totals?
I could do this in plain SQL and dump into a tablix in a heartbeat but this has to be wrapped in SSRS and used with an existing matrix which must not be changed otherwise.
The #ERROR you get on the date rows is due to the CInt conversion failing.
This is because IIF is a function, not a language construct so both the true and false parameters get evaluated before being passed to the function regardless of the value of the boolean condition parameter. This means that:
=Sum(Iif(IsDate(Fields!Data.Value), 0, CInt(Fields!Data.Value)))
will always attempt the conversion to integer regardless of the result of the IsDate function.
Try using Val instead of CInt. The problem with CInt is it errors when the string to be converted is an inappropriate form; Val doesn't have that problem - it simply grabs whatever numbers it can. So you can use the expression:
=Sum(Iif(IsDate(Fields!Data.Value), 0, Val(Fields!Data.Value)))
and then simply format it like an integer.
Note that the Val function is still being run even when the field is not numeric but this expression succeeds because the Val function doesn't raise errors like Cint. We simply make the calculation and discard the result when the field is a date.
This expression, combining the tips from both answers with additional protection, works:
=Iif(
IsNumeric(Fields!Data.Value),
Sum(Val(Iif(InStr(Fields!Data.Value, "/"), "", Fields!Data.Value))),
0
)
Just wondering if the following expressions used for Value are equivalent (the column "Contrib" in DataSet "MyDataSet" is nullable) :
option 1 :
=Format(First(Fields!Contrib.Value, "MyDataSet"), "C2")
option 2 :
=IIF(First(Fields!Contrib.Value, "MyDataSet") Is Nothing, "", Format(First(Fields!Contrib.Value, "MyDataSet"), "C2"))
i.e. does SSRS have special processing, so that in option 1, it internally checks for a null value, and effectively ends up doing something similar to option 2. From trial and error, they seem to give the same results (when "Contrib" is null/not null), but just wanted to be sure.
In my experence Reporting Services will by default output a blank value if the value is Null.
As you are using IIF to modify results I think your issue may be similar to a problem that I have with preventing divide by zero errors on calculated columns.
The IIF will evaluate all of it's operands so an error will occur even if the divide by zero occurs in "false" part. I capture a divide by zero by showing "-" in the report and I use a nested IIF to replace the divisor with a value of 1 but this result is never shown in the report.
=IIf(Fields!LastYearMonthToDateSales.Value = 0, "-", (Fields!ThisYearMonthToDateSales.Value - Fields!LastYearMonthToDateSales.Value) / Abs(IIf(Fields!LastYearMonthToDateSales.Value = 0, 1, Fields!LastYearMonthToDateSales.Value)))