ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 郁孤亭

[求助] 如何用vba实现模糊查找

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-31 10:55 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
zhaogang1960 发表于 2012-7-30 23:05
请看附件

查帮助大概看懂了find法,做了个注释
有个问题,这个算法没有匹配度
我想做到:
完全匹配的排在最前,不完全匹配的排在后面
同匹配度的按照本来顺序(原来的姓名是有序的,所以查找结果在同匹配度内无需重新排序)。
Sub Find法()
    Dim c As Range, firstAddress$, arr(), m&
ReDim arr(1 To [a65536].End(xlUp).Row, 1 To 1)
【重定义数组大小。这里1to1是干啥的?这是个一维数组吧?
【[a65536].End(xlUp).Row,a列最后一个非空单元格的行号   
With Range("a:a")
        Set c = .Find([c1], , , 2)【部分匹配查找,返回单元格区域
        If Not c Is Nothing Then
            firstAddress = c.Address【单元格位置
            Do
                m = m + 1【m定义后默认初始化为0?
                arr(m, 1) = c.Offset(, 1)【区域偏移,返回匹配首字母对应的姓名
                Set c = .FindNext(c)【从当前匹配单元格后面开始,继续查找
            Loop While Not c Is Nothing And c.Address <> firstAddress【在找不到目标,或从头开始重新查找之前,循环
        End If
    End With
    Range("d2:d65536").ClearContents
    If m > 0 Then [d2].Resize(m) = arr【d[2]……d[m+1]=arr(i)
End Sub

TA的精华主题

TA的得分主题

发表于 2012-7-31 11:09 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
郁孤亭 发表于 2012-7-31 10:55
查帮助大概看懂了find法,做了个注释
有个问题,这个算法没有匹配度
我想做到:

ReDim arr(1 To [a65536].End(xlUp).Row, 1 To 1)中的1 to 1是定义数组为只有一列的二维数组,为了避开使用Transpose函数转置,以加快速度

TA的精华主题

TA的得分主题

发表于 2012-7-31 11:14 | 显示全部楼层
全匹配的在前,部分匹配的在后面:
  1. Sub Find法()
  2.     Dim c As Range, firstAddress$, arr(), brr(), m&, n&, temp$
  3.     temp = [c1]
  4.     ReDim arr(1 To [a65536].End(xlUp).Row, 1 To 1)
  5.     ReDim brr(1 To [a65536].End(xlUp).Row, 1 To 1)
  6.     With Range("a:a")
  7.         Set c = .Find(temp, , , 2)
  8.         If Not c Is Nothing Then
  9.             firstAddress = c.Address
  10.             Do
  11.                 If c.Value = temp Then
  12.                     m = m + 1
  13.                     arr(m, 1) = c.Offset(, 1)
  14.                 Else
  15.                     n = n + 1
  16.                     brr(n, 1) = c.Offset(, 1)
  17.                 End If
  18.                 Set c = .FindNext(c)
  19.             Loop While Not c Is Nothing And c.Address <> firstAddress
  20.         End If
  21.     End With
  22.     Range("d2:d65536").ClearContents
  23.     If m > 0 Then [d2].Resize(m) = arr
  24.     If n > 0 Then [d65536].End(xlUp).Offset(1).Resize(n) = brr
  25. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2012-7-31 11:19 | 显示全部楼层
本帖最后由 zhaogang1960 于 2012-7-31 11:20 编辑

优化一下,使用一个数组arr:
  1. Sub Find法()
  2.     Dim c As Range, firstAddress$, arr(), m&, n&, temp$
  3.     temp = [c1]
  4.     n = WorksheetFunction.CountIf(Range("a:a"), temp)
  5.     ReDim arr(1 To [a65536].End(xlUp).Row, 1 To 1)
  6.     With Range("a:a")
  7.         Set c = .Find(temp, , , 2)
  8.         If Not c Is Nothing Then
  9.             firstAddress = c.Address
  10.             Do
  11.                 If c.Value = temp Then
  12.                     m = m + 1
  13.                     arr(m, 1) = c.Offset(, 1)
  14.                 Else
  15.                     n = n + 1
  16.                     arr(n, 1) = c.Offset(, 1)
  17.                 End If
  18.                 Set c = .FindNext(c)
  19.             Loop While Not c Is Nothing And c.Address <> firstAddress
  20.         End If
  21.     End With
  22.     Range("d2:d65536").ClearContents
  23.     If n > 0 Then [d2].Resize(n) = arr
  24. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-31 12:49 | 显示全部楼层
zhaogang1960 发表于 2012-7-31 11:19
优化一下,使用一个数组arr:

这么简单。呵呵。
原来我想得是完全匹配在最前,部分匹配中匹配位置次之(如查找a,找到a*),匹配位置在中间和后面的在最后(如查找a,找到*a*)。那样的话用find好像就不行,或者还要再做一次比较。

不过这样也很好了。谢谢。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-31 13:30 | 显示全部楼层
zhaogang1960 发表于 2012-7-31 11:19
优化一下,使用一个数组arr:

如果输入的查找字段为小写字母,查找结果的前几个是空格。
什么原因呢?想不出来。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-31 13:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
查找之前用VBA.UCase()进行转换,避免了问题
但为什么小写字母会有这个问题呢?

TA的精华主题

TA的得分主题

发表于 2012-7-31 18:00 | 显示全部楼层
郁孤亭 发表于 2012-7-31 12:49
这么简单。呵呵。
原来我想得是完全匹配在最前,部分匹配中匹配位置次之(如查找a,找到a*),匹配位置在 ...

Find方法不支持通配符,可以在不匹配查找后再用Like结合通配符比较

TA的精华主题

TA的得分主题

发表于 2012-7-31 18:01 | 显示全部楼层
郁孤亭 发表于 2012-7-31 13:30
如果输入的查找字段为小写字母,查找结果的前几个是空格。
什么原因呢?想不出来。

没有理解请上传附件说明,Find区分大小写有参数:
MatchCase      Variant 类型,可选。若为 True,则进行区分大小写的查找。默认值为 False。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-31 19:00 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
zhaogang1960 发表于 2012-7-31 18:01
没有理解请上传附件说明,Find区分大小写有参数:
MatchCase      Variant 类型,可选。若为 True,则进 ...

模糊查找.rar (125.15 KB, 下载次数: 580)
如附件,用find法
c1=ax,则结果前面有几个空单元格
c1=AX,则没有

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-15 16:32 , Processed in 0.045580 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表