
从网上下载的讲义资料往往带有试题来源标记,既占位置,也不重要。如上图的时间地点等内容。统一清理的一般方法是使用通配符查找替换,虽然在单一场景下基本可行,但需要在每个文档中重复手动设置规则,并且由于缺乏预览机制,在全文替换时,用户无法直观看到将被删除的内容,从而增加了误操作风险。
编写 Word 中的 VBA 宏,可以实现自动化处理,避免以上缺点。代码以如下框架构造:

设置方法:打开 Word → 文件 → 选项 → 自定义功能区 → 勾选“开发工具”;按 Alt+F11 打开 VBA 编辑器 → 在左侧选中 Normal → 插入 → 模块 → 粘贴代码 ;然后添加到自定义功能区:文件 → 选项 → 自定义功能区 → 右侧新建选项卡或新建组 → 左侧下拉选择“宏” → 选中你的宏点击“添加” → 点击“重命名”修改名称和图标 → 确定。再从文件 → 选项 → 信任中心 → 信任中心设置 → 宏设置 → 选择“启用所有宏”。即可在功能区直接点击使用。正确设置后运行,需要删除的题目来源信息会显示在通知窗口。信息过多时会分页显示,逐一确认后将执行删除。

Sub DeleteSource()Dim doc As DocumentSet doc = ActiveDocument'====================================' 统一预处理:将手动换行替换为段落标记'====================================With doc.Content.Find.Text = "^l".Replacement.Text = "^p".Execute Replace:=wdReplaceAllEnd With'===============' 设置正则表达式'===============Dim reg As ObjectSet reg = CreateObject("VBScript.RegExp")' 匹配规则:左括号-四位或两位年份-其它内容-右括号reg.pattern = "[((](\d{4}|\d{2}-\d{2})[^((]*?[))]"reg.Global = False'==========================' 设置删除范围与预览显示集合'==========================Dim delRanges As CollectionSet delRanges = New CollectionDim pages As CollectionSet pages = New CollectionDim currentPage As StringDim lineCount As LongcurrentPage = ""lineCount = 0'=============' 遍历段落匹配'=============Dim para As ParagraphDim matches As Object, match As ObjectFor Each para In doc.Paragraphs' 先判断是否可能匹配Set matches = reg.Execute(para.Range.Text)If matches.Count > 0 ThenSet match = matches(0)' 过滤条件跳过“多选”If InStr(match.Value, "多选") = 0 Then' 记录预览内容currentPage = currentPage & match.Value & vbCrLflineCount = lineCount + 1If lineCount Mod 30 = 0 Thenpages.Add currentPagecurrentPage = ""End If' 记录删除范围delRanges.Add Array( _para.Range.Start + match.FirstIndex, _para.Range.Start + match.FirstIndex + match.Length _)End IfEnd IfNext para' 添加剩下的预览内容到最后一个预览页If currentPage <> "" Thenpages.Add currentPageEnd If'================' 没有预览文本直接退出'================If lineCount > 0 Then'=========' 预览阶段'=========' - 未确认则不进入删除逻辑If Not PreviewPage(pages, lineCount) ThenExit SubEnd If'=========' 执行删除'=========' 把所有删除合并成 1 步Application.UndoRecord.StartCustomRecord "Delete Source"Dim i As Long' 倒序删除,防止前面删除影响后面索引For i = delRanges.Count To 1 Step -1doc.Range( _delRanges(i)(0), _delRanges(i)(1) _).DeleteNext i' 之后可以 1 次 ctrl+z 全部撤消Application.UndoRecord.EndCustomRecordEnd IfEnd SubFunction PreviewPage(pages As Collection, totalCount As Long) As Boolean'===================' 分页参数, 分页循环'===================Dim startLine As LongDim endLine As LongDim i As LongFor i = 1 To pages.CountstartLine = (i - 1) * 30 + 1endLine = i * 30If endLine > totalCount Then endLine = totalCountIf MsgBox( _"将删除内容共 " & totalCount & " 条" & vbCrLf & _"当前显示:第 " & startLine & _" 条 - 第 " & endLine & " 条" & vbCrLf & _String(45, "-") & vbCrLf & _pages(i) & _String(45, "-") & vbCrLf & _"是否确认?", _vbYesNo + vbQuestion, "预览") = vbNo ThenPreviewPage = FalseExit FunctionEnd IfNext i' 全部确认通过PreviewPage = TrueEnd Function
夜雨聆风