1M行的INDEX MATCH数组公式

时间:2015-10-21 01:38:34

标签: sql excel vba excel-vba

我有两组需要根据ID和时间戳匹配的数据(+/- 3个单位从时间转换),下面是我在Excel中用来进行匹配的公式。最近我不得不在Excel中运行多达100万行的这个公式,并且它需要很长时间,也会崩溃。我想知道是否有更快的方法来执行此操作,如果不是在Excel中?

=INDEX(A:A,MATCH(1,--(B:B=E3)*--(ABS(C:C-F3)<=3),0),1)

数据集1: A栏:国家 B列:ID C列:时间戳

数据集2: D栏:电子邮件地址 E栏:ID F列:时间戳

G栏=INDEX(A:A,MATCH(1,--(B:B=E3)*--(ABS(C:C-F3)<=3),0),1)

目标:将“状态”列附加到与ID匹配的数据集2和时间戳(+/- 3个时间单位)匹配。

只是不知道如何在非常大的数据集上运行此公式。

2 个答案:

答案 0 :(得分:1)

将以下VBA例程放在标准代码模块中。

运行MIAB1290()例程。

这模拟了INDEX / MATCH公式的精确结果,但效率更高。在我的计算机上,一百万条记录正确关联,结果显示在 G列中仅需10秒钟。

Public Sub MIAB1290()

    Dim lastB&, k&, e, f, z, v, w, vErr, r As Range

    With [a2]
        Set r = .Resize(.Item(.Parent.Rows.Count - .Row + 1, 5).End(xlUp).Row - .Row + 1, .Item(, .Parent.Columns.Count - .Column + 1).End(xlToLeft).Column - .Column + 1)
        lastB = .Item(.Parent.Rows.Count - .Row + 1, 2).End(xlUp).Row - .Row + 1
    End With

    With r
        .Worksheet.Sort.SortFields.Clear
        .Sort Key1:=.Item(1, 2), Order1:=1, Key2:=.Item(1, 2), Order2:=1, Header:=xlYes
        v = .Value2
    End With

    ReDim w(1 To UBound(v), 1 To 1)
    vErr = CVErr(xlErrNA)

    For k = 2 To UBound(v)
        e = v(k, 5)
        f = v(k, 6)
        w(k, 1) = vErr
        z = BSearch(v, 2, e, 1, lastB)
        If z Then
            Do While v(z, 2) = e
                If Abs(v(z, 3) - f) <= 3 Then
                    w(k, 1) = v(z, 1)
                    Exit Do
                End If
                z = z + 1
                If z > UBound(v) Then Exit Do
            Loop
        End If
    Next

    r(1, 8).Resize(r.Rows.Count) = w

End Sub


Private Function BSearch(vA, col&, vVal, ByVal first&, ByVal last&)
    Dim k&, middle&
    While last >= first
        middle = (last + first) / 2
        Select Case True
            Case vVal < vA(middle, col)
                last = middle - 1
            Case vVal > vA(middle, col)
                first = middle + 1
            Case Else
                k = middle - 1
                Do While vA(k, col) = vA(middle, col)
                    k = k - 1
                    If k > last Then Exit Do
                Loop
                BSearch = k + 1
                Exit Function
        End Select
    Wend
    BSearch = 0
End Function

答案 1 :(得分:0)

Excel并不是真正适用于大量数据,并且可能没有代码可以更快地为你做一个内置的excel公式。在这种情况下,我会想你试试PowerPivot插件,看看它是如何处理这种情况的。