我的文档中有一个特定的单词,该单词具有以前作者的各种内联格式。我想找到该单词并删除其内联格式。如果使用键盘,则一次选择一项,对每项应用CTRL +空格键。相反,我写了一个宏。 总体上,我不想假设内联格式的本质;我不想担心它是粗体还是斜体。我只想执行一个通用的CTRL + Spacebar,将其转换为VBA中的.Font.Reset。但是,这不起作用。这是我的代码,可以工作,但是请参阅我添加的注释,这些注释共同询问为什么.Font.Reset不起作用:
Sub Inline_Formatting_Replacement()
Dim MyDocRange As Range
Set MyDocRange = ActiveDocument.Range
With MyDocRange.Find
.ClearFormatting
.Text = "word_with_inline_formatting"
With .Replacement
.ClearFormatting
.Text = "word_with_inline_formatting"
.Font.Bold = False 'I shouldn't have to use this.
.Font.Italic = False 'I shouldn't have to use this.
.Font.Reset 'This should work instead of using .Bold and .Italic, _
'but this line does nothing. Why?
End With
.Forward = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
End Sub
答案 0 :(得分:3)
As Cindy Meister pointed out,Font.Reset
是方法,而不是属性。
您正在配置Range.Find.Replacement.Font
,告诉对象模型您要替换的对象以及应该如何格式化。当您调用读/写 properties 时,此方法有效,因为读/写属性存储了 state 。在该状态上的方法 act 。
当您了解属性的工作原理时,这更有意义-这是一个示例:
Option Explicit
Private internalState As Boolean
Public Property Get State() As Boolean
'invoked when .State is on the right-hand side of an expression, e.g. foo = obj.State
State = internalState
End Property
Public Property Let State(ByVal value As Boolean)
'invoked when .State is on the left-hand side of an expression, e.g. obj.State = foo
'the "value" parameter is the result of the right-hand side expression.
internalState = value
End Property
想象一下,internalState
包含有关字体是否应该粗体的信息:Font
返回的对象的Replacement
属性是{ {1}}对象,即Font
类的 instance 。因此,当您执行Font
时,您就是在那个.Bold = False
对象的内部状态内将该值封装。
现在说您在这个虚构的类模块中还有一个方法:
Font
现在我不知道Public Sub Reset()
internalState = False
End Sub
真的的作用-人们将不得不窥视该源代码……或查看文档中是否有任何有用的东西:>
删除手动字符格式(不使用样式应用的格式)。例如,如果您手动将单词的格式设置为粗体,并且基础样式为纯文本(而非粗体),则 Reset 方法将删除粗体格式。
https://msdn.microsoft.com/en-us/vba/word-vba/articles/font-reset-method-word
那么为什么不重置 Reset
对象的Font
?实际上,这是一个很好的问题:人们可以合理预期在Replacement
上调用Reset
可以有效地“重置”该字体。
我对ms-word对象模型不是很熟悉(尽管Cindy是专家!),但是为了让Replacement.Font
可以替代,我相信{{1} }类需要执行以下操作:
.Reset
然后在实际执行替换时,Word可以检查Font
并在受影响的Option Explicit
Private doReset As Boolean
Public Property Get ShouldReset() As Boolean
ShouldReset = doReset
End Property
Public Sub Reset()
'does whatever it does
'...
doReset = True
End Sub
的ShouldReset
实例上调用方法-是一个与Font
对象上的Range
实例不同的实例。
Font
进行上述操作没有任何意义,因为当然,如果您调用Replacement
,则应该重置-所缺少的是像Font
类之类的东西可以合理地保存该状态/信息...而它不存在。
如果VBA具有一等公民的功能,那么您也许可以执行以下类似的杂乱无味的伪代码:
Reset
然后,当您使用ReplacementFont
时,假设的Set .ReplacementAction = New Function(ByVal r As Range)
r.ClearFormatting
r.Text = "word_with_inline_formatting"
r.Font.Reset
End Function
函数会将实际的Find.Execute
作为参数传递给此... 委派的动作 ,并且ReplacementAction
在目标Range
被调用时将针对目标.Reset
进行操作,而不是在Range.Font
设置时对其进行操作。
A,VBA无法做Replacement.Font
的事情……or can it?。
答案 1 :(得分:0)
我敢肯定,调用Find.Replacement.Font.Reset
只会清除所有替换字体信息,因此当您进行替换时,字体不会更改。
我正在遇到类似的效果,我想使用查找/替换从全局文本中删除字符样式,但我没有找到任何方法来实现。
Replacement.Font
,.Style
等似乎无法将它们设置为“清除任何特定的字体/样式/等”。唯一的选择是什么都不做或设置特定的值。
作为我的结果,我将不得不编写一个循环,该循环单独查找每个搜索命中,并在结果范围内等效于ctrl-space。不幸的是,这将比全局替换慢得多。