¿Debería usar la palabra clave Call en VB / VBA?

Utilizo la palabra clave Call cuando llamo a subs en VB / VBA. Sé que es opcional, pero ¿es mejor usarlo o dejarlo? Siempre pensé que era más explícito, pero tal vez solo sea ruido.

Además, leí esto en otro foro: el uso de la palabra clave Call es más rápido porque sabe que no va a devolver ningún valor, por lo que no necesita configurar ningún stackspace para dejar espacio para el valor devuelto.

Ah, ja. Hace tiempo que me lo pregunto e incluso leer un libro de dos pulgadas de grosor en VBA dice básicamente que no lo use a menos que quiera usar la función Buscar del VBE para encontrar fácilmente llamadas en proyectos grandes.

Pero acabo de encontrar otro uso.

Sabemos que es posible concatenar líneas de código con el carácter de dos puntos, por ejemplo:

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

Pero si hace esto con llamadas de procedimiento al comienzo de una línea, el VBE supone que se está refiriendo a una etiqueta y elimina cualquier sangría, alineando la línea al margen izquierdo (aunque el procedimiento se llame como se pretendía):

 Function Test() Function1 : Function2 End Function 

El uso de la statement de llamada permite la concatenación de llamadas a procedimientos mientras se mantienen las sangrías de código:

 Function Test() Call Function1 : Call Function2 End Function 

Si no utiliza la instrucción Call en el ejemplo anterior, el VBE asumirá que “Function1” es una etiqueta y la alineó en la ventana de código, aunque no causará un error.

Para VB6, si hay alguna posibilidad de que se convierta a VB.NET, usar Call significa que la syntax no cambia. (Se requieren paréntesis en VB.NET para las llamadas a métodos.) (Personalmente, no creo que valga la pena, cualquier conversor de .NET al menos podrá poner entre paréntesis cuando sea necesario. Solo lo estoy enumerando como una razón.)

De lo contrario, es solo azúcar sintáctico.

Tenga en cuenta que es probable que la palabra clave Call no sea más rápida cuando se llama a otro método / función porque una función devuelve su valor de todos modos, y VB no necesita crear una variable local para recibirla, incluso cuando no se utiliza Call .

Siempre uso Call in VBA. Para mí, simplemente se ve más limpio. Pero, estoy de acuerdo, es solo azúcar sintáctica, lo que lo ubica directamente en el ámbito de las preferencias personales. Me he topado con una docena de chicos de VBA a tiempo completo en los últimos años, y ninguno de ellos usó Call . Esto tenía la ventaja adicional de que siempre supe qué código era el mío. :pag

No, solo agregará 7 caracteres por llamada sin ningún beneficio determinado.

Utilizo Call for all VBA para el desarrollo de funciones de biblioteca comunes que posiblemente usaré en VB.NET. Esto me permite mover código usando copiar y pegar entre todos los sabores de VB. Hago esto para evitar los errores de syntax que crea el editor de código cuando “formatea” o “imprime bastante” el código pegado. Las únicas ediciones generalmente son Set inclusión / exclusión de afirmaciones.

Si no tiene planes de mover su código VB / VBA a VB.NET, entonces no hay necesidad de usar la statement de Call .

Si lee la página de soporte de MSDN para la statement de llamadas , para el caso específico de VBA, al menos, dice que la llamada es opcional, pero lo que es muy relevante al respecto y nadie parece notar es esta línea citada:

Si utiliza la syntax de llamada para llamar a cualquier función intrínseca o definida por el usuario, se descarta el valor de retorno de la función.

Es por eso que Call está lejos de ser inútil. Digamos que está escribiendo Sub SupportTasks que hace muchas cosas muy relevantes para usted Main Subs (por ejemplo, importa datos de un archivo para ser utilizados por diferentes procedimientos). Ahora, tenga en cuenta que, dado que SupportTasks está leyendo datos externos, siempre existe la posibilidad de que estos datos no sean estándar y que el sub no pueda cumplir su función. ¿Qué haces?

Podría, por ejemplo, usar funciones booleanas que devuelvan False si algo sale mal. En lugar de llamar a un sub, llame a una función SupportTasks dentro y If que saldrá del sub Main si hay una anomalía:

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

Si se está preguntando qué diablos tiene esto que ver con Call , considere lo siguiente: en otro sub, llamo SupportTasks , pero no necesito su valor booleano devuelto (por ejemplo, estoy seguro de que no ocurrirá un error). ) Bueno, si no lo pongo en una statement If o asigno la función a una variable inútil, VBA no comstackrá y me devolverá un error ( llamada de procedimiento inválida, bla, bla, bla, debe asignar valor a algo, bla, bla, bla ). ¡Ahí es donde entra Call para salvar el día!

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

Si aún crees que es inútil, considéralo un recurso para mantenerte organizado. Escribir procedimientos separados para rutinas compartidas por muchos procedimientos hace que su código sea más corto y más comprensible , especialmente cuando está escribiendo aplicaciones realmente grandes. Los ERP creados a partir de integraciones de Excel-Access, por ejemplo, pueden ser más fáciles de operar, reparar y personalizar si su departamento de TI tarda en entregar / implementar el sistema real ...

Para concluir, cierta sabiduría de internet:

Siempre escriba su código como si la persona que lo revisará es un psicópata asesino que sabe dónde vive.

Amén.

Llego 7 años tarde a la fiesta, pero me encontré con la palabra clave Call hace unos minutos mientras leía algo en MSDN. En particular, se usó para hacer algo que pensé que era imposible en VB.NET (a diferencia de C #), que está relacionado con la respuesta de @ FCastro.

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

En el caso extraño, no necesita la instancia de objeto real, pero requiere uno de sus métodos, puede usar Call para guardar una línea. Tenga en cuenta que esto no es necesario cuando se trata del lado derecho de una operación:

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

El único caso que encontré “llamada” es útil es un gran accidente, sobre algunos operadores especiales.

 Dim c As IAsyncOperation(Of StartupTask) = StartupTask.GetAsync("Startup") …… (Await c).Disable() 

Tengo un error de syntax para la segunda línea, al igual que lo que obtendrá con un operador “Nuevo”. Realmente no quiero una nueva variable, que es demasiado poco elegante para mí. Así que lo intenté:

 DirectCast(Await c, StartupTask).Disable() 

Esto es sintácticamente correcto. Pero luego el IDE me insinuó que el “DirectCast” es innecesario y me dio una simplificación. Si eso es:

 Call (Await c).Disable() 

Es por eso que me encanta VS2017 Preview. 😄