我应该在VB / VBA中使用Call关键字吗?

在VB / VBA中调用subs时使用Call关键字。 我知道这是可选的,但使用它还是离开它更好? 我一直认为这是更明确的,但也许只是噪音。

此外,我在另一个论坛上读到:使用Call关键字更快,因为它知道它不会返回任何值,所以不需要设置任何堆栈空间来为返回值腾出空间。

啊哈。 我一直很想知道,甚至在VBA上阅读一本厚达两英寸的书,基本上说不要使用它,除非你想使用VBE的查找function来轻松地在大型项目中查找调用。

但我只是find了另一个用途。

我们知道可以将代码行与冒号字符连接起来,例如:

 Function Test(mode as Boolean) if mode = True then x = x + 1 : Exit Sub y = y - 1 End Sub 

但是,如果你在一行的开始处用过程调用来做到这一点,那么VBE就会假定你正在引用一个标签,并删除所有的缩进,将行alignment到左边距(即使这个过程是按照预期调用的):

 Function Test() Function1 : Function2 End Function 

使用Call语句允许在维护代码缩进的同时连接过程调用:

 Function Test() Call Function1 : Call Function2 End Function 

如果在上面的例子中没有使用Call语句,那么VBE会假定“Function1”是一个标签,并且将它保留在代码窗口中,即使它不会导致错误。

对于VB6,如果有机会将其转换为VB.NET,使用Call意味着语法不会改变。 (在VB.NET中,方法调用需要括号)(我个人认为这是不值得的 – 任何.NET转换器至less可以在需要的时候放入括号,我只是把它列为一个原因。)

否则,它只是语法糖。

请注意,调用某个其他方法/函数时,调用关键字的速度可能不会更快,因为函数返回它的值,并且VB不需要创build局部variables来接收它,即使不使用“ Call也是如此。

我总是使用VBA Call 。 对我来说,它看起来更干净。 但是,我同意,这只是句法糖,它正是个人偏好的领域。 在过去的几年里,我遇到过十几个全职的VBA家伙,而且他们中没有一个使用Call 。 这有另外的好处,我一直知道哪个代码是我的。 :p

不,它只会增加7个字符,没有给定的好处。

我使用CallCall VB.NET中可能使用的通用库函数的所有VBA开发。 这使我可以在VB的所有风格之间使用复制和粘贴来移动代码。 我这样做是为了避免代码编辑器在“格式化”或“漂亮打印”粘贴代码时创build的语法错误。 唯一的编辑通常是Set语句包含/排除。

如果你没有计划将VB / VBA代码移动到VB.NET,那么就不需要使用Call语句。

如果您阅读了Call Statement的MSDN支持页面 ,至less在VBA的具体情况中,它确实表示Call是可选的,但是与此非常相关,没有人会注意到这个引用的行:

如果使用Call语法来调用任何内部或用户定义的函数,则函数的返回值将被丢弃。

这就是为什么Call远没有用处。 假设您正在编写Sub SupportTasks ,它为您执行了许多非常相关的工作(例如,从一个文件中导入数据以供不同的过程使用)。 现在请注意,由于SupportTasks正在读取外部数据,所以这个数据总是有一个很大的可能性,而这个数据不会达到标准,而且这个数据将无法发挥作用。 你是做什么?

例如,你可以使用布尔函数,如果出现错误,返回False 。 而不是调用一个子,调用一个函数SupportTasks里面和If语句,如果有一个exception将退出Main子:

 If Not SupportTasks(SomeArgument) Then Application.ScreenUpdating = True Exit Sub 'Else continue the Main sub regularly without writing anything in here End If 

如果你想知道这与Call有什么关系,请考虑以下内容:在另一个子集中,我调用SupportTasks ,但是我不需要返回的布尔值(例如,我确定不会发生错误)。 那么,如果我不把它放在一个If语句或将函数分配给一个无用的variables,VBA将不会编译并返回给我一个错误( 过程调用无效等等等等等等等等等等等等 。 这就是Call来拯救一天的地方!

 Call SupportTasks(SomeArgument) '<< "Call Function" call doesn't return an error 

如果你仍然认为这是无用的,那么把它当作保持组织的资源。 为许多过程共享的例程编写单独的过程使您的代码更短更容易理解 ,特别是在编写真正大型的应用程序时。 例如,由Excel-Access集成构build的ERP可以更容易地进行操作,修理和定制,如果您的IT部门迟迟不能交付/实施真正的系统…

总之,一些互联网的智慧:

总是写你的代码,好像那个将要审查的人是一个知道你住在哪里的杀人精神病患者。

阿门。

我已经晚了7年,但是刚好在几分钟前遇到了Call关键字,而在MSDN上阅读了一些内容。 特别是,它被用来做一些我认为是不可能在VB.NET(而不是C#) – 这是@ FCastro的答案。

 Class Test Public Sub DoSomething() Console.WriteLine("doing something") End Sub End Class Sub Main() Call (New Test()).DoSomething() End Sub 

在奇怪的情况下,你不需要实际的对象实例,但需要一个方法,你可以使用Call来保存一行。 请注意,当它是操作的右侧时,这是不必要的:

 Class Test Public Function GetSomething() As Integer Return 0 End Function End Class Sub Main() Dim x As Integer = (New Test()).GetSomething() End Sub