IIF construct not resolving the correct way (SSRS) - sql-server

I've got a problem with this piece of code inside a parameter in SSRS2012.
=IIF(InStr(Parameters!P1.Value,"#")=0,
"missing #",
Left(Parameters!P1.Value(InStr(Parameters!P1.Value,"#")-1)))
My aim is to check if the parameter P1 contains a "#" if it doesn't i will print "missing #" otherwise i want to remove from that parameter what's after the "#" ("#" inculded).
example:
P1 = 123456 --> print "missing #"
P1 = 123#56 --> print 123
The problem is that SSRS drops the error: "Argument 'length' must be greater or equal to zero" when i insert a value with no "#". (when i insert a value with an "#" it goes all well)
It seems like the IIF resolves the 2 expressions first (rather than one is true or false) and after that it gives you the correct one based on the evaluation of the first condition.
Looking for some help. Thanks!

it is a weird bug, here is one solution
=replace(replace(IIF(InStr(Fields!P1.Value,"#")<> 0,
left(Fields!P1.Value,InStr(Fields!P1.Value,"#")),"missing"),"#",""),"missing","missing #")

Related

How do you extract characters from a string?

I want to send emails from my google sheet. I want the emails to address recipients by their first name or the name they are known by. The following is an example of my data in column A.
I need a formula in column B that extracts the first name from column A but if they are known by a different name, the name in the brackets in column A, then I want that name extracted to column B instead. I have the following formula which works for names in brackets but I need help with the formula to extract the first name when there are no brackets.
=(SPLIT(REGEXEXTRACT(A2,"\((.*)\)"),","))
one-cell solution:
=ARRAYFORMULA(IFNA(IFNA(
REGEXEXTRACT(A2:A, "\((.*)\)"),
REGEXEXTRACT(A2:A, ", (.*)"))))
Try this. In B2, enter this formula:
=iferror(SPLIT(REGEXEXTRACT(A2,"\((.*)\)"),","), mid(A2, find(", ", A2)+2, len(A2)))
Explanation:
The first part is yours:
SPLIT(REGEXEXTRACT(A2,"((.*))"),",")
As you've seen, this returns an #ERROR if the "(" isn't found. So use iferror to wrap that. The second part is returned if there is an error:
=mid(A2, find(", ", A2)+2, len(A2))
The mid() function returns a substring from a string. The first argument is the string that you're looking in, found in A2. Then, The starting position of the substring is the location of ", " (offset by 2), and continues to the end of the string.
Try this. In B1, enter this formula:
={"Salutation";arrayformula(if(A2:A="","",iferror((SPLIT(REGEXEXTRACT(A2:A,"\((.*)\)"),",")),index(split(A2:A," "),,2))))}
Explanation:
The first part is yours: SPLIT(REGEXEXTRACT(A2,"((.*))"),",")
As you've seen, this returns an #ERROR if the "(" isn't found. So use iferror to wrap that. The second part is returned if there is an error: index(split(A2:A," "),,2)
The index() function returns the second column from the split(). The advantage to doing it this way is you will not have to drag formulas down.

SSIS Expression cannot be evaluated -- why not?

I have variable in an SSIS package name User::FileFullPathLDR.
From this variable at run time of the SSIS package I want to extract the file name from FileFullPathLDR and put it in another variable called User::FileName.
I have tried all types of combinations to try and get this code to resolve in Expression Builder to resolve except standing on my head with incense burning saying OM 4 million times, and nothing seems to work.
I put the following expression in Expression Builder for the variable User::FileName:
REVERSE(SUBSTRING(REVERSE(#[User::FileFullPathLDR]),1,FINDSTRING(REVERSE(#[User::FileFullPathLDR] ),"\\",1)-1))
From the full path I expect to get the filename similar to: LDRFile01242019.txt.
But I keep getting the following error when expression builder parses this statement:
The length -1 is not valid for function "Substring". The length parameter cannot be negative. Change the length parameter to zero or a positive value.
I tested this expression:
REVERSE(SUBSTRING(REVERSE(#[User::FileFullPathLDR]),1,FINDSTRING(REVERSE(#[User::FileFullPathLDR]),"\\",1)-1))
against this test string:
C:\Folder1\Folder2\FileName.TXT
and it returned
FileName.TXT
There was no error
I tested it by creating a variable and defining an expression for it, then evaluating that expression.
You can try the following expression:
RIGHT(#[User::FileFullPathLDR],FINDSTRING(REVERSE(#[User::FileFullPathLDR]),"\\",1)-1)
Also try to add a conditional operator to avoid bad values errors:
FINDSTRING(REVERSE(#[User::FileFullPathLDR]),"\\",1) == 0 ? "" : RIGHT(#[User::FileFullPathLDR],FINDSTRING(REVERSE(#[User::FileFullPathLDR]),"\\",1)-1)
References
SSIS Expression to get filename from FilePath
SSIS Expression to Get File Name From Full Path
The part FINDSTRING(#[User::FileFullPathLDR],"\\",1) returns 0 if FileFullPathLDR does not contain a \. Since you are subtracting -1, you might end up with a negative value if your string doesn't match the pattern, or if the variable is set at runtime (you might have an empty string during validation).
If you need it to work with an empty string as well, you could add a \\ in front of it if there is no \\ present yet, using something like FINDSTRING(#[User::FileFullPathLDR],"\\",1) == 0 ? "\\"+ #[User::FileFullPathLDR] : #[User::FileFullPathLDR]
So the whole thing will be:
REVERSE(
SUBSTRING(
REVERSE(
#[User::FileFullPathLDR]),1,FINDSTRING(REVERSE(FINDSTRING(#[User::FileFullPathLDR],"\\",1) == 0 ? "\\"+ #[User::FileFullPathLDR] : #[User::FileFullPathLDR])
,"\\",1
)-1
)
)
So, if there is no \ present, it will just return the string itself.

SQL Server Report expression failing for NULL int values

IIF is giving me some hell. When I do this everything works:
=IIF (IsNothing(First(Fields!Temperature.Value, "ReportInfoDataSet")),"NULL","GOOD")
But when I want to actually use the value, I end up with #Error for the NULL values, and from what I've read it's because IIF evaluates everything at once, so the .ToString() argument fails for the "GOOD" condition even though it is not used.
This gives #Error when I have a null value:
=IIF(
IsNothing(First(Fields!Temperature.Value, "ReportInfoDataSet")),
"N/A",
First(Fields!Temperature.Value, "ReportInfoDataSet").ToString()
)
So how do I work around the fact that IIF wants to evaluate all terms? There is a TechNet article that shows nesting another IIF statement as the "GOOD" condition that helps with the NULL value, but I still get the error (doing this for example):
=IIF(
IsNothing(First(Fields!Temperature.Value, "ReportInfoDataSet")),
"N/A",
IIF(
IsNothing(First(Fields!Temperature.Value, "ReportInfoDataSet")),
"N/A",
First(Fields!Temperature.Value,"ReportInfoDataSet").ToString() & ChrW("&H00B0") & "F"
)
)
Here is the article that indicates this potential solution, but it seems that I am still missing something, or that something changed invalidating this solution.
One further bit of information: I put a breakpoint in just after I fill the datatable, thinking that I would just intercept the table fill and modify so that NULLs turn to 0 or something, and it seems that datatables are strongly typed and don't allow for nullable data types so there is an exception for the temperature column:
'(ReportInfoRow((new System.Linq.SystemCore_EnumerableDebugView((test.Table).Rows)).Items[0]))
.Temperature' threw an exception of type 'System.Data.StrongTypingException'
Any insights are valued . . . I'm pondering whether I just want to add an extension to the dataset and add a MyTemp parameter that fixes the value for the report.
To not have the .ToString() forced in the lack of short-circuit Boolean evaluation above, replace it with CSTR().
CSTR(First(Fields!Temperature.Value, "ReportInfoDataSet"))

Hide row based on parameter value

How can I simply hide row based on selected parameter in SSRS 2012.
I have LineGuid parameter that has two values: Earthquake and Wind
I want to hide the row if 'Wind' parameter is chosen, because it shows sum value for Earthquake.
So I am entering an Expression in Row Visibility but it gives me an error saying: "Overload resolution failed because no Public '=' can be called..."
I also tried to pass Value(GUID), not Label but gives me the same error.
What am I missing here?
You have the Line GUID parameter set to accept multiple values. The values are passed in as an array which is why you see the String() syntax in the error message. One option is to change that to not accept multiple values. Another option is to use the First selected value like so:
=Parameters!lineGuid.Value(0)
Note the reference to the array index on the end of the expression.
If you want to combine all the values you can also join them like this:
=Join(Parameters!lineGuid.Value, ", ")
This will concatenate the values in the array into a comma separated string.
Join all of your parameters together, then check to see if Wind is part of the string.
= IIF(InStr(Join(Parameters!lineGuid.Label,","),"Wind") > 0,True,False)
In my case I needed to display row when "Earthquake" parameter is chosen, and also when both parameter chosen: Earthquake and Wind.
This expression made it work:
=IIF(InStr(JOIN(Parameters!lineGuid.Label,","),"E")
OR
InStr(JOIN(Parameters!lineGuid.Label,","),"W")
AND
InStr(JOIN(Parameters!lineGuid.Label,","),"E")>0,False,True)
Try use the actually parameter .value not .label name

CONCATENATE syntax error "unable to interpret text-cb1"

I've been trying to make a dynamic col for a select. it's just for learning.
I've made a selection screen with some select-options and checkbox parameters. whenever i have a checked checkbox i want to concatenate a string to my lineselection var.
lineselect = ' CARRID CONNID'.
SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-001.
[...]
SELECTION-SCREEN END OF BLOCK block1.
IF cbcofr EQ 'X'. "where cbcofr is checkbox
CONCATENATE text-cb1 INTO lineselect SEPARATED BY space. "where text-cb1 is 'CONTRYFR
ENDIF.
When i check for error the compiler just says "Unable to interpret "text-cb1". possible cause: incorrect spelling or comma error."
Is not about text-cb1 , i've tried with string 'COUNTRYFR' and says the same thing. I don't get where my error is.
The syntax for concatenate is as follows:
CONCATENATE c1 c2 [... cn] INTO targetc [SEPARATED by sep].
or
CONCATENATE lines of itab into targetc [SEPARATED by sep].
As you have already noted, you need at least two source variables to concatenate.
Full documentation can be found here
As of Netweaver release 7.02 you can also do this:
targetc = c1 && [c2 ... && cn].
In this case, you lose the "separator" functionality, though.

Resources