Word 借助VBA一键实现插入交叉引用
最近写论文的时候,经常需要向上或向下插入题注的交叉引用,word 自带的界面往往需要操作多次,才能实现插入。而平时使用较多的只是交叉引用附近的题注,比如如图1.1所示,在图1.1中等,距离较远的引用则可以直接复制已经存在的交叉引用项,复制的项只要保留原格式复制,仍然是存在超链接的。所以可以借助 VBA 写一个函数,用来在当前位置插入向上或向下距离最近指定的题注类型,然后给指定的脚本指定快捷键,就可以实现一键插入。
首先 Word VBA中关于题注和插入交叉引用,我只找到两个函数,分别是 GetCrossReferenceItems 和 InsertCrossReference,一个是获得当前所有的特定题注,一个是插入指定的题注,其中InsertCrossReference 需要使用 GetCrossReferenceItems 来确定插入的题注所在的位置。
由于 GetCrossReferenceItems 的对象是全文,因此需要首先找到距离最近的题注所在的位置,然后取得其相应的特征值,最后与GetCrossReferenceItems返回的结果进行对比,确定其索引值后,再使用InsertCrossReference进行插入。
根据上述思路, 整体代码如下:
- Public Function autoInsertReferece(crossRefName As String, direction As Integer) As Boolean
- ' 功能:自动插入最靠近当前位置的题注,需要指定向上或向下搜索
- ' 变量名:
- ' crossRefName: 题注名
- ' direction: 方向 0-> 向下搜索 其它整数->向上搜索
- ' 注意事项:
- ' 必须要文档中定义相应的标签
- ' 先找到向上或向下距离最近的标注所在的段落,获得其文本后,再确定其在所有该类题注中所处的位置
- ' 工具》引用》Microsoft VBScript Regular Expressions 5.5打勾
- Dim target_para As Long
- Dim flag As Boolean
- Dim flagUpdate As Boolean
- Dim rngParagraph As Range
- Dim currentParaNum As Long
- Dim endParaNum As Long
- target_para =
- flag = False
- flagUpdate = False
- ' 根据方向做不同处理, 找到距离最近的题注对象,获得其所在的段落
- currentParaNum = ActiveDocument.Range(, Selection.End).Paragraphs.Count '获得当前的段落数
- Set rngParagraph = ActiveDocument.Paragraphs(currentParaNum).Range
- If direction = Then
- endParaNum = ActiveDocument.Paragraphs.Count
- rngParagraph.SetRange Start:=rngParagraph.Start, _
- End:=ActiveDocument.Paragraphs(endParaNum).Range.End
- target_para = findTargetPara(crossRefName, direction, rngParagraph)
- Else
- '以20段为周期,向上遍历,直到行首
- Dim para_step As Integer
- para_step =
- Do While currentParaNum > para_step
- currentParaNum = currentParaNum - para_step
- rngParagraph.SetRange Start:=rngParagraph.End, _
- End:=ActiveDocument.Paragraphs(currentParaNum).Range.End
- target_para = findTargetPara(crossRefName, direction, rngParagraph)
- If target_para <> Then
- Exit Do
- End If
- '重新设置 range
- Set rngParagraph = ActiveDocument.Paragraphs(currentParaNum).Range
- Loop
- '没找到目标段落,处理到开关
- If target_para = Then
- rngParagraph.SetRange Start:=rngParagraph.Start, _
- End:=ActiveDocument.Paragraphs().Range.End
- target_para = findTargetPara(crossRefName, direction, rngParagraph)
- End If
- End If
- '找到段落后进行相应的处理
- If target_para <> Then
- ' 获取目标段落的文本
- Dim target_text As String
- ActiveDocument.Paragraphs(target_para).Range.Fields.Update '更新目标域代码,以防出错
- target_text = ActiveDocument.Paragraphs(target_para).Range.Text
- ' 正则表达式设置
- Dim regEx, Match, Matches '创建变量
- Set regEx = New RegExp '创建正则表达式
- regEx.Pattern = "\s*\d+(.\d+)*" '设置匹配字符串, 匹配 2 2.1 2.1.1等
- regEx.IgnoreCase = True '设置是否区分大小写
- regEx.Global = True '设置全程匹配
- Set Match = regEx.Execute(target_text) '执行搜索
- target_item = Match.Item().Value '目标题注
- allCrossRef = ActiveDocument.GetCrossReferenceItems(crossRefName)
- For I = To UBound(allCrossRef) '遍历所有的给定题注直至找到目标题注
- Set Match = regEx.Execute(allCrossRef(I))
- compare_item = Match.Item().Value
- If target_item = compare_item Then
- If crossRefName <> "公式" Then
- ' 非公式只引用题注
- Selection.InsertCrossReference ReferenceType:=crossRefName, ReferenceKind:= _
- wdOnlyLabelAndNumber, ReferenceItem:=CStr(I), InsertAsHyperlink:=True, _
- IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
- flag = True
- Else
- ' 公式全文引用
- Selection.InsertCrossReference ReferenceType:=crossRefName, ReferenceKind:= _
- wdEntireCaption, ReferenceItem:=CStr(I), InsertAsHyperlink:=True, _
- IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
- End If
- Selection.TypeText Text:=" " '输出一个空格
- flag = True
- Exit For
- End If
- Next
- End If
- autoInsertReferece = flag
- End Function
- Private Function findTargetPara(crossRefName As String, direction As Integer, rngParagraph As Range)
- '在指定的范围内查找目标段落
- '参数说明
- 'direction = 0 向下搜索,找到后立即跳出,否则向上搜索,完全遍历后再确定是否找到目标项
- Dim target_para As Long
- target_para =
- For Each para In rngParagraph.Paragraphs:
- 'If para.Range.Tables.Count = 0 Then '跳过表格,以加快处理速度
- For Each oField In para.Range.Fields
- With oField
- If .Code.Text = " SEQ " + crossRefName + " \* ARABIC \s 1 " Then
- target_para = ActiveDocument.Range(, para.Range.End).Paragraphs.Count
- If direction = Then
- Exit For
- End If
- End If
- End With
- Next
- If direction = And target_para <> Then
- Exit For
- End If
- Next
- findTargetPara = target_para
- End Function
- Sub InsertPictureCrossReferenceDown()
- autoInsertReferece "图",
- End Sub
- Sub InsertPictureCrossReferenceUp()
- autoInsertReferece "图",
- End Sub
- Sub InsertTableCrossReferenceDown()
- autoInsertReferece "表",
- End Sub
- Sub InsertTableCrossReferenceUp()
- autoInsertReferece "表",
- End Sub
- Sub InsertMathCrossReferenceDown()
- Selection.TypeText Text:=" "
- flag = autoInsertReferece("公式", )
- If Not flag Then
- Selection.TypeBackspace
- End If
- End Sub
- Sub InsertMathCrossReferenceUp()
- Selection.TypeText Text:=" "
- flag = autoInsertReferece("公式", )
- If Not flag Then
- Selection.TypeBackspace
- End If
- End Sub
代码中 autoInsertReferece 为主体实现函数,由于 Word 中的 Range 遍历只能从上向下进行,而自己用索引去遍历,运行速度会非常慢。所以,当需要向上搜索目标题注时,只能以一个一个段落范围的range向前推进,如果一个范围搜索后,找到结果,就说明其为最后的结果;而向下搜索时,则可以直接把 range 设为从当前到文未,找到目标题注后,即可立即停止搜索。findTargetPara 的主要功能是在给定的范围内,找到题注所在的段落。
最后的相应 Sub 函数是具体的应用,由于我对文中的公式有特殊的处理,插入时需要引用题注和内容,其余的默认只引用题注。实际使用时,可以给相应的 Sub 设定快捷键,比如将 InsertPictureCrossReferenceDown 宏的快捷键设为 Alt + 1,然后在Word文档中按 Alt + 1 键,即可在当前位置插入距离当前位置最近的题注(向下搜索)。
宏的使用及快捷键设置参照 Onenote代码高亮的实现方法
Word 借助VBA一键实现插入交叉引用的更多相关文章
- Word 图片表格自动编号、交叉引用、批量更改图片标题格式、生成图录和表录
1. 前言 论文往往里往往需要插入很多图片,下放需要标上 图a-b,其中 a 是章节号码,b是该章节中第几张图.比如第一章第二副图就是 图1-2.但是有个问题,每次我们插入了一张图或删掉了一张,前后的 ...
- 第五周 Word注释与交叉引用
第五周 Word注释与交叉引用 教学时间 2013-3-26 教学课时 2 教案序号 4 教学目标 1.掌握脚注.尾注.题注的概念和应用 2.掌握交叉引用的操作方法 教学过程: 复习提问 1.如何利用 ...
- 【Word】自动化参考文献-交叉引用
第一步:设置参考文献标号 开始-定义新编号格式中,定义参考文献式的方框编号: 这里注意不要把他原来的数字去掉 第二步:选择交叉引用 插入-交叉引用: 第三步:更新标号 如果更新标号,使用右键-更新域. ...
- Word2010设置题注和交叉引用方法
设置题注 点击图片-->右键-->插入题注-->新建标签:“图”-->选择新建标签“图”-->修改“编号”-->勾选包含章节号-->设置章节起始样式:标题2- ...
- Word操作之参考文献自动关联和引用
转载:https://blog.csdn.net/qq_40078121/article/details/88681605 编号选项->定义新编号格式: 选择插入->交叉引用选项: 然后选 ...
- WPS2012交叉引用技巧,word比wps这点强更新參考文献
WPS2012交叉引用技巧,word比wps这点强更新參考文献 到时生成仅仅有有一条线,好像WPS不能够,word能够,假设谁知道能够补充.^_^ 1.写论文,參考文献的改动非 ...
- WPS2012交叉引用提示word比wps这种强烈的更新参考
WPS2012交叉引用技巧,word比wps这点强更新參考文献 到时生成仅仅有有一条线,好像WPS不能够,word能够,假设谁知道能够补充.^_^ 1.写论文,參考文献的改动非 ...
- word正文中怎么引用章节编号、怎么引用图片表格编号、交叉引用
摘自:https://blog.csdn.net/m0_37549050/article/details/88823135 在写文档的时候,可能会出现需要在文档中引用其它段落的编号.比如文档分了章节, ...
- word交叉引用公式编号时和连公式一起引用
如下所示: 假定一副待处理图像中的灰度值个数为m,灰度值为i的像素个数为 个,那么图像中的总像素数为N,公式如m=x+y (2)所示: m=x+y ...
随机推荐
- (转)C#抽象类和接口对比
c#中抽象类(abstract)和接口(interface)的相同点与区别 转自:http://blog.csdn.net/fxh_hua/archive/2009/08/20/4464739.as ...
- List和set集合:交集、差集、合集的区别retainAll,removeAll、addAll
set .list集合的交集(retainAll).差集(removeAll)是没有区别的都是一样的. set .list集合的合集addAll是有区别的:set可以去重复:list不去重复 publ ...
- Error: Can't set headers after they are sent.
Error: Can't set headers after they are sent. 错误:无法设置头信息后发送. 具体报错: 看到了一下代码,自己写错了 没有进行错误判断,两个条件都直接返回, ...
- C#实现程序单例日志输出
对于一个完整的程序系统,一个日志记录是必不可少的.可以用它来记录程序在运行过程中的运行状态和报错信息.比如,那些不想通过弹框提示的错误,程序执行过程中捕获的异常等. 首先,在你的解决方案中,适当的目录 ...
- MySQL存储过程多条修改语句
DROP procedure Sel_Function_ActivityPastDueDELIMITER $$DROP procedure IF EXISTS`shouyi`.`Sel_Functio ...
- 第12届D2前端技术论坛
第12届D2前端技术论坛 最近参加了阿里的D2前端技术论坛,听了一天的报告,收获良多,下面对几场报告做一个记录. 自己选择听的主线也是从: 实践应用 -> 管理 -> 性能 -> 新 ...
- JavaScript中函数对象和对象的区别
function Test (word) { console.log (word); } Test('哈哈,我是函数'); new Test('哈哈,我是对象'); //将以上的调用方式换种通俗易懂的 ...
- 64位Windows系统下32位应用程序连接MySql
1.首先得安装“Connector/ODBC”,就是Mysql的ODBC驱动,这个是与应用程序相关的,而不是与操作系统相关的,也就是说,不管你的系统是x64还是x86,只要你的应用程序是x86的那么, ...
- HDU 3681 Prison Break 越狱(状压DP,变形)
题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...
- Linux 的数字权限意义
三个组 每个都有三个权限 r w x每个权限用二进制 0 和 1 标示 1即为有此权限 0 标示无权限 ower group other r w x r w x r w x 每个组 ...