【问题标题】:VBA If And multiple conditionsVBA If 和多个条件
【发布时间】:2016-08-29 06:27:26
【问题描述】:

谁能帮助解决我的编码问题? If 语句需要三个单独的条件 = true,否则它会检查下一个 if 语句并循环返回数组中的所有单元格。没有错误,所以很难确定问题,而且我对 VBA 很陌生,所以可能有更好的方法来完成这个。

注意:数组中所需的单元格不是静态的,因此需要查找。

    Sub test()
Dim i As Integer
Dim col1 As Range, col2 As Range, col3 As Range, col4 As Range, col5 As Range, col6 As Range
Dim c1arr, c2arr, c3arr, c4arr, c5arr, c6arr As Variant

Set col1 = ActiveSheet.Cells.find("Reference", , xlValues, xlWhole)
Set col2 = ActiveSheet.Cells.find("Amount", , xlValues, xlWhole)
Set col3 = ActiveSheet.Cells.find("Action", , xlValues, xlWhole)
Set col4 = ActiveSheet.Cells.find("Reference2", , xlValues, xlWhole)
Set col5 = ActiveSheet.Cells.find("Amount2", , xlValues, xlWhole)
Set col6 = ActiveSheet.Cells.find("Action2", , xlValues, xlWhole)

lastrow = Cells(Rows.Count, col1.Column).End(xlUp).Row

c1arr = Range(Cells(2, col1.Column), Cells(lastrow, col1.Column)).Value
c2arr = Range(Cells(2, col2.Column), Cells(lastrow, col2.Column)).Value
c3arr = Range(Cells(2, col3.Column), Cells(lastrow, col3.Column)).Value
c4arr = Range(Cells(2, col4.Column), Cells(lastrow, col4.Column)).Value
c5arr = Range(Cells(2, col5.Column), Cells(lastrow, col5.Column)).Value
c6arr = Range(Cells(2, col6.Column), Cells(lastrow, col6.Column)).Value

For i = 1 To UBound(c1arr)
    If c2arr(i, 1) > 0 And c1arr(i, 1) = c4arr(i, 1) And c2arr(i, 1) = c5arr(i, 1) Then
            c6arr(i, 1) = c3arr(i, 1)
    ElseIf c2arr(i, 1) > 0 And c1arr(i, 1) <> c4arr(i, 1) And c2arr(i, 1) <> c5arr(i, 1) Then
            c6arr(i, 1) = "Manual Review"
    End If
Next

Range(Cells(2, col6.Column), Cells(lastrow, col6.Column)).Value = c6arr
End Sub

UPDATED IMAGE

【问题讨论】:

  • 所以需要一点调试。将光标放在 For i 行并按 F9。然后运行代码。它将停在这条线上。在 VBE 中,您可以在“Locals”窗口中查看所有内容的值。您可以展开所有数组并确保有数据。如果不检查所有其他变量以确保它们返回正确的数字。然后,如果一切正常,按 F8 逐步进行,验证每一步。另外我不相信你想要Exit For 在那里。您还知道您是逐行比较,而不是一个数组中的每个值与其他数组中的所有值进行比较?
  • 您永远不会将c6arr 的内容写回工作表。此外,在您的数据的第 1 行中,c2arr 为负数,因此两个测试都将失败。此外,在您的代码中,c1arr 永远不会等于c4arrc5arr,因此如果c2arr > 0,那么“手动审查”将始终是结果。正如 Scott 所写,如果您通过第一个测试并停止处理其余行,Exit For 将退出循环。您的预期结果似乎也存在错误,因为您有一个 result2 既不是“手动审查”也不是 c3arr 的实例。
  • 所有数据都正确返回。我输入了 Exit For,因为我认为第二个语句可能会覆盖第一个语句。看起来问题就像您指出的那样:逐行比较数组的每个值与另一个值的所有值。这很容易解决吗?
  • @J.T.我希望你的代码能做到这一点。在您的示例中的 NO 实例中,Reference = Reference2 或 Amount = Amount2。
  • 您至少需要一个循环、查找或工作表函数。匹配来做您想做的事情。

标签: vba excel if-statement multiple-conditions


【解决方案1】:

添加了一个额外的循环并分解了 if 逻辑以获得正确的 (?) 行为。

我得到了这些结果...

...从此代码...

Sub test()
Dim i As Integer, j As Integer, lastrow As Long
Dim col1 As Range, col2 As Range, col3 As Range, col4 As Range, col5 As Range, col6 As Range
Dim c1arr, c2arr, c3arr, c4arr, c5arr, c6arr As Variant

    Set col1 = ActiveSheet.Cells.Find("Reference", , xlValues, xlWhole)
    Set col2 = ActiveSheet.Cells.Find("Amount", , xlValues, xlWhole)
    Set col3 = ActiveSheet.Cells.Find("Action", , xlValues, xlWhole)
    Set col4 = ActiveSheet.Cells.Find("Reference2", , xlValues, xlWhole)
    Set col5 = ActiveSheet.Cells.Find("Amount2", , xlValues, xlWhole)
    Set col6 = ActiveSheet.Cells.Find("Action2", , xlValues, xlWhole)

    lastrow = Cells(Rows.Count, col1.Column).End(xlUp).Row

    c1arr = Range(Cells(2, col1.Column), Cells(lastrow, col1.Column)).Value
    c2arr = Range(Cells(2, col2.Column), Cells(lastrow, col2.Column)).Value
    c3arr = Range(Cells(2, col3.Column), Cells(lastrow, col3.Column)).Value

    lastrow = Cells(Rows.Count, col4.Column).End(xlUp).Row

    c4arr = Range(Cells(2, col4.Column), Cells(lastrow, col4.Column)).Value
    c5arr = Range(Cells(2, col5.Column), Cells(lastrow, col5.Column)).Value
    c6arr = Range(Cells(2, col6.Column), Cells(lastrow, col6.Column)).Value

    For i = 1 To UBound(c4arr)
        If c6arr(i, 1) = "" Then ' if already determined an answer, don't try again
            For j = 1 To UBound(c1arr)
                If c1arr(j, 1) = c4arr(i, 1) Then ' found Reference2 within Reference
                    If c2arr(j, 1) = c5arr(i, 1) And c2arr(j, 1) > 0 Then
                        c6arr(i, 1) = c3arr(j, 1)
                    Else
                        c6arr(i, 1) = "Manual Review"
                    End If
                End If
            Next j
        End If
        If c6arr(i, 1) = "" Then ' if haven't found an answer yet, it needs review
            c6arr(i, 1) = "Manual Review"
        End If
    Next i

    Range(Cells(2, col6.Column), Cells(lastrow, col6.Column)).Value = c6arr

End Sub

【讨论】:

    【解决方案2】:

    从您的代码和示例中,我不清楚您何时想在 Action2 中看到“手动审查”。显然,如果 References 匹配但 Amounts 不匹配;但由于这并不包含所有的可能性,这部分代码有点“草率”。在下面的代码中,所有不匹配的实例都将被标记为“手动审查”。如果确实如此,那么代码可以变得更简洁(更快)。

    这是另一种方法,使用WorksheetFunction.Match

    Option Explicit
       Sub test()
    Dim i As Integer, lastrow As Long, J As Long
    Dim col1 As Range, col2 As Range, col3 As Range, col4 As Range, col5 As Range, col6 As Range
    Dim c1arr, c2arr, c3arr, c4arr, c5arr, c6arr As Variant
    
    
    Set col1 = ActiveSheet.Cells.Find("Reference", , xlValues, xlWhole)
    Set col2 = ActiveSheet.Cells.Find("Amount", , xlValues, xlWhole)
    Set col3 = ActiveSheet.Cells.Find("Action", , xlValues, xlWhole)
    Set col4 = ActiveSheet.Cells.Find("Reference2", , xlValues, xlWhole)
    Set col5 = ActiveSheet.Cells.Find("Amount2", , xlValues, xlWhole)
    Set col6 = ActiveSheet.Cells.Find("Action2", , xlValues, xlWhole)
    
    lastrow = Cells(Rows.Count, col1.Column).End(xlUp).Row
    
    c1arr = Range(Cells(2, col1.Column), Cells(lastrow, col1.Column)).Value
    c2arr = Range(Cells(2, col2.Column), Cells(lastrow, col2.Column)).Value
    c3arr = Range(Cells(2, col3.Column), Cells(lastrow, col3.Column)).Value
    c4arr = Range(Cells(2, col4.Column), Cells(lastrow, col4.Column)).Value
    c5arr = Range(Cells(2, col5.Column), Cells(lastrow, col5.Column)).Value
    c6arr = Range(Cells(2, col6.Column), Cells(lastrow, col6.Column)).Value
    
    'Clear c6arr
    ReDim c6arr(1 To UBound(c6arr, 1), 1 To 1)
    
    For i = 1 To UBound(c1arr)
        If c2arr(i, 1) > 0 Then
            On Error Resume Next
                J = WorksheetFunction.Match(c1arr(i, 1), c4arr, 0)
                If Err.Number = 0 Then
                    If c2arr(i, 1) = c5arr(J, 1) Then
                        c6arr(J, 1) = c3arr(i, 1)
                    Else
                        c6arr(J, 1) = "Manual Review"
                    End If
                End If
            On Error GoTo 0
        End If
    Next i
    
    'Fill the blanks
    For i = 1 To UBound(c6arr, 1)
        If c6arr(i, 1) = "" Then c6arr(i, 1) = "Manual Review"
    Next i
    
    Range(Cells(2, col6.Column), Cells(lastrow, col6.Column)).Value = c6arr
    End Sub
    

    这些是使用您最近发布的图片的结果:

    【讨论】:

      猜你喜欢
      • 2017-09-25
      • 2023-03-31
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      相关资源
      最近更新 更多