我有许多在 Unicode 之前时代制作的文档,其中包含各种语言的转录,每种语言都有自己的字体。 我制作了一个宏,将文档中的每个字符替换为另一个字符(从多个旧的转录字体替换为 unicode 字体)。 (请参阅下面的宏代码以了解其中一种字体)
出于某种原因,宏保留某些字符的格式(在我的例子中,主要是斜体),而不是其他字符。这给我留下了很多单词,其中一些字母是斜体的,而其他字母则不是,例如
al-Malik al-Muǧāhid ḫuṭba
丢失格式的字符都是带有变音符号的字符,但并非所有带有变音符号的字符都会丢失其格式(例如示例中的 ḫ)。 并非所有保留其格式的字符在原始字体中都具有与 unicode 字体中相同的代码点(例如,示例中的 ḫ 在原始字体中具有 unicode 编号 U+23,在 unicode 字体中具有 U+1E2B)。
您知道为什么保留某些字符的格式,而不保留其他字符的格式吗?或者我该如何解决这个问题?
或者,我可以在该过程中添加另一个宏,将至少包含一个斜体字母的所有单词格式化为斜体(但如何做到这一点是另一个问题: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
最佳答案
首先,作为一个建议,如果将数组设置为:-
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
关于你的问题的答案。我不知道如何阻止它失去斜体,我怀疑这可能是由于通过样式而不是格式将其设置为斜体引起的,反之亦然,但调查的深度不适合这种环境(问答)我不知道不敢想。
至于解决方案,有很多方法可以满足您的需要,如您的 other question 中所解决的那样,我认为这不能以一揽子方式完成(即没有办法一次性将所有斜体设置回斜体),因为执行查找和替换后不会保留信息。因此,必须在交换角色时完成此操作,这意味着它一次只能进行一次查找和替换,这会对性能产生影响。
在下面的示例中,我还使用了上述较短的数组方法。
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
(此代码未经测试,旨在举例说明解决方案)
关于vba - 某些字符在 vba 宏中会丢失格式,而其他字符则不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38742435/