使用VBA

时间:2018-02-11 21:59:23

标签: vba ms-word typography quotation-marks

我正在尝试为MS Word 2010创建一个VBA过程,帮助我在某些地方设置引号,并进行一些额外的文本替换。

我需要德国风格的引号(在引用开头低99,在末尾高66)。

(当手动输入文档时,语言设置为德语,MS Word 自动用正确的德语替换上部直引号(“)。但插入引号时没有用通过VBA程序标记,因为只有当通过键盘打出直引号时才会触发引号的特殊处理。)

这是我的代码:

Sub SetInPhraseQuotation()

Dim strString As String

'Mark a certain piece of the text 
Selection.MoveRight Unit:=wdCharacter, Count:=3, Extend:=wdExtend

strString = Selection

'Do some replacements in the string that are not of interest here
strString = replace(strString, Left(strString, 1), ":")

'Do some more replacment and add a lower-99-quotation mark 
strString = replace(strString, Right(strString, 1), Chr(132) & UCase(Right(strString, 1)))

Selection.TypeText text:=strString
'Same result also when using
'Selection.Range.text = strString

End Sub

我正在处理的文件通常设置在Times New Roman中。

以下是问题:一切正常,特别是我在计算机上创建的新文档。但是,在包含从同事文档中粘贴的文本副本的文档中,引号(Chr(132) - 恰好设置在与周围文本(我的案例中为Times New Roman)不同的字体(Calibri)中。

问题:如何以编程方式确保插入的引号 - Chr(132) - 与周围文本设置在同一类型的面上(此处为:Times New Roman)。

顺便说一句:我不明白为什么这是一个问题。由于周围的文字是Times New Roman,为什么突然插入文本Calibri呢?特别是在没有改变类型面的情况下执行其他步骤(各种替换)。此外,我有几个其他程序以编程方式插入文本,并且错误的类型面没有问题。看来,这个问题尤其与那些德国99式的引号有关......

更多实验后的其他信息

我试图通过添加到我的程序来懒散地解决问题:

Selection.MoveLeft Unit:=wdCharacter, Count:=4, Extend:=wdExtend

Selection.Font.Name = "Times New Roman"

Selection.MoveRight

应标记问题中的四个字符,并为其分配“Times New Roman”。惊喜:Calibri引号的弹性足以完全不受影响。

当检查应用于段落和字母的各种样式时(使用“样式检查器”),我观察到这些引号上的“Calibri”在Word菜单的字体选择器(下拉列表)中说明(或者他们称之为Ribbon现在?),但不是在Style Inspector中的任何其他地方或任何地方。根本没有“Calibri”在那里说。仅在功能区下拉列表中。

3 个答案:

答案 0 :(得分:0)

经过一些额外的实验(由评论者Cindy Meister支持)我现在能够提出问题的实用解决方案,尽管不是理论解释其深层原因

这是实用的解决方案:

在受影响的文档中,在前面的步骤中,运行了另一个过程,将所有段落的类型面设置为" TimesNewRoman" (记住拼写!)。这些文档似乎已经出现在我的屏幕上和我的客户的屏幕上多年来没有任何问题,就像Times New Roman一样(但在Word菜单的下拉选择器中表示为" TimesNewRoman")。

然而,由于我并不理解的原因,Word无法应用这个" TimesNewRoman"通过我的新过程插入到现有文本中的引号的字体。 (奇怪的是,我通过其他程序插入的其他内容没有这个问题,它们很好地出现在文档的标准类型面上。)

当新程序在形成为" Times New Roman"的文本中执行时。 (注意拼写),Calibri中出现的以编程方式插入引号的问题不会发生。

作为解决方案,我在我的格式化程序中更换了" TimesNewRoman"通过" Times New Roman"来打字。

现在我可以使用预期的结果执行我的文本替换过程:很好地格式化低-99样式的引号。

更深层次的原因......或者更确切地说是一些可能指向它的证据

我在这里没有最终意见,但到目前为止,我的印象是Word默认情况下,当存在有问题的字体名称时(" TimesNewRoman"似乎有问题),插入来自的文字VBA程序为" Calibri"。这种格式化不会出现在" Style Inspector"等等。我看到它的唯一地方是菜单下拉菜单(功能区)。并且不可能使用VBA以编程方式覆盖Calibri格式化:

Selection.Font.Name = "Times New Roman"

Calibri的引号只是对此免疫并保持Calibri。

我发现有效改变此类Calibri引号的类型面的唯一方法是通过下拉选择器分配不同类型的面(例如" Times New Roman")手动 ......

更了解MS Word内部运作的人可能会对这种奇怪的行为做出最终解释。

答案 1 :(得分:0)

基于@ChristianGeiselmann的答案中的信息:

TimesNewRoman是某些打印机的有效字体名称,可以购买。因此,Word正在尽最大努力处理它所获得的信息,并且尽可能地替换其他字体来显示。出于某种原因,这为“东亚”添加了一些奇怪的,模糊的属性到Word Open XML。

在Word Open XML中显示正确的字符,但请查看运行如何分解,并在下面的代码提取中添加有关w:hint = East Asia的注释。如果我删除这些,然后将Word Open XML写回文档,我得到正确的结果。

<w:r><w:t>Test„ wrong</w:t></w:r>
<w:r><w:rPr><w:rFonts w:hint="eastAsia"/></w:rPr><w:t>„</w:t></w:r>
<w:r><w:t xml:space="preserve"> asdf„ ads</w:t></w:r>
<w:r><w:rPr><w:rFonts w:hint="eastAsia"/></w:rPr><w:t>„</w:t></w:r>
<w:r><w:t xml:space="preserve"> font„</w:t></w:r> 

结论:由于使用了机器上不存在的字体名称,Word正在执行字体替换,即在字体格式化/样式时无法根除的情况下将信息写入Word Open XML中。改变了。完全摆脱它的唯一方法是编辑底层的Word Open XML。

以下是一些示例代码,用于替换和重写文档:

Sub ReplaceInWordOpenXML()
    Dim sWordOpenXML As String, sCleanedXML As String
    Dim sFindTerm1 As String
    Dim sFindTerm2 As String
    Dim bFound As Boolean
    Dim findRange As word.Range

    Set findRange = ActiveDocument.content
    sFindTerm1 = Chr(132)
    sFindTerm2 = Chr(147)

    With findRange.Find
        .MatchWildcards = True
        .Text = "(" & sFindTerm1 & ")*(" & sFindTerm2 & ")"
        bFound = .Execute
    End With
    If bFound Then
        sWordOpenXML = findRange.WordOpenXML
        sCleanedXML = Replace(sWordOpenXML, "w:hint=" & Chr(32) & "eastAsia" & Chr(32), "")
        findRange.InsertXML sCleanedXML
    End If
End Sub

答案 2 :(得分:0)

只要您无需直接设置字符格式和/或使用字符样式即可,Selection.ClearCharacterDirectFormatting对我(Word 2016 / Windows 10)非常有用:

Sub clearDirectFormat()

    ActiveDocument.StoryRanges(wdMainTextStory).Select
    Selection.ClearCharacterDirectFormatting
    Selection.ClearParagraphDirectFormatting

    'footnotes and endnotes need to be treated as individual ranges
    Dim fn As Footnote, en As Endnote

    For Each fn In ActiveDocument.Footnotes
        fn.Range.Select
        Selection.ClearCharacterDirectFormatting
        Selection.ClearParagraphDirectFormatting
    Next fn

    For Each en In ActiveDocument.Endnotes
        en.Range.Select
        Selection.ClearCharacterDirectFormatting
        Selection.ClearParagraphDirectFormatting
    Next en

End Sub