为什么';是否在查找/替换VBA宏中重置工作?

为什么';是否在查找/替换VBA宏中重置工作?,vba,replace,ms-word,Vba,Replace,Ms Word,我的文档中有一个特定的单词,它具有以前作者的各种内联格式。我想找到那个单词并去掉它的内联格式。如果我使用键盘,我会一次选择一个项目,对每个项目应用CTRL+空格键。相反,我编写了一个宏。一般来说,我不想假设内联格式的性质;我不想担心它是否是粗体或斜体或其他任何东西;我只想执行一个通用的CTRL+空格键,在VBA中转换为.Font.Reset。但这不管用。这是我的代码,它确实有效,但请查看我添加的注释,它们共同询问.Font.Reset不起作用的原因: Sub Inline_Formatting_

我的文档中有一个特定的单词,它具有以前作者的各种内联格式。我想找到那个单词并去掉它的内联格式。如果我使用键盘,我会一次选择一个项目,对每个项目应用CTRL+空格键。相反,我编写了一个宏。一般来说,我不想假设内联格式的性质;我不想担心它是否是粗体或斜体或其他任何东西;我只想执行一个通用的CTRL+空格键,在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
Font.Reset
是一种方法,而不是属性

您正在配置
Range.Find.Replacement.Font
,告诉对象模型您要替换什么以及应该如何格式化。这在调用读/写属性时有效,因为读/写属性存储状态。方法作用于该状态

当您了解属性的工作原理时,这会更有意义-以下是一个示例:

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
包含有关字体是否应为bold的信息:由
Replacement
返回的对象上的
font
属性是
font
对象,即
font
类的实例。因此,当您执行
.Bold=False
时,您将该值封装在
Font
对象的内部状态中

现在假设在这个虚构的类模块中还有一个方法:

Public Sub Reset()
    internalState = False
End Sub
现在我不知道“重置”的真正作用是什么-你必须看一下源代码。。。或者查看文档中是否有有用的内容:

删除手动字符格式(未使用样式应用格式)。例如,如果手动将单词设置为粗体格式,并且基础样式为纯文本(非粗体),则重置方法将删除粗体格式。

那么为什么它不重置
替换对象的
字体
?这实际上是一个很好的问题:我们可以合理地预期,在
Replacement.Font
上调用
Reset
将有效地“重置”该字体

我对对象模型不是很熟悉(不过Cindy是个专业人士!),但是为了让
.Reset
作为替代品工作,我相信
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
然后,当实际执行替换时,Word可以检查
ShouldReset
,并在受影响的
范围
字体
实例上调用该方法,该实例与
替换
对象上的
字体
实例不同

除非
Font
执行上述操作没有任何意义,因为如果调用
Reset
,那么它应该重置-缺少的是类似于
ReplacementFont
类的东西,可以合理地保存该状态/信息。。。但它并不存在

如果VBA具有作为一等公民的功能,那么您可能可以执行类似于以下这种卑鄙的、无意义的伪代码:

Set .ReplacementAction = New Function(ByVal r As Range)
        r.ClearFormatting
        r.Text = "word_with_inline_formatting"
        r.Font.Reset
    End Function
然后,当您转到
Find.Execute
时,假设的
ReplacementAction
函数会将实际的
范围
作为参数传递给此…委托操作,
.Reset
将在调用时针对目标
范围.Font
进行操作,与设置时在
Replacement.Font
上操作相反


唉,VBA不能做
delegate
之类的事情

我很确定调用
Find.Replacement.Font.Reset
只会清除所有替换字体信息,因此在执行替换时,字体不会更改

我遇到了类似的效果,我想使用find/replace全局删除文本中的字符样式,但我还没有找到任何方法

Replacement.Font
Style
等似乎无法将它们设置为“清除任何特定的字体/样式/etc”。唯一的选择是什么也不做或设置特定的值


因此,在我的例子中,我必须编写一个循环,分别查找每个搜索命中,并在结果范围上执行与ctrl空格等效的操作。不幸的是,这比全局替换要慢得多。

因为Font.Reset是一种方法,它执行一个操作。粗体和斜体是属性。查找/替换只能使用属性。您可以“循环”查找(不替换)并对每个循环的搜索范围执行字体重置。有数百个这样做的例子。所以,我假设你说的是粗体=形容词=属性,斜体=形容词=属性,重置=动词=方法,其中最后一个在查找/替换脚本中不起作用。动词=>method/Adj./名词=>Class/property仅仅是命名约定。使用对象浏览器(F2)了解哪个是哪个,或者在您键入
点解引用运算符时,请注意/注意IntelliSense下拉列表中各自的图标。@Cindymister和Mathieu Guindon,谢谢您的帮助。多年来,我一直在为Word编写VBA宏,但始终没有真正理解该语言。相反,我只是对通过谷歌搜索找到的一点点代码进行了破解,然后逐步调试,这样整个宏就可以正常工作了,但有时我会因为没有真正理解方法和属性之间的区别,以及其他基本的知识差距而碰壁。我仍然感到困惑。IntelliSense系统的选项之一是,.Font.Reset。VBA编辑器知道我位于With.Replacement容器中,这意味着它知道它实际上是在建议.Replacement.Font.Reset。如果这个语法在这里什么都不起作用,为什么它作为一个选项存在?换句话说