VBA:双循环通过大量的数据

我有大量的数据存储在一个csv文件(约60MB),其中有一个名称列表和两个date名称相邻

A1name1 B1date1 C1date2 A2name2 B2date1 C2date2 

我有另一个文件,其中有一个名称列表:

 names1 names2 names3 names4 

例如,我想以names1为例,search名称的大数据库,如果find了names1,则返回date1和date2。 我已经做了这个使用双循环。 伪代码如下:

 For i = 1 to SMLendofrow for j = 1 to LRGendofrow if cells(i,"A").value = lrgwkbook.wrksheet.cells(j,"A").value then cells(i,"B").value =lrgwkbook.wrksheet.cells(j,"B").Value cells(i,"C").value =lrgwkbook.wrksheet.cells(j,"C").Value end if next j next i 

现在这个代码完美的工作,但它只是太长。 由于所有名字的大型工作簿非常大,大约需要10分钟左右才能search到。 这是一个更有效的方法吗? 我已经使用python作为替代,并在2分钟内完成它,但我想与VBA特别的东西。

谢谢

依靠。 如果第二个文件中的内存大小和名称数量允许,则'Idbuild议为较大的文件设置一个循环,将name – date1和name – date2键值对分别推送到两个字典(或其他语言,hash表),当它完成时,一个单独的循环(不embedded到另一个循环中)处理另一个文件,并从两个哈希中获取名称。

您必须在项目中引用microsoft.scripting.runtime。

将CSV文件转换为MDB(Access数据库),然后连接此数据库并执行必要的操作。 它比上面的方法工作得更快。 注意:如果对CSV文件进行更改,则每次都需要从CSV重新创buildMDB

您可以使用Match函数,它将为您节省内部循环(以及许多宝贵的运行时间),请参阅下面的代码(只需要修改部分)

 Dim MatchRow As Long Dim SearchedRng As Range ' set the range for "Match" all active rows and columns >> modify as needed ' I assumed "LRGendofrow" is the last row Set SearchedRng = lrgwkbook.wrksheet.Range("A1:C" & LRGendofrow) For i = 1 To SMLendofrow ' For j = 1 To LRGendofrow If Not IsError(Application.Match(Cells(i, "A").Value, SearchedRng, 0)) Then MatchRow = Application.Match(Cells(i, "A").Value, SearchedRng, 0) Cells(i, "B").Value = lrgwkbook.wrksheet.Cells(MatchRow, "B").Value Cells(i, "C").Value = lrgwkbook.wrksheet.Cells(MatchRow, "C").Value Else ' "names" record not found >> do something ' in my example I put #NA in cells, to know it's not found Cells(i, "B") = CVErr(xlErrNA) Cells(i, "C") = CVErr(xlErrNA) End If Next i 

为了避免内部(和更大的)循环,你可以使用下面的代码:

 Option Explicit Sub main() Dim namesRng As Range Dim f As Range, cell As Range With Worksheets("Names") '<-- change "Names" with actual name of your sheet with the list of names Set namesRng = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)) '<--| get the list of names form cell A1 down to last non empty row End With With Workbooks.Open("C:\Users\...\data.csv").Worksheets(1).UsedRange.Columns(1) '<-- open your CSV file and refer to "used" cells in its column "A" For Each cell In namesRng '<-- loop through names list Set f = .Find(what:=cell.value, LookIn:=xlValues, lookat:=xlWhole) '<-- try finding current name in referenced range of csv file If Not f Is Nothing Then cell.Offset(, 1).Resize(, 2).value = f.Offset(, 1).Resize(, 2).value '<--| if found, then write its two adjacent cells values next to current name ones Next cell End With ActiveWorkbook.Close False End Sub