ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[已解决] 提取两个字符串中最大相同部分的字符串。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-6-18 20:44 | 显示全部楼层
香川群子 发表于 2015-6-18 12:52
自定义函数 =f(s1,s2,[n],[k])
1.s1/s2为比较对象字符串、必须参数。
2.n为相同字符最低个数、可选参数。 ...

n=0  最好再设一个参数

TA的精华主题

TA的得分主题

发表于 2015-6-19 08:59 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 香川群子 于 2015-6-19 09:24 编辑
dyho2010 发表于 2015-6-18 20:35
谢谢,你的程序很棒,且注释得很仔细,我这种小白也可以看的懂,我以后可以通过更改参数实现其他我想要的 ...


自定义函数改进后,比较次数更为减少,速度效率更高!
在长字符串、大数据量时应该有好处。

  1. Function f(s1$, s2$, Optional n& = 3, Optional k& = 1)
  2.     If k = 1 Then s1 = LCase(s1): s2 = LCase(s2)
  3.     If k = 2 Then s1 = UCase(s1): s2 = UCase(s2)
  4.     If Len(s1) > Len(s2) Then s = s2: s2 = s1: s1 = s
  5.     Do While i + r < Len(s1)
  6.         i = i + 1: j = r
  7.         Do While j < Len(s1)
  8.             j = j + 1: s = Mid(s1, i, j): If InStr(s2, s) Then r = Len(s): f = s
  9.         Loop
  10.     Loop
  11.     If n = 0 Then f = r Else If r < n Then f = ""
  12. End Function
复制代码


参数设置没有变化。

但是请注意:如果含有相同长度的字符串有几组,则仅返回第一次出现的那一组。

TA的精华主题

TA的得分主题

发表于 2015-6-19 09:13 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 香川群子 于 2015-6-19 09:25 编辑
yjh_27 发表于 2015-6-18 20:44
n=0  最好再设一个参数


没问题。n=0是个不会冲突的冗余条件,可以这样设置。

我在楼下用Do循环方式重写了代码,效率更高!

Function f(s1$, s2$, Optional n& = 3, Optional k& = 1)
    If k = 1 Then s1 = LCase(s1): s2 = LCase(s2) 'k=1 时转为小写比较模式并输出
    If k = 2 Then s1 = UCase(s1): s2 = UCase(s2) 'k=2 时转为大写比较模式并输出
   'k=0时不做字符处理、因此是按通常原始状态即区分大小写的比较模式进行。

    If Len(s1) > Len(s2) Then s = s2: s2 = s1: s1 = s '设置长度小的字符串作为s1 提高效率

    Do While i + r < Len(s1) '仅比较至当前位置 i 的字符串长度不小于最大值 r 时
        i = i + 1: j = r            '每次按已知最大值r的长度作为比较长度 j 然后开始比较
        Do While j < Len(s1)  '当前位置的比较长度j不小于s1长度时继续比较
            j = j + 1: s = Mid(s1, i, j) '截取比较字符s、然后Instr检查s2中是否含有相同
            If InStr(s2, s) Then r = Len(s): f = s '如含有则更新最大长度时的s并记录r
        Loop
    Loop
    If n = 0 Then f = r Else If r < n Then f = "" '如参数设置n=0时返回个数r、如r不足n时则返回空白
End Function

如果含有相同长度的字符串有几组,则仅返回第一次出现的那一组。

TA的精华主题

TA的得分主题

发表于 2015-6-19 09:55 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
都很好用,但是都在不同列的同一行上对比,我想需要的是在不同一行上对比,请高手们修改一下参数,以适应的范围更广.

TA的精华主题

TA的得分主题

发表于 2015-6-19 12:02 | 显示全部楼层
写着玩玩:取最长相同部分
Sub test()
Dim ar, i&, j&, k&, s, s1, s2, s3, n&
ar = [a1].CurrentRegion
For i = 2 To UBound(ar)
    s = ""
    n = 0
    s1 = LCase(ar(i, 1))
    s2 = LCase(ar(i, 2))
    For j = 1 To Len(s1)
        For k = 1 To Len(s1) - j + 1
            s3 = Mid(s1, j, k)
            If InStr(s2, s3) > 0 And Len(s3) >= n Then
                s = s3
                n = Len(s3)
            End If
        Next k
    Next j
    ar(i, 1) = s
Next i
[g1].Resize(i - 1, 1) = ar
End Sub

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-6-19 13:51 | 显示全部楼层
xieyidh 发表于 2015-6-19 09:55
都很好用,但是都在不同列的同一行上对比,我想需要的是在不同一行上对比,请高手们修改一下参数,以适应的范围 ...

用我的自定义函数。像工作表函数那样很方便地使用。任意位置都可以。

TA的精华主题

TA的得分主题

发表于 2015-6-19 14:16 | 显示全部楼层
  1. Function GetS$(s1$, s2$)
  2. Dim s$
  3. If Len(s1) > Len(s2) Then s = s2 Else s = s1: s1 = s2
  4. n = Len(s)
  5. For i = n To 1 Step -1
  6.   For j = 1 To n - i + 1
  7.     If InStr(s1, Mid(s, j, i)) Then GetS = Mid(s, j, i): Exit Function
  8.   Next
  9. Next
  10. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-6-19 14:23 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-6-19 14:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
如果要进行文本比较,Instr本身就可以,改为InStr(1,s1, Mid(s, j, i),1)。
22楼那样可谓笨到家。

TA的精华主题

TA的得分主题

发表于 2015-6-19 14:32 | 显示全部楼层
香川群子 发表于 2015-6-19 09:13
没问题。n=0是个不会冲突的冗余条件,可以这样设置。

我在楼下用Do循环方式重写了代码,效率更高!
...

原代码n=0 时  输出 f=R有时会出错
  1. Function f(s1$, s2$, Optional n& = 3, Optional k& = 1)
  2.     If k = 1 Then s1 = LCase(s1): s2 = LCase(s2)
  3.     If k = 2 Then s1 = UCase(s1): s2 = UCase(s2)
  4.     If Len(s1) > Len(s2) Then s = s2: s2 = s1: s1 = s
  5.     If n > 0 Then R = n Else R = 1
  6.     i = 1
  7.     f = ""
  8.     Do While i <= Len(s1) - n + 1
  9.         r0 = 0
  10.         For j = R To Len(s1)
  11.             s = Mid(s1, i, j): m = InStr(s2, s)
  12.             If m Then
  13.                 If Len(s) > R Then R = Len(s): f = s
  14.                 r0 = 1
  15.             Else
  16.                 Exit For
  17.             End If
  18.         Next
  19.         If r0 = 0 Then i = i + 1 Else i = i + R + 1
  20.     Loop
  21.     If n = 0 Then f = Len(f)
  22. End Function
复制代码
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-15 12:28 , Processed in 0.040094 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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