19

Ifステートメント内で「And」と「Or」を使用しようとしています。構文が間違っている可能性があります。

データがtrueになるはずのときに、結果はfalseに戻ります。コードは次のとおりです。

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

'do things here

End If

-デバッグしてこの行に到達すると、それを飛び越えて入力しません。

-origNumは実際には"006260006"およびcreditOrDebit="D"に等しくなります。

-したがって、「Or」ステートメントが機能していないと想定しています。

-うまくいけば、これは簡単な質問です。ありがとう!

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のいずれかがtrueの場合、ステートメントは実行されません)?

于 2012-06-20T15:48:30.640 に答える
3

これは答えではありませんが、コメントするには長すぎます。

JPの回答/コメントに応えて、2つの方法のパフォーマンスを比較するために次のテストを実行しました。オブジェクトは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ループの場合はms単位):

2012年6月20日19
:28:25nested_ifs(x1):156-最終実行:156-平均実行:156
or_and(x1):125-最終実行:125-平均実行:125

2012年6月20日19
:28:26nested_ifs(x1):156-最終実行:156-平均実行:156
or_and(x1):125-最終実行:125-平均実行:125

2012年6月20日19
:28:27nested_ifs(x1):140-最終実行:140-平均実行:140
or_and(x1):125-最終実行:125-平均実行:125

2012年6月20日19
:28:28nested_ifs(x1):140-最終実行:140-平均実行:140
or_and(x1):141-最終実行:141-平均実行:141

2012年6月20日19
:28:29nested_ifs(x1):156-最終実行:156-平均実行:156
or_and(x1):125-最終実行:125-平均実行:125

ノート

そうcreditOrDebitでない場合"D"、JPのコードはより高速に実行されます(or / andコードの125msに対して約60ms)。

于 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%の時間しか速くなりません。ただし、速度が遅い場合は、表面的にのみ遅くなります。しかし、 assyliascreditOrDebitが指摘したように、の場合<>"D"、私の手順は少なくとも2倍速くなります。1億回の反復で合理的にテストすることができました。

そしてそれが私がそれをリファクタリングした理由です-ロジックを短絡して、origNumいつ評価する必要がないようにするためcreditOrDebit <> "D"です。

この時点で、残りはOPのスプレッドシートに依存します。creditOrDebitDに等しい可能性が高い場合は、通常はより高速に実行されるため、 assyliasの手順を使用します。ただしcreditOrDebit、可能な値の範囲が広くD、ターゲット値になる可能性が低い場合、私の手順ではそれを利用して、他の変数を不必要に評価することを防ぎます。

于 2012-06-20T16:27:30.833 に答える