2011-08-10 37 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「和」運算符是否會評估第二個參數?

我在使用是麻煩時,傳遞到該函數的單元是空的殼體存在,以測試特定子串的存在(欄,在這種情況下) ,thisCell.hasFormula是錯誤的,但是在和之後的語句仍然被評估,這給我一個下標超出了運行時的範圍錯誤

是否VBA實際上繼續評估第二個參數和,首先是假的?

+3

請注意,VBA的'And'運算符不會短路,因爲它是*位運算符而不是*邏輯*運算符。請參閱:http://stackoverflow.com/questions/8042744/excel-vba-instr-condition-doesnt-work-with-2-or-more-conditions/8047021#8047021 – jtolle

+3

@jtolle不正確 - 它將返回一個布爾值如果它的參數是布爾值,那麼它支持按位和邏輯運算。 (當然,你可能會認爲邏輯是一種使用1位整數的特殊情況,但重點是如果他們選擇微軟可能會支持短路) –

+0

@Hugh,有趣。我一直假設'And'只是一個按位運算符,儘管模擬邏輯運算是因爲'True = -1'和'False = 0'。但是你是對的,如果傳遞給它的表達式都是布爾型的,則'*'是一個邏輯運算符。如果一個或兩個操作數都是數字,它只是按位進行的。但我想它不能短路,因爲無論如何都必須對兩個表達式進行評估,以確保其中一個或兩個不是數字而不是布爾值。所以我認爲「比特級」仍然會導致這裏沒有短路。 – jtolle

回答

51

你在找什麼叫做「短路評估「。

VBA沒有它。

您可以看到一種可能適用於您的情況的方法here

在那裏選擇的方法涉及用Select Case代替If。還有一個使用嵌套的示例Ifs

+65

當我在工作時用VBA它開始感覺我想用蠟筆畫出蒙娜麗莎。 – James

+1

確實。太糟糕了,你不能使用C#而是:( –

10

作爲DOK mentioned:否,VBA沒有短路評估。

使用2 If-then聲明而不是使用AND運算符在技術上效率更高,但除非您多次執行此操作,否則您不會注意到節省,因此請選擇更具可讀性的內容。如果你想獲得真正的技術,VBA也可以比Select Case更快地處理多個If-then語句。

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確實有一個短路的行爲。 通常Null通過表達式傳播,例如。 3 + NullNullTrue And NullNull。 不過:

? False And Null
False

這看起來像短路行爲 - 這是怎麼回事?當聯合(And)的另一個參數是False0時,Null不會傳播 - 結果僅爲False0。它是左或右參數無關緊要。如果析取的另一個參數(Or)爲True或非零整數(浮點值將使用this rule四捨五入爲整數),則情況也是如此。

因此,在AndOr的參數中不能防止副作用和錯誤,但Null傳播可以「短路」。這種行爲似乎是從SQL繼承。

+0

嗯,我迷路了,你可以添加一個例子說明它是如何工作的條件'A和B' – Enissay

+0

@ Enissay我的例子中有兩個使用'And'。你可以更好地解釋一下你感到困惑嗎? –

+0

這與短路行爲無關,兩個表達式被評估,第一個返回False,第二個返回True,這裏沒有短路,然後VBA做了一些奇怪的投射並且不一致地返回了'假'或'空' – stenci

-1

考慮必須運行的機器代碼。 最快的應該是沿着類似的代碼混合的線...

如果SFSF然後轉到SkipAB

如果FDF然後轉到goneBad

如果dffdefedwf然後轉到MustHave

SkipAB: 如果DSDA> 4然後MustHave

GoneBad: 退出功能

MustHave: THISIS =真

'不僅節省了片刻,當程序有通過它 數千次運行...如文件搜索大驅動 或當一個簡單的布爾測試用於跳過一個耗時函數 比如尋找所有的片材和名稱在一個封閉的工作表 [代碼]

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

SkipExt: 如果不wFF.UsingFileNameMatch然後轉到SkipFileMatch 如果不wFF.OKFileNameMatch然後轉到BADFILE 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年前,OP詢問條件語句中的「和」關鍵字是否「短路」,如果第一個條件是錯誤的,您是否回答了這個問題? – ppovoski

+0

@ppovoski yep我真的是 – Moreno

相關問題