大家好!這段時間發現論壇上越來越多的同學開始詢問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 方法呢?我們下周就給大家科普一下。