2011-08-10 6 views
40
Function Foo(thiscell As Range) As Boolean 
    Foo = thiscell.hasFormula And (InStr(1, UCase(Split(thiscell.formula, Chr(40))(0)), "bar") > 0) 
End Function 

この関数は、関数に渡されたセルが空であるときに私が悩みを抱えている(。VBAの "And"演算子は、最初の引数がfalseのときに2番目の引数を評価しますか?

場合がある前に、特定のサブストリング(この場合はバー)の存在について試験するために存在しますこのCel.hasFormulaはfalseですが、との後ろのステートメントは評価されています。これにより、実行時に下付き文字が範囲外エラーになります。

VBAは実際にAndの第2引数を評価し続けますか?最初は偽でしたか?

+3

VBAの 'And'演算子は*論理演算子ではなくビット演算子*であるため、短絡しないことに注意してください。参照してください:http://stackoverflow.com/questions/8042744/excel-vba-instr-condition-doesnt-work-with-2-or-more-conditions/8047021#8047021 – jtolle

+3

@jtolle not true - ブール値を返します引数がブール値の場合、ビット単位と論理単位の両方の操作がサポートされます。 (論理が1ビット整数を使用するビット単位の特別なケースだと主張することもできますが、興味があったらマイクロソフトでは短絡がサポートされている可能性があります) –

+0

@Hugh、interesting。今度は、「真= -1」と「False = 0」なので、論理演算をシミュレートしたにもかかわらず、「And」はビット演算子だと仮定しています。しかし、あなたが正しいことは、両方の式がBoolean型であれば、 'And' *は論理演算子です。一方または両方のオペランドが数字の場合はビット単位でしかありません。しかし、どちらか一方または両方が数字ではなくブール値でないことを保証するために、両方の式を評価しなければならないので、短絡できないと思います。だから私は "敏感さ"はまだここで短絡につながっていないと思う。 – jtolle

答えて

51

あなたが探しているのは "短絡評価 "となります。

VBAはありません。

あなたの状況におそらく適応可能なアプローチを見ることができますhere

Ifの代わりにSelect Caseを代入する方法が選択されました。ネストされたIfsを使用する例もあります。

+65

私が働いているときVBAでは、モナリザをクレヨンで描こうとしているような気分になります。 – James

+1

確かに。あなたはC#を使うことができないのは残念です。( –

10

DOK mentioned:いいえ、VBAには短絡の評価がありません。

AND演算子を使用する代わりに2 If-then文を使用するのが技術的に効率的ですが、何度もやっていないと節約に気付かないため、読みやすいものになります。そして、あなたが本当に技術的になりたいのであれば、VBAは複数のIf-then文をSelect Caseより速く扱います。

VBAは風変わりです:)

2

答えはイエスである、VBAはない短絡評価を行います。

これは単なるスタイルの問題ではありません。

If i <= UBound(Arr, 1) And j <= UBound(Arr, 2) And Arr(i, 1) <= UBound(Arr2, 1) Then 
    Arr2(Arr(i, 1), j) = Arr(i, j) 
End If 

...これは間違っています。より適切:

If i <= UBound(Arr, 1) And j <= UBound(Arr, 2) Then 
    If Arr(i, 1) <= UBound(Arr2, 1) Then 
     Arr2(Arr(i, 1), j) = Arr(i, j) 
    End If 
End If 

それとも、ネストされたIFSへの嫌悪感がある場合:

If i > UBound(Arr, 1) Or j > UBound(Arr, 2) Then 
    ' Do Nothing 
ElseIf Arr(i, 1) > UBound(Arr2, 1) Then 
    ' Do Nothing 
Else 
    Arr2(Arr(i, 1), j) = Arr(i, j) 
End If 
1

をVBAが1短絡のような振る舞いを持っています。 通常はNullが式を伝搬します。 3 + NullNullであり、True And NullNullである。しかし :

? False And Null
False

これは短絡行動のように見える - 何が起こっているのか? Nullは、Falseまたは0の接続(And)のもう1つの引数が伝播しても伝播しません。結果はちょうどFalseまたは0です。左か右の引数かどうかは関係ありません。論理和(Or)のもう1つの引数がTrueまたはゼロ以外の整数(浮動小数点値はthis ruleを使用して整数に丸められます)の場合も同様です。

AndOrの引数で副作用とエラーを防ぐことはできませんが、Nullの伝播は「短絡」する可能性があります。この動作はSQLから継承されているようです。

+0

私は迷っています。条件AとBのためにどのように動作するかの例を追加できますか? – Enissay

+0

@Enissayの2つの例は 'And'を使用しています。 –

+0

2つの式が評価され、最初は 'False'を返し、2回目は' True'を返します。ここでは短絡はありません。いくつかの奇妙なキャスティングを行い、一貫して「False」または「Null」のいずれかを返す – stenci

-1

実行しなければならないマシンコードを考えてみましょう。 SFSF場合FDF場合、最速はdffdefedwfその後、後藤MustHave

SkipAB場合は、後藤goneBad

その後、後藤SkipAB

のようなコードの混在の線に沿って...

次のようになります。 DSDAは> 4次にMustHave場合

GoneBad: 出口関数

MustHave: ThisIS =プログラムは、単純なブールテストをするために使用される大きな駆動 場合、または検索...倍の 何千、それによって例えばファイルを実行しなければならないとき

'の唯一のいくつかの瞬間を保存し、真 ない場合はwFF.UsingFileNameMatch次に後藤SkipFileMatch ない場合はwFF.OKFileNameMatch次に後藤BADFILE 0:時間、閉じたワークシートに [コード]

 If Not wFF.UsingFileExtMatch Then GoTo SkipExt 
       If Not wFF.OKFileEXTMatch Then GoTo BADFile 

SkipExtをすべてのシートや名前を見つけることのような機能 を消費をスキップSkipFileMatch: ない場合はwFF.UsingDaysAgo次に後藤SkipDaysAgo ない場合はwFF.OKDaysAgo次に後藤BADFILE SkipDaysAgo:

[/コード]

0

私はこれが最善の方法だと思う:

sub my conditions() 
     If Condition1=constraint1 then 
     if Condition2=constraint2 then 
      if condition3=constraint3 then 
      ... 
      .... 
     end if 
     end if 
      end if 
    else 
     end if 
      .... 
    end if 
end sub 

したがって、条件iが満たされている場合に限り、条件を満たすことができます。

+0

5年以上前、最初の条件がfalseだった場合、条件文の 'and'キーワードが' short circuited 'であるかどうかを質問していました。 ? – ppovoski

+0

@ppovoskiうん、本当に – Moreno

関連する問題