某些字符会在 vba 宏中丢失格式,而其他字符则不会 [英] some characters lose formatting in vba macro others don't

查看:75
本文介绍了某些字符会在 vba 宏中丢失格式,而其他字符则不会的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多在 Unicode 出现之前制作的文档,其中包含各种语言的转录本,每种语言都有自己的字体.我制作了一个宏,用另一个字符替换文档中的每个字符(从多个旧的转录字体到一个 unicode 字体).(有关这些字体之一,请参阅下面的宏代码)

I have a number of documents that are made in the pre-Unicode era, and contain transcriptions of various languages, each with their own fonts. I made a macro that replaces every character in a document with another character (from multiple old transcription fonts into a unicode font). (see code below of the macro for one of these fonts)

出于某种原因,宏保留了某些字符的格式(在我的情况下,主要是斜体),而不是其他字符.这给我留下了很多单词,其中一些字母是斜体,而其他字母不是,例如

For some reason, the macro keeps the formatting (in my case, mostly italics) for some characters, not for others. This leaves me with a lot of words in which some letters are italicized, and other letters aren't, e.g.

al-Malik al-Muǧāhid ḫuba

丢失格式的字符都是带有变音符号的字符,但并非所有带有变音符号的字符都会丢失格式(例如,示例中的 ḫ).并非所有保持格式的字符在原始字体中都具有与 unicode 字体相同的代码点(例如,示例中的 ḫ 在原始字体中具有 unicode 编号 U+23,在 unicode 字体中具有 U+1E2B).

The characters that lose the formatting are all characters with diacritics, but not all characters with diacritics lose their formatting (e.g., the ḫ in the example). Not all characters that keep their formatting have the same code point in the original font as in the unicode font (e.g., the ḫ in the example has unicode number U+23 in the original font and U+1E2B in the unicode font).

您知道为什么保留某些字符的格式而不保留其他字符的格式吗?或者我怎么能解决这个问题?

Do you have an idea why the formatting is kept for some characters, and not for others? Or how I could solve this problem?

或者,我可以在程序中添加另一个宏,将包含至少一个斜体字母的所有单词格式化为斜体(但如何做到这一点是另一个问题:MS Word 宏来纠正部分格式化的单词).

Alternatively, I could add another macro to the procedure that would format all words that contain at least one letter in italics into italics (but how to do that is another question: MS Word macro to correct partially formatted words).

Sub BatchReplaceAOTimes()

'Replace the font AO Times New Roman in the body and footnotes
'of the active document

Debug.Print "Replacing AO Times New Roman font"
Dim old_values(270) As String
Dim unicode_values(270) As Long

old_values(0) = &H30
old_values(1) = &H31
(...)
old_values(263) = &HFD
old_values(264) = &HDD
old_values(265) = &H178
old_values(266) = &HFF
old_values(267) = &H5A
old_values(268) = &H7A
old_values(269) = &H2C
old_values(270) = &H9

unicode_values(0) = &H30
unicode_values(1) = &H31
(...)
unicode_values(263) = &H2BE
unicode_values(264) = &H2BF
unicode_values(265) = &H1E6E
unicode_values(267) = &H5A
unicode_values(268) = &H7A
unicode_values(269) = &H2C
unicode_values(270) = &H9

Selection.HomeKey Unit:=wdStory

Dim ThisRng As Range

'do body text
Set ThisRng = ActiveDocument.StoryRanges(wdMainTextStory)
For i = 0 To 270
    Debug.Print i

    ThisRng.Find.ClearFormatting
    ThisRng.Find.Replacement.ClearFormatting

    With ThisRng.Find
        .Font.Name = "AO Times New Roman"
        .Text = ChrW(old_values(i))
        .Replacement.Font.Name = "Arial Unicode MS"
        .Replacement.Text = ChrW(unicode_values(i))
        .Forward = True
        .Wrap = wdFindContinue
        .Format = True
        .MatchCase = True
        .MatchWholeWord = False
        .MatchKashida = False
        .MatchDiacritics = False
        .MatchAlefHamza = False
        .MatchControl = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    ThisRng.Find.Execute Replace:=wdReplaceAll
    Next i

   (...: do the same for the footnotes)

    End Sub

推荐答案

首先,作为一个建议,如果您将数组设置为:-

Firstly, just as a suggestion, you could have a smaller code base if you set the array as: -

Dim ValueMap(270)  As String
Dim AryTemp()      As String
ValueMap(0) = "&H30|&H30"

For i = 0 To 270
    AryTemp = Split(ValueMap(i),"|")
    'AryTemp(0) = The Old
    'AryTemp(1) = The New
Next

至于你的问题的答案.我不知道如何阻止它丢失斜体,我怀疑这可能是由于它通过样式而不是格式设置为斜体引起的,反之亦然,但这种调查深度不适合这种环境(问答)我不认为.

As to an answer to your question. I am unaware of how to stop it losing the italic, I suspect this could be caused by it being set to italic via a style instead of formatting or vice versa, but that depth of investigation would not fit in this environment (Q&A) I don't think.

至于解决方案,有很多方法可以做您需要做的事情,如您的 其他问题,我认为这不能以一揽子的方式完成(即无法一次性将所有斜体设置为斜体)作为信息执行查找和替换后不保留.因此,它必须在字符交换时完成,这意味着它一次只能进行一次查找和替换,这会对性能产生影响.

As for a solution, there are many ways to do what you need to, as solutioned in your other question, I don't think this can be done in a blanket manner (i.e. there is no way to set all those that were italic back to italic in one go) as the information is not retained after the find and replace is executed. So it would have to be done at the point the character is swapped, meaning it can only do one find and replace at a time which will have a performance impact.

在下面的示例中,我还使用了上述较短的数组方法.

In the below example I have also used the shorter array method described above.

Public Sub Sample()
Dim BlnWasItalic        As Boolean
Dim AryValueMap(270)    As String
Dim AryTemp()           As String
Dim LngLocation         As Long
Dim LngValueID          As Long
Dim WdDoc               As Word.Document
Dim WdFnd               As Word.Find
Dim WdRng               As Word.Range
Dim WdSlct              As Word.Selection

AryValueMap(0) = "&H30|&H30"
AryValueMap(1) = "&H31|&H31"
'...
AryValueMap(269) = "&H2C|H2C"
AryValueMap(270) = "&H9|&H9"

Set WdDoc = ThisDocument
    For Each WdRng In WdDoc.StoryRanges
        For LngValueID = 0 To 270
            WdRng.Select
            Set WdSlct = Selection
                WdSlct.SetRange 0, 0
                Set WdFnd = WdSlct.Find

                    'Clear any previous find settings
                    If LngValueID = 0 Then
                        WdFnd.ClearAllFuzzyOptions
                        WdFnd.ClearFormatting
                        WdFnd.ClearHitHighlight

                        .Font.Name = "AO Times New Roman"

                    End If

                    AryTemp = Split(AryValueMap(LngValueID), "|")

                    'Look for any italic character
                    Do Until Not WdFnd.Execute(FindText:=ChrW(AryTemp(0)), MatchCase:=True, _
                                                MatchWholeWord:=False, MatchWildcards:=False, _
                                                MatchSoundsLike:=False, MatchAllWordForms:=False, _
                                                Forward:=True, Wrap:=wdFindStop, Format:=True, _
                                                ReplaceWith:="", Replace:=wdReplaceNone, _
                                                MatchKashida:=False, MatchDiacritics:=False, _
                                                MatchAlefHamza:=False, MatchControl:=False)

                        'Take note if it was italic
                        BlnWasItalic = WdSlct.Font.Italic

                        'Make the replacement
                        WdSlct = ChrW(AryTemp(1))

                        'Remember the location (in case there are due to be more than
                        'one change in one word
                        LngLocation = WdSlct.End

                        'Expand the selection to the whole word
                        WdSlct.Expand wdWord

                        'Set the font
                        WdSlct.Font.Name = "Arial Unicode MS"

                        'Set the word to be italic if it was meant to be
                        WdSlct.Font.Italic = BlnWasItalic

                        'Move past the word
                        WdSlct.SetRange LngLocation, LngLocation
                    Loop
                Set WdFnd = Nothing
            Set WdSlct = Nothing
            DoEvents
        Next
        DoEvents
    Next
Set WdDoc = Nothing
End Sub

(此代码未经测试并用于举例说明解决方案)

(This code is untested and formed to exemplify a solution)

这篇关于某些字符会在 vba 宏中丢失格式,而其他字符则不会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆