繁体   English   中英

vba Word:为什么Word不能在书签创建中使用特殊字符,我不能?

[英]vba Word: Why can Word use special chars in bookmark creation, and I cant?

这里有一个头分离器:我想在一个文档程序创建现有标题隐藏的书签,这样我就可以在指向这些书签的文档在其他地方创建超链接。 (我想使用超链接而不是交叉引用,因此我可以为链接指定自己的“显示文本”,而使用交叉引用是不可能的)。

我希望我的书签以与它们相关的标题命名,并带有一个自定义前缀。 例:

  1. 风格:Heading1
  2. 标题文字:入口和走廊
  3. 书签名称:_Hd1_Entrance _&_ Hallway

我要指定一个自定义前缀,以使每个书签都具有其样式唯一,因此,只要它们具有不同的标题样式,我就可以在文档中具有2个匹配的标题。 (示例: _Hd1_Entrance _&_ Hallway_Hd3_Entrance _&_ Hallway

要注意的是:如果我的标题包含特殊字符(如“&”),则会收到我理解的“不良书签名称”错误,该错误已记录在网络上。 我只允许使用有限的字符集。

那么,如果我使用Word自己的对话框手动创建超链接,选择“在此文档中放置”(例如标题为“ Entrance&Hallway”(入口和走廊)),Word会如何处理呢? 一旦创建了HLINK,我现在可以看到这个HLINK在Word中的“书签”对话框相关的隐藏的书签 - 这是相当愉快地命名为“_Entrance _&_走廊”。 这让我感到困惑!

有人解释吗? 我真的很想能够利用这一相同的功能,但无法理解如何做。 任何帮助都非常宝贵! 谢谢,

Sub ScratchPad_Bookmarks()
Dim doc As Document
Dim rng As Range
Dim sHdName As String
Dim sBmName As String
    Set doc = ActiveDocument
    'Insert a heading at start of document
    sHdName = "Entrance & Hallway"
    doc.Range.InsertBefore sHdName & vbCr
    doc.Paragraphs(1).Range.Style = doc.Styles("Heading 1")

    'Find the above heading in the active document
    Set rng = doc.Range
    With rng.Find
        .ClearFormatting
        .Text = sHdName
        .Style = "Heading 1"
        If Not .Execute Then
            'Heading not found, so quit
            Exit Sub
        End If
    End With

    'rng has collapsed to the found heading, so create a bookmark
    'rng.Select 'debug
    sBmName = Replace(rng.Text, " ", "_")
    rng.Collapse wdCollapseStart
    rng.Bookmarks.Add sBmName
    'sBmName contains '&' so this throws a Runtime error:
    '5828: Bad Bookmark Name  (as expected)
End Sub

以上不起作用。 但是,自己测试手动操作很容易。 只需创建一个包含'&'字符的标题 ,并将其设置为标题1即可 在下一段中,使用Word自己的对话框插入超链接。 选择“ 放置在此文档中”,然后选择刚创建的标题。 应该不是问题。 现在打开Word的“书签”对话框,启用“ 隐藏的书签”视图,然后瞧瞧:一个带有'&'字符的隐藏书签。 (Wd 2010)说什么?!

IMO Word正在“作弊”,要么破坏其自己的书签名称规则,要么拒绝您使用该规范允许的全部名称。

如果您使用.docx的早期ECMA标准,则书签的名称定义为ST_String,这是对xsd:string的限制,最大长度为255个字符。 从标准的任何ECMA或ISO版本开始,我认为这没有改变。

但是,Microsoft的实施说明[MS-OE376] .pdf与规范的ECMA版本有关,而[MS-OI29500] .pdf与2012 ISO版本有关,规定该名称不能超过40字符,但不描述任何其他限制。

我(以前)的理解是,书签名称最多只能包含40个字符,必须由“字母”,“数字”和“下划线”组成,并且必须以下划线(对于隐藏的书签)或字母开头。 (不确定,例如“ _1”)。 而且我相信VBA仍然会施加这些规则,尽管我从未检查过它对“字母”或“数字”的理解是什么-是否允许使用非拉丁字母/数字?

但是,如果将文档另存为.xml或在.docx中编辑document.xml,则可以修改书签名称,使其包含例如“&”。 此外,Word将重新保存此类字符。 但是,当您打开时,它将名称截断为40个字符,并且在重新保存时,它不会保留原始名称。 我也不认为标准中使用了首字母“ _”来表示“隐藏”。

因此,在给定规范的情况下,我想说Word是在“欺骗”,因为不允许您使用所有可能的名称,而不是在“欺骗”通过允许超链接目标包含“&”。

您可以在VBA的Windows版本的Word中通过使用InsertXML插入带有预先配置的书签名称的XML块(请参见下面的一些简单示例代码)来在“ Word”的Windows版本中使用“&”插入书签,但是我怀疑您将不得不更加努力地移动书签。 您可能必须提取要“覆盖”的事物的现有XML,然后将其用bookmarkStart和bookmarkEnd标记包围,这对我来说听起来像是一个很讨厌的练习。

作为最后的观察,AFAICR可以为旧版表单字段指定的书签名称具有20个字符的长度限制。

该代码:

Sub insertbm()
Dim x As String
x = ""
x = x & "<?xml version='1.0' encoding='utf-8' standalone='yes'?>"
x = x & "<pkg:package xmlns:pkg='http://schemas.microsoft.com/office/2006/xmlPackage'>"
x = x & "  <pkg:part pkg:name='/_rels/.rels' pkg:contentType='application/vnd.openxmlformats-package.relationships+xml'>"
x = x & "    <pkg:xmlData>"
x = x & "      <Relationships xmlns='http://schemas.openxmlformats.org/package/2006/relationships'>"
x = x & "        <Relationship Id='rId1' Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument' Target='word/document.xml' />"
x = x & "      </Relationships>"
x = x & "    </pkg:xmlData>"
x = x & "  </pkg:part>"
x = x & "  <pkg:part pkg:name='/word/document.xml' pkg:contentType='application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml'>"
x = x & "    <pkg:xmlData>"
x = x & "      <w:document xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>"
x = x & "        <w:body>"
x = x & "          <w:p>"
x = x & "            <w:bookmarkStart w:id='0' w:name='bookmark&amp;name' />"
x = x & "            <w:r>"
x = x & "              <w:t>"
x = x & "bookmarkedtext</w:t>"
x = x & "            </w:r>"
x = x & "            <w:bookmarkEnd w:id='0' />"
x = x & "          </w:p>"
x = x & "        </w:body>"
x = x & "      </w:document>"
x = x & "    </pkg:xmlData>"
x = x & "  </pkg:part>"
x = x & "</pkg:package>"
Selection.InsertXML x
End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM