从列中查找值并快速返回其单元格的行号

我拥有的

我有一个零件号和每个零件供应商的文件。 有1500个零件,每个有大约20个可能的供应商。 为了简单起见,假设零件列在A列,每个供应商之后都占用一列。 供应商的价值是手动input,但并不重要。

在另一张表中,我有一个从Access数据库导入的零件列表。 零件清单是导入的,但不是供应商信息。 在这两种情况下,每个部分只出现一次。

我想做的事

我只是想匹配来自第一张工作表的供应商信息与导入列表中的部分。 现在,我有一个函数可以查看供应商列表中的每个部分,将供应商信息复制到一个数组中,在导入的部分列表中find部件号(总是有唯一的匹配项),并将数组复制到其旁边(与供应商信息里面)。 有用。 不幸的是,find函数每次使用都会显着减慢。 我知道这是通过各种testing的罪魁祸首,我不明白为什么它减慢(从200循环每秒开始,减慢到每秒1和Excel崩溃)。 我可能有某种泄漏? 文件大小始终保持7mb。 这里是:

Function LigneNum(numAHNS As String) As Integer Dim oRange As Range, aCell As Range Dim SearchString As String Set oRange = f_TableMatrice.Range("A1:A1500") SearchString = numAHNS Set aCell = oRange.Find(What:=SearchString, LookIn:=xlValues, _ LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _ MatchCase:=False, SearchFormat:=False) If Not aCell Is Nothing Then 'We have found the number by now: LigneNum = aCell.Row Exit Function Else MsgBox "Un numéro AHNS n'a pas été trouvé: " & SearchString Debug.Print SearchString & " not found!" LigneNum = 0 Exit Function End If End Function 

该函数只是返回find该值的行号,如果找不到,则返回0。

我需要帮助

我想要找出减慢的原因,或者findFind方法的替代品。 我之前用过Find,这是我第一次遇到这种情况。 它最初是从Siddarth Rout的网站上获取的: http : //www.siddharthrout.com/2011/07/14/find-and-findnext-in-excel-vba/奇怪的是它启动不慢,随着时间的推移变得缓慢。

我认为使用匹配可能工作,或者可能转储范围search(部件号)到一个数组,并试图匹配这些与导入的部件号列表可以工作。 我不确定该怎么做,但是我的问题更多的是关于哪一个会更快(只要不到15秒,我真的不在乎),但是从表单中循环1500次1500次就是出了问题)。 有人会build议匹配arrays解决scheme/花费更多的小时来修复我的代码吗?

编辑

这里是从它被调用的循环。 我不认为这是有问题的:

 For Each cellToMatch In rngToMatch Debug.Print cellToMatch.Row 'The cellsToMatch's values are the numbers I want, rngToMatch is the column where they are. For i = 2 To nbSup + 1 infoSup(i - 2) = f_TableMatrice.Cells(cellToMatch.Row, i) Next 'infoSup contains the required supplier data now 'I call the find function here to find the row where the number appears in the imported sheet 'To copy the array nbSup on that line LigneAHNS = LigneNum(cellToMatch.Value) 'This is the Find function If LigneAHNS = 0 Then Exit Sub 'This loop just empties the array in the right line. For i = LBound(infoSup) To UBound(infoSup) f_symix.Cells(LigneAHNS, debutsuppliers + i) = infoSup(i) Next Next 

例如,如果我用LigneAHNS = 20代替LigneAHNS = LigneNum,代码执行速度非常快。 因此泄漏来自查找function本身。

另一种不使用find函数的方法可能是这样的。 首先,将零件ID和他们的行号放入一个脚本字典中。 这些真的很快从查找。 喜欢这个:

 Dim Dict As New Scripting.Dictionary Dim ColA As Variant Lastrow=range("A50000").end(xlUp).Row ColA = Range("A1:A" & LastRow).Value For i = 1 To LastRow Dict.Add ColA(i, 1), i Next i 

为了进一步优化,您可以将Dict声明为公共variables,填充一次,并在查找中多次引用它。 我希望这会比每次执行查找时在一个范围内运行一个cells.find更快。

有关在字典中查找项目的语法,请参阅使用索引/项目编号循环访问Scripting.Dictionary

如果您愿意为您的主要零件表上的每个供应商提供一个单独的列,则只需使用Excel单元格公式就可以实现此function。 然后,您可以使用条件格式来使其更具视觉吸引力。 我已经试过了1500行,这很快。 增加到5000行变得明显慢,但是你说现在只有1500行,所以它应该是合适的。

  • 在表1中,为每个供应商定义一个零件号码栏和一个单独的栏。
  • 为每个供应商创build一个单独的表格,列出A列出的供应商提供的所有零件号码。确保供应商页面上的行按部件号sorting。
  • 将每个供应商表格命名为与表1中显示的相关联的列标题相同。
  • 在Sheet 1的每个供应商栏标题下的每个单元格中分配以下公式:

    = NOT(ISNA(VLOOKUP($ A2,INDIRECT( “ ' ”&B $ 1“' A:A”),1,FALSE)))

下面的屏幕截图显示了这一点以及条件格式,以突出显示哪些供应商拥有哪些部分:

在这里输入图像说明

如果您想要显示供应商提供的数量,则可以在供应商页面上始终在第二列(B)中包含每个部件的最后已知数量,并使用VLOOKUP检索B列而不是A.