【说明】此文中在页眉插入跳转到目录项的超链接的代码几经改进,但改进后并未删除改进之前的代码,是为了有个对比利于学习。如果想节约时间,该步骤可直接查看该部分最后一个代码块。
对于Word
长文档,标准做法是按文章结构为不同段落指定不同大纲级别的样式,方便插入目录并在文档中灵活跳转到所需内容。这样的文档在Word
中编辑或查阅固然方便跳转,但是一旦转换为pdf
文档,阅读时跳转就不方便了,需要不停地滚动页面。
在文档中插入自动目录,转换为pdf
文件后可以方便从目录跳转到相应内容处,但要想返回目录就只能靠手工翻页或者先为pdf
文件创建书签目录。如果在编辑Word
文档时事先就建立标题段落到目录项的链接,并在每页的页眉也插入超链接,链接到本页所属标题段落对应的目录项,那么转换为pdf
文件后在任意页面都可以很方便地返回对应的目录区域。
如下图中的文档自动生成的目录:
点击其中的目录项“一、域应用基础”,可以很方便地跳到对应的大纲级别为1、样式名称为“标题 1”的段落所在位置,如下图:
但是点击图中的“标题 1”段落“一、域应用基础”,无法返回目录中相应的目录项。此外,如果在这一小节中阅读几页后,就无法直观地看出当前页面属于哪一节的内容(可以通过在页眉中插入styleref
域实现这个功能,但styleref
域无法实现超链接功能),当然也无法通过点击文档中的内容跳回目录。再看下面这个页面:
从页面右上角可以很清楚地看到当前内容属于“二、域速查一览”这一节,如果想跳转到其他章节,也可以方便地点击页眉中的超链接回到目录,再从目录中跳转到其他章节。完成上图中的效果需要文档符合以下要求:
1、每个章节的标题指定了“标题 1”样式,且文档中不存在样式为“标题 1”的空行;
2、在每个章节的标题前插入了分页型分节符。
如果文档符合上述要求,通过以下四个步骤即可实现上图中的效果:
1、在文档中插入自动目录,此步骤可通过引用面板上的目录工具完成。
2、在自动目录的目录项处插入书签。
3、在各节标题处插入跳转到到对应目录项的超链接。
4、在各节页眉处插入跳转到到对应目录项的超链接。
以下介绍使用VBA
完成第2、3、4步的方法。三个步骤可以在一个宏里完成,但是文档如果很长,执行时间可能也很长,易出问题,而且很难做到以最高效率完成每一个步骤,因此用三个宏分步执行。
在自动目录的目录项处插入书签
下面的VBA
代码完成在自动目录的目录项处插入书签的功能(仅在一级目录处插入书签),原理参见代码注释:
Sub 为自动生成的目录中的目录项创建书签()
Dim aPara As Paragraph, i As Integer
On Error Resume Next
' 选择目录
ActiveDocument.TablesOfContents(1).Range.Select
' 变量i用于为目录定义的书签名编序号
i = 1
' 遍历目录项,为一级标题目录项创建书签
For Each aPara In Selection.Paragraphs
If aPara.Style = "TOC 1" And Len(aPara.Range.Text) > 1 Then
' 为一级标题建立书签,命名方式为“con_”加上序号
With ActiveDocument.Bookmarks
.DefaultSorting = wdPosition
.Add Range:=aPara.Range, _
name:="con_" & i
End With
i = i + 1
End If
Next
End Sub
从各章节标题跳回目录
下面的VBA
代码在各章节的标题处插入跳转到上一个宏生成的书签的超链接,从而提供从各章节标题跳回目录的功能:
Sub 创建标题段落到目录项的链接()
'
' 自动生成的目录只能从目录项链接到标题段落
' 此宏通过为一级目录创建书签,再在一级目录
' 对应的标题段落处插入到相应书签的链接,从
' 而建立标题段落与相应目录项的链接。
'
Dim aPara As Paragraph, i As Integer
On Error Resume Next
i = 1
' 在每一个样式为“标题 1”的段落插入超链接,目标为相应书签。
' 注意在遍历文档段落时分节符也算一个段落,所以要排除空白段落(文本长度为1的段落)
For Each aPara In ActiveDocument.Paragraphs
If aPara.Style = "标题 1" And Len(aPara.Range.Text) > 1 Then
ActiveDocument.Hyperlinks.Add Anchor:=aPara.Range, Address:="", _
SubAddress:="con_" & i
i = i + 1
End If
Next
End Sub
再补充一种效率更高的方式。上面的代码是遍历文档中所有段落,下面的代码直接在文档的标题段落中跳转,省去了对正文段落的判断:
Sub 创建标题段落到目录项的链接v2()
Dim i As Integer, title As String
' 变量title用于保存标题文本,初始值用一个不是文档标题的字符串即可,空字符串也行
title = ""
' 变量i用于计算书签编号
i = 1
' 禁止屏幕更新,避免光标跳转时屏幕滚动影响效率
Application.Scree