19

我试图在 If 语句中使用“And”和“Or”。我可能有我的语法错误。

当数据应该使结果为真时,结果返回为假。这是代码:

ElseIf (origNum = "006260006" Or origNum = "30062600006") And creditOrDebit = "D" Then

'do things here

End If

- 当我调试并来到这条线时,它会跳过它并且不会进入。

-origNum 实际上等于“006260006”和 creditOrDebit =“D”。

- 所以我假设我的“或”语句不起作用。

-希望这是一个快速简单的问题。谢谢!

4

3 回答 3

27

问题可能出在其他地方。试试这个代码,例如:

Sub test()

  origNum = "006260006"
  creditOrDebit = "D"

  If (origNum = "006260006" Or origNum = "30062600006") And creditOrDebit = "D" Then
    MsgBox "OK"
  End If

End Sub

你会看到你的Or作品符合预期。您确定您的ElseIf语句已执行(如果之前的任何 if/elseif 为真,则不会执行)?

于 2012-06-20T15:48:30.640 回答
3

这不是答案,但评论太长了。

在回复JP 的回答/评论时,我运行了以下测试来比较两种方法的性能。该Profiler对象是一个自定义类 - 但总的来说,它使用了一个相当准确的 kernel32 函数(Private Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME))。

Sub test()

  Dim origNum As String
  Dim creditOrDebit As String
  Dim b As Boolean
  Dim p As Profiler
  Dim i As Long

  Set p = New_Profiler

  origNum = "30062600006"
  creditOrDebit = "D"

  p.startTimer ("nested_ifs")

  For i = 1 To 1000000

    If creditOrDebit = "D" Then
      If origNum = "006260006" Then
        b = True
      ElseIf origNum = "30062600006" Then
        b = True
      End If
    End If

  Next i

  p.stopTimer ("nested_ifs")
  p.startTimer ("or_and")

  For i = 1 To 1000000

    If (origNum = "006260006" Or origNum = "30062600006") And creditOrDebit = "D" Then
      b = True
    End If

  Next i

  p.stopTimer ("or_and")

  p.printReport

End Sub

5 次运行的结果(以毫秒为单位,1m 循环):

2012 年 6 月 20 日 19:28:25
nested_ifs (x1):156 - 上次运行:156 - 平均运行:156
or_and (x1):125 - 上次运行:125 - 平均运行:125

2012 年 6 月 20 日 19:28:26
nested_ifs (x1):156 - 上次运行:156 - 平均运行:156
or_and (x1):125 - 上次运行:125 - 平均运行:125

2012 年 6 月 20 日 19:28:27
nested_ifs (x1):140 - 上次运行:140 - 平均运行:140
or_and (x1):125 - 上次运行:125 - 平均运行:125

2012 年 6 月 20 日 19:28:28
nested_ifs (x1):140 - 上次运行:140 - 平均运行:140
or_and (x1):141 - 上次运行:141 - 平均运行:141

2012 年 6 月 20 日 19:28:29
nested_ifs (x1):156 - 上次运行:156 - 平均运行:156
or_and (x1):125 - 上次运行:125 - 平均运行:125

笔记

如果creditOrDebit不是"D",JP 的代码运行得更快(大约 60 毫秒,而 or/and 代码为 125 毫秒)。

于 2012-06-20T18:31:24.447 回答
1

我喜欢assylias的回答,但我会重构它如下:

Sub test()

Dim origNum As String
Dim creditOrDebit As String

origNum = "30062600006"
creditOrDebit = "D"

If creditOrDebit = "D" Then
  If origNum = "006260006" Then
    MsgBox "OK"
  ElseIf origNum = "30062600006" Then
    MsgBox "OK"
  End If
End If

End Sub

creditOrDebit这可能会为您节省一些 CPU 周期,因为如果<> "D"检查origNum.

更新:

我使用以下过程来测试我的理论,即我的过程更快:

Public Declare Function timeGetTime Lib "winmm.dll" () As Long

Sub DoTests2()

  Dim startTime1 As Long
  Dim endTime1 As Long
  Dim startTime2 As Long
  Dim endTime2 As Long
  Dim i As Long
  Dim msg As String

  Const numberOfLoops As Long = 10000
  Const origNum As String = "006260006"
  Const creditOrDebit As String = "D"

  startTime1 = timeGetTime
  For i = 1 To numberOfLoops
    If creditOrDebit = "D" Then
      If origNum = "006260006" Then
        ' do something here
        Debug.Print "OK"
      ElseIf origNum = "30062600006" Then
        ' do something here
        Debug.Print "OK"
      End If
    End If
  Next i
  endTime1 = timeGetTime

  startTime2 = timeGetTime
  For i = 1 To numberOfLoops
    If (origNum = "006260006" Or origNum = "30062600006") And _
      creditOrDebit = "D" Then
      ' do something here
      Debug.Print "OK"
    End If
  Next i
  endTime2 = timeGetTime

  msg = "number of iterations: " & numberOfLoops & vbNewLine
  msg = msg & "JP proc: " & Format$((endTime1 - startTime1), "#,###") & _
       " ms" & vbNewLine
  msg = msg & "assylias proc: " & Format$((endTime2 - startTime2), "#,###") & _
       " ms"

  MsgBox msg

End Sub

我的计算机一定很慢,因为与assylias的测试相比,1,000,000 次迭代所花费的时间远不及 ~200 毫秒。我不得不将迭代次数限制在 10,000 次——嘿,我还有其他事情要做 :)

运行上述程序 10 次后,我的程序只快了 20% 的时间。然而,当它变慢时,它只是表面上变慢。然而,正如assylias指出的那样,creditOrDebit<>"D"的过程至少快两倍。我能够在 1 亿次迭代中合理地测试它。

就是我重构它的原因——将逻辑短路,这样origNum就不需要在creditOrDebit <> "D".

此时,其余的取决于 OP 的电子表格。如果creditOrDebit可能等于 D,则使用assylias程序,因为它通常会运行得更快。但是,如果creditOrDebit具有广泛的可能值,并且D不再可能是目标值,我的程序将利用它来防止不必要地评估其他变量。

于 2012-06-20T16:27:30.833 回答