martes, 29 de abril de 2014

VBA: Variables Dim, Public, Private y Static

En definitiva hablaremos hoy del ámbito de las variables, es decir, dónde aplican nuestras variables una vez definidas. Es importante saber que el ámbito de una variable se determina en el momento en que se declara la variable.
En VBA para Excel, los tres ámbitos existentes para las variables son: Públicas, Módulo y Procedimiento.


Comenzamos por el más habitual el ámbito de Procedimiento, es decir, la variable así definida se reconoce únicamente dentro del procedimiento en el que la declaramos.
Podremos declarar una variable local de procedimiento con una instrucción Dim o Static.

Cuando definimos o declaramos una variable local con la instrucción Dim, la variable permanece en memoria sólo mientras se ejecuta el procedimiento en el que la hemos declarado, y por tanto, normalmente, cuando termina el procedimiento de ejecución, no se conservan los valores de las variables locales del procedimiento y se libera la memoria asignada a esas variables. La próxima vez que se ejecute el procedimiento, se reinicializarán todas las variables locales declaradas.

Un ejemplo de variable local DIM:

En un módulo cualquiera de nuestro proyecto de VBA insertamos los siguientes procedimientos:

Sub Local1()
   Dim X As Integer 'variable local dentro del Procedimiento
   X = 1313
   MsgBox "X tiene un valor de " & X
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub Local2()
   Dim X As String 'variable local dentro del Procedimiento
   X = "Afirmativo"
   MsgBox "La respuesta ha sido " & X
End Sub


Muy importante!!: Cada variable X es independiente del otro procedimiento, sólo se reconoce la variable dentro de su propio procedimiento respectivo (Local1 ó Local2).

La otra forma de definir una variable local de Procedimiento es declarar la variable como Static. Una variable local declarada con la instrucción Static sigue existiendo todo el tiempo que se ejecuta en Visual Basic. La variable se restablece cuando se produzca cualquiera de las siguientes acciones:
- La macro genera un error de tiempo de ejecución no interceptado.
- VBA se detiene.
- Salimos de Excel.
- Cambiamos el módulo.

Un ejemplo de variable local STATIC:

En un módulo cualquiera de nuestro proyecto de VBA insertamos los siguientes procedimientos:

Sub Estatica()
   Static Acum 'variable local que retiene su valor
   'tras finalizar el procedimiento...
   num = Application.InputBox(prompt:="Introduce un valor: ", Type:=1)
   Acum = Acum + num
   MsgBox "La variable acumulada (estática) nos devuelve un valor " & Acum
End Sub


Muy Importante!!: En nuestro procedimiento Estatica, la variable 'Acum' conserva su valor cada vez que se ejecuta. Por ejemplo, la primera vez que se ejecuta el módulo, introducimos en el cuadro el valor 10, el MsgBox mostrará el valor 10 (lógicamente)... si la siguiente vez que se ejecuta el módulo, introducimos el valor 20, el MsgBox mostrará el valor de 30 (10+20...) !!.

El siguiente ámbito interesante para conocer es el de Módulo.
Una variable que es reconocida en todos los procedimientos en un módulo se denomina una variable de Módulo. Una variable de nivel de módulo está disponible para todos los procedimientos de ese mismo módulo, pero no está disponible para los procedimientos de otros módulos.
Mientras VBA se ejecuta, hasta que se modifique el módulo en el que se declara, una variable de módulo sigue existiendo.
Se pueden declarar variables de ámbito de módulo con una instrucción Dim o Private en la parte superior del módulo, encima de la primera definición de procedimiento.

En el ámbito de módulo, no hay ninguna diferencia entre Dim y Private... pero debemos tener en cuenta que no se pueden declarar variables de ámbito de módulo dentro de un Procedimiento.
En general, una recomendación, si utilizamos Private en lugar de Dim para las variables de ámbito módulo, el código será más fácil de leer esto es, si utilizamos Dim solamente para variables locales de procedimiento y Private para las variables de módulo, el ámbito de una variable determinada será más claro.
Un ejemplo de variable de módulo:

En un módulo cualquiera de nuestro proyecto de VBA insertamos los siguientes procedimientos:

'Variables A y B de ámbito Módulo
'que sirven para todos los procedimientos de este módulo
Dim A As Integer
Private B As Integer

Sub Procedimiento1()
    A = 100
    B = A + 1
End Sub

Sub Procedimiento2()
    MsgBox "A es igual a " & A
    MsgBox "B es igual a " & B
End Sub

Sub Procedimiento3()
     Dim C As Integer    'Variable local de procedimiento
     C = A + B
     MsgBox "C es igual a" & C
End Sub

Sub Procedimiento4()
     MsgBox A     'Este MsgBox muestra el valor de A
     MsgBox B     'Este MsgBox muestra el valor de B
     MsgBox C     'Este MsgBox NO muestra nada, porque C la habíamos definido como variable local de procedimiento
End Sub


Muy importante!!!: En el ejemplo siguiente, hemos comenzado declarando dos variables A y B, de ámbito de módulo (antes de todos los procedimientos!!), por tanto estarán disponibles para cualquiera de los procedimientos de dicho módulo. La tercera variable C, que se declara en la macro de Procedimienti3, es una variable local y sólo está disponible para ese procedimiento.

Tengamos en cuenta que en Procedimiento4, cuando la macro intenta utilizar la variable C, el tercer MagBox está vacíoporque C es una variable local y no está disponible en Procedimiento4, mientras que las variables A y B si lo están al tener como ámbito todo el módulo.


Finalizaremos con las variables Públicas (recordemos que eran tres los ámbitos).
Las variables públicas - Public - tienen el ámbito más amplio de todas las variables. Una variable pública es reconocida por todos los módulos del libro de trabajo activo.
Una variable pública se declara igual que una variable de ámbito de módulo, es decir, en la parte superior del módulo, encima de la primera definición de procedimiento. NO se puede declarar una variable pública dentro de un procedimiento. Siempre se declara una variable pública con una instrucción Public (podremos declarar una variable pública en cualquier módulo).

Atención por que es posible que varios módulos tengan variables públicas con el mismo nombre !!!, por tanto, para evitar confusiones y posibles errores, una buena práctica sería utilizar nombres únicos.
Un ejemplo de variable PUBLIC:

En un módulo cualquiera de nuestro proyecto de VBA insertamos el siguiente procedimiento:

Public precio As Double  'variables públicas válidas para todo el libro
Public uds As Integer
Public costes As Integer
Private factor As Double

Sub CDSales()
precio = 1.313
uds = 1000
costes = 1
factor = 1.1

MsgBox "El resultado es " & uds * (precios - (costes * factor))
End Sub


Importante!!: Las tres variables Public sirven para cualquier módulo dentro del libro, mientras que la cuarta (Pirvate factor) únicamente serviría dentro de este módulo.

5 comentarios: