有些字符会在vba宏中丢失格式,而有些则不会 [英] some characters lose formatting in vba macro others don't
问题描述
我有许多在Unicode以前时代编写的文档,其中包含各种语言的转录本,每种都有自己的字体. 我做了一个宏,用另一个字符(从多个旧的转录字体转换为unicode字体)替换了文档中的每个字符. (有关这些字体之一,请参见下面的宏代码)
由于某种原因,宏会保留某些字符(而不是其他字符)的格式(在我的情况下,大多数是斜体).这给我留下了很多单词,其中有些字母是斜体的,而其他字母不是斜体的,例如.
al-Malik al-Mu ǧā hidḫuṭ ba
丢失格式的字符都是带有变音符号的字符,但并非所有带有变音符号的字符都失去了格式(例如,示例中的ḫ). 并非所有保持格式的字符在原始字体中都具有与unicode字体相同的代码点(例如,示例中的has在原始字体中具有unicode号U + 23,在unicode字体中具有U + 1E2B). /p>
您是否知道为什么保留某些字符而不保留其他字符的格式?或者我该如何解决这个问题?
或者,我可以在该过程中添加另一个宏,该宏将把至少包含一个斜体字母的所有单词格式化为斜体(但是如何做到这一点是另一个问题:
首先,作为一个建议,如果将数组设置为:- 关于您的问题的答案.我不知道如何阻止它失去斜体,我怀疑这可能是因为通过样式而不是格式将其设置为斜体,反之亦然,但是这种深度的调查不适用于此环境(问与答)我不认为. 作为一种解决方案,您可以按照 (此代码未经测试且构成示例性解决方案) 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 ḫuṭba 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? 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).
Firstly, just as a suggestion, you could have a smaller code base if you set the array as: - 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. (This code is untested and formed to exemplify a solution) 这篇关于有些字符会在vba宏中丢失格式,而有些则不会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!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
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
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