【问题标题】:Converting Headings to Bookmarks将标题转换为书签
【发布时间】:2020-09-22 00:11:39
【问题描述】:

我正在使用Office 2016。我想制作一个循环遍历文档中每个标题的宏,然后使用标题文本(根据需要修改)作为书签名称在标题的位置创建一个书签。大部分标题都是X.X.X.X格式,如"3.3.4.1. sometexthere"

我仍然是使用VBA 的初学者,但经过大量谷歌搜索后,我设法改编了一些几乎可以工作的科学怪人代码:

Sub HeadingsToBookmarks()
    Dim heading As Range
    Set heading = ActiveDocument.Range(Start:=0, End:=0)
    Do
        Dim current As Long
        current = heading.Start
        Set heading = heading.GoTo(What:=wdGoToHeading, Which:=wdGoToNext)
        If heading.Start = current Then
            Exit Do
        End If
        ActiveDocument.Bookmarks.Add MakeValidBMName(heading.Paragraphs(1).Range.Text), Range:=heading.Paragraphs(1).Range
    Loop
End Sub

Function MakeValidBMName(strIn As String)
    Dim pFirstChr As String
    Dim i As Long
    Dim tempStr As String
    strIn = Trim(strIn)
    pFirstChr = Left(strIn, 1)
    If Not pFirstChr Like "[A-Za-z]" Then
        strIn = "Section_" & strIn
    End If
    For i = 1 To Len(strIn)
        Select Case Asc(Mid$(strIn, i, 1))
            Case 49 To 58, 65 To 90, 97 To 122
                tempStr = tempStr & Mid$(strIn, i, 1)
            Case Else
                tempStr = tempStr & "_"
        End Select
    Next i
    tempStr = Replace(tempStr, " ", " ")
    tempStr = Replace(tempStr, ":", "")

    If Right(tempStr, 1) = "_" Then
        tempStr = Left(tempStr, Len(tempStr) - 1)
    End If

    MakeValidBMName = tempStr
 End Function

这段代码几乎可以正常工作,并在某些标题(但不是全部)处制作了适当的书签。谁能帮我弄清楚我需要在这里修复什么,或者对我如何清理这段代码有其他建议?

编辑:更多信息:上面的代码转换了我一直在测试的文档中的前 5 个左右的标题,以及其他一些分散在各处的标题。执行实际转换的代码的后半部分似乎工作正常 - 问题位于循环通过每个标题的部分。后半部分将无法使用的字符转换为符合书签名称要求的字符,并将“Section_”添加到以数字开头的书签/标题的开头(因为书签不允许以数字开头)。

我的目标是能够超链接到文档中具有来自不同 Word 文档的标题的所有部分。据我所知,标准的目录创建者只允许在同一个文档中建立链接。我知道当 word 保存为 PDF 时,它可以将标题转换为书签;我希望能够做同样的事情,但保留 word 格式的文档。

很遗憾,我无法使用内置编号。我正在处理已经创建并具有特定格式的文档。

【问题讨论】:

  • 您需要提供更详细的信息。您向我们展示的代码如何确切地不起作用?只是没有找到所有的标题,还是有其他问题?您要选择的所有标题是否都以正确的标题样式格式化?究竟应该如何命名书签?稍后你想对这些书签做什么?没有这些信息,就无法为您提供准确的答案...

标签: vba ms-word


【解决方案1】:

您没有描述为什么需要书签,或者文档的未来用户将如何使用/访问书签。

MS Word 具有许多用作书签的内置功能。最好的方法是使用样式。内置的heading 样式允许一些本机导航功能(Word 自己的隐藏书签)。另外,不要重新发明轮子 - 使用内置编号。

这需要一些文档纪律。仅对标题使用标题,对非标题文本使用正文。

这些好处使这门学科值得。您可以轻松创建使用标题(甚至某些自定义样式)的目录,并且标题会显示在导航窗格中。当您保存为 PDF 时,您可以将标题用作 PDF 中的书签(显示在阅读器导航栏上)。

请注意,我所描述的内容甚至没有涉及 VBA。

如果您对标题使用设置样式,并且想要做的比您本机可以做的多一点,那么您可以简单地:

Loop through all paragraphs in the document
See if that paragraph is set to your heading style
Place a bookmark (valid bookmark name!) over that paragraph

我已经把实际的编码留给了你,但我想你会发现根据上面的伪代码很容易做到。我的伪代码循环不是找到段落的唯一方法,但它是最容易可视化的。

一旦你使用了上面的简化方法和内置编号,你应该会发现你可以修改你的ValidBMName 函数——简化它。但是,如前所述,根据您想要书签的原因,您也许可以完全避免使用 VBA。

【讨论】:

  • 此外,如果向文档添加目录或插入对标题的交叉引用,Word 会为相关标题创建自己的(隐藏)书签。
  • @macropod:谢谢,细微的措辞更新以反映这一点。我自己应该记得的!
  • 我正在处理已经创建的文档。我可能不会以这种方式开始设置它们,但我仍然需要尝试找到解决方案。我需要能够从其他 word 文档中链接到文档的基本上所有特定部分,并且内置的目录功能不会生成跨文档超链接。
  • 如果你能帮助我弄清楚如何编写你提到的实际代码,那将非常有帮助。
  • @PM_ME_YOUR_DATASETS:你在这里强调了一个不同的问题。研究跨文档目录的主/子文档。
【解决方案2】:

此代码适用于我:

  Sub HeadingsToBookmarks()
    Dim heading As Range
    Set heading = ActiveDocument.Range(Start:=0, End:=0)
    Do
        Dim current As Long
        current = heading.Start
        Set heading = heading.GoTo(What:=wdGoToHeading, Which:=wdGoToNext)
        If heading.Start = current Then
            Exit Do
        End If
    'This is the part I changed: ListFormat.ListString
        ActiveDocument.Bookmarks.Add MakeValidBMName(heading.Paragraphs(1).Range.ListFormat.ListString), Range:=heading.Paragraphs(1).Range
        Loop
    End Sub  

【讨论】:

    猜你喜欢
    • 2012-10-04
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多