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.
Related
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 have a multi row dataset that I want to do a lookup on and take the bit/Boolean value of one of it's columns and apply it to the hidden property of a tablix.
Here is the expression for the hidden property on the tablix.
= IIF(Lookup(6, Fields!ServiceOfferingID.Value, Fields!UseCustomCalculator.Value, "JobBuyerDetails") = 0, True, False)
If the ServiceOfferingID is 6, get what is in the UseCustomCalculator column to show or hide the tablix.
I don't know if you can compare values like this, what may need to be a string or if they are all just variants.
I have tried converting the values to string with CStr(), putting quotes around the searched value (6 in this case) but have had no luck getting the tablix to show or hide correctly.
There doesn't seem to be a good way to debug this, check what the Lookup is returning etc.
How can I change my expression to get it to work?
What am I missing?
I am pretty new to SQL Server Reporting Services.
I am using SQL Server 2008 R2.
Debugging in the traditional sense isn't really an option. What I normally do is add a textbox and set the expression to the expression you want to test, in your case, set the expression to
=Lookup(6, Fields!ServiceOfferingID.Value, Fields!UseCustomCalculator.Value, "JobBuyerDetails")
and see what you get.
Once you've established what is being returned and corrected the comparison then you can simplify the hidden expression a little.
The hidden expression would just be something like (assuming lookup issues are resolved)
=Lookup(6, Fields!ServiceOfferingID.Value, Fields!UseCustomCalculator.Value, "JobBuyerDetails") = 0
There's no need to use an IIF here as the comparison will return return or false anyway.
I am facing very simple issue but not getting solution over it.
I have textbox in my ssrs report, I am passing value "1;prashant" or null to it. Now, if I pass value "1;prashant" to textbox then textbox should show only "prashant" and If I am passing nothing then it should be blank.
I have tried following IIF condition:
=IIF(IsNothing(FieldS!WIAPPORVER.Value),"",Split(Fields!WIAPPORVER.Value,"#")(1).ToString())
But, I above code is giving an error ["#error" shows in textbox] if I am passing blank value.
Please let me know, where I am wrong in this.
Thanks
There are probably better ways of doing this, but this is what my head came up with at the time:
=IIF(
IsNothing(Fields!WIAPPROVER.Value)
,""
,Right(Fields!WIAPPROVER.Value,Len(Fields!WIAPPROVER.Value) -InStr(Fields!WIAPPROVER.Value,";"))
)
I believe SSRS is trying to compute everything in the report at runtime, so in your case it is still trying to fetch index 1 from an array even though there is nothing in it and it crashes.
Edit: Changed parameters to Fields. I created a parameter to remake the issue at my side.
Just get the split out of the iif. Then in your iif, if field is nothing create a string that when split will return ""
=Split(IIF(IsNothing(FieldS!WIAPPORVER.Value),"#", Fields!WIAPPORVER.Value),"#")(1)
You are relying on the IIf expression short circuiting, but SSRS IIf expressions do not short circuit - the expression will try and work out Split(Fields!WIAPPORVER.Value,"#")(1).ToString() for all rows and fail when this value doesn't exist.
You can get this going by using text expressions, which don't get this error.
With test data:
And a simple table:
I have added columns with both your existing expression and a new expression:
=Right(Fields!WIAPPORVER.Value, Len(Fields!WIAPPORVER.Value) - InStr(Fields!WIAPPORVER.Value, "#"))
This new expression works for NULL values, empty strings and strings with no delimiter present:
I'm having an issue and everything i've tried doesn't work. I have a phone number datafield that returns numbers with no formatting '3055558798' but i want it to look like this '(305)555-8798'. I can get that done with this expression:
= Format(Convert.ToDouble(Fields!MyFieldName.Value), "(###)###-####")
The only issue is that when the return is null i get #ERROR in the space. I found an expression that got rid of the #ERROR but still no luck putting them both together. I would have to dig through my reports to find the expression but hopefully someone can help me. I've been doing reports for a couple of months but i'm still not very good with all the expressions that there are. I just need to format the phone number and if the return is null then not show anything. There's also this on the same site that i found the expression but it doesn't work so i dont know why the guy said it worked for him.
=Iif (Fields!MyFieldName.Value Is Nothing, Nothing,
Format(Convert.ToDouble(Fields!MyFieldName.Value), "(###)###-####"))
That just doesn't work for me, I believe the syntax is wrong but i don't know what to change to fix it. Thanks.
The error you have got is nothing to do with formatting, it is the conversion to Double that is failing. So your expression works perfectly as long as your field consists entirely of numeric characters. However, you have some data with non-numeric characters in it, causing the Convert.ToDouble() function to throw an error.
Unfortunately this can not be solved with an IIF expression 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:
=IIF(IsNumeric(Fields!Phone.Value), Format(Convert.ToDouble(Fields!Phone.Value), "(###)###-####"), Fields!Phone.Value)
will always attempt the conversion to double regardless of the result of the IsNumeric function. There are two ways to solve this:
Use Val instead of ToDouble
The problem with ToDouble 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 now we can use the expression:
=IIF(Fields!Phone.Value Is Nothing,
Nothing,
IIF(IsNumeric(Fields!Phone.Value),
Format(Val(Fields!Phone.Value), "(000)000-0000"),
Fields!Phone.Value)
)
(Use 0 rather than # so that leading zeroes aren't suppressed)
This expression returns Nothing if the field is Null, checks to see if it is numeric and if so converts it to a number and formats it, otherwise it just returns whatever is in the field.
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 ToDouble. We simply make the calculation and discard the result.
Custom code
On the Report menu, click Report Properties... and go to the Code tab. Insert the following code:
Function FormatPhone(Phone AS String) AS String
IF (Phone Is Nothing) Then
Return Nothing
Else If (IsNumeric(Phone)) Then
Return Format(Convert.ToDouble(Phone), "(000)000-0000")
Else
Return Phone
End If
End Function
Use the following expression in your phone number cell:
=Code.FormatPhone(Fields!Phone.Value)
Item in the recordset rstImportData("Flat Size") is = Null
With that, given the following statement:
IIF(IsNull(rstImportData("Flat Size")), Null, cstr(rstImportData("Flat Size")))
Result: Throws error 94: Invalid use of Null
If I change the statement by removing the type conversion upon a false comparison:
IIF(IsNull(rstImportData("Flat Size")), Null, 0)
Result: Null
It returns Null as it should have the first time. It appears that I cannot do a type conversion in an IIF if the value passed in should ever be null even if it passes an IIF test, it still attempts to evaluate it at both the true and false answer. The only reason I'm using IIF like this is because I have a 25 line comparison to compare data from an Import against a matching record in a database to see if I need to append the prior to history.
Any thoughts? The way data is imported there will be null dates and where the spreadsheet import is in a string format I must convert either side to the other to compare the values properly but if either side is null this exception occurs :(
EDIT
Example of why I was using IIF (and considering using a universal function)
If master("one") <> import("one") Or _
master("two") <> import("two") Or _
master("date") <> import("date") Or _ //import("date") comes from a spreadsheet, it comes in as string, CAN be a null value
master("qty") <> import("qty") Or _ //import("qty") comes from spreadsheet, comes in as a string can CAN be null
master("etc") <> import("etc") Then
....stuff....
End If
This code expands for roughly 20 columns to compare in the database. I would prefer to check as part of the statement. I can think of a bunch of solutions but they involve adding much more code. If that is the case power to it, however I'm not one to give in so easily.
Options I see are
Creating temp vars to do the work prior to comparing and using these new vars instead of the recordset
Creating an object to pass the record into to preformat and work with, though extra work would provide this functionality to each import type since there are different files with similar fields
I'm here for ideas, and I'm open to any interesting pieces that can be thrown my way as I get to decide how to do it I'm looking for the most reusable approach.
The simple expedient of changing the value to a string helps tremendously. The trick is that trimming a string which is NULL will get a null string. Which can then be operated on as if it wasn't a database null.
I frequently use the form:
CInt("0" & Trim(SomeVariant & " "))
To get a valid number without having to go through a bunch of hijinks. The null is a nonentity for this problem.
The behavior you described is the standard way IIf operates under VBA. This is part of what Access 2003 Help says about it:
"IIf always evaluates both truepart and falsepart, even though it returns only one of them. Because of this, you should watch for undesirable side effects. For example, if evaluating falsepart results in a division by zero error, an error occurs even if expr is True."
However, if you use an IIf statement in a query, evaluation short circuits after truepart when expr is True --- falsepart is not evaluated in that case. Unfortunately this information is not useful for you ... unless you can incorporate a query into your comparison.
I don't know of any other way to avoid your error with IIf. I would try appending the Excel data into a table whose structure matches that of the table you will compare against, thereby eliminating the need to do a string conversion at the same time you do the comparison.