0

在此处输入图像描述

任何人都可以建议一个 VBA 解决方案来提供帮助吗?我正在尝试将一行数据(多个标准)与同一数据集中的其他行进行比较,然后用标识符对其进行标记以供以后使用。这是一个更大的 VBA 代码项目的一部分,我正在寻找一种方法来尽可能有效地比较数据,因为数据可能超过 10K 行。到目前为止,我使用 if/then 数组尝试的所有操作都不会产生所需的结果,并且会将行与自身进行比较,这是不必要的。我不精通 VBA,所以可能忽略了一个简单的解决方案。

示例代码尝试和附加数据。任何帮助是极大的赞赏。

Arr1 = WS.ListObjects("mockdata").DataBodyRange.Value
For i = 1 To UBound(Arr1)
    If Arr1(i, 1) = "AC" Then
        For j = 1 To UBound(Arr1)
            'concat doctype/reference/amount for comparison
            If Arr1(i, 1) & Arr1(i, 4) & Arr1(i, 3) = Arr1(j, 1) & Arr1(j, 4) & Arr1(j, 3) * -1 Then
                Arr1(i, 7) = "ZD"
            ElseIf Arr1(i, 1) & Arr1(i, 4) & Arr1(i, 3) <> Arr1(j, 1) & Arr1(j, 4) & Arr1(j, 3) * -1 Then
                Arr1(i, 7) = "CFWD"
            End If
            Exit For
        Next j
    ElseIf Arr1(i, 1) = "XJ" Then
        For j = 1 To UBound(Arr1)
            If Arr1(j, 1) = "PY" Then
                For k = 1 To UBound(Arr1)
                    'concat reference/co for comparison
                    If Arr1(i, 4) & Arr1(i, 5) = Arr1(k, 4) & Arr1(k, 5) And Arr1(i, 3) + Arr1(k, 3) = "0" Then
                        Arr1(i, 7) = "ZD"
                    ElseIf Arr1(i, 4) & Arr1(i, 5) = Arr1(k, 4) & Arr1(k, 5) And Arr1(i, 3) + Arr1(k, 3) <> "0" Then
                        Arr1(i, 7) = "Variance"
                    'if ref match but co does not
                    ElseIf Arr1(i, 4) = Arr1(k, 4) And Arr1(i, 3) + Arr1(k, 3) = "0" And Arr1(1, 5) <> Arr1(k, 5) Then
                        Arr1(i, 7) = "Cross Co"
                    ElseIf Arr1(i, 4) = Arr1(k, 4) And Arr1(i, 3) + Arr1(k, 3) <> "0" And Arr1(1, 5) <> Arr1(k, 5) Then
                        Arr1(i, 7) = "Cross Co/Variance"
                    End If
                Next k
            End If
        Next j
    ElseIf Arr1(i, 1) = "PY" Then
        For j = 1 To UBound(Arr1)
            If Arr1(j, 1) = "XJ" Then
                For k = 1 To UBound(Arr1)
                    'concat reference/co for comparison
                    If Arr1(i, 4) & Arr1(i, 5) = Arr1(k, 4) & Arr1(k, 5) And Arr1(i, 3) + Arr1(k, 3) = "0" Then
                        Arr1(i, 7) = "ZD"
                    ElseIf Arr1(i, 4) & Arr1(i, 5) = Arr1(k, 4) & Arr1(k, 5) And Arr1(i, 3) + Arr1(k, 3) <> "0" Then
                        Arr1(i, 7) = "Variance"
                    'if ref match but co does not
                    ElseIf Arr1(i, 4) = Arr1(k, 4) And Arr1(i, 3) + Arr1(k, 3) = "0" And Arr1(1, 5) <> Arr1(k, 5) Then
                        Arr1(i, 7) = "Cross Co"
                    ElseIf Arr1(i, 4) = Arr1(k, 4) And Arr1(i, 3) + Arr1(k, 3) <> "0" And Arr1(1, 5) <> Arr1(k, 5) Then
                        Arr1(i, 7) = "Cross Co/Variance"
                    End If
                Next k
            End If
        Next j
    End If
Next i
Range("A2").Resize(UBound(Arr1, 1), 7).Value = Arr1
4

1 回答 1

2

原始答案将保留在下面,但这是该数据集的工作版本。但是,您的原始代码中缺少一些东西:没有检查以生成 XJ 类型的“CFWD”,就像您想要的结果显示的那样,所以您仍然需要解决这个问题。同样在您的 AC 中,您没有选择会返回 ZD 结果

Sub RUNME()

arr1 = Sheet1.ListObjects("mockdata").DataBodyRange.Value
For i = 1 To UBound(arr1)
If arr1(i, 1) = "AC" Then
    For j = 1 To UBound(arr1)
        'concat doctype/reference/amount for comparison
        If arr1(i, 1) & arr1(i, 4) & arr1(i, 3) = arr1(j, 1) & arr1(j, 4) & arr1(j, 3) * -1 Then
            arr1(i, 7) = "ZD"
        
        ElseIf arr1(i, 1) & arr1(i, 4) & arr1(i, 3) <> arr1(j, 1) & arr1(j, 4) & arr1(j, 3) * -1 Then
            arr1(i, 7) = "CFWD"
        End If
        Exit For
    Next j
ElseIf arr1(i, 1) = "XJ" Then
    For j = 1 To UBound(arr1)
        If arr1(j, 1) = "PY" Then
            If j = i Then
                'skip this line we don't need to compare to itself
            Else
                If arr1(i, 4) & arr1(i, 5) = arr1(j, 4) & arr1(j, 5) Then
                    If arr1(i, 3) + arr1(j, 3) <> "0" Then
                        arr1(i, 7) = "Variance"
                    ElseIf arr1(i, 3) + arr1(j, 3) = "0" Then
                        arr1(i, 7) = "ZD"
                    End If
                ElseIf arr1(i, 4) = arr1(j, 4) Then
                    If arr1(i, 5) <> arr1(j, 5) Then
                        If arr1(i, 3) + arr1(j, 3) <> 0 Then
                            arr1(i, 7) = "Cross Co"
                        ElseIf arr1(i, 3) + arr1(j, 3) = 0 Then
                            arr1(i, 7) = "Cross Co/Variance"
                        End If
                    End If
                End If
            End If
        End If
    Next j
ElseIf arr1(i, 1) = "PY" Then
    For j = 1 To UBound(arr1)
        If arr1(j, 1) = "XJ" Then
            If j = i Then
                'skip this line we don't need to compare to itself
            Else
                If arr1(i, 4) & arr1(i, 5) = arr1(j, 4) & arr1(j, 5) Then
                    If arr1(i, 3) + arr1(j, 3) <> "0" Then
                        arr1(i, 7) = "Variance"
                    ElseIf arr1(i, 3) + arr1(j, 3) = "0" Then
                        arr1(i, 7) = "ZD"
                    End If
                ElseIf arr1(i, 4) = arr1(j, 4) Then
                    If arr1(i, 5) <> arr1(j, 5) Then
                        If arr1(i, 3) + arr1(j, 3) <> 0 Then
                            arr1(i, 7) = "Cross Co"
                        ElseIf arr1(i, 3) + arr1(j, 3) = 0 Then
                            arr1(i, 7) = "Cross Co/Variance"
                        End If
                    End If
                End If
            End If
        End If
    Next j
End If
Next i
Range("A2").Resize(UBound(arr1, 1), 7).Value = arr1
End Sub

原答案如下

你的逻辑有缺陷。

每当您进行一组比较(此处的 if 语句)并且您正在检查除了单个 true 条件之外的双重 true 条件时,您需要首先检查您的双重 true,否则您的单一 true 将结束比较并且您会得到你得到的结果。

如果我们有 2 列,则简化:

x - 真 y - 真

如果我们做了以下事情:

if x = True then
    b = Yes
elseif x = true and y = true
    b = YesYes
end if

代码将在第一次检查后退出,并且永远不会评估 elseif

您需要相应地重新排序 If 语句。我正在尝试为您解决问题,但我并没有真正遵循您的逻辑检查 - 如果您能澄清这一点,我可以再看一遍。

我也不确定您是否需要深入 3 个循环。

我确实通过以下方式获得了它:

    ElseIf Arr1(i, 1) = "XJ" Then
    For j = 1 To UBound(Arr1)
        If Arr1(j, 1) = "PY" Then
            For k = 1 To UBound(Arr1)
                'concat reference/co for comparison
                
                If Arr1(i, 4) = Arr1(k, 4) Then
                    If Arr1(i, 3) + Arr1(k, 3) = "0" And Arr1(1, 5) <> Arr1(k, 5) Then
                        Arr1(i, 7) = "Cross Co"
                    ElseIf Arr1(i, 3) + Arr1(k, 3) <> "0" And Arr1(1, 5) <> Arr1(k, 5) Then
                        Arr1(i, 7) = "Cross Co/Variance"
                    End If
                ElseIf Arr1(i, 4) & Arr1(i, 5) = Arr1(k, 4) & Arr1(k, 5) Then
                    If Arr1(i, 3) + Arr1(k, 3) <> "0" Then
                        Arr1(i, 7) = "Variance"
                    ElseIf Arr1(i, 3) + Arr1(k, 3) = "0" Then
                        Arr1(i, 7) = "ZD"
                    End If
                End If
            Next k
        End If
    Next j

与其进行 5 次比较并失败,然后再进行 5 次比较,不如将其分解并做一个,然后再做另一个较小的集合。它可能有助于加快整个过程

编辑:多看一下,我看不到您当前的“方差”条件将在您的示例数据集中得到满足的情况。

ElseIf Arr1(i, 4) & Arr1(i, 5) = Arr1(k, 4) & Arr1(k, 5) And Arr1(i, 3) + Arr1(k, 3) <> "0" Then
                   Arr1(i, 7) = "Variance"

您想要获得方差的行是第 15 行和第 9 行

Arr1(9,4) & Arr1(9,5) 将给出“781498071220055”

Arr1(15,4) & Arr1(15,5) 将给出“781498071220008”

于 2020-08-18T16:56:23.417 回答