【自定义函数】编码-查询-匹配

守听  论坛元老 | 2025-1-26 11:00:41 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1026|帖子 1026|积分 3078

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
自定义编码匹配

在wps vb情况写一个新的excel函数名为编码匹配,第一个参数指定待匹配文本所在单位格(相对引用),第二个参数指定关键词区域(绝对引用,一行或者一列单位格),第三个参数指定一个自定义编码区域(绝对引用一行或者一列,但是要查抄其长度是否与关键词区域相等,不等则体现错误),完成参数填写以后,将参数2中每个关键词依次在参数1中进行匹配,如果存在则记录其次序,返回值参数3中与改次序相同的自定义编码文本,如果存在多个匹配结果,用逗号隔断后返回
gpt错误是把关键词和编码定义为了String,应该是Variant
改进:跳过关键词的空值,这样引用区域可以预留空间
  1. Function 编码匹配(待匹配文本 As Range, 关键词区域 As Range, 自定义编码区域 As Range) As String
  2.     Dim 关键词() As Variant ' 关键词数组
  3.     Dim 编码() As Variant ' 编码数组
  4.     Dim 匹配结果 As String ' 最终匹配结果
  5.     Dim i As Long ' 循环变量
  6.     Dim 匹配次序 As Collection ' 用于存储匹配次序
  7.     Dim 匹配项 As Variant ' 用于遍历匹配次序集合
  8.     ' 检查关键词区域和自定义编码区域的长度是否相等
  9.     If 关键词区域.Count <> 自定义编码区域.Count Then
  10.         编码匹配 = "错误:关键词区域和自定义编码区域长度不匹配"
  11.         Exit Function
  12.     End If
  13.     ' 将关键词区域和自定义编码区域的值存入数组
  14.     关键词 = 关键词区域.Value
  15.     编码 = 自定义编码区域.Value
  16.     ' 检查待匹配文本是否为空
  17.     If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
  18.         编码匹配 = ""
  19.         Exit Function
  20.     End If
  21.     ' 初始化匹配次序集合
  22.     Set 匹配次序 = New Collection
  23.     ' 遍历关键词区域,检查关键词是否在待匹配文本中
  24.     For i = LBound(关键词, 1) To UBound(关键词, 1)
  25.         ' 检查关键词是否为空
  26.         If Not IsEmpty(关键词(i, 1)) And Trim(关键词(i, 1)) <> "" Then
  27.             ' 检查关键词是否在待匹配文本中
  28.             If InStr(1, 待匹配文本.Value, 关键词(i, 1), vbTextCompare) > 0 Then
  29.                 匹配次序.Add i
  30.             End If
  31.         End If
  32.     Next i
  33.     ' 如果没有匹配结果,返回空字符串
  34.     If 匹配次序.Count = 0 Then
  35.         编码匹配 = ""
  36.         Exit Function
  37.     End If
  38.     ' 根据匹配次序获取对应的自定义编码
  39.     For Each 匹配项 In 匹配次序
  40.         If 匹配结果 = "" Then
  41.             匹配结果 = 编码(匹配项, 1)
  42.         Else
  43.             匹配结果 = 匹配结果 & "," & 编码(匹配项, 1)
  44.         End If
  45.     Next 匹配项
  46.     ' 返回最终结果
  47.     编码匹配 = 匹配结果
  48. End Function
复制代码
编码匹配改进

  1. 对以下代码进行修改和改进,以提供个性化的匹配,
复制代码
做一些预处理,先用一个另外的’关键词排序数组’将’关键词’中的数列根据字符串长度升序分列,随后自上而下遍历,将较短的关键词在比它长的其他所有关键词中进行搜刮,如果匹配成功,较短一方添加到’上级’数组,较长一方添加到’下级’数组,
在For i = LBound(关键词, 1) To UBound(关键词, 1)这个遍历关键词过程中,如果当前关键词在上级数组中且待匹配文本搜刮成功,请将所有的下级数组中的关键词在待匹配文本中进行搜刮,如果有一个下级数组关键词匹配成功,阐明这个待匹配文本可能是对应下级数组关键词的编码,而不实用当前上级关键词对应的编码,所以不添加匹配次序
  1. Function 编码匹配(待匹配文本 As Range, 关键词区域 As Range, 自定义编码区域 As Range) As String
  2.     Dim 关键词() As Variant ' 关键词数组
  3.     Dim 编码() As Variant ' 编码数组
  4.     Dim 匹配结果 As String ' 最终匹配结果
  5.     Dim i As Long, j As Long ' 循环变量
  6.     Dim 匹配次序 As Collection ' 用于存储匹配次序
  7.     Dim 匹配项 As Variant ' 用于遍历匹配次序集合
  8.     Dim 上级数组() As Boolean ' 标记是否为上级关键词
  9.     Dim 下级数组() As Collection ' 存储每个关键词的下级关键词
  10.     ' 检查关键词区域和自定义编码区域的长度是否相等
  11.     If 关键词区域.Count <> 自定义编码区域.Count Then
  12.         编码匹配 = "错误:关键词区域和自定义编码区域长度不匹配"
  13.         Exit Function
  14.     End If
  15.     ' 将关键词区域和自定义编码区域的值存入数组
  16.     关键词 = 关键词区域.Value
  17.     编码 = 自定义编码区域.Value
  18.     ' 检查待匹配文本是否为空
  19.     If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
  20.         编码匹配 = ""
  21.         Exit Function
  22.     End If
  23.     ' 初始化匹配次序集合和上级/下级数组
  24.     Set 匹配次序 = New Collection
  25.     ReDim 上级数组(LBound(关键词, 1) To UBound(关键词, 1))
  26.     ReDim 下级数组(LBound(关键词, 1) To UBound(关键词, 1))
  27.     For i = LBound(关键词, 1) To UBound(关键词, 1)
  28.         Set 下级数组(i) = New Collection
  29.     Next i
  30.     ' 按字符串长度对关键词进行排序
  31.     Dim 排序数组() As Variant
  32.     ReDim 排序数组(LBound(关键词, 1) To UBound(关键词, 1))
  33.     For i = LBound(关键词, 1) To UBound(关键词, 1)
  34.         排序数组(i) = Array(i, Len(Trim(关键词(i, 1))))
  35.     Next i
  36.     QuickSort 排序数组, LBound(排序数组), UBound(排序数组)
  37.     ' 遍历排序后的关键词,构建上级和下级数组
  38.     For i = LBound(排序数组) To UBound(排序数组)
  39.         Dim 当前关键词索引 As Long
  40.         当前关键词索引 = 排序数组(i)(0)
  41.         For j = i + 1 To UBound(排序数组)
  42.             Dim 比较关键词索引 As Long
  43.             比较关键词索引 = 排序数组(j)(0)
  44.             If InStr(1, 关键词(比较关键词索引, 1), 关键词(当前关键词索引, 1), vbTextCompare) > 0 Then
  45.                 上级数组(比较关键词索引) = True
  46.                 下级数组(当前关键词索引).Add 比较关键词索引
  47.             End If
  48.         Next j
  49.     Next i
  50.     ' 遍历关键词区域,检查关键词是否在待匹配文本中
  51.     For i = LBound(关键词, 1) To UBound(关键词, 1)
  52.         ' 检查关键词是否为空
  53.         If Not IsEmpty(关键词(i, 1)) And Trim(关键词(i, 1)) <> "" Then
  54.             ' 检查关键词是否在待匹配文本中
  55.             If InStr(1, 待匹配文本.Value, 关键词(i, 1), vbTextCompare) > 0 Then
  56.                 ' 检查是否为上级关键词
  57.                 If Not 上级数组(i) Then
  58.                     匹配次序.Add i
  59.                 Else
  60.                     ' 检查下级关键词是否匹配成功
  61.                     Dim 下级关键词匹配成功 As Boolean
  62.                     下级关键词匹配成功 = False
  63.                     Dim 下级关键词 As Variant
  64.                     For Each 下级关键词 In 下级数组(i)
  65.                         If InStr(1, 待匹配文本.Value, 关键词(下级关键词, 1), vbTextCompare) > 0 Then
  66.                             下级关键词匹配成功 = True
  67.                             Exit For
  68.                         End If
  69.                     Next 下级关键词
  70.                     ' 如果没有下级关键词匹配成功,则添加当前上级关键词
  71.                     If Not 下级关键词匹配成功 Then
  72.                         匹配次序.Add i
  73.                     End If
  74.                 End If
  75.             End If
  76.         End If
  77.     Next i
  78.     ' 如果没有匹配结果,返回空字符串
  79.     If 匹配次序.Count = 0 Then
  80.         编码匹配 = ""
  81.         Exit Function
  82.     End If
  83.     ' 根据匹配次序获取对应的自定义编码
  84.     For Each 匹配项 In 匹配次序
  85.         If 匹配结果 = "" Then
  86.             匹配结果 = 编码(匹配项, 1)
  87.         Else
  88.             匹配结果 = 匹配结果 & "," & 编码(匹配项, 1)
  89.         End If
  90.     Next 匹配项
  91.     ' 返回最终结果
  92.     编码匹配 = 匹配结果
  93. End Function
  94. ' 快速排序算法
  95. Sub QuickSort(arr, ByVal first As Long, ByVal last As Long)
  96.     Dim lower As Long, upper As Long, pivot As Variant, temp As Variant
  97.     lower = first: upper = last
  98.     pivot = arr((first + last) \ 2)(1)
  99.     Do While lower <= upper
  100.         Do While (arr(lower)(1) < pivot And lower < last)
  101.             lower = lower + 1
  102.         Loop
  103.         Do While (pivot < arr(upper)(1) And upper > first)
  104.             upper = upper - 1
  105.         Loop
  106.         If lower <= upper Then
  107.             temp = arr(lower)
  108.             arr(lower) = arr(upper)
  109.             arr(upper) = temp
  110.             lower = lower + 1
  111.             upper = upper - 1
  112.         End If
  113.     Loop
  114.     If first < upper Then QuickSort arr, first, upper
  115.     If lower < last Then QuickSort arr, lower, last
  116. End Sub
复制代码
sheet泉源汇总

在wps vb情况写一个新的excel函数名为泉源汇总,第一个参数指定待匹配文本所在单位格(相对引用且不得为空),第二个参数开始指定sheet页(详细方式是选中任意区域,在处理时仅辨认sheet名),当第二个参数不为空时增加第三个参数用来添加新的检索sheet页,遍历所有的检索区域,当待匹配文本包含在检索区域的某个单位格的文本值中,将该单位格所在sheet名+单位格位置如“A1”这样的字串添加到文返回值中
考虑检索区域是二维表格,且为该sheet中包含所有数据的最小矩形区域
注意在利用时填A1绝对引用
  1. Function 来源汇总(待匹配文本 As Range, ParamArray 检索区域() As Variant) As String
  2.     Dim 匹配结果 As String
  3.     Dim 区域 As Variant
  4.     Dim 工作表 As Worksheet
  5.     Dim 单元格 As Range
  6.     Dim 匹配地址 As String
  7.     Dim 区域索引 As Long
  8.     ' 检查待匹配文本是否为空
  9.     If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
  10.         来源汇总 = "EmptyError"
  11.         Exit Function
  12.     End If
  13.     ' 初始化匹配结果
  14.     匹配结果 = ""
  15.     ' 遍历所有指定的检索区域
  16.     For 区域索引 = LBound(检索区域) To UBound(检索区域)
  17.         ' 检查当前区域是否为空
  18.         If Not IsEmpty(检索区域(区域索引)) Then
  19.             ' 获取区域所在的工作表
  20.             Set 工作表 = 检索区域(区域索引).Parent
  21.             ' 遍历工作表中的每个单元格(仅在已使用的范围内)
  22.             For Each 单元格 In 工作表.UsedRange
  23.                 ' 检查单元格是否包含待匹配文本
  24.                 If InStr(1, 单元格.Value, 待匹配文本.Value, vbTextCompare) > 0 Then
  25.                     ' 构造匹配地址
  26.                     匹配地址 = 工作表.Name & "!" & 单元格.Address(False, False)
  27.                     ' 将匹配地址添加到结果中
  28.                     If 匹配结果 = "" Then
  29.                         匹配结果 = 匹配地址
  30.                     Else
  31.                         匹配结果 = 匹配结果 & "," & 匹配地址
  32.                     End If
  33.                 End If
  34.             Next 单元格
  35.         End If
  36.     Next 区域索引
  37.     ' 返回最终结果
  38.     来源汇总 = 匹配结果
  39. End Function
复制代码
泉源汇总改进

进行泉源汇总时也对关键词做一个上级和下级的区分,然后在搜刮区域匹配时,上级关键词要剔撤除对应的下级关键词的匹配结果
  1. Function 来源汇总(待匹配文本 As Range, ParamArray 检索区域() As Variant) As String
  2.     Dim 匹配结果 As String
  3.     Dim 区域 As Variant
  4.     Dim 工作表 As Worksheet
  5.     Dim 单元格 As Range
  6.     Dim 匹配地址 As String
  7.     Dim 区域索引 As Long
  8.     Dim 关键词() As Variant
  9.     Dim 上级数组() As Boolean
  10.     Dim 下级数组() As Collection
  11.     Dim i As Long, j As Long
  12.     ' 检查待匹配文本是否为空
  13.     If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
  14.         来源汇总 = "----"
  15.         Exit Function
  16.     End If
  17.     ' 初始化匹配结果
  18.     匹配结果 = ""
  19.     ' 获取所有关键词并初始化上级和下级数组
  20.     ReDim 关键词(1 To 1)
  21.     ReDim 上级数组(1 To 1)
  22.     ReDim 下级数组(1 To 1)
  23.     Set 下级数组(1) = New Collection
  24.     ' 遍历所有指定的检索区域
  25.     For 区域索引 = LBound(检索区域) To UBound(检索区域)
  26.         ' 检查当前区域是否为空
  27.         If Not IsEmpty(检索区域(区域索引)) Then
  28.             ' 获取区域所在的工作表
  29.             Set 工作表 = 检索区域(区域索引).Parent
  30.             ' 遍历工作表中的每个单元格(仅在已使用的范围内)
  31.             For Each 单元格 In 工作表.UsedRange
  32.                 ' 检查单元格是否包含待匹配文本
  33.                 If InStr(1, 单元格.Value, 待匹配文本.Value, vbTextCompare) > 0 Then
  34.                     ' 构造匹配地址
  35.                     匹配地址 = 工作表.Name & "!" & 单元格.Address(False, False)
  36.                     ' 检查是否为上级关键词
  37.                     If Not 上级数组(i) Then
  38.                         ' 添加匹配地址到结果
  39.                         If 匹配结果 = "" Then
  40.                             匹配结果 = 匹配地址
  41.                         Else
  42.                             匹配结果 = 匹配结果 & "," & 匹配地址
  43.                         End If
  44.                     Else
  45.                         ' 检查下级关键词是否匹配成功
  46.                         Dim 下级关键词匹配成功 As Boolean
  47.                         下级关键词匹配成功 = False
  48.                         Dim 下级关键词 As Variant
  49.                         For Each 下级关键词 In 下级数组(i)
  50.                             If InStr(1, 单元格.Value, 下级关键词, vbTextCompare) > 0 Then
  51.                                 下级关键词匹配成功 = True
  52.                                 Exit For
  53.                             End If
  54.                         Next 下级关键词
  55.                         ' 如果没有下级关键词匹配成功,则添加当前上级关键词
  56.                         If Not 下级关键词匹配成功 Then
  57.                             If 匹配结果 = "" Then
  58.                                 匹配结果 = 匹配地址
  59.                             Else
  60.                                 匹配结果 = 匹配结果 & "," & 匹配地址
  61.                             End If
  62.                         End If
  63.                     End If
  64.                 End If
  65.             Next 单元格
  66.         End If
  67.     Next 区域索引
  68.     ' 返回最终结果
  69.     来源汇总 = 匹配结果
  70. End Function
复制代码
END


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表