我有一个带有可选参数的子程序
Public Sub FaR_Wild_Stories_Extras(ByVal rngStory As Word.Range, _
ByVal strSearch As String, ByVal strReplace As String, _
Optional extra1 As String = "", Optional extra2 As String = "")
With rngStory.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = strSearch
.Replacement.Text = strReplace
.Forward = True
.MatchWildcards = True
.MatchCase = True
.IgnorePunct = True
.IgnoreSpace = True
.Format = False
.Wrap = wdFindContinue
If extra1 <> "" Then eval(extra1)
If extra2 <> "" Then eval(extra2)
.Execute Replace:=wdReplaceAll
End With
End Sub
我希望能够在.font.size=14
中放置类似“.MatchDiacritics = False
”或extra1
的内容并对其进行评估,以便在调用查找和替换子例程时(如果有)我希望在查找和替换中包含特定的额外参数作为一次性的事情,我不必为它创建一个完整的单独的子。
有办法做到这一点吗? Eval()似乎不存在于单词VBA中。 Object.string是不可能的,除了复制子例程或者有一个带有10个很少使用的可选参数的子例程之外,还有一些更聪明的方法可以构建我的代码吗?
对于更一般化的情况,是否可以call
像这样的子或结构代码,通过巧妙地传递参数来产生相同的效果
...
call Example , true, ".prop1=5", ".prop2=6"
...
Sub Example1(x, Optional param1 As String, Optional param2 As String)
With Application.ExampleObject
.property1 = "foo"
.property2 = x
Expand (param1)
Expand (param2)
.excecute
End With
End Sub
答案 0 :(得分:2)
CallByName允许您设置一个Property或使用一个以字符串命名的Object调用Method。
Sub Example(x, Optional Method1 As String ="", _
Optional Param1 As String = "", Optional Param1Value as Variant)
Dim MyObject as Object
Set MyObject = Application.ExampleObject
'invoke a method from its name
if method1 <> "" Then CallByName MyObject, Method1, VbMethod
'set a property from its name and a variant representing the value to set
if param1 <> "" Then CallByName MyObject, Param1, VbSet, Param1Value
With MyObject
.property1 = "foo"
.property2 = x
.excecute
End With
End Sub
(有关如何优雅地处理具有多个值的属性的信息,请参阅此帖子http://www.vbforums.com/showthread.php?405366-RESOLVED-Using-CallByName-with-variable-number-of-arguments)
将很少使用的属性存储到外部子例程。如果你不想弄乱主子程序的参数,那么结合上面的内容仍然有用。
Sub Example(x, Optional ExternalSub as String)
'pull any additional rarely used properties from another sub
Application.Run(ExternalSub)
With Application.ExampleObject
.property1 = "foo"
.property2 = x
.excecute
End Sub
Sub External_MoreProperties
Application.ExampleObject.property3 = "bar"
End Sub
答案 1 :(得分:0)
聚会晚了一点,但在这种情况下,我会使用stdLambda
。
stdLambda是一个外部库,旨在将完整的解析器,编译器和评估器引入VBA。我们解析VBA式的代码,将其转换为字节码,然后在需要时在VBA运行时中对其进行评估!
在这种情况下,用法应该非常简单:
Public Sub FaR_Wild_Stories_Extras(ByVal rngStory As Word.Range, _
ByVal strSearch As String, ByVal strReplace As String, _
Optional ByVal extraFilters As stdICallable)
Dim f as Find
set f = rngStory.Find
With f
'Default search params:
.ClearFormatting
.Replacement.ClearFormatting
.Text = strSearch
.Replacement.Text = strReplace
.Forward = True
.MatchWildcards = True
.MatchCase = True
.IgnorePunct = True
.IgnoreSpace = True
.Format = False
.Wrap = wdFindContinue
Call extraFilters.Run(f)
.Execute Replace:= wdReplaceAll
End With
End Sub
Sub Main()
Call FaR_Wild_Stories_Extras(Doc.Contents, "Hello","Bye", stdLambda.CreateMultiline( _
"$1.Font.Size = 10", _
"$1.MatchDiacritics = False" _
))
End Sub