我正在表演一个像#join; like'操作(类似于数据库),其中我有两个不同的数据集A和B,它们有一些共同的标识符(让我们称之为' id')。我的目标是创建第三个数据集C,它包含A和B的交集(连接id)。在SQL中,相应的查询类似于
SELECT a.id, a.some_column, b.another_column
FROM a,b
WHERE a.id = b.id
我可以在Excel中执行相同的操作,循环遍历A< id id列中的所有行,并在A的每一行上对B&#39}的id列执行Range.Find
这样的事情:
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上找到的最接近的问题是here,但我并不是真正理解最佳答案,而且我不确定它是否适用于我的方案。
答案 0 :(得分:0)
您尝试使用ADO (ActiveX Data Object)
这将允许您使用简单的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
这种方法对您来说可能有点新鲜,但我确定有效且确实很快(虽然我实际上没有比较速度)。
要了解XL 2003 and below和XL 2007 and up的连接字符串,请检查链接
顺便说一下,您可以将数据源设置为运行宏的同一工作簿。
示例:强>
datasource = ThisWorkbook.FullName
您可以在其中输出表格 A 和 B 以及另一张图纸 C 。 HTH。
答案 1 :(得分:0)
加速此类事情的最重要方法是知道“VBA世界”和“工作表世界”之间的交互很慢,因此您应该将它们保持在最低限度。
所以你应该重构你的代码:
这是使用变体数组完成的,如下所示:
http://msdn.microsoft.com/en-us/library/ff726673.aspx#xlFasterVBA
标记为:在单个操作中读取和写入大块数据
重构比看起来容易,因为数组也采用行和列坐标,就像原始表一样。
当然,如果你的桌子太大,你可能会遇到内存问题,但是对于今天的RAM大小,它们必须非常非常大,才能成为一个问题......