Performance EXCELVBA-一种快速循环一系列范围的方法。查找
我正在执行一个类似于数据库的“类联接”操作,在这个数据库中,我有两个不同的数据集a和B,它们有一些共同的标识符,我们称之为“id”。我的目标是创建第三个数据集C,它由连接id的a和B的交集组成Performance EXCELVBA-一种快速循环一系列范围的方法。查找,performance,vba,excel,Performance,Vba,Excel,我正在执行一个类似于数据库的“类联接”操作,在这个数据库中,我有两个不同的数据集a和B,它们有一些共同的标识符,我们称之为“id”。我的目标是创建第三个数据集C,它由连接id的a和B的交集组成 SELECT a.id, a.some_column, b.another_column FROM a,b WHERE a.id = b.id 我可以在Excel中通过在A的id列中的所有行上循环并执行一个范围来执行相同的操作。为A中的每一行查找B的id列。类似如下: For Each r in
SELECT a.id, a.some_column, b.another_column
FROM a,b
WHERE a.id = b.id
我可以在Excel中通过在A的id列中的所有行上循环并执行一个范围来执行相同的操作。为A中的每一行查找B的id列。类似如下:
For Each r in Worksheet_A.Range(Cells(start_row_a,id_column_a),Cells(end_row_A,id_column_a))
Set found = Worksheet_B.Range(Cells(start_row_b,id_column_b),Cells(end_row_b,id_column_b)).Find(r.Value)
If Not found is Nothing Then
' write stuff to Worksheet_C, e.g. found.Value, found.Offset(0,1).Value, r.Offset(0,-1).Value, etc.
End If
Next r
这很好,但速度很慢。我知道像VB这样的语言中的显式循环相当慢。我的问题是:有没有捷径?我是否错过了更好的实施?关于SO,我能找到的最接近的问题是,但我并不真正理解最佳答案,我也不确定它是否适用于我的场景。您尝试使用。
这将允许您使用示例中的简单SQL语句
样本:
Sub ject()
Dim con As Object: Set con = CreateObject("ADODB.Connection")
Dim rec As Object: Set rec = CreateObject("ADODB.Recordset")
Dim datasource As String
datasource = "C:\Users\user.name\Desktop\TestFolder\Test.xlsx" 'change to suit
Dim sconnect As String
'Connection string used is for Excel 2007 and up
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & datasource & ";" & _
"Extended Properties=""Excel 12.0;HDR=YES"";"
con.Open sconnect
Dim sqlstr As String
sqlstr = "SELECT e.column1, u.column2, e.column3, e.column4 "
sqlstr = sqlstr & "FROM [A$] e " 'from a sheet named A
sqlstr = sqlstr & "INNER JOIN [B$] u " 'compare with a sheet named B
sqlstr = sqlstr & "ON e.id = u.id "
sqlstr = sqlstr & "GROUP BY e.column1, u.column2, e.column3, e.column4 "
rec.Open sqlstr, con, 3, 1
Dim lrow As Long
With Sheets("C") 'Change to suit
.Range("A1").CopyFromRecordset rec
End With
rec.Close: con.Close
Set rec = Nothing: Set con = Nothing
End Sub
这种方法对你来说可能有点新,但我确信它是有效的,而且它确实很快,尽管我没有实际比较速度。
了解和检查链接的连接字符串。
顺便说一句,您可以将数据源设置到运行宏的同一工作簿中
例如:
其中有A和B页以及另一张C页作为输出。HTH.加速这类事情的最重要的方法是知道VBA世界和工作表世界之间的交互是缓慢的,因此您应该将它们保持在最低限度 因此,您应该像这样重构代码:
For Each r in Worksheet_A.Range(Cells(start_row_a,id_column_a),Cells(end_row_A,id_column_a))
Set found = Worksheet_B.Range(Cells(start_row_b,id_column_b),Cells(end_row_b,id_column_b)).Find(r.Value)
If Not found is Nothing Then
' write stuff to Worksheet_C, e.g. found.Value, found.Offset(0,1).Value, r.Offset(0,-1).Value, etc.
End If
Next r
将整个工作表合并到一个数组中
将整个工作表吞并到一个数组中
像现在一样执行for循环工作,但在这些数组上,并写入第三个数组
将整个第三个数组放入工作表中
这是通过使用变体阵列完成的,如下所述:
在标有“在单个操作中读取和写入大块数据”的部分中
重构比看起来更容易,因为数组也采用行和列坐标,就像原始表一样
当然,如果您的表太大,您可能会有内存问题,但是对于今天的RAM大小,它们必须非常非常大才能成为问题