El d铆a de hoy, hablaremos de c贸mo compartir informaci贸n entre subrutinas de VBA al invocarlas, a trav茅s del pasaje de argumentos ByVal y ByRef.Seguramente conozcas que puedes invocar una macro a partir de otra: esto significa, durante la ejecuci贸n de una subrutina de VBA determinada, hacer el llamado a una segunda subrutina, y tras la ejecuci贸n completa de esta 煤ltima, retomar la primera. Esto puede ayudarte a dividir c贸digos extensos en fragmentos manejables, as铆 como reutilizar y evitar la duplicaci贸n de c贸digo que puede utilizarse para m谩s de un prop贸sito espec铆fico.
Sin embargo, muchos estudiantes y programadores de VBA se topan con dificultades ante la necesidad de ya no solamente llamar y ejecutar macros, sino procurar pasarles alg煤n tipo de informaci贸n que estas macros secundarias puedan utilizar, leer o transformar. Sabemos que podemos almacenar informaci贸n en variables, por lo que estos "paquetes" parecen apropiados para enviar informaci贸n de un lado a otro. ¿Pero c贸mo?
VBA nos proporciona herramientas diferenciadas para los casos en que requerimos modificar variables, o 煤nicamente leerlas. Gestion谩ndolo adecuadamente, esto nos permitir谩 regular los "permisos" que existen en cuanto al acceso a las variables, para garantizar que los cambios que se produzcan sobre las mismas sean verdaderamente buscados y no accidentales. Estas herramientas son ByVal y ByRef.
- ByRef es la forma predeterminada con la cual podemos pasar argumentos: lo que se transmite es la variable en s铆, con lo cual puede ser modificada antes de ser devuelta, actualizada con su nuevo valor
- ByVal es la forma en la que se proporciona acceso de "solo lectura": se env铆a una copia de la variable a otra macro tal que pueda leerse su valor, pero dicha variable no ver谩 su valor alterado luego de la ejecuci贸n de la segunda macro.
Veamos c贸mo utilizarlas para hacer una correcta invocaci贸n a trav茅s de un ejemplo.
En primer lugar, necesitaremos contar con dos macros. Consideremos una macro Principal, que ejecuta una serie de instrucciones sin depender de otra, y una macro secundaria, llamada en este caso CalculoMonto, que es invocada por la macro Principal y debe recibir informaci贸n de ella.
El objetivo de la macro Principal ser谩 capturar una serie de datos, invocar a la macro secundaria que los procesar谩, y finalmente mostrar un mensaje con el resultado obtenido por la segunda macro.
Para ello, crearemos tres variables: salario, que ser谩 un valor entero cargado en una celda de la hoja de c谩lculo, porcentaje_bono, que ser谩 un porcentaje de aumento sobre la base de salario, y monto_total, en la cual ser谩 almacenado el resultado de sumar el bono al salario. La macro secundaria, CalculoMonto, necesitar谩 tomar estos datos y devolver un resultado. Sin embargo, no le dar谩 el mismo tratamiento a todas las variables: 煤nicamente necesitar谩 leer los valores de salario y porcentaje_bono, pero necesitar谩 actualizar el valor de monto_total, una vez realizado el c谩lculo.
Sub Principal()
Dim salario As Integer
Dim porcentaje_bono As Double
Dim monto_total As Double
'Capturar informaci贸n
salario = Range("A1").Value
porcentaje_bono = Range("A2").Value
monto_total = 0
' Llamado para ejecutar CalculoMonto
MsgBox "Este mes percibir谩s un total de $" & monto_total
End Sub
En la subrutina anterior, dejamos pendiente completar la l铆nea de invocaci贸n a CalculoMonto. Veamos primero en qu茅 consiste esta:
Sub CalculoMonto()
resultado = valor * (1 + porcentaje)
End Sub
Como vemos, es una macro sencilla. Para que pueda recibir las variables valor, porcentaje y resultado, deberemos indicarlo dentro de los par茅ntesis iniciales, del siguiente modo:
Sub CalculoMonto(ByVal valor, porcentaje, ByRef resultado)
resultado = valor * (1 + porcentaje)
End Sub
En este caso, hemos hecho uso tanto de la referencia ByVal, con lo cual CalculoMonto har谩 煤nicamente lectura de los valores de las variables valor y porcentaje, y ByRef, con lo cual tendr谩 la capacidad de modificar el valor de resultado y devolverlo actualizado.
valor, porcentaje, resultado reciben el nombre de par谩metros: valores que se esperan al invocar un procedimiento.
Sin embargo, puede que te hayas dado cuenta de algo: los nombres de las variables utilizadas en Principal y CalculoMonto no coinciden. No es motivo de preocupaci贸n: la interpretaci贸n de cu谩l variable se corresponde con cu谩l se da por la posici贸n, como si fuera una funci贸n de Excel. Sabremos que si invocamos la subrutina CalculoMonto, tendremos que pasar en primer lugar la variable que oficiar谩 de valor, en segundo la de porcentaje, y tercera la de resultado. En la macro Principal, estos roles las cumplen, respectivamente:
- salario
- porcentaje_bono
- monto_total
Por lo que una invocaci贸n a CalculoMonto desde Principal, se ver铆a del siguiente modo:Call CalculoMonto(salario, porcentaje_bono, monto_total)
En esta oportunidad, no indicamos ByVal o ByRef, ya que esto se hace 煤nicamente en la definici贸n de la macro CalculoMonto.
salario, porcentaje_bono, monto_total reciben el nombre de argumentos: valores que se proporcionan al invocar un procedimiento.
Con ello, la situaci贸n final de ambas macros ser谩:
Dim salario As Integer
Dim porcentaje_bono As Double
Dim monto_total As Double
'Capturar informaci贸n
salario = Range("A1").Value
porcentaje_bono = Range("A2").Value
monto_total = 0
Call CalculoMonto(salario, porcentaje_bono, monto_total)
MsgBox "Este mes percibir谩s un total de $" & monto_total
End Sub
Sub CalculoMonto(ByVal valor, porcentaje, ByRef resultado)
resultado = valor * (1 + porcentaje)
End Sub
Y ambas macros trabajar谩n juntas para lograr un objetivo. Si bien trabajamos sobre un ejemplo muy sencillo, el provecho de este m茅todo adquiere mayor significado a medida que se incrementa la complejidad del proceso, ya que dividirlo en partes nos ayuda a abarcarlo de a poco. Y piensa finalmente el beneficio de invocar la macro CalculoMonto para procesar cualquier otro tipo de valor: con solo pasarle los argumentos requeridos, podr谩 procesar informaci贸n de cualquier origen, sin duplicar o crear nuevo c贸digo.