前段
UiPathで"If"アクティビティを利用しているとき、複数のIfを重ねると見栄え的につらいので、なんとか出来ねーかなと調べていたところ、「AndAlso/OrElse」なるものがあることを知った。
実際に使ってみたところ、自分のケースでは効果があった。また開発の一環で非エンジニアに説明をする機会があり、その違いを簡単にまとめたのでQiitaでも書いてみようと思った。
(Flowchart使えよ、というツッコミはなしで………)
TL;DR
__上手に使えば__AndAlso/OrElseは効果的かな、と思った
それぞれの比較
And/Or
- 結合した要素(変数、数式)を「全部」評価する
- 要素を左側からひとつずつ評価していく過程で、全体の評価結果が確定した場合でも、問答無用で「すべて評価」する
- 全部評価するので、要素の結合順序は問わない。要素同士の可換性がある
- 例えば下記コードは、最終的にすべて同様の評価プロセスを経る
A And B And C
B And C And A
C And B And A
- 要素ごとの評価結果によらず、全部の要素が評価されるため
- 例えば下記コードは、最終的にすべて同様の評価プロセスを経る
AndAlso/OrElse
- 結合した要素を「全部または一部」評価する
- 要素を左側からひとつずつ評価していく過程で、ある要素を評価した段階で全体の評価が確定した場合、「以降の要素を評価しない」
- 場合によって全部の要素を評価しないため、要素の結合順序の影響を受ける。要素同士の可換性はない
- 例えば前述のコードと類似する下記コードは、いずれも評価プロセスが異なる
A AndAlso B AndAlso C
B AndAlso C AndAlso A
C AndAlso B AndAlso A
- 要素ごとの評価結果およびその位置によって、評価されない要素が異なる
- 例えば前述のコードと類似する下記コードは、いずれも評価プロセスが異なる
ケース紹介
自分が使ったのは、下記のようなコードをズボラしたとき。
datarows[]には任意のDataTableに対してselectでDataRowを抽出した結果を入れるけど、その結果がゼロである可能性がある。
if(datarows.count > 0){
if(datarows(0).item("total") < 0){
console.write(datarows(0)("label").toString);
}
}
上記のようにネストされたIfを外したいときに、下記のように書くとエラーが起こる。
if(datarows.count > 0 And datarows(0).item("total") < 0){
console.write(datarows(0)("label").toString);
}
なぜなら、結果がゼロであった場合に次のプロセスを踏むから。
-
datarows.count > 0
がfalse
を返す -
And
で結合しているので、上記の結果は次の要素の評価に影響しない - そのためプログラムはそのまま
datarows(0).item("total") < 0
を評価する - しかし
datarows(0)
はnull
であり、上記の文はエラーとなる - したがってifの条件判定においてエラーが発生する
これが、AndAlso
に置き換えるとどうなるか。
if(datarows.count > 0 AndAlso datarows(0).item("total") < 0){
console.write(datarows(0)("label").toString);
}
-
datarows.count > 0
がfalse
を返す- (
datarows.count = 0
)、datarows(0)
はnull
になる
- (
-
AndAlso
で結合しているので、上記の結果を元に、結合された文全体を評価する - すでに上記の結果で
false
が出ているため、文全体ではfalse
となることが確定している - 文全体での結果が確定しているため、残りの要素は評価しない
- したがって
datarows(0).item("total") < 0
は評価されないため、エラーとならない
- 2018/11/26
- コメントでのご指摘をもとに修正。