Word VBA 文字提取(1) —— 天蚕土豆到底有多么 “恐怖如斯”?

论坛 期权论坛 期权     
杨氏在线教学   2019-6-9 21:27   605   0
大家好!这段时间发现论坛上越来越多的同学开始询问Word VBA的问题,想必各位在学习一段时间之后,单纯提高Excel效率已经无法满足自己日渐狂野的内心了。所以本周开始,我们就通过公众号为大家讲解几个最常用的Word VBA技巧,也算对我们视频课程做的一点补充。

用Word当然是要处理文字。所以我们今天先给大家介绍第一个常用技巧——怎样从Word文档中查找关键字、并提取它的所在段落。比如,网络上一直有江湖传言,天蚕土豆最爱使用 “恐怖如斯” 四个字,其频繁程度已经令人发指。即使杨老师这样一章网文都没读完过的工作狂,也在知乎上早有耳闻。不过本着严肃客观的学术精神,我们毕竟应该亲自检验一下:这个问题到底是真实存在,还是大家夸张的形容。所以,我们不妨亲自做一个小程序看看这个词到底出现过多少次,并且把所有包含这四个字的段落都提取到一个新的文档里,以便我等学习一下:最正宗的 “天蚕派” 文法里要怎样使用 “恐怖如斯” 。




首先,杨老师从一位爱读网文的朋友那里要来了一份《斗破苍穹》的文本文件(声明:写完本文随即删除此文件,杨老师没有时间读网文,读也会支持正版)。然后用Word打开这个文本文件,再保存为 .docm 格式,以便在里面编写VBA程序。

接下来当然就是打开Word VBA编辑器,开始设计程序逻辑。对于本例任务,既然我们的目标是 “把符合条件的某个段落写入新文档” ,所以一个很自然的想法就是 “循环遍历当前文档的每一个段落,每循环到一个段落,就检查其是否符合条件 ”。那么怎样循环遍历每个段落呢?我们在《提高篇》和《实战篇》中都讲过:代表整个 Word 文档的Document 对象有一个集合属性 Paragraphs,里面存放了很多Paragraph对象,而每一个Paragraph对象就是一个段落。因此,使用 For Each 就可以遍历当前文档中的每一个段落。




这里的 ThisDocument 对象在视频课程没有介绍过,不过《深入浅出Excel VBA》一书中却讲解过一个类似的对象—— Excel 中的 ThisWorkbook。简单的说,ThisDocument 对象代表的就是“本VBA程序所在的这个文档”。由于我们的代码与《斗破苍穹》原文处于同一个文档中,所以 ThisDocument.Paragraphs 就是《斗破苍穹》的所有段落。

在找到每一个段落之后,我们又该怎样判断该段落是否 “符合条件(也就是包含 ‘恐怖如斯’)” 而应写入新文档呢?首先,假如程序中用变量 p 代表当前正在处理的段落,那么 就像《提高篇》中介绍的,p.Range 属性就代表该段落中所有文字、版式等信息;再进一步,p.Range.Text 代表的就是这个段落中的纯粹文字内容。所以,只要判断这个文字内容中是否包含 “恐怖如斯” 就能知道段落 p 该不该被作为结果。而在VBA中,判断文字包含的最简单写法,就是我们在《基础篇》中介绍的 Instr 函数!




除了 Text 外,段落对象的 Range 属性还提供了一个 Information 方法,只要给它提供不同的参数,它就可以返回给我们有关该段落的各种信息。例如,p.Range.Information (wdActiveEndPageNumber )  就可以告诉我们 “段落p的内容处于文档中的第几页”。所以利用这个方法,我们不仅可以把符合条件的段落提取到新文档中,而且还可以标记出该段落在原文档的位置,以便检索。




最后说来说去,我们到底怎样把找到的文字放进新文档中呢?这个可以算是《全民一起VBA》课程中最常出现的例行操作之一了:(1)在程序开始时用 Documents.Add 创建换一个新文档,并指定一个变量(比如 docNew )代表它;(2)每次发现有符合条件的段落时,就用 docNew.Content.InsertAfter 方法将指定的字符串添加到该文档的末尾。Document 的这个 Content 对象我们在视频课程中没有介绍过,不过顾名思义,就是文档全体内容的含义,而 InsertAfter  自然就是在后面添加,相信大家一读就懂。




以上就是本例中所有可能用到的知识点。利用它们,我们就能写出一个提取程序,核心代码总共只有 6 行:





程序的代码含义已经用注释语句标清,接下来我们运行一下,就会得到一个新的Word文档,里面就是史上最全的天蚕派恐怖如斯权威例句:



统计一下,“恐怖如斯” 一共出现了18次。相比于总计 5879页513万字 的体量,杨老师倒觉得还真不算滥用 ,个人以为网上的指责有点夸大其词了。不过能在几年里连写500万字,不得不说作者的耐力着实是“恐怖如斯”!

给作者正名后意犹未尽,杨老师又把程序稍作修改,让它只输出页码到Excel中,随后做了极简单的频度分析,如下图所示。



可以看到,在作者写前3000页时,每一千页出现三个“恐怖如斯”,非常平均;而在写作3000页到4000页时,一千页里就出现了六次,相比之前可以算是 “高发” 了。假如作者写作本书时的更新速度是恒定的,那么可以不负责任的推断,网络上对于本书“滥用恐怖如斯”的评价也许就出现在这一时期。同样,或许就是因为作者此时注意到了这种评价,所以在后面写作第4000到6000页时格外留神,每一千页只使用了一次“恐怖如斯”,比前期作品还要少很多。当然,以上分析只是基于对这些数字的猜测,杨老师并没有与网络舆情进行参照查证。如果同学们喜欢这一题材,可以自行搜集整理相关网络话题的演变数据、并结合百度热度等工具,做一个完善的 “互联网文学创作平台中网络评论对作者行文风格的影响研究” (一瞬间回到了当年指导毕业生选题的日子……)

当然,这本小说只是用来举个例子,本文真正希望大家了解的是使用Word VBA实现指定段落提取的思路和知识点。不过需要指出的是——本文所用的方法虽然易于理解(都是《全民一起VBA》中讲过的知识和思路),但并不是速度最快的方法。比如本程序在杨老师电脑上运行时,整整耗时20秒,而如果采用另一个技巧——Word VAB的 Find 方法,则会在 2 秒钟内全部搞定!那么怎样使用 Find 方法呢?我们下周就给大家科普一下。


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP