excel 在另一个VBA中查找一个列的元素的最快方法

mwg9r5ms  于 2023-05-30  发布在  其他
关注(0)|答案(2)|浏览(252)

我实现的一个算法的一部分是比较不同列表的两列,如果找到匹配的值,就将这些行复制到一起,我想知道最快的方法。目前,它比较了大约100-150行彼此和它需要大约3分钟,有时更多,我觉得这是相当可怕的。这就提出了一个问题,如果有比Range.Find()更快的方法,那么知道这个方法使用的搜索算法也会很有趣。
我是VBA的新手,开始使用它是出于必要,我是一个工作的学生,来自C/#和Python,所以我绝不是Maven,也许我的期望太高了。文件保存在服务器上,这样可能会增加运行时间,但我不确定有多少因素。
我的代码的相关部分看起来像这样:

  1. For Each LineA In sheet1.Range("B1:B" & LastRowSheet1)
  2. Set LineB = sheet2.Range("B1:B" & LastRowSheet2).Find(LineA.Value, LookIn:=xlValues)
  3. If Not LineB Is Nothing Then
  4. With sheet2
  5. .Range(.Cells(LineB.Row, 3), .Cells(LineB.Row, 12)).Copy sheet3.Range(sheet3.Cells(i, 4), sheet3.Cells(i, 13))
  6. End With
  7. With sheet1
  8. .Range(.Cells(LineA.Row, 2), .Cells(LineA.Row, 4)).Copy sheet3.Range(sheet3.Cells(i, 1), sheet3.Cells(i, 3))
  9. End With
  10. i = i + 1
  11. End If
  12. Next LineA
  13. (changed variable names from my code, so if something doesn't make sense, tell me)
a1o7rhls

a1o7rhls1#

尝试

  1. Sub find()
  2. Dim dataSheet As Worksheet, lookupSheet As Worksheet, resultSheet As Worksheet
  3. Dim dataRange As Range, lookupRange As Range
  4. Dim dataArray As Variant, lookupArray As Variant
  5. Dim i As Long, j As Long, lastRowData As Long, lastRowLookup As Long, found As Long
  6. Set dataSheet = ThisWorkbook.Worksheets("Sheet1")
  7. Set lookupSheet = ThisWorkbook.Worksheets("Sheet2")
  8. Set resultSheet = ThisWorkbook.Worksheets("Sheet3")
  9. With dataSheet
  10. lastRowData = .Cells(.Rows.Count, "B").End(xlUp).Row
  11. Set dataRange = .Range("B1:B" & lastRowData)
  12. dataArray = dataRange.Value
  13. End With
  14. With lookupSheet
  15. lastRowLookup = .Cells(.Rows.Count, "B").End(xlUp).Row
  16. Set lookupRange = .Range("B1:B" & lastRowLookup)
  17. lookupArray = lookupRange.Value
  18. End With
  19. i = 1
  20. For j = 1 To UBound(dataArray, 1)
  21. found = Application.Match(dataArray(j, 1), lookupArray, 0)
  22. If Not IsError(found) Then
  23. resultSheet.Range("D" & i & ":M" & i).Value = lookupSheet.Range("C" & found & ":L" & found).Value
  24. resultSheet.Range("A" & i & ":C" & i).Value = dataSheet.Range("B" & j & ":D" & j).Value
  25. i = i + 1
  26. End If
  27. Next j
  28. End Sub

复制列格式

  1. Sub CopyColumnFormats()
  2. Dim srcRange As Range
  3. Dim destRange As Range
  4. Dim srcCol As Range
  5. Dim destCol As Range
  6. Dim i As Long
  7. Set srcRange = ThisWorkbook.Worksheets("Sheet2").Range("C1:L1")
  8. Set destRange = ThisWorkbook.Worksheets("Sheet3").Range("D1:M1")
  9. For i = 1 To srcRange.Columns.Count
  10. Set srcCol = srcRange.Columns(i)
  11. Set destCol = destRange.Columns(i)
  12. srcCol.Copy
  13. destCol.PasteSpecial Paste:=xlPasteFormats
  14. Next i
  15. Set srcRange = ThisWorkbook.Worksheets("Sheet1").Range("B1:D1")
  16. Set destRange = ThisWorkbook.Worksheets("Sheet3").Range("A1:C1")
  17. For i = 1 To srcRange.Columns.Count
  18. Set srcCol = srcRange.Columns(i)
  19. Set destCol = destRange.Columns(i)
  20. srcCol.Copy
  21. destCol.PasteSpecial Paste:=xlPasteFormats
  22. Application.CutCopyMode = False
  23. Next i
  24. End Sub
展开查看全部
djp7away

djp7away2#

VBA查询

  1. Sub LookupData()
  2. Const LKP_COLUMN As Long = 1
  3. Const LKP_LEFT_COLUMNS_TO_EXCLUDE As Long = 1
  4. Const SRC_COLUMN As Long = 1
  5. ' Your code...
  6. ' These two lines are just for this code to compile.
  7. Const LastRowSheet2 As Long = 3 ' Lookup
  8. Const LastRowSheet1 As Long = 4 ' Source
  9. Dim lrg As Range: Set lrg = Sheet2.Range("B1:L" & LastRowSheet2) ' 3-12
  10. Dim srg As Range: Set srg = Sheet1.Range("B1:D" & LastRowSheet1) ' 2-4
  11. Dim dfCell As Range: Set dfCell = Sheet3.Range("A2")
  12. ' Write the values from the lookup range to an array.
  13. Dim lrCount As Long: lrCount = lrg.Rows.Count
  14. Dim lcCount As Long: lcCount = lrg.Columns.Count
  15. Dim lData(): lData = lrg.Value
  16. ' Write the unique values ('keys') and their correcesponding
  17. ' row indexes ('items') to a dictionary.
  18. Dim lDict As Object: Set lDict = CreateObject("Scripting.Dictionary")
  19. lDict.CompareMode = vbTextCompare
  20. Dim lr As Long, lStr As String
  21. For lr = 1 To lrCount
  22. lStr = CStr(lData(lr, LKP_COLUMN))
  23. If Len(lStr) > 0 Then
  24. If Not lDict.Exists(lStr) Then
  25. lDict(lStr) = lr
  26. End If
  27. End If
  28. Next lr
  29. ' The source data is also...
  30. Dim srCount As Long: srCount = srg.Rows.Count
  31. Dim scCount As Long: scCount = srg.Columns.Count
  32. ' ... the left part of the destination so write it to an array
  33. ' and resize the array to accommodate the lookup data on the right.
  34. Dim Data(): Data = srg.Value
  35. Dim dcCount As Long:
  36. dcCount = srCount + lrCount - LKP_LEFT_COLUMNS_TO_EXCLUDE
  37. ReDim Preserve Data(1 To srCount, 1 To dcCount)
  38. ' Loop through the source array and write the matching rows
  39. ' to the top of the destination array.
  40. Dim sr As Long, dr As Long, c As Long, sStr As String
  41. For sr = 1 To srCount
  42. sStr = Data(sr, SRC_COLUMN)
  43. If lDict.Exists(sStr) Then ' match found
  44. lr = lDict(sStr) ' retrieve the lookup row
  45. dr = dr + 1
  46. ' Write source.
  47. For c = 1 To scCount
  48. Data(sr, c) = Data(sr, c)
  49. Next c
  50. ' Write lookup.
  51. For c = 1 + LKP_LEFT_COLUMNS_TO_EXCLUDE To lcCount
  52. Data(sr, c + scCount - LKP_LEFT_COLUMNS_TO_EXCLUDE) _
  53. = lData(lr, c)
  54. Next c
  55. End If
  56. Next sr
  57. ' Write the result from the top of the array to the range.
  58. Dim drg As Range: Set drg = dfCell.Resize(dr, dcCount)
  59. drg.Value = Data
  60. ' Clear below.
  61. drg.Resize(drg.Worksheet.Rows.Count - drg.Row - dr + 1).Offset(dr).Clear
  62. ' Inform.
  63. MsgBox "Lookup is done.", vbInformation
  64. End Sub
展开查看全部

相关问题