在Excel VBA中使用多个条件搜索记录

时间:2012-10-01 06:13:29

标签: excel excel-vba vba

我搜索了很多博客,但仍然无法找到有效的解决方案。 请帮我。

我有像这样的工作表数据

Recipie Ingredient      No of Grams     Ingredient Cost  
A10     OREGANO          0.25 gr        10  
A10     OSTUR           60.00 gr        11  
A10     SÓSA            65.50 gr        14  
Á10     HAKK            38.00 gr        18  

如果已经存在成分,我想更新食谱的成分成本。 否则我需要插入一条新记录。

我可以通过使用简单的for循环并检查匹配配方然后在该配方中搜索成分并更新来完成此操作。我试过这个,这很好用。 我的问题是当没有行增加到10K时,搜索将逐个运行所有10K行。

我正在寻找解决方案,它允许我通过在搜索中指定多个列来搜索记录,直接找到该单个记录而不是扫描每一行。

在自动过滤器中,过滤器发生在后台,当宏运行时,我能够看到 过滤器正在发生。我希望工作表显示所有记录。

请帮帮我。

数据结构如下。

4 个答案:

答案 0 :(得分:0)

正如我在上面的评论中所说,这是您应该访问的典型功能(即使您更喜欢使用Excel作为前端)。我上面看到的是一个表结构,要求在被送到电子表格之前查询食物。

MS Access允许您根据索引创建索引和搜索,这样可以在您有许多记录时显着提高性能。 (系统将根据索引记录进行搜索,而不是需要遍历每条记录)。如果你在谈论一个有10K记录的表,我怀疑Access毫无疑问更好。

虽然我不推荐它,但您可以通过向文件添加库引用,将Excel工作表视为使用ADODB或DAO(Access使用本机DAO)的数据库表。 这样,您就可以使用SQL在数据表上执行所有CRUD操作 我之所以不推荐它,是因为Excel并不意味着被RDBMS取代(例如,不支持关系数据库结构,这使得它更难以支持,这使得您需要管理您的参考/通过VBA或手动完成数据完整性 学习如何在Access中做一些基本的事情可能需要1天,但通过编程所有内容(包括检查和从另一个表格中检索数据等)来维护这个系统可能会让你永远。

此外:
代码缓慢的原因是因为我怀疑您从Excel工作表中每行显式读取并检查每条记录。
如果您仍希望使用循环更快地运行此代码,则需要将整个范围读入数组并通过循环遍历数组在内存中执行检查。
我怀疑代码执行是可以接受的,但您可以通过设置计时器来检查其性能,并在状态栏(application.statusbar)上显示计数器的进度的其他通知。

答案 1 :(得分:0)

使用Find方法而不是循环可能会有很多运气但是这些天我发现自己越来越多地使用Dictionary对象,特别是对于像这样的任务。您需要从“工具”菜单中启用“Microsoft Scripting Runtime”作为参考,然后它很简单:

Dim dCompare As New Dictionary 
....
For i = 2 To bottomRow
    dCompare.Add (Worksheets("...").Range("L" & i).value & Worksheets("...").Range("I" & i).value), i
Next i

基本上你可以按你想要的方式填写它,但我只是将我需要的工作表值作为键连接起来并将行号作为值。然后进行检索:

Function findCorrelate(ByVal value1, value2 As String) As Long
Dim oppositeRow As Long
    oppositeRow = dCompare.Item(value1 & value2)
findCorrelate = oppositeRow
End Function

你输入了你需要搜索的值(它们一起是键),如果它存在,它将为你输出行号作为值。否则它将返回0(但您可能更喜欢它为-1)。这样你只需要循环一次。至少,你会看到这样做的执行时间显着减少。

答案 2 :(得分:0)

我想提出一些建议: 1.在模块级别将dCompare声明为Dictionary 2.在填写字典的过程中创建一个新的dCompare实例:

Set dCompare = New Dictionary

3.转换为字符串构成KEY CStr(Value1),...

的所有值
  1. 当所有对象不再有用时丢弃它们(引号不起作用???):

    如果不是dCompare什么都没有那么设置dCompare = Nothing

  2. 5.以正确的方式宣布你的论点:

    findCorrelate(ByVal value1 As String, ByVal value2 As String) As Long
    

    而不是:

    我也喜欢使用这个非常强大的对象

答案 3 :(得分:0)

为什么不使用简单的vlookup来查找另一个工作表(或同一工作表中的其他范围)中的成分的价格(每单位)?

这意味着只需要在一个地点更改/添加内容,就需要更新价格或添加成分。这甚至可以手动完成,而不是通过VBA。