设为首页收藏本站|繁體中文

Excel 技巧网

 找回密码
 注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

查看: 4352|回复: 9

[Excel VBA] 一个字典与正则结合的实例。

[复制链接]
发表于 2011-7-29 16:16:34 | 显示全部楼层 |阅读模式
  • 署名作者: liuguansky
  • 版权声明: 版权归本站与作者共有 除本站官方外非作者本人转载须经许可并注明出处
  • 本文来自:
  • 引用作品:
  • 适用版本: 2010 2007 2003以前版本 
  • 语言环境: 简体中文
  • 学习方法: 掌握Excel技巧的关键是动手操作 | 下载 ≠ 知识


  • 免费注册成为本站会员,享用更多功能,结识更多Office办公高手!

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

    x
    本帖最后由 liuguansky 于 2011-7-29 17:08 编辑

    问题的提出:

    一个字典与正则结合的实例。

    一个字典与正则结合的实例。


    数量/箱来计算每件或每箱的数量,同时来对原版中的内容进行分配。
    分配规则如下:
    类似这样的表达方式1-R28L748(36):前面是代码,后面()中的是数量。
    先分配前面的,再依次向后进行分配,同一编号用同一原版进行处理。
    比如1.2.231.80100编号:第一个记录是288/4=72
    那么应该分配前面的两个36/36,结果应该返回为:
    1-R28L748(36)  1-R28L749(36)
    第二条记录,就拉着分配:
    1-R28L750(72)
    这样依次下去。
    如果一箱的数量小于一个代码的数量,则需把代码进行拆分返回。


    问题的分析:
    1.对于特殊形式的字符串处理,我们可以很容易的考虑到正则表达式,同时结合分组来进行数据的提取。
    2.在为同一编号,运用同一原版,故可以想到用字典来进行编号的惟一性识别。
    3.因为同一编号是对同一原版进行数量的判断处理,故可以设置数组进行相应的数量元素的减少或消失[设置为空文本]
    因为字典的ITEM项目操作多种 元素会比较烦琐,故直接引用数组入ITEM项目。
    4.对每条记录的实际数量,与字典ITEM数组中的数量元素进行比较判断来进行字符串返回即可。

    问题的实现:
    1. Sub justtest()
    2.     Dim arr, i&, arrt() As String, K&, d, j%, StrTemp$, arrk, ark '定义变量
    3.     arr = Range("a2:d" & Cells(Rows.Count, 1).End(3).Row).Value '获取待处理数据区域入数组
    4.     Set d = CreateObject("scripting.dictionary") '创建字典项目
    5.     ReDim arrt(1 To UBound(arr, 1), 1 To 1) '重定义结果数组
    6.     With CreateObject("vbscript.regexp") '创建正则项目
    7. '知识点1:正则对字符串的处理
    8.         .Global = True '全局为真
    9.         .Pattern = "(\d-R\d{2}L\d{3})\((\d+)\)" '匹配代码段与数量段,进行分组$1$2
    10. '知识点2:分组便于分段截获项目
    11.         For i = 1 To UBound(arr, 1) '循环数据源数组
    12.             If Not d.exists(arr(i, 1)) Then '如果字典项目不存在的话
    13.                 If .test(arr(i, 3)) Then '如果原版匹配有正则段
    14.                     ark = Split(.Replace(Replace(arr(i, 3), " ", ""), "@$1@$2"), "@") '生成代码段与数量段间隔数组
    15. '知识点3:正则.replace方法的分组替换,配合SPLIT返回结果数组
    16.                 End If
    17.                 d.Add arr(i, 1), ark '同时创建项目,设置ITEM项为数组,方便后续处理
    18. '知识点4:依处理需求,添加数组入字典ITEM项目
    19.             End If
    20.             K = arr(i, 2) / arr(i, 4) '返回每箱装数量
    21.             arrk = d(arr(i, 1)) '获取相应编码对应的字典ITEM项入数组,方便后续取值判断
    22.             StrTemp = "" '初始化返回代码+数量字符串
    23. '知识点5:标识字符串或标识位的初始化,防止前期结果对后期标识的影响
    24.             For j = 1 To UBound(arrk) Step 2 '循环原版处理后的字符串,因代码段与数量段相隔,故STEP2
    25.                 If arrk(j) <> "" Then '对非空元素 进行判断处理
    26.                     If K >= CLng(arrk(j + 1)) Then '如果待生成数量不小于元素数量
    27.                         StrTemp = StrTemp & "  " & arrk(j) & "(" & CLng(arrk(j + 1)) & ")" '则返回对应代码+数量
    28.                         K = K - CLng(arrk(j + 1)): arrk(j) = "": arrk(j + 1) = "" '同时对K进行减少,清空对应的数组元素
    29.                         If K = 0 Then Exit For '如果刚好处理完,则跳出循环
    30. '知识点6:循环达到目的即跳出循环,避免无用或多余的循环判断
    31.                         Else '如果待生成数量小于元素数量
    32.                         StrTemp = StrTemp & " " & arrk(j) & "(" & K & ")" '生成对应代码+待生成数量
    33.                         arrk(j + 1) = CLng(arrk(j + 1)) - K '处理对应元素的数量
    34.                         Exit For '同时进行循环跳出
    35.                     End If
    36.                 End If
    37.             Next j
    38.             d(arr(i, 1)) = arrk '更新字典对应项目的ITEM项
    39. '知识点7:字典ITEM项目的独立性[只依附于对应的KEY],需重新赋值回去
    40.             arrt(i, 1) = Mid(StrTemp, 3) '返回字符串
    41. '知识点8:字符串连接后,直接以MID来去除第一个连接多余间隔符。
    42.         Next i
    43.         Range("e:e").ClearContents '清空返回数据区域
    44.         Range("e2").Resize(i - 1, 1) = arrt '返回结果
    45.     End With
    46.     Set d = Nothing '清空变量
    47. End Sub
    复制代码
    知识点分析:
    1.正则用于处理字符串上有很大的优势,通过分析数据的通性,来书写PATTERN进行目标字符的匹配,可以很方便的辅以我们来进行后续的其他操作。
    2.匹配后,当我们要抽取其中的部分匹配结果可以用()加以分组,分组后有两种方式返回:
    第一种就是通过每一个匹配结果的submatches集合进行调用。
    第二种就是本例中的结合replace来进行处理。
    每一个分组在REPLACE中的匹配结果用$1/2/3...这样编号下去。
    本例中把代码与数量分组,进行特殊字符的间隔REPLACE后再SPLIT返回为数组,是一种常用的取分组匹配结果入数组的方式。
    3.关于字典的ITEM,它是个大肚能容天下物的东西,数组、字典、对象都可以放进去。
    所以有时我们可以根据我们处理的数据结果,对其进行不同的赋值。
    需要注意的是ITEM为数组、字典、对象等的时候,要把它赋值时的变量名与其本身区分开来。
    ITEM是个依附于对应KEY值而存在的,不能单独去获取其值,所以只能字典进行返回,所以进行ITEM的处理时,应先赋值给对象/变量,操作完后再赋值回字典的ITEM项目
    4.有时我们在数组的循环中,会设定很多标识位/参照值等等的中间变量 ,这些变量我们要分清哪些是在全过程累加,哪些是只在单一循环中累加,这个时候我们要进行合理的分析并进行清空与初始化。
    5.循环过程中,如果达到某些条件后,我们应该进行跳出循环处理 ,防止循环的继续运行,发生多余或不必要的循环。

    写在最后:
    此例是一个字典+正则+数组的结合实例,对我们综合处理问题很有帮助。其中涉及的几个小技巧与知识点很实用,希望以上分析对大家有帮助,若对上述实例中的知识点或代码有疑问或更好的建议,请跟帖或短消息我。

    桌面.rar (33.23 KB, 下载次数: 99)

    评分

    参与人数 6魅力值 +30 收起 理由
    windimi007 + 5 花花出的精品,得支持一下!
    wcymiss + 5 学习。
    双脚着地 + 5 看不懂感觉好 嘿
    小叶子 + 5 好强大
    wxin + 5 好强大的说

    查看全部评分

    发表于 2011-7-29 17:56:34 | 显示全部楼层
    谢谢老师分享 学习到很多知识 见识到正则的强大
    回复 支持 反对

    使用道具 举报

    发表于 2011-8-17 10:32:16 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    发表于 2011-10-9 11:25:02 | 显示全部楼层
    谢谢分享,学习学习
    回复 支持 反对

    使用道具 举报

    发表于 2011-10-21 00:50:58 | 显示全部楼层
    好东西 我下载来好好学习
    回复 支持 反对

    使用道具 举报

    发表于 2014-4-4 11:49:34 | 显示全部楼层
    学习正则
    回复

    使用道具 举报

    发表于 2015-3-22 00:20:47 | 显示全部楼层
    下载了,谢谢.
    回复 支持 反对

    使用道具 举报

    发表于 2017-12-11 15:08:02 | 显示全部楼层
    谢谢老师分享
    回复 支持 反对

    使用道具 举报

    发表于 2018-1-3 21:45:20 | 显示全部楼层
    学习了,收藏了,谢谢
    回复 支持 反对

    使用道具 举报

    发表于 2018-1-23 09:00:08 | 显示全部楼层
    谢谢老师分享
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    Excel技巧网的会员探讨问题仅代表其个人意见,与网站的立场无关。任何违反国家和地方相关法律法规的言论,本站有义务协助政府相关部门追究发言者的责任!
    本站中非注明转载文章与案例的版权为作者与Excel技巧网共有。若非原文作者,本站之外任何单位或个人未经允许,不得将其用于商业用途。
    若非原文作者,任何形式的非商业性转载必须获得Excel技巧网或作者允许,并注明作者和出处。
    会员发表的帖子如涉及版权纠纷,须自行负责。详情请参考注册时的网站服务条款。
    本站特聘法律顾问:沈学律师

    Archiver|手机版|Excel技巧网 ( 闽ICP备08107682号-2 ) | 闽公网安备 35020302032608号  

    GMT+8, 2018-6-22 05:24

    Powered by Discuz! X3.3

    © 2001-2017 Comsenz Inc.

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