在VBA中结合正则表达式和查找功能给文档添加交叉连接
在VBA
中搜索文本有两种方式可用,一种是利用Range.Find
对象(更常见的形式可能是Selection.Find
,Selection
是Range
的子类,Selection.Find
其实就是特殊的Range.Find
),另一种方法是利用正则表达式,但是,这两种方法各有各的问题。
Range.Find
对象的问题是正则表达式功能太差。尽管可以通过将MatchWildcards
属性设置为True
来使用通配符,但通配符表达式并不完全兼容常用的正则表达式语法,而且不同版本的VBA
支持的通配符表达式语法还不一样,例如,我在Word2013
中使用通配符表达式(#\d+)|([①-⑨])
,它居然因为使用了|
操作符,就不能得到预期的结果。
正则表达式的问题则是无法准确定位匹配项在文档中的位置。尽管理论上可以用下面这样的方法定位到匹配项,但是实际运行就会发现除了第一个能定位到,后面的全部会出错:
Dim i As Long
Dim rng As Word.Range
For i = 0 To matchColl.Count - 1' 根据匹配项的位置信息创建Word.Range对象Set rng = doc.Range(matchColl(i).FirstIndex + 1, matchColl(i).FirstIndex + matchColl(i).Length + 1)rng.Select ' 选择第i个匹配项进行其他处理,如打印匹配项内容等
Next i
为了各取所长避其所短,比较好的思路是将二者结合,先用正则表达式查找匹配项,再用Range.Find
来定位匹配项。下面就用这个思路在Word
文档主体内容中的注释引用和注释内容中的注释编号之间建立交叉连接来进行一个实践。
我们有这样一个文档:
要在这个文档中建立如图所描述的交叉链接,需要在主体内容的注释引用和注释区的注释编号位置分别插入书签以及连接到对方的超链接。当然,这里的查找内容用简单的通配符表达式也可以完成任务,但是如果编辑过程中出现失误,导致部分注释引用被替换成了别的样式,重新修复的时候就不得不用到|
操作符,这时候Range.Find
对象就不见得能按预期完成任务了。
下面的宏要求先在文档中选择主体内容,然后运行宏对主体内容进行处理,处理完后再选择注释中的内容,再次运行宏处理注释,交叉链接就建立完毕。我将插入书签和链接的功能写成了如下函数:
Function DealCrossLink(searchRange As Range, regStr As String, chapter As Integer, _Optional useSelection As Boolean = True, Optional contentStr As String = "cont_c", _Optional commentStr As String = "comm_c", Optional formatStr As String = "000", _Optional ignoreCase As Boolean = True)''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 参数说明:' searchRange:搜索范围' regStr:应匹配的正则表达式' chapter:当前书签的章节序号' useSelection:插入超链接时显示的文本是否用在文档中选择的文本,默认为True,否则显示#加阿拉伯数字' contentStr,commentStr:区分主体内容区和注释区的字符串' formatStr:注释引用序数扩充到固定长度所用的格式字符串,默认扩充为至少3字符("000")' ignoreCase:匹配内容时是否忽略大小写,默认为True'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Dim regEx As RegExpDim match, matches As ObjectDim tmpRange As RangeDim i%, serial$, hyperText$Set regEx = CreateObject("VBScript.RegExp")With regEx.Global = True.ignoreCase = ignoreCase.Pattern = regStr 'End WithSet matches = regEx.Execute(searchRange.Text) ' 在搜索范围内执行匹配操作searchRange.Collapse Direction:=wdCollapseStart ' 将搜搜范围折叠到开头For Each match In matchesSet tmpRange = searchRangeWith tmpRange.Find.Text = match.Value.Forward = True.Wrap = 1 ' wdFindContinue.Execute ' 执行查找,定位匹配项的位置If tmpRange.Find.found Then' 注释引用和注释区注释编号设置为上标tmpRange.Font.Superscript = -1i = i + 1 ' 计算当前书签序号,用于书签命名serial = "_" & Format(i, formatStr) ' 将序号扩充为等长字符串,默认长度为3("000")With ActiveDocument.Bookmarks.Add Range:=tmpRange, Name:=contentStr & chapter & serial.DefaultSorting = wdSortByName.ShowHidden = FalseEnd WithIf useSelection Then hyperText = tmpRange.Text Else hyperText = "#" & iActiveDocument.Hyperlinks.Add Anchor:=tmpRange, Address:="", _SubAddress:=commentStr & chapter & serial, ScreenTip:="", TextToDisplay:=hyperText' 调整搜索范围起始位置,准备定位下一个匹配项searchRange.SetRange Start:=tmpRange.End, End:=searchRange.EndEnd IfEnd WithNext matchEnd Function
上面的代码也展示了在选定区域中进行查找的方法。
调用上述函数的代码如下:
Sub test()Dim chapter% chapter = 1' 处理主体内容中的书签和超链接,超链接文本用文档中的匹配文本DealCrossLink Selection.Range, regStr, chapter' 处理注释内容中的书签和超链接,超链接文本用文档中的匹配文本
' DealCrossLink Selection.Range, regStr, chapter, contentStr:="comm_c", commentStr:="cont_c"' 处理主体内容中的书签和超链接,超链接文本用#号连接阿拉伯数字编号
' DealCrossLink Selection.Range, regStr, chapter,False
' ' 处理注释内容中的书签和超链接,超链接文本用#号连接阿拉伯数字编号
' DealCrossLink Selection.Range, regStr, chapter, contentStr:="comm_c", commentStr:="cont_c", FalseEnd Sub
可以根据需要,将以上代码中最后四行具体调用函数的语句选择一条执行。
下面是选择主体内容后执行第一条语句的结果:
下面是选择注释内容执行第四条语句的结果:
主体内容中的“①”与注释内容中的“#1”之间成功建立起了交叉链接,其它编号也是如此。
如果觉得每次选一个段落有点麻烦,可以考虑在诗标题和校注前先插入连续型分节符(可参阅文档目录、页眉和文档章节标题之间插入相互链接的最佳实践中的过程Sub 指定级别标题前插入分节符()
),然后遍历档中的所有节,各节第一段文本为“【校注】”的即为注释区,否则当做主体内容区,然后在调用DealCrossLink
函数时将section.Range
取代Selection.Range
作为第一个参数传入,即可无需选择内容建立全文的交叉链接。示例代码如下:
Sub 全文主体内容的注释引用与注释区注释序号之间建立交叉链接()Dim aSec As Section, chapter%, regStr$, addChapter As Boolean'是否递增章节序号。只有处理完了一个注释区后才递增章节号,以确保对应的主体内容和注释章节号相同addChapter = TrueregStr = "〔\d+〕"For Each aSec In ActiveDocument.SectionsIf addChapter Then chapter = chapter + 1If Left(aSec.Range.Paragraphs(1).Range.Text, 4) = "【注释】" ThenDealCrossLink aSec.Range, regStr, chapter, contentStr:="comm_c", commentStr:="cont_c"addChapter = TrueElseDealCrossLink aSec.Range, regStr, chapteraddChapter = FalseEnd IfNext
End Sub
相关文章:

在VBA中结合正则表达式和查找功能给文档添加交叉连接
在VBA中搜索文本有两种方式可用,一种是利用Range.Find对象(更常见的形式可能是Selection.Find,Selection是Range的子类,Selection.Find其实就是特殊的Range.Find),另一种方法是利用正则表达式,但…...

动手学深度学习-多层感知机-7前向传播、反向传播和计算图
目录 前向传播 前向传播计算图 反向传播 训练神经网络 小结 我们已经学习了如何用小批量随机梯度下降训练模型。 然而当实现该算法时,我们只考虑了通过前向传播(forward propagation)所涉及的计算。 在计算梯度时,我们只调用…...
【Python】基于Python的CI/CD工具链:实现自动化构建与发布
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在现代软件开发中,持续集成(CI)和持续交付(CD)已经成为提高开发效率和软件质量的重要实践。CI/CD流程帮助开发团队自动化构建、测试、…...

FPGA-PS端编程1:
目标 在小梅哥的zynq 7015上,完成以下目标: 读取 S1 按键的电平, 当 S1 按键为按下状态时,驱动 PS LED 以 1S 的频率闪烁(注意理解 1S 的频率闪烁和 1S的时间翻转两种描述之间的差别), 当 S1 释放后,停止…...

自制数据库迁移工具-C版-06-HappySunshineV1.5-(支持南大Gbase8a、PostgreSQL、达梦DM)
目录 一、环境信息 二、简述 三、架构图 四、升级点 五、支持功能 六、后续计划支持功能 七、安装包下载地址 八、配置参数介绍 九、安装步骤 1、用户创建 2、安装包解压 3、环境变量配置 4、环境变量生效 5、动态库链接检验 (1)HsManage…...
了解RPC
本文来自智谱清言 --------- RPC(Remote Procedure Call,远程过程调用)是一种允许程序调用位于远程计算机上的子程序或服务的技术。这种技术使得构建分布式计算变得更加容易,因为它提供了强大的远程调用能力,同时保持…...
centos7 安装docker
文章目录 介绍docker特点安装1.前提准备2.下载1.移除旧版docker命令2.切换centos7的镜像源3.配置docker yum源4.安装最新docker5.输入命令验证docker 安装是否成功6.配置docker 镜像加速7.设置为开机自启 总结 介绍 Docker是一种开源的容器化平台,旨在简化应用…...

Docker 入门:如何使用 Docker 容器化 AI 项目(一)
引言 在人工智能(AI)项目的开发和部署过程中,环境配置和依赖管理往往是开发者遇到的挑战之一。开发者通常需要在不同的机器上运行同样的代码,确保每个人使用的环境一致,才能避免 “在我的机器上可以运行”的尴尬问题。…...

LLMs之rStar:《Mutual Reasoning Makes Smaller LLMs Stronger Problem-Solvers》翻译与解读
LLMs之rStar:《Mutual Reasoning Makes Smaller LLMs Stronger Problem-Solvers》翻译与解读 导读:这篇论文提出了一种名为rStar的自我博弈互推理方法,用于增强小型语言模型 (SLMs) 的推理能力,无需微调或依赖更强大的模型。rStar…...
【RK3588 Linux 5.x 内核编程】-内核中断与ThreadedIRQ
内核中断与ThreadedIRQ 文章目录 内核中断与ThreadedIRQ1、Threaded IRQ介绍2、Threaded IRQ相关API3、驱动实现4、驱动验证当 Interrupt 触发时,Interrupt handler 应该执行得非常快,它不应该运行更多的时间(它不应该执行耗时的任务)。 如果我们有执行更多任务的中断处理程…...
Message Processing With Spring Integration高级应用:自定义消息通道与端点
一、Spring Integration 简介 Spring Integration 是 Spring 框架的扩展,支持企业集成模式(EIP),提供轻量级的消息处理功能,帮助开发者构建可维护、可测试的企业集成解决方案。 核心目标: 提供简单的模型…...

S32K324 MCAL中的Postbuild和PreCompile使用
文章目录 前言Postbuild和PreCompile的概念MCAL中配置差异总结 前言 之前一直看到MCAL配置中有这个Postbuild和PreCompile的配置,但是不太清楚这两个的区别和使用方法。最近在使用中出现了相关问题,本文介绍一下MCAL中这两种配置的区别和使用。 Postbu…...

kubeadm_k8s_v1.31高可用部署教程
kubeadm_k8s_v1.31高可用部署教程 实验环境部署拓扑图**部署署架构****Load Balance****Control plane node****Worker node****资源分配(8台虚拟机)**集群列表 前置准备关闭swap开启ipv4转发更多设置 1、Verify the MAC address and product_uuid are u…...

【AI日记】24.12.22 容忍与自由 | 环境因素和个人因素
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 内容:看 OpenAi 这周的发布会和其他 AI 新闻,大佬视频时间:3 小时 读书 书名:富兰克林自传时间:1 小时评估:读完,总体…...
【Java基础面试题030】Java和Go的区别?
回答重点 可以从语言的设计理念、并发模型、内存管理、生态系统与应用场景来说: 1)语言设计理念: Java:Java是一种面向对象编程语言,强调继承、多态和封装等OOP特性。它运行在Java虚拟机(JVM)…...
学习嵩山版《Java 开发手册》:编程规约 - 常量定义(P5)
概述 《Java 开发手册》是阿里巴巴集团技术团队的集体智慧结晶和经验总结,他旨在提升开发效率和代码质量 《Java 开发手册》是一本极具价值的 Java 开发规范指南,对于提升开发者的综合素质和代码质量具有重要意义 学习《Java 开发手册》是一个提升 Jav…...

洛谷 P1595 信封问题 C语言递归
题目描述 某人写了 n 封信和 n 个信封,如果所有的信都装错了信封。求所有信都装错信封共有多少种不同情况。 输入格式 一个信封数 n,保证 n≤20。 输出格式 一个整数,代表有多少种情况。 输入输出样例 输入 #1 2 输出 #1 1 输入 #2 …...
QT创建一个模板槽和信号刷新UI
文章目录 信号与槽的声明work.cpp 信号与槽的连接 在Qt中,若您想设计一个仅含一个信号和槽函数框架,用以刷新UI上多个类型相同但可能属性各异的控件,我们可以借助QVariant的灵活性来传递不同种类的数据,同时利用控件的名称或某种标…...

【计算机视觉基础CV-图像分类】01- 从历史源头到深度时代:一文读懂计算机视觉的进化脉络、核心任务与产业蓝图
1.计算机视觉定义 计算机视觉(Computer Vision)是一个多学科交叉的研究领域,它的核心目标是使计算机能够像人类一样“看”并“理解”视觉信息。换句话说,它希望赋予计算机从图像、视频中自动提取、有意义地分析、理解并解释视觉场…...

C# cad启动自动加载启动插件、类库编译 多个dll合并为一个
可以通过引用costura.fody的包,编译后直接变为一个dll 自动加载写入注册表、激活码功能: 【CAD二次开发教程-实例18-启动加载与自动运行-哔哩哔哩】 https://b23.tv/lKnki3f https://gitee.com/zhuhao1912/cad-atuo-register-and-active...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...