ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] WordVBA中字符串查找替换进阶

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-11-20 00:20 来自手机 | 显示全部楼层
loquat 发表于 2016-11-20 00:07
具体Selection对象和Range对象的效率差别,最好是自己谢谢代码对比一下
记忆中我好想做过demo对比过,在不 ...

搬砖的老师,您的认同和我一样,感谢老师的光临!

TA的精华主题

TA的得分主题

发表于 2016-11-20 09:30 | 显示全部楼层
麻烦老兄每段代码跟个附件吧,谢谢了
在这里跟着你学习WORDVBA

TA的精华主题

TA的得分主题

发表于 2016-11-20 10:11 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
第一段代码修改了一下,排除表格,不知对不对?
Sub Word文档中修改格式()
    Dim i As Paragraph, mt, oRang As Range, n%, m%
    With CreateObject("vbscript.regexp")
        .Pattern = "^第[^条]+条" '这里各显其能输入正则表达式(根据自己的需求)
        .Global = True   ': .IgnoreCase = False: .MultiLine = True
        For Each i In ActiveDocument.Paragraphs
            For Each mt In .Execute(i.Range.Text)
                If Asc(Right(i.Range, 1)) <> 7 Then
                    m = mt.FirstIndex: n = mt.Length
                    Set oRang = ActiveDocument.Range(i.Range.Start + m, i.Range.Start + m + n)
                    oRang.Bold = True '字符加粗,有一系列的修改格式(根据自己的需求)
                End If
            Next
        Next
    End With
End Sub

TA的精华主题

TA的得分主题

发表于 2016-11-20 10:55 | 显示全部楼层
第一段代码作业:
Sub test()
Dim reg, pg, jh, zj, c&, c1, tm
Set reg = CreateObject("vbscript.regexp")
reg.Global = True
reg.Pattern = "第[^条]+条"
For Each pg In ActiveDocument.Paragraphs
    Set jh = reg.Execute(pg.Range)
    If Asc(Right(pg.Range, 1)) <> 7 Then
        For Each zj In jh
            c = zj.firstindex
            c1 = zj.Length
            Set tm = ActiveDocument.Range(pg.Range.Start + c, pg.Range.Start + c + c1)
            tm.Bold = True
        Next zj
    End If
Next pg
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-11-20 10:56 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 duquancai 于 2016-11-20 12:51 编辑
小花鹿 发表于 2016-11-20 10:11
第一段代码修改了一下,排除表格,不知对不对?
Sub Word文档中修改格式()
    Dim i As Paragraph, mt,  ...

若果文档中无表格,可以把整个文档“作为目标字符”进行查找
1、把整个文档“作为目标字符”进行查找(因为表格中的内容不用关心):
  1. Sub Word文档中修改格式()
  2.    Dim mt, oRang As Range, n%, m%, act As Range
  3.    Set act = ActiveDocument.Content '把整个文档区域赋值个range对象变量act
  4.    With CreateObject("vbscript.regexp")
  5.       .Pattern = "^第[^条]+条" '这里各显其能输入正则表达式(根据自己的需求)
  6.       .Global = True: .MultiLine = True: '.IgnoreCase = False
  7.       For Each mt In .Execute(act.Text) '整个文档内容作为“目标文本”进行查找
  8.          m = mt.FirstIndex: n = mt.Length
  9.          Set oRang = ActiveDocument.Range(act.Start + m, act.Start + m + n)
  10.          oRang.Bold = True '字符加粗,有一系列的修改格式(根据自己的需求)
  11.       Next
  12.    End With
  13. End Sub
复制代码

2、有表格单有不关心表格,可以在表格之外的段落而遍历其余每一个段落:
  1. Sub Word文档中修改格式()
  2.    Dim i As Paragraph, mt, oRang As Range, n%, m%
  3.    With CreateObject("vbscript.regexp")
  4.       .Pattern = "^第[^条]+条" '这里各显其能输入正则表达式(根据自己的需求)
  5.       .Global = True   ': .IgnoreCase = False: .MultiLine = True
  6.       For Each i In ActiveDocument.Paragraphs
  7.          If Not i.Range.Information(wdWithInTable) Then '如果段落range对象不在表格内
  8.             For Each mt In .Execute(i.Range.Text)
  9.                m = mt.FirstIndex: n = mt.Length
  10.                Set oRang = ActiveDocument.Range(i.Range.Start + m, i.Range.Start + m + n)
  11.                oRang.Bold = True '字符加粗,有一系列的修改格式(根据自己的需求)
  12.             Next
  13.          End If
  14.       Next
  15.    End With
  16. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-11-20 12:41 | 显示全部楼层
小花鹿 发表于 2016-11-20 10:11
第一段代码修改了一下,排除表格,不知对不对?
Sub Word文档中修改格式()
    Dim i As Paragraph, mt,  ...

从根本上来看,Word 文档不过是一个巨大的字符流。人们倾向于认为文档是单词、句子和段落的集合。但实际上,文档就是一些字符。每个字符都有一定的作用。某些字符是字母、空格或制表符,另一些字符是段落标记或分页符。
但是,文档中如果有表格:(罪魁祸首:单元格结束符),正则中用 \x07 或者 \u0007 来表示这个字符。
1、把整个文档当做“目标文本”的时候,word中自身的find对象是找不到这个“罪魁祸首:单元格结束符”,因此word在统计字符的时候这个“单元格结束符”是“没有统计的”。但是正则又能查找到这个字符,那么就存在一个矛盾:range对象的Start属性是从文档(注意:这时候整个文档作为一个目标字符串)最开始0计算到整个文档未的数量 而通过正则查找到的对象属性FirstIndex的起始位置与range对象的Start属性得到的位置就不准确了,所以会出错!
2、把每一个段落当做“目标文本”的时候,情况就不一样了!那就定位准确了,不详述了。
3、所以在word中使用正则的时候注意:什么时候把word中什么对象(文档、段落、单元格等)作为正则的目标文本来进行查找是至关重要的!!!
4、本帖主要是阐述wordvba中怎么充分利用正则对象来扩展find对象的不足。比如这个单元格结束符find对象就无能为力,当然还有find对象无能为力的还比较多:这涉及到word通配符及表达式与正则表达式之间的差别了!!!这个不是本帖的讨论范围了。


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2016-11-20 13:10 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
duquancai 发表于 2016-11-20 12:41
从根本上来看,Word 文档不过是一个巨大的字符流。人们倾向于认为文档是单词、句子和段落的集合。但实际 ...

谢谢讲解,跟你慢慢学习
不知道实际工作中WORDVBA到底能起到多大作用?

TA的精华主题

TA的得分主题

发表于 2016-11-20 13:15 | 显示全部楼层
....谢谢 杜先生 回复,又写了几段代码,辛苦!
....谢谢 loquat 老朋友!
....区域对象 Range 和 选择对象 Selection 和 Select 方法,众所周知,简单地说,Range 对象操作起来,光标是不移动的,速度比较快;而 Selection对象操作起来,要用 Select 方法选定,大大影响了处理速度。
....但我在测试 VBA宏 运行时间时,发现有时用 Selection 对象处理却比 Range 对象稍微快一点,也许未进行大文本测试。——现在我追求代码越少越好,能少一行就少一行,代码太多如果用不上就纯属浪费了。
....昨晚,我也查找了 vbscript.regexp 对象的一些相关知识,初步了解了它有 3 个属性,3 个方法等,但后来感觉还是一头雾水。
....查找时勾选通配符(附加 @ 字符),这还是最近向 杜先生 学到的呢!以前看到过别人写的代码,我自己并未学会,现在用这个方法觉得真不错。——最近我也会使用 Do While...Loop + 查找操作了,以前这个循环我只会 Do...Loop ,结束条件在中间写。连我最爱的至宝 For Each...Next 也放弃了,能不用就不用,尽量用 Do While...Loop 循环。
....我会录制宏许多年,但真正会编辑 VBA 宏,还是最近 2011年7月才会的,过去也曾自学过 VB6,但没学会,稀里糊涂。
....最后真诚地感谢 杜先生 及 loquat 老朋友!谢谢!

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-11-20 13:18 | 显示全部楼层
小花鹿 发表于 2016-11-20 13:10
谢谢讲解,跟你慢慢学习
不知道实际工作中WORDVBA到底能起到多大作用?

实际中,大多数的操作在word的前台就完成,而不必要在后台用wordvba来操控,所以wordvba的资料非常少。如果在word前台无法操作了以及前台操作过于繁琐或者前台需要大量的重复性的操作,这是候wordvba才会登场表演!!!呵呵

TA的精华主题

TA的得分主题

发表于 2016-11-20 13:33 | 显示全部楼层
i.Range.Text
我试了,去掉Text也行,不知有什么区别
是不是i.Range代表段落中的文本,图片,图表,等等一切,而i.Range.Text只代表文本
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-25 15:48 , Processed in 0.031634 second(s), 5 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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