PowerQuery if with multiple conditions AND OR - if-statement

How can I replicate this on PowerQuery ??
if(ATC[WorkitemAssetState]=64,
if(ATC[WorkitemIsClosed]=FALSE,
if(ATC[WorkitemIsDeleted]=FALSE,
if(ATC[M_WorkitemStatus]IN{"Reviewing","Available","Research","Progressing","Testing","Resolved","<none>"},
if(ATC[M_DefectResolutionId]IN {"-","<Unknown>","Resolution:1","Resolution:7"},1,-1)
,0)
,0)
,0)
,0)
I have done the following, but it does not seem to work properly:
if [WorkitemAssetState]=64 and
[WorkitemIsClosed]="FALSE" and
[WorkitemIsDeleted]="FALSE" and
[M_WorkitemStatus]="Reviewing" or [M_WorkitemStatus]= "Available" or [M_WorkitemStatus]= "Research" or [M_WorkitemStatus] = "Progressing" or [M_WorkitemStatus] = "Testing" or [M_WorkitemStatus] = "Resolved" or [M_WorkitemStatus] = "<none>" or [M_WorkitemStatus] = "<none>" or [M_WorkitemStatus] = "-" and
[M_DefectResolutionId]= "-" or [M_DefectResolutionId] = "<Unknown>" or [M_DefectResolutionId] = "Resolution:1" or[M_DefectResolutionId] = "Resolution:7" then 1 else 0
I am pretty sure it's because of the multiple OR statements.
I don't think it's because of the FALSE's, btw.
Thanks!!

If you are not sure about the priorities of "and" and "or", it's better to use parentheses.
In fact, "and"'s are evaluated first, then "or"'s.
So "a and b or c and d" is equivalent with "(a and b) or (c and d)".
Not with "a and (b or c) and d", which - I understand - you are looking for.
If so, you need to add parentheses around the collections of "or"'s.
Assuming you have logical values, then "FALSE" won't work: you need false without quotes and in all lower case.
By the way "does not seem to work properly" is not exactly the preferred way to explain what is going wrong. I guess you get (almost) all 1's and (almost) no 0's?

Related

How to handle null values in custom function?

I'm trying to add a custom column to combine values of 2 columns (Col3 and Col4) with the result of a custom function fnMyFunction() in this way
#"Added Custom" = Table.AddColumn(#"Previous Step", "Custom Column",
each
Text.Combine(
{
[Col3],
[Col4],
fnMyFunction([Col5],[Col6])
}
)),
I'm getting this error when function handles null values
Expression.Error: We cannot convert the value null to type Text.
Details:
Value=
Type=[Type]
The function fnMyFunction is like this:
(input1 as text, input2 as text)=>
let
Inputs = {input1, input2},
SplitAndZip = List.Zip(List.Transform(Inputs, each Text.ToList(_))),
OtherStep
...
..
LastStep
in
LastStep
I've tried to add the if else in Input step in order to get empty as output for the function but doesn't work
(input1 as text, input2 as text)=>
let
Inputs = if input1 <> null then {input1, input2} else {"",""}, //Added "if else" here
SplitAndZip = List.Zip(List.Transform(Inputs, each Text.ToList(_))),
OtherSteps
...
..
LastStep
in
LastStep
How can be fix this?
Change your function definition to be the following:
(optional input1 as text, optional input2 as text)=>
PQ has a null-coalesce operator ??. Try this:
Inputs = {input1 ?? "", input2 ?? ""}
edit from the future - #2 is wrong. My bad. Still, read Ben's guide. It's the best PQ text-book there is.
Once you fix the fn, each... Combine([col3],[col4]..) will break because you forgot to _ before [col3] and [col4]. each..._ is syntactic sugar for a single-argument function (eating a whole row, in this case). See here: https://bengribaudo.com/blog/2017/12/08/4270/power-query-m-primer-part3-functions-function-values-passing-returning-defining-inline-recursion
Use
each try Text.Combine() otherwise ""

Condition "else" is not allowed? Why?

Why is the else statement is not allowed to have a then or other conditions?
Is it because it is the final condition within the else-if conditions it represents?
I am struggling to understand this concept since I'm a beginner who just learned about variables.
I'm asking this because I received an error with my else statement in the code:
message = 0
condition = 30
if condition <=10
message = “try harder”
elseif
condition <=20 then
message = "Almost learning"
else
condition = <=30 **—This is the line where I get the error message**
message = "Now you’re getting it"
end
print(message)
Would appreciate someone breaking down in laymen terms, why else is not allowed to have < or > or then or other conditions.
else condition = <= 30
(which is the way your code was originally formatted) would be a very unusual feature in a language.
The whole point of else on its own is to execute if none of the other conditions were true. So a condition on the else is absolutely useless.
The Programming in Lua book if statement shows the normal usage:
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error("invalid operation")
end
However, your actual code (when formatted correctly) ends up looking like:
else
condition = <=30
which is correct in terms of the else but unfortunately makes the next line a statement. And this statement is very much incorrect syntax.
Now it may be that you meant to assign 30 to condition but, based on your other lines (that sort of match this as a condition), I suspect not. So it's probably best just to remove that line totally.

Split string by . but ignore whats inside []

I have a string:
s='articles[zone.id=1].comments[user.status=active].user'
Looking to split (via split(some_regex_here)). The split needs to occur on every period other than those inside the bracketed substring.
Expected output:
["articles[zone.id=1]", "comments[user.status=active]", "user"]
How would I go about this? Or is there something else besides split(), I should be looking at?
Try this,
s.split(/\.(?![^\[]*\])/)
I got this result,
2.3.2 :061 > s.split(/\.(?![^\[]*\])/)
=> ["articles[zone.id=1]", "comments[user.status=active]", "user"]
You can also test it here:
https://rubular.com/r/LaxEFQZJ0ygA3j
I assume the problem is to split on periods that are not within matching brackets.
Here is a non-regex solution that works with any number of nested brackets. I've assumed the brackets are all matched, but it would not be difficult to check that.
def split_it(s)
left_brackets = 0
s.each_char.with_object(['']) do |c,a|
if c == '.' && left_brackets.zero?
a << '' unless a.last.empty?
else
case c
when ']' then left_brackets -= 1
when '[' then left_brackets += 1
end
a.last << c
end
end.tap { |a| a.pop if a.last.empty? }
end
split_it '.articles[zone.id=[user.loc=1]].comments[user.status=active].user'
#=> ["articles[zone.id=[user.loc=1]]", "comments[user.status=active]", "user"]

Cannot Combine Conditions Normally in If Statement in VBScript

I'm trying to determine if it's between the hours of 12 am and 1 am. Here is my if statement:
If InStr(Time,"12") AND InStr(Time,"AM") Then
' Do something
Else
' Do something else
End If
The problem is that this statement evaluates to false, even if both of the conditions are true. I know this because I have tried a nested if like this
If InStr(Time,"12") Then
If InStr(Time,"AM") Then
' Do something
...
And that works. This also works
If InStr(Time,"12")<>0 AND InStr(Time,"AM")<>0 Then
' Do something
...
But if it works as a nested if, why can't I test both of the nested if conditions in a single if statement?
I replaced the InStr function calls with the values that they return
If 1 AND 10 Then
' Do something
Else
' Do something else
End If
And the same thing happened: the if statement evaluated as false and the "Do something else" commands were executed instead. But when I nested the second condition as another if statement inside the first if statement, the "Do something" commands were executed.
Why is that and is there any way to do this without the <>0 and without nesting?
If Time() >= TimeValue("12:00:00") AND Time() <= TimeValue("23:59:59") then
'Do Something
ElseIf Time() >= TimeValue("00:00:00") AND Time() <= TimeValue("01:00:00") then
'Do the same
Else
'Do something different
End If
This should work :)
The problem you observed is caused by the fact that VBScript uses the same operators for boolean and bit operations, depending on the data type of the operands. The InStr function returns a numeric value unless one of the strings is Null, so the operation becomes a bitwise comparison instead of a boolean comparison, as JosefZ pointed out. The behavior is documented:
The And operator also performs a bitwise comparison of identically positioned bits in two numeric expressions and sets the corresponding bit in result [...]
Demonstration:
>>> WScript.Echo "" & (True And True)
True
>>> WScript.Echo "" & (6 And 1) '0b0110 && 0b0001 ⇒ 0b0000
0
>>> WScript.Echo "" & (6 And 2) '0b0110 && 0b0010 ⇒ 0b0010
2
To enforce a boolean comparison you need to use InStr(...) > 0 or CBool(InStr(...)) (both of which evaluate to a boolean result) instead of just InStr(...) (which evaluates to a numeric result).
Date and Time are stored as number of days, where midnight is 0.0, and 1 am is 1/24 :
If Time <= 1/24 Then ' or If Time <= #1am# Then
When you using Time() function and if result like that 10:12:12 AM in this way Instr will result Ture because Instr by default use vbbinarycompare looking For any 12in binary format in 10:12:12 AM and there is sec and min 12 so it will Return True .
just try this :
myHour=replace(Time,Right(Time,9),"") 'get only the hour from time
myAMPM=replace(Time,Time,Right(Time,2)) 'get only AM or PM from time
If InStr(1,myHour,12,1) > 0 AND InStr(1,myAMPM,"AM",1) > 0 Then
wscript.echo "True"
Else
wscript.echo "False"
End If

Jasper Report If Else Condition Expression

I would like to ask about the if else expression in ireport jasper report. May I know is it possible to have multiple or more parameter in the if else statement?
(($P{endDate}.isEmpty()==true || $P{endDate}.equals(""))? "" :
" createDate>='" + $P{startDate} +"'" && " createDate<='" + $P{endDate} +"'")
Based on the code above, there are not allowed me to use "&&". It prompt out syntax error.
Besides that, May I know any solution to solve it? Thank you very much.
I'm assuming it's a query expression your trying to write. You probably would have to do something as follows:
Create a parameter for your dataset. This parameter should not be "prompted" and lets call it DATE_LIMIT_EXPRESSION. You should then set its default value as your expression. For example (if I a get what you meant), this could be your default expression:
"1" +
(($P{startDate}.isEmpty() == false) ? (" AND createDate >= " + $P{startDate}) : "") +
(($P{stopDate}.isEmpty() == false) ? (" AND stopDate <= " + $P{stopDate}) : "")
Now, your dataset query should be something like:
select
...
where $P!{DATE_LIMIT_EXPRESSION}
Just notice the "$P!" syntax. You can find more information about this in the Jasper Reports' documentation.