ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何利用vba代码通过模糊匹配标识重复数据?

如何利用vba代码通过模糊匹配标识重复数据?

作者:绿色风 分类: 时间:2022-08-17 浏览:107
楼主
kevinchengcw
Q: 如何利用vba代码通过模糊匹配标识重复数据?
A: 问题描述:
实现功能1:C列姓名要求实现,姓名相同或近似相同(前六个字相同)则标注为黄色,认为是重复。
           E列身份证号要求实现,号码相同或仅有一位不同则标注为红色,认为是重复。
           L列联系电话要求实现,号码相同或仅有一位不同则标注为黄色,认为是重复。
实现功能2:把工作表中,一行中所有单元格没有标注背景的行隐藏,(认为不重复则隐藏)
实现代码及解释如下:
  1. Sub test()
  2. Dim Rng As Range, R As Range, Dic As Object, Str$, Str2$, Arr, N&
  3. Set Dic = CreateObject("scripting.dictionary")  '创建字典项目
  4. On Error Resume Next    '设置出错继续执行
  5. Application.ScreenUpdating = False  '关闭屏幕刷新
  6. Rows("2:" & Rows.Count).Interior.ColorIndex = xlNone  '清空原有填充色
  7. For Each Rng In Range("c2:c" & Cells(Rows.Count, "C").End(3).Row)  '循环C列有效数据区
  8.     Str = Left(Rng.Value, 6)  '提取单元格前6位数据
  9.     If Dic.exists(Str) Then Set Dic(Str) = Union(Rng, Dic(Str)) Else Set Dic(Str) = Rng  '如果存在该字典项,则合并当前循环单元格到字典item项,否则添加新字典项目
  10. Next
  11. Arr = Dic.keys  '提取字典的keys到数组
  12. For N = LBound(Arr) To UBound(Arr)  '循环数组各项
  13.     If Dic(Arr(N)).Cells.Count > 1 Then Dic(Arr(N)).Interior.Color = vbYellow  '如果当前循环到的字典key项对应的item项单元格数量大于1,则将对应的单元格底色设置为黄色
  14. Next N
  15. With CreateObject("vbscript.regexp")  '创建正则项目
  16.     .Global = True  '设置全局有效
  17.     For Each Rng In Range("e2:e" & Cells(Rows.Count, "E").End(3).Row)  '外层循环循环E列有效数据区
  18.         If Rng <> "" And Rng.Interior.Color <> vbRed Then  '如果当前循环到的单元格内容不为空且单元格还未填充颜色,则
  19.             Str = Rng.Value  '提取单元格内容
  20.             For N = 1 To Len(Rng.Value)  '循环数据文本各项
  21.                 Str2 = Left(Rng.Value, N - 1) & ".?" & Right(Rng.Value, Len(Rng.Value) - N)  '替换循环到的位置的数据为.?以匹配一个不同或无此字符情况
  22.                 Str = Str & "|" & Str2  '串接生成的匹配规则
  23.             Next
  24.             .Pattern = Str  '设定匹配规则为设定的字符串
  25.             For Each R In Range("e2:e" & Cells(Rows.Count, "E").End(3).Row)  '内层循环循环E列有效数据区
  26.                 If R <> "" And Rng.Address <> R.Address And Abs(Len(R.Value) - Len(Rng.Value)) <= 1 Then  '如果单元格内容不为空且与外层循环单元格当前循环位置不同且与外层循环到的单元格数据长度差在一个字符以内时,则
  27.                     If .test(R.Value) Then  '如果当前规则能与内层循环当前循环到的单元格相匹配,则
  28.                         Rng.Interior.Color = vbRed  '外层循环当前循环到的单元格填充红色
  29.                         R.Interior.Color = vbRed  '内层循环当前循环到的单元格填充红色
  30.                         Exit For  '跳出循环
  31.                     End If
  32.                 End If
  33.             Next R
  34.         End If
  35.     Next Rng
  36.     For Each Rng In Range("l2:l" & Cells(Rows.Count, "l").End(3).Row)  'L列判断模式同上
  37.         If Rng <> "" And Rng.Interior.Color <> vbRed Then
  38.             Str = Rng.Value
  39.             For N = 1 To Len(Rng.Value)
  40.                 Str2 = Left(Rng.Value, N - 1) & ".?" & Right(Rng.Value, Len(Rng.Value) - N)
  41.                 Str = Str & "|" & Str2
  42.             Next
  43.             .Pattern = Str
  44.             For Each R In Range("l2:l" & Cells(Rows.Count, "l").End(3).Row)
  45.                 If R <> "" And Rng.Address <> R.Address And Abs(Len(R.Value) - Len(Rng.Value)) <= 1 Then
  46.                     If .test(R.Value) Then
  47.                         Rng.Interior.Color = vbYellow
  48.                         R.Interior.Color = vbYellow
  49.                         Exit For
  50.                     End If
  51.                 End If
  52.             Next R
  53.         End If
  54.     Next Rng
  55. End With
  56. For Each Rng In Intersect(Rows("2:" & Cells(Rows.Count, 3).End(3).Row), ActiveSheet.UsedRange).Rows  '循环数据区各行
  57.     N = 0  '以变量作为判定开关,初始为0
  58.     For Each R In Rng.Cells  '循环当前循环到的数据区行中的单元格
  59.         If R.Interior.ColorIndex <> xlNone Then  '如果有填充颜色则
  60.             N = 1  '变量赋值为1
  61.             Exit For  '跳出循环
  62.         End If
  63.     Next R
  64.     If N = 0 Then Rng.EntireRow.Hidden = True  '如果变量值为0(即对应行中未发现填充颜色单元格),则对应行隐藏
  65. Next Rng
  66. Application.ScreenUpdating = True  '打开屏幕刷新
  67. Set Dic = Nothing  '清空字典项目
  68. End Sub
模糊匹配:以E2单元格为例子
单元格数据:'653101194706270627'
生成的匹配规则:'653101194706270627'|.?653101194706270627'|'.?53101194706270627'|'6.?3101194706270627'|'65.?101194706270627'|'653.?01194706270627'|'6531.?1194706270627'|'65310.?194706270627'|'653101.?94706270627'|'6531011.?4706270627'|'65310119.?706270627'|'653101194.?06270627'|'6531011947.?6270627'|'65310119470.?270627'|'653101194706.?70627'|'6531011947062.?0627'|'65310119470627.?627'|'653101194706270.?27'|'6531011947062706.?7'|'65310119470627062.?'|'653101194706270627.?
如此即可匹配对应位置上的字符不同或不存在的情况
注:本例中因未出现特殊字符,故未有增加转义字符\的情况,其他情况下使用请酌情调整代码

详见附件及素材源帖。


模糊查重.rar
2楼
fengjiyong
再次谢谢兄台,能在百忙中解决我的问题,兄台辛苦了。要好好学习学习。
3楼
icenotcool


4楼
水星钓鱼
感谢分享
5楼
老糊涂
学习
6楼
月沁烟渚
正好需要这方面的知识,可是怎么下载不了呢?
7楼
335081548
谢谢分享

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap