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))
Related
While converting some Access queries to T-SQL, I came across the Access function IIf. I read the documentation here and understand it takes 3 parameters: the expression, the if true, and the if false. What I have yet to find is if the "false" param is required? And if a false is not provided, what is the behavior?
UPDATE:
When this question was asked, I did not know if the query worked with only 2 parameters (b/c I can not run the query in Access). I did, however, suspect it might work (with only 2 params) b/c a few queries I am converting (to T-SQL) have nested IIF's and the last IIF has only 2 params.
It's IIf, not IFF. All arguments are required in VBA and textbox expressions and both must be calculatable (no error result such as DivBy0) because both parts will be calculated - if either errors, the entire expression errors. The IIf() in Access query works differently - 'falsepart' calculates only if 'truepart' fails and if 'falsepart' is not provided, expression returns Null if 'truepart' fails.
Try some expressions and see what happens. One for testing: IIf(1=2,"T").
Addendum to June7's excellent answer:
Here are two simple queries that work in Access SQL:
SELECT IIf(1=1, "yes")
(returns "yes")
SELECT IsNull(IIf(1=2, "yes"))
(returns -1 aka True) - so if you omit falsepart, IIf() returns indeed NULL if expr doesn't evaluate to True.
Yes, it's required, it's actually like an if else statement.
i.e an action occurs if the condition is fulfilled, and another action occurs if condition is not fulfilled
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] = "*"
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.]", "")
Trying to understand what the following conditional split expression is trying to do:
ISNULL(Employee_ID_WD) || (RIGHT(REPLACENULL(Employee_ID_WD,"0"),LEN(REPLACENULL(Employee_ID,"0"))) != REPLACENULL(Employee_ID,"0"))
I am new to SSIS, can anyone explain this?
It’s a relatively straight forward expression when you break it down.
To put it succinctly (tl;dr), if the Employee_ID_WD is null OR the Employee_ID value is not in the Employee_ID_WD value, then return true. Otherwise, return false.
Details:
The first part, ISNULL(Employee_ID_WD), checks to see of the Employee_ID_WD is null. If it is, the expression will return true, right away. The reason for that is the || right after. This is called a logical or. If you see this in many programming it indicates that the programmer wants to the expression to return right away if any part of it before the || is true. In other words, if something before the || is true, start doing what I need you to do, there is no sense in checking anything in this expression, I know what I need to know in order to move on. This is referred to as short-circuit evaluation. Wiki.
If the Employee_ID_WD is not null, we move on to the next part of the expression.
This part:
(RIGHT(REPLACENULL(Employee_ID_WD,"0"),LEN(REPLACENULL(Employee_ID,"0")))
is grabbing the characters on the right side of the Employee_ID_WD. The number of characters it is asking for is what is returned from the LEN (length) function being run on the Employee_ID. Also, both parts of this are checking if the value they pass in is null, as indicated by the REPLACENULL function. If they are null, a string with the value 0 is returned. This is done in case one of the values are null, this way you get a true value comparison. Using the REPLACENULL function in all parts of this expression makes it that much more robust, meaning inconsistencies with data will be handled without something error-ing out, or giving in consistent results in the end.
The results from the part above are compared to REPLACENULL(Employee_ID,"0"). If the part above and this are not equal (!= is not equal to), then the expression returns true.
SSIS Expression Reference
I have a textbox in my SSRS 2005 report. The expresssion for this textbox is:
=IIF(IsDBNull(Fields!fOrgID), Code.SetMyVar("null"), Code.SetMyVar(Fields!fOrgID.Value))
I have also tried IsNothing(Fields!fOrgID) and a few other variations of checking for nulls.
I have modified the SetMyVar function for testing and it now looks like this:
Public Function SetMyVar (var as String)
MsgBox(var, VbOKCancel, "Test1")
If var Is Nothing Then
Return "NOTHING"
Else
MyVar = var
Return var
End If
End Function
I also have the public variable MyVar:
Public Shared Dim MyVar as String
When my database query returns data, this correctly evaluates, a messagebox is displayed with the value, the textbox gets set with the value, and the world is generally a happier place.
When my database query does not return a value though, I get the error:
The query returned no rows for the data set. The expression therefore
evaluates to null.
and the SetMyVar function never appears to be ran (you never get the messagebox popup). As expected, my emotions range from anger, sadness, and bitter hatred of SSRS.
I read something about SSRS evaluating both sides of an IF statement, so perhaps that is why I get the error (likely then on Code.SetMyVar(Fields!fOrgID.Value))... not sure how I get around that though.
Thoughts? Suggestions? Words of comfort?
From the sound of things, it seems likely that the issue is that SSRS is having a problem displaying zero records. I'd recommend one of the following:
1) Use a control that handles zero records appropriately (Tables do. I think Lists do as well).
2) Modify your query to return a single record with blank values if it would otherwise return zero records.
An answer to the original question:
=IIF(IsNothing(Fields!fOrgID),
Code.SetMyVar("null"),
Code.SetMyVar(IIF(IsNothing(Fields!fOrgID),"Foo",Fields!fOrgID.Value)))
The error was from both sides of IIF being evaluated. The extra IIF in the statement above will avoid Code.SetMyVar from ever being called with a null value.
I believe you're right about about Iif always evaluating both of its value arguments (at least, it does in Visual Basic). I'm not sure why you're getting this precise error (unless strings can't be assigned a value of DBNull?), but you almost certainly want to attack this problem with a different method.
The reason for this is that your current code will likely always call both set methods regardless of the conditional value.
Formula that worked for my SSRS 2008 reports.
=IIf(String.IsNullOrEmpty(Fields!NullableFieldwithPossibleBlankStrings.Value),"Yes","No")
I tried this too (also tried a version with IsNothing)...
=Code.SetField(IsDBNull(Fields!fOrgID))
And changed the function to be one that accepts a boolean. I figure this above function would always return a true or false, but in the event of a NULL, I again get "The query returned no rows for the data set. The expression therefore evaluates to null.".
I need to pass back to my code if the field is null or not (as this will let me know if the datasource is null or not).
Let me know if you can think of a better way because I cannot.