Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 将标题转换为书签_Vba_Ms Word - Fatal编程技术网

Vba 将标题转换为书签

Vba 将标题转换为书签,vba,ms-word,Vba,Ms Word,我使用的是Office2016。我想创建一个宏,循环遍历文档中的每个标题,然后使用标题文本(根据需要修改)作为书签名称,在标题位置创建一个书签。大多数标题都是X.X.X.X格式,例如“3.3.4.1.sometexthere” 我仍然是一个使用VBA的初学者,但在谷歌搜索了很多之后,我成功地修改了一些几乎可以工作的弗兰肯斯坦代码: Sub HeadingsToBookmarks() Dim heading As Range Set heading = ActiveDocument

我使用的是
Office2016
。我想创建一个宏,循环遍历文档中的每个标题,然后使用标题文本(根据需要修改)作为书签名称,在标题位置创建一个书签。大多数标题都是
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格式的文件


不幸的是,我不能使用内置的编号。我正在处理已经创建的文档,这些文档具有一套特定的格式。

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

MS Word具有许多内置功能,可以用作书签。最好的方法是使用样式。内置的
标题
样式允许一些本机导航功能(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
我已经把实际的编码留给了您,但是我认为您会发现基于上面的伪代码很容易做到。我的伪代码循环不是找到段落的唯一方法,但它是最容易可视化的方法


使用上述简化方法和内置编号后,您会发现可以修改
validbName
函数-简化它。但是,如前所述,根据您想要书签的原因,您可以完全避免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
    '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  

此外,如果向文档中添加目录或插入标题的交叉引用,Word会为相关标题创建自己的(隐藏)书签。@macropod:谢谢,为了反映这一点,会进行一些小的措辞更新。我自己应该记得的!我正在处理已经创建的文档。我可能不会以这种方式设置它们,但我仍然需要尝试并找到解决方案。我需要能够从其他word文档链接到文档的基本所有特定部分,并且内置的目录功能不会生成跨文档超链接。如果您能帮助我了解如何编写您提到的实际代码,这将非常有帮助。@PM_ME_YOUR_数据集:您在这里强调了一个不同的问题。研究跨文档目录的主/子文档。您需要提供更详细的信息。你给我们看的代码到底是怎么不起作用的?只是没有找到所有的标题,还是有其他问题?您要选取的所有标题是否都采用了正确的标题样式?书签应该如何命名?稍后,您想如何处理这些书签?如果没有这些信息,就不可能为您提供准确的答案。。。