Vba Call关键字-是否已弃用

Vba Call关键字-是否已弃用,vba,Vba,我一直看到有人提到Call语句被弃用,但我似乎找不到任何官方证据支持这一说法 此外,该页面最近有一次更新(2018年3月12日),所以不能说是过时的信息 我一直在我的代码中使用Call,大部分时间都是因为我发现: 调用函数(arg1、arg2、arg3) 易读 函数arg1、arg2、arg3 现在,关于问题,有人能提供一些见解来解释为什么我不应该再使用Call语句了吗?如果您确实说已弃用,请提供指向资源的链接 如果这个问题违反了网站规则,请务必让我知道,我会很高兴自己删除它,不过如果能得到答案

我一直看到有人提到Call语句被弃用,但我似乎找不到任何官方证据支持这一说法

此外,该页面最近有一次更新(2018年3月12日),所以不能说是过时的信息

我一直在我的代码中使用Call,大部分时间都是因为我发现:

调用函数(arg1、arg2、arg3)
易读
函数arg1、arg2、arg3

现在,关于问题,有人能提供一些见解来解释为什么我不应该再使用
Call
语句了吗?如果您确实说已弃用,请提供指向资源的链接


如果这个问题违反了网站规则,请务必让我知道,我会很高兴自己删除它,不过如果能得到答案,我会很高兴。

当我重构代码或剪切我还不确定的新代码时,我经常使用
Call
。为了解释,使用
Call
需要在参数周围加括号,从函数返回值也需要括号。我可能希望从函数返回值,或者希望通过引用传递参数(
ByRef


编辑:我认为一直使用括号(这意味着使用
Call
作为Subs的关键字)意味着更少的时间在代码周围跳跃,去掉括号,然后在改变主意后再放回去

> P>我试图避免以下代码< <代码> >(因此,它是贬值的),原因如下:在VBA中,我考虑在括号中传递变量作为超越标准<代码> ByVal < /代码> /<代码> ByRef < /代码>参数规范的方式。我是什么意思?考虑这个例子:

Public Sub TestMe()

    Dim var1 As Long: var1 = 1
    Dim var2 As Long: var2 = 1

    IncrementByVal (var1)
    IncrementByRef (var2)

    Debug.Print var1, var2

End Sub

Public Function IncrementByVal(ByVal a As Variant) As Variant
    a = a + 100
    IncrementByVal = a
End Function

Public Function IncrementByRef(ByRef a As Variant) As Variant
    a = a + 100
    IncrementByRef= a
End Function

正如您可能看到的,
var1
var2
都返回
1
,而
var2
应该是
101
,只要是
ByRef
调用
-word类改进了VBA中的这一“功能”,但当括号覆盖
ByRef
时,以及当不覆盖时,读取代码时,它变得太复杂,无法记住。因此,有3个案例相当多:

Public Sub TestMe()

    Dim var1 As Long: var1 = 1
    Dim var2 As Long: var2 = 1
    Dim var3 As Long: var3 = 1
    Dim var4 As Long: var4 = 1
    Dim var5 As Long: var5 = 1
    Dim var6 As Long: var6 = 1

    IncrementByVal (var1)           '1
    IncrementByRef (var2)           '1
    IncrementByVal var3             '1
    IncrementByRef var4             '101
    Call IncrementByVal(var5)       '1
    Call IncrementByRef(var6)       '101

    Debug.Print var1, var2
    Debug.Print var3, var4
    Debug.Print var5, var6

End Sub

Public Function IncrementByVal(ByVal a As Variant) As Variant
    a = a + 100
    IncrementByVal = a
End Function

Public Function IncrementByRef(ByRef a As Variant) As Variant
    a = a + 100
    IncrementByRef = a
End Function
一致性为王 无论您调用的是
子函数
还是
函数
,都没有任何区别。重要的是一致性,这就是
所说的
——情侣们声称使用这个关键词会带来什么。与参数列表周围是否需要括号一致

因此,与这个简单的as-get隐式call语句不同:

MsgBox "I'm a function but you're discarding my return value, so no parentheses."
我们得到这样的东西:

MsgBox ("I'm a function but you're discarding my return value, and this call looks weird.")
我还没有看到实际使用的
调用
具有任何实际的一致性:

如果一直使用,
Call
会很快变得令人讨厌,显然是多余的,并且会减慢阅读速度,因为眼睛会忍不住停在关键词上,然后大脑会说“哦,嘿,小心,我们在这里调用某些东西”。我想在某一点上,你只是不去看它,如果它不见了,你就会觉得好像有什么东西坏了

每一条可执行语句中的绝大多数都是在某个抽象级别的某个地方对某个东西的调用—使用
call
一致地使语言比现在更加庞大

除非
Call
实际上不是关于一致性,更多的是关于能够轻松查看自己的用户过程调用。。。在这一点上,这只是抓住稻草来合法化一个没有任何用途的古老构造:调用
关键字
没有合法用途

这是唯一的“合法”用例:

Public Sub Test()
DoSomething: DoSomethingElse
'vs.
'Call DoSomething: Call DoSomethingElse
End Sub

Private Sub DoSomething() '<~ dead code. can you see why?
End Sub

Private Sub DoSomethingElse()
End Sub
公共子测试()
DoSomething:DoSomethingElse
'对。
“呼叫DoSomething:calldosomethingelse
端接头

“我不会说它不受欢迎,只是它不是必需的,这可能会让人们相信它从来都不需要。。。从技术上讲,这确实是过时的。我个人不喜欢它,并且会对广泛使用它的代码更加怀疑。这会让我觉得我现在应该更仔细地检查代码,检查那些在20年前工作得很好,但现在应该以不同的方式完成的技术。我对引发这个问题的前一个问题的评论,应该包含在您的问题中。我不会转载我已经拥有的东西。当然不会被弃用,它在vb.net中变得更有用。顺便说一句,这也消除了调用子函数和函数之间的尴尬区别。我所能想到的vba中最实际的用法是,您使不使用函数的返回值变得更加明显,这是故意的。它消除了代码的味道。我发现微软的文档越来越乏味了。曾几何时,这些文档还包括了从函数和例程中获得最佳效果的提示和上下文,以及使用它的禁忌症。现在它简单地说明了函数应该做什么。该页面还用于说明
Call
关键字已被弃用,仅保留用于向后兼容。它不再是一个“办公开发中心”,而是一个供裸体人士使用的VBA 101。我曾经在这里或SuperUser上发布过两个链接,正式声明调用已被弃用,但我找不到它们。我不知道
callnotsureIfthiswillendupasuborafunction(1,2)
如何比
notsureIfthiswillendupasuborafunction 1,2
更好。这两种方法都不能告诉您是调用sub还是函数,如果有返回值,则两者都会丢弃返回值。谢谢@S Meaden,我知道如何使用它,我只是想知道人们在什么基础上说它不受欢迎,我得出的结论是,这只是因为它已经存在很长时间了,而且越来越不受欢迎。但是不是不赞成。@FAB:是的,对不起,我已经重读了你的问题。我站在你这边,
打电话
没有什么问题。谢谢@vityta,我想你是对的
Call MsgBox("I'm a function but you're discarding my return value, so I have a Call keyword.")
Call MyProcedure(42)
Call ActiveSheet.Range("A1:A10").Clear
Call Beep
Call CallByName(obj, "SomeMethod", VbCalType.VbMethod)
Public Sub Test()
DoSomething: DoSomethingElse
'vs.
'Call DoSomething: Call DoSomethingElse
End Sub

Private Sub DoSomething() '<~ dead code. can you see why?
End Sub

Private Sub DoSomethingElse()
End Sub