简体   繁体   English

使用VBA将文本插入MS Word文档时出现错误的字体

[英]Wrong type face when inserting text into MS Word document using VBA

I am trying to create a VBA procedure for MS Word 2010 that helps me set quotation marks in certain places, and do some additional text replacements. 我正在尝试为MS Word 2010创建VBA过程,以帮助我在某些位置设置引号,并进行一些其他文本替换。

I need Germany style quotation marks (lower 99 at the beginning of quote, upper 66 at the end). 我需要德国风格的引号(引号的下面是99,结尾的上面是66)。

(When typing manually into a document, with language set to German, MS Word automatically replaces upper straight quotation marks (") by the correct German ones. But this is of no use when inserting quotation marks via VBA procedure as this special treatment of quotation marks seems to be triggered only when the straight quotation marks are punched in via keyboard.) (当手动输入文档时,语言设置为德语,MS Word会自动用正确的德语替换右上引号(“)。但这在通过VBA程序插入引号时没有用,因为这种特殊的引号处理似乎只有在通过键盘打出直接引号的情况下才触发标记。)

Here is my code: 这是我的代码:

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

The documents I am working with are usually set in Times New Roman. 我正在使用的文档通常设置在Times New Roman中。

Here is the problem: Everything works fine, especially on fresh documents I created on my computer. 问题出在这里:一切正常,尤其是在我用计算机创建的新文档上。 However, in documents that contain text copy pasted from my colleagues' documents, the quotation marks - Chr(132) - happen to be set in a different font face (Calibri) than the surrounding text (Times New Roman in my case). 但是,在包含从同事文档中粘贴的文本副本的文档中,引号-Chr(132)-设置为与周围文本不同的字体(Calibri)(在我的情况下为Times New Roman)。

Question : How can I programmatically make sure that the quotation marks inserted - Chr(132) - are set in the same type face as the surrounding text (here: Times New Roman). 问题 :如何以编程方式确保所插入的引号-Chr(132)-与周围的文本设置在相同的字体中(此处:Times New Roman)。

By the way: I do not understand why this is a problem at all. 顺便说一句:我根本不明白为什么这是一个问题。 As the surrounding text is Times New Roman, why is inserted text Calibri out of a sudden? 由于周围的文本是Times New Roman,为什么突然插入了Calibri文本? Especially as the other steps (various replacements) are carried out without type faces being changed. 尤其是在执行其他步骤(各种替换)时,无需更改字样。 Also, I have a couple of other procedures that insert text programmatically, and there is no problem with wrong type faces. 另外,我还有其他一些以编程方式插入文本的过程,并且使用正确的字体没有问题。 It seems, the issue is related especially to those German lower-99-style quotation marks... 看来,该问题尤其与那些德国99式以下的引号有关...

Additional information, after more experiments 更多实验后的其他信息

I tried to circumvent the issue by adding to my procedure, lazily: 我试图通过添加到我的程序中来偷懒地解决这个问题:

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

Selection.Font.Name = "Times New Roman"

Selection.MoveRight

which should mark the four characters in questions and assign "Times New Roman" to them. 应当标记出问题中的四个字符并为其分配“ Times New Roman”。 Surprise: the Calibri quotation marks are resilient enough to be not at all affected. 惊喜:Calibri引号的弹性足以完全不受影响。

When checking the various styles applied to paragraphs and letters (using the "Style Inspector") I observe that "Calibri" on these quotation marks is stated in the font selector (dropdown) in Word's menu (or do they call it Ribbon now?) solely, however at not a single other place in the Style Inspector or wherever. 当检查应用于段落和字母的各种样式时(使用“样式检查器”),我观察到这些引号上的“ Calibri”是在Word菜单的字体选择器(下拉列表)中声明的(或者它们现在称为功能区吗?) ,但不能在Style Inspector中的任何其他地方或任何地方。 Simply no "Calibri" stated there. 根本就没有“ Calibri”这样的说法。 Only in the Ribbon dropdown. 仅在功能区下拉列表中。

After some additional experimentation (supported by commenter Cindy Meister) I am now able to present the practical solution of the problem, although not the theoretical explanation of its deeper cause . 经过一些额外的实验(在评论员辛迪·梅斯特的支持下),我现在可以提出该问题的实际解决方案 ,尽管不能从理论上解释其更深层次的原因

Here is the practical solution: 这是实际的解决方案:

In the affected documents, in an earlier step, another procedure had been run that set type face of all paragraphs to "TimesNewRoman" (mind the spelling!). 在受影响的文档中,在较早的步骤中,已运行另一个过程,该过程将所有段落的字体设置为“ TimesNewRoman”(注意拼写!)。 These documents seem to have appeared on my screen and on the screens of my customers over years without any problems just as Times New Roman (but stated as "TimesNewRoman" in the dropdown selector of the Word menu). 这些文档似乎已经出现在我的屏幕上以及我的客户的屏幕上,多年来没有出现任何问题,就像Times New Roman(但在Word菜单的下拉选择器中表示为“ TimesNewRoman”)一样。

However, for reasons I do not really comprehend, Word was not able to apply this "TimesNewRoman" font to the quotation marks that were inserted into the existing text through my new procedure. 但是,由于我不太了解的原因,Word无法将此“ TimesNewRoman”字体应用于通过我的新过程插入到现有文本中的引号。 (Strangely other things I inserted through other procedures did not have this problem, they appeared nicely in the standard type face of the document.) (奇怪的是,我通过其他过程插入的其他东西没有这个问题,它们很好地出现在文档的标准类型中。)

When the new procedure is executed in a text that is formated as "Times New Roman" (mind the spelling), the problem with programmatically inserted quotation marks appearing in Calibri does not occur. 当在格式为“ Times New Roman”的文本中执行新过程时(注意拼写),不会出现在Calibri中以编程方式插入引号的问题。

As as solution I replaced in my formating procedure the "TimesNewRoman" type face by "Times New Roman". 作为解决方案,我在格式化过程中将“ TimesNewRoman”类型的面孔替换为“ Times New Roman”。

Now I can execute my text replacement procedure with the expected result: nicely formated lower-99-style quotation marks. 现在,我可以执行文本替换过程,并得到预期的结果:格式正确的下99样式的引号。

The deeper cause... or rather some evidence that may point to it 更深层次的原因...或者可能是一些证据指出了这一点

I have no final opinion here, but so far my impression is that Word somehow by default, when there is a problematic font name ("TimesNewRoman" appears to be a problem), inserts text that comes from VBA procedures as "Calibri". 我在这里没有最终意见,但是到目前为止,我的印象是,默认情况下,Word以某种方式在字体名称有问题(“ TimesNewRoman”似乎有问题)时,将来自VBA过程的文本插入为“ Calibri”。 This formating does not appear in the "Style Inspector" and so on. 这种格式不会出现在“样式检查器”中,依此类推。 The only place where I saw it being stated was in the dropdown in the menu (Ribbon). 我唯一看到它的地方是在菜单中的下拉菜单(功能区)。 And it was not possible to overwrite the Calibri formating programmatically using VBA: 而且无法使用VBA以编程方式覆盖Calibri格式:

Selection.Font.Name = "Times New Roman"

The Calibri quotation marks simply were immune against this and remained Calibri. Calibri引号完全不受此影响,并保持Calibri。

The only way I found to effectively alter the type face of such Calibri quotation marks was assigning a different type face (eg "Times New Roman") manually via the dropdown selector... 我发现有效更改此类Calibri引号的字体的唯一方法是通过下拉选择器手动分配其他字体(例如“ Times New Roman”)。

Somebody who knows the inner workings of MS Word better may come up with the final explanation of this strange behaviour. 某个更了解MS Word的内部运作方式的人可能会提出这种奇怪行为的最终解释。

Building on the information posted in @ChristianGeiselmann 's Answer: 以@ChristianGeiselmann的答案中发布的信息为基础:

TimesNewRoman is a valid font name for some printers and it can be bought. TimesNewRoman是某些打印机的有效字体名称,可以购买。 So Word is doing its best to work with the information it's getting and is substituting some other font to display, as best it can. 因此,Word会尽力处理其获取的信息,并尽其所能替换其他字体来显示。 For some reason, this is adding some odd, obscure attributes for "East Asia" to the Word Open XML. 出于某种原因,这给Word Open XML添加了一些“奇怪的”“东亚”属性。

In the Word Open XML the correct character is displayed, but look at how the run is broken up, with remarks about w:hint = East Asia in the code extract, below. 在Word Open XML中,将显示正确的字符,但请看下面的代码摘录,其中以w:hint = East Asia说明如何w:hint = East Asia运行。 If I remove these then write the Word Open XML back into the document I get the correct result. 如果删除这些内容,然后将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> 

Conclusion: Due to the use of a font name not present on the machine, Word is performing a font substitution that is writing information into the Word Open XML at a very deep level that is not getting eradicated when the font formatting/styles are changed. 结论:由于使用了机器上不存在的字体名称,Word正在执行字体替换,该替换操作将信息写入到Word Open XML的很深的级别,而当更改字体格式/样式时,该信息不会被消除。 The only way to completely get rid of it would be to edit the underlying Word Open XML. 完全摆脱它的唯一方法是编辑基础的Word Open XML。

Here is some sample code that makes that replacement and re-writes to the document: 以下是一些示例代码,可以进行替换并重新写入文档:

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

Provided you can do without direct character formatting and/or are working with character styles, Selection.ClearCharacterDirectFormatting worked for me (Word 2016 / Windows 10) like a charm: 如果您可以不使用直接字符格式设置和/或使用字符样式, 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

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

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