我有两组需要根据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个时间单位)匹配。
只是不知道如何在非常大的数据集上运行此公式。
答案 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插件,看看它是如何处理这种情况的。