当前位置: 首页 > article >正文

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

目录

    • 自定义编码匹配
      • 编码匹配改进
    • sheet来源汇总
      • 来源汇总改进
  • END

自定义编码匹配

在wps vb环境写一个新的excel函数名为编码匹配,第一个参数指定待匹配文本所在单元格(相对引用),第二个参数指定关键词区域(绝对引用,一行或者一列单元格),第三个参数指定一个自定义编码区域(绝对引用一行或者一列,但是要检查其长度是否与关键词区域相等,不等则显示错误),完成参数填写以后,将参数2中每个关键词依次在参数1中进行匹配,如果存在则记录其次序,返回值参数3中与改次序相同的自定义编码文本,如果存在多个匹配结果,用逗号间隔后返回
gpt错误是把关键词和编码定义为了String,应该是Variant
改进:跳过关键词的空值,这样引用区域可以预留空间

Function 编码匹配(待匹配文本 As Range, 关键词区域 As Range, 自定义编码区域 As Range) As String
    Dim 关键词() As Variant ' 关键词数组
    Dim 编码() As Variant ' 编码数组
    Dim 匹配结果 As String ' 最终匹配结果
    Dim i As Long ' 循环变量
    Dim 匹配次序 As Collection ' 用于存储匹配次序
    Dim 匹配项 As Variant ' 用于遍历匹配次序集合

    ' 检查关键词区域和自定义编码区域的长度是否相等
    If 关键词区域.Count <> 自定义编码区域.Count Then
        编码匹配 = "错误:关键词区域和自定义编码区域长度不匹配"
        Exit Function
    End If

    ' 将关键词区域和自定义编码区域的值存入数组
    关键词 = 关键词区域.Value
    编码 = 自定义编码区域.Value

    ' 检查待匹配文本是否为空
    If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
        编码匹配 = ""
        Exit Function
    End If

    ' 初始化匹配次序集合
    Set 匹配次序 = New Collection

    ' 遍历关键词区域,检查关键词是否在待匹配文本中
    For i = LBound(关键词, 1) To UBound(关键词, 1)
        ' 检查关键词是否为空
        If Not IsEmpty(关键词(i, 1)) And Trim(关键词(i, 1)) <> "" Then
            ' 检查关键词是否在待匹配文本中
            If InStr(1, 待匹配文本.Value, 关键词(i, 1), vbTextCompare) > 0 Then
                匹配次序.Add i
            End If
        End If
    Next i

    ' 如果没有匹配结果,返回空字符串
    If 匹配次序.Count = 0 Then
        编码匹配 = ""
        Exit Function
    End If

    ' 根据匹配次序获取对应的自定义编码
    For Each 匹配项 In 匹配次序
        If 匹配结果 = "" Then
            匹配结果 = 编码(匹配项, 1)
        Else
            匹配结果 = 匹配结果 & "," & 编码(匹配项, 1)
        End If
    Next 匹配项

    ' 返回最终结果
    编码匹配 = 匹配结果
End Function

编码匹配改进

对以下代码进行修改和改进,以提供个性化的匹配,

做一些预处理,先用一个另外的’关键词排序数组’将’关键词’中的数列根据字符串长度升序排列,随后自上而下遍历,将较短的关键词在比它长的其他所有关键词中进行搜索,如果匹配成功,较短一方添加到’上级’数组,较长一方添加到’下级’数组,
在For i = LBound(关键词, 1) To UBound(关键词, 1)这个遍历关键词过程中,如果当前关键词在上级数组中且待匹配文本搜索成功,请将所有的下级数组中的关键词在待匹配文本中进行搜索,如果有一个下级数组关键词匹配成功,说明这个待匹配文本可能是对应下级数组关键词的编码,而不适用当前上级关键词对应的编码,所以不添加匹配次序

Function 编码匹配(待匹配文本 As Range, 关键词区域 As Range, 自定义编码区域 As Range) As String
    Dim 关键词() As Variant ' 关键词数组
    Dim 编码() As Variant ' 编码数组
    Dim 匹配结果 As String ' 最终匹配结果
    Dim i As Long, j As Long ' 循环变量
    Dim 匹配次序 As Collection ' 用于存储匹配次序
    Dim 匹配项 As Variant ' 用于遍历匹配次序集合
    Dim 上级数组() As Boolean ' 标记是否为上级关键词
    Dim 下级数组() As Collection ' 存储每个关键词的下级关键词

    ' 检查关键词区域和自定义编码区域的长度是否相等
    If 关键词区域.Count <> 自定义编码区域.Count Then
        编码匹配 = "错误:关键词区域和自定义编码区域长度不匹配"
        Exit Function
    End If

    ' 将关键词区域和自定义编码区域的值存入数组
    关键词 = 关键词区域.Value
    编码 = 自定义编码区域.Value

    ' 检查待匹配文本是否为空
    If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
        编码匹配 = ""
        Exit Function
    End If

    ' 初始化匹配次序集合和上级/下级数组
    Set 匹配次序 = New Collection
    ReDim 上级数组(LBound(关键词, 1) To UBound(关键词, 1))
    ReDim 下级数组(LBound(关键词, 1) To UBound(关键词, 1))
    For i = LBound(关键词, 1) To UBound(关键词, 1)
        Set 下级数组(i) = New Collection
    Next i

    ' 按字符串长度对关键词进行排序
    Dim 排序数组() As Variant
    ReDim 排序数组(LBound(关键词, 1) To UBound(关键词, 1))
    For i = LBound(关键词, 1) To UBound(关键词, 1)
        排序数组(i) = Array(i, Len(Trim(关键词(i, 1))))
    Next i
    QuickSort 排序数组, LBound(排序数组), UBound(排序数组)

    ' 遍历排序后的关键词,构建上级和下级数组
    For i = LBound(排序数组) To UBound(排序数组)
        Dim 当前关键词索引 As Long
        当前关键词索引 = 排序数组(i)(0)
        For j = i + 1 To UBound(排序数组)
            Dim 比较关键词索引 As Long
            比较关键词索引 = 排序数组(j)(0)
            If InStr(1, 关键词(比较关键词索引, 1), 关键词(当前关键词索引, 1), vbTextCompare) > 0 Then
                上级数组(比较关键词索引) = True
                下级数组(当前关键词索引).Add 比较关键词索引
            End If
        Next j
    Next i

    ' 遍历关键词区域,检查关键词是否在待匹配文本中
    For i = LBound(关键词, 1) To UBound(关键词, 1)
        ' 检查关键词是否为空
        If Not IsEmpty(关键词(i, 1)) And Trim(关键词(i, 1)) <> "" Then
            ' 检查关键词是否在待匹配文本中
            If InStr(1, 待匹配文本.Value, 关键词(i, 1), vbTextCompare) > 0 Then
                ' 检查是否为上级关键词
                If Not 上级数组(i) Then
                    匹配次序.Add i
                Else
                    ' 检查下级关键词是否匹配成功
                    Dim 下级关键词匹配成功 As Boolean
                    下级关键词匹配成功 = False
                    Dim 下级关键词 As Variant
                    For Each 下级关键词 In 下级数组(i)
                        If InStr(1, 待匹配文本.Value, 关键词(下级关键词, 1), vbTextCompare) > 0 Then
                            下级关键词匹配成功 = True
                            Exit For
                        End If
                    Next 下级关键词
                    ' 如果没有下级关键词匹配成功,则添加当前上级关键词
                    If Not 下级关键词匹配成功 Then
                        匹配次序.Add i
                    End If
                End If
            End If
        End If
    Next i

    ' 如果没有匹配结果,返回空字符串
    If 匹配次序.Count = 0 Then
        编码匹配 = ""
        Exit Function
    End If

    ' 根据匹配次序获取对应的自定义编码
    For Each 匹配项 In 匹配次序
        If 匹配结果 = "" Then
            匹配结果 = 编码(匹配项, 1)
        Else
            匹配结果 = 匹配结果 & "," & 编码(匹配项, 1)
        End If
    Next 匹配项

    ' 返回最终结果
    编码匹配 = 匹配结果
End Function

' 快速排序算法
Sub QuickSort(arr, ByVal first As Long, ByVal last As Long)
    Dim lower As Long, upper As Long, pivot As Variant, temp As Variant
    lower = first: upper = last
    pivot = arr((first + last) \ 2)(1)
    Do While lower <= upper
        Do While (arr(lower)(1) < pivot And lower < last)
            lower = lower + 1
        Loop
        Do While (pivot < arr(upper)(1) And upper > first)
            upper = upper - 1
        Loop
        If lower <= upper Then
            temp = arr(lower)
            arr(lower) = arr(upper)
            arr(upper) = temp
            lower = lower + 1
            upper = upper - 1
        End If
    Loop
    If first < upper Then QuickSort arr, first, upper
    If lower < last Then QuickSort arr, lower, last
End Sub

sheet来源汇总

在wps vb环境写一个新的excel函数名为来源汇总,第一个参数指定待匹配文本所在单元格(相对引用且不得为空),第二个参数开始指定sheet页(具体方式是选中任意区域,在处理时仅识别sheet名),当第二个参数不为空时增加第三个参数用来添加新的检索sheet页,遍历所有的检索区域,当待匹配文本包含在检索区域的某个单元格的文本值中,将该单元格所在sheet名+单元格位置如“A1”这样的字串添加到文返回值中
考虑检索区域是二维表格,且为该sheet中包含所有数据的最小矩形区域
注意在使用时填A1绝对引用

Function 来源汇总(待匹配文本 As Range, ParamArray 检索区域() As Variant) As String
    Dim 匹配结果 As String
    Dim 区域 As Variant
    Dim 工作表 As Worksheet
    Dim 单元格 As Range
    Dim 匹配地址 As String
    Dim 区域索引 As Long

    ' 检查待匹配文本是否为空
    If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
        来源汇总 = "EmptyError"
        Exit Function
    End If

    ' 初始化匹配结果
    匹配结果 = ""

    ' 遍历所有指定的检索区域
    For 区域索引 = LBound(检索区域) To UBound(检索区域)
        ' 检查当前区域是否为空
        If Not IsEmpty(检索区域(区域索引)) Then
            ' 获取区域所在的工作表
            Set 工作表 = 检索区域(区域索引).Parent

            ' 遍历工作表中的每个单元格(仅在已使用的范围内)
            For Each 单元格 In 工作表.UsedRange
                ' 检查单元格是否包含待匹配文本
                If InStr(1, 单元格.Value, 待匹配文本.Value, vbTextCompare) > 0 Then
                    ' 构造匹配地址
                    匹配地址 = 工作表.Name & "!" & 单元格.Address(False, False)
                    ' 将匹配地址添加到结果中
                    If 匹配结果 = "" Then
                        匹配结果 = 匹配地址
                    Else
                        匹配结果 = 匹配结果 & "," & 匹配地址
                    End If
                End If
            Next 单元格
        End If
    Next 区域索引

    ' 返回最终结果
    来源汇总 = 匹配结果
End Function

来源汇总改进

进行来源汇总时也对关键词做一个上级和下级的区分,然后在搜索区域匹配时,上级关键词要剔除掉对应的下级关键词的匹配结果

Function 来源汇总(待匹配文本 As Range, ParamArray 检索区域() As Variant) As String
    Dim 匹配结果 As String
    Dim 区域 As Variant
    Dim 工作表 As Worksheet
    Dim 单元格 As Range
    Dim 匹配地址 As String
    Dim 区域索引 As Long
    Dim 关键词() As Variant
    Dim 上级数组() As Boolean
    Dim 下级数组() As Collection
    Dim i As Long, j As Long

    ' 检查待匹配文本是否为空
    If IsEmpty(待匹配文本.Value) Or Trim(待匹配文本.Value) = "" Then
        来源汇总 = "----"
        Exit Function
    End If

    ' 初始化匹配结果
    匹配结果 = ""

    ' 获取所有关键词并初始化上级和下级数组
    ReDim 关键词(1 To 1)
    ReDim 上级数组(1 To 1)
    ReDim 下级数组(1 To 1)
    Set 下级数组(1) = New Collection

    ' 遍历所有指定的检索区域
    For 区域索引 = LBound(检索区域) To UBound(检索区域)
        ' 检查当前区域是否为空
        If Not IsEmpty(检索区域(区域索引)) Then
            ' 获取区域所在的工作表
            Set 工作表 = 检索区域(区域索引).Parent

            ' 遍历工作表中的每个单元格(仅在已使用的范围内)
            For Each 单元格 In 工作表.UsedRange
                ' 检查单元格是否包含待匹配文本
                If InStr(1, 单元格.Value, 待匹配文本.Value, vbTextCompare) > 0 Then
                    ' 构造匹配地址
                    匹配地址 = 工作表.Name & "!" & 单元格.Address(False, False)

                    ' 检查是否为上级关键词
                    If Not 上级数组(i) Then
                        ' 添加匹配地址到结果
                        If 匹配结果 = "" Then
                            匹配结果 = 匹配地址
                        Else
                            匹配结果 = 匹配结果 & "," & 匹配地址
                        End If
                    Else
                        ' 检查下级关键词是否匹配成功
                        Dim 下级关键词匹配成功 As Boolean
                        下级关键词匹配成功 = False
                        Dim 下级关键词 As Variant
                        For Each 下级关键词 In 下级数组(i)
                            If InStr(1, 单元格.Value, 下级关键词, vbTextCompare) > 0 Then
                                下级关键词匹配成功 = True
                                Exit For
                            End If
                        Next 下级关键词
                        ' 如果没有下级关键词匹配成功,则添加当前上级关键词
                        If Not 下级关键词匹配成功 Then
                            If 匹配结果 = "" Then
                                匹配结果 = 匹配地址
                            Else
                                匹配结果 = 匹配结果 & "," & 匹配地址
                            End If
                        End If
                    End If
                End If
            Next 单元格
        End If
    Next 区域索引

    ' 返回最终结果
    来源汇总 = 匹配结果
End Function

END


http://www.kler.cn/a/519638.html

相关文章:

  • 豆包MarsCode:字符串字符类型排序问题
  • WPF常见面试题解答
  • 高德开放平台:红绿灯倒计时与车车协同安全预警,开启出行新时代
  • miniconda学习笔记
  • Mono里运行C#脚本36—加载C#类定义的成员变量和方法的数量
  • 996引擎 - NPC-动态创建NPC
  • python爬虫 爬取站长素材 (图片)(自学6)
  • Pyecharts之词云图、面积图与堆叠面积图
  • 一文讲解Java中的重载、重写及里氏替换原则
  • uniapp商城项目之商品详情
  • 在 Windows 系统上,将 Ubuntu 从 C 盘 迁移到 D 盘
  • 家政预约小程序10首先显示服务内容
  • 有关ORM
  • golang命令大全1--概述
  • Maven面试试题及其答案解析
  • 基础项目实战——学生管理系统(c++)
  • 【Elasticsearch】Springboot编写Elasticsearch的RestAPI
  • Vue 响应式渲染 - 模板语法
  • BroadCom-RDMA博通网卡如何进行驱动安装和设置使得对应网口具有RDMA功能以适配RDMA相机
  • 如何实现一个简单的中文错别字高亮系统?
  • 使用python-docx包进行多文件word文字、字符批量替换
  • 【数据分享】1929-2024年全球站点的逐日降水量数据(Shp\Excel格式)
  • springboot使用tomcat浅析
  • 【全栈】SprintBoot+vue3迷你商城(7)
  • 从入门到精通:HttpClient深度剖析与实战指南
  • SpringBoot--基本使用(配置、整合SpringMVC、Druid、Mybatis、基础特性)