Páginas de este artículo: 1 2 3
Introducción
Manual de VBA (Visual Basic para Aplicaciones) para Microsoft Access
Con este artículo pretendo que las personas puedan inicializarse en la programación con código VBA y que aunque sean principiantes puedan interpretar cualquier código que se les presente. Para ello intentare usar el lenguaje más sencillo posible para que sea mas claro para todos.
No pretendo enseñar todos los detalles, solo pretendo "Abrirles la puerta" para que vean este gran mundo, y con el camino indicado puedan descubrir muchas cosas por su cuenta
¿Porque leer este artículo?
Porque intento que las personas aprendan todo de manera general en tiempo record
Para continuar es necesario que el usuario haya hecho cosas sencillas en Access, como macros formularios, no es necesario saber mucho
Tampoco es un articulo solo para principiantes, espero abarcar varios puntos y al finalizar espero que todos estén preparados para el siguiente articulo (Aprendiendo Funciones API), así que es mejor que todos lo lean
Importante:
Conforme se vallan tocando los temas quizá quieras profundizar mas en algo e investigar al respecto, te sugiero que te aguantes las ganas, espera a leer/terminar todo el articulo. Esto es porque los temas los voy a tocar de manera básica, para que tengas el concepto general y puedas relacionarlo con los demás temas, de esta manera lograras entender todo sin complicaciones. Luego de terminar este articulo y haberlo comprendido, ya podrás especializarte en cualquier tema o quizá ya empieces a generar tus códigos, y conforme vas avanzando se te irán presentando los temas para que profundices.
Iniciamos...
Parte I
¿Que son las macros?
Las macros son objetos que nos permiten realizar diferentes acciones, si ves una macro en vista de diseño veras que hay un campo llamado "Acciones", campo que se puede desplegar y te aparece el listado de las opciones de lo que puedes realizar.
En realidad estas acciones son procedimientos internos, líneas de código o instrucciones que el programa seguirá y ejecutara.
¿Cual es el límite de las Macros?
Pues el total de acciones que te aparecen en la "Lista de las Acciones", aunque combinando diferentes Acciones se convierten en muchas posibilidades
Nosotros podemos escribir directamente estas acciones en procedimientos (líneas de código o instrucciones), tendremos a disposición todas las opciones que nos dan las macros y muchas mas, las posibilidades se hacen casi infinitas. Cuando nosotros empezamos a escribir los procedimientos es cuando empezamos a sentir que tomamos el verdadero control de las cosas, una vez que has iniciado no vuelves atrás, las macros casi pasan al olvido porque te parecerán que se quedan muy cortas. Escribiendo tus procedimientos pasas de ser un usuario(a) a programador(a).
¿Interesante verdad?, bueno, estas a punto de se parte de todo eso...
Para iniciar, crea una base de datos nueva que nos servirá para realizar pruebas, recuerda que no debes borrar nada de lo que vallamos realizando, porque vamos a ir reutilizando ejemplos
Convirtiendo Macros a Procedimientos de Código
Como mencionábamos antes, las macros son en realidad procedimientos de código, estos procedimientos se escriben en los objetos llamados "Módulos".
Vamos a realizar lo siguiente:
Creemos una nueva macro, en la lista de Acciones escogemos "Bip", le damos guardar, ahora nos pide un nombre para la macro, le ponemos como nombre "Bip" y por ultimo cerrar.
Si corremos la macro (doble clic) nos dará un sonido (Es la acción que escogimos).
Ahora démosle un clic secundario a la macro, en el menú contextual que se nos desplega escogemos la opción "Guardar como", nos aparecerá un formulario, allí le ponemos el nuevo nombre, pongámosle "Procedimiento de la macro Bip", el cuadro combinado de abajo que tiene como nombre "Como", lo desplegamos y escogemos la opción "Módulo", le damos Aceptar, ahora nos aparece un formulario con dos checks, desmarca los dos y pulsamos el botón "Convertir".
Si se quedo en la ventana VBA vacía, dale cerrar (arriba en la "X")
En la ventana principal de Access nos aparecen los diferentes objetos (Tablas, Consultas, Formularios, Informes, Páginas, Macros y Módulos), vamos a los objetos "Módulos" y nos aparece el modulo de la macro convertida, si le damos doble clic nos abrirá el modulo y podremos observar algo como esto:
'------------------------------------------------------------
' Bip
'
'------------------------------------------------------------
Function Bip()
Beep
End Function
Este es el procedimiento interno que esta corriendo la macro "Bip".
Como Se Escriben Los Procedimientos
Analicemos el procedimiento que acabamos de crear al convertir la macro:
Las primeras líneas inician con un apostrofe ( ' ), esto le indica al sistema que no son líneas para ejecutar, simplemente son notas o apuntes que podemos utilizar para dar alguna descripción de lo que hará el procedimiento o notas personales, si las borráramos no pasaría nada, no influyen en la ejecución del procedimiento. Estas notas las podemos colocar en cualquier lugar, fuera o dentro del procedimiento. Las reconocemos fácilmente porque aparecen en el código en color verde
El procedimiento en si contiene las 3 líneas:
Línea 1: Function Bip()
Es la declaración del procedimiento, donde la palabra "Function" esta indicando que inicia un procedimiento, la palabra "Bip" es el nombre del procedimiento. Los nombres no pueden contener espacios en blanco y tampoco pueden tener nombres de palabras reservadas por el sistema.
Por ultimo tenemos los paréntesis, todos los procedimientos deben terminar con paréntesis.
Hagamos lo siguiente, cambiémosle el nombre al procedimiento, cambiemos la palabra "Bip" por "EmitirSonido"
Línea 2: Beep
Es el cuerpo del procedimiento o las instrucciones (en realidad la palabra Beep es una instrucción que le ordena al sistema que emita un sonido), en este caso el cuerpo del procedimiento es de solo una línea, pero puede ser cualquier cantidad
Línea 3: End Function
Aquí estamos indicando que termina el procedimiento
Corriendo/Ejecutando Un Procedimiento
Para que puedas correr/ejecutar/probar un procedimiento, haz clic en cualquiera de sus líneas, esto es para seleccionar el procedimiento (porque puedes tener muchos), luego tienes cualquiera de estas 3 opciones:
1. Ir al menú: Ejecutar/Ejecutar Sub/UserForm
2. Pulsar la tecla F5
3. O en la barra de herramientas pulsa el triangulo verde
Haz la prueba con las 3 opciones, corre el procedimiento anterior, ¿Todo correcto?, ok, continuamos...
En el mismo modulo podemos escribir muchos procedimientos, pero mejor vamos a crear un nuevo modulo que nos servirá para realizar nuestras pruebas:
Antes vamos a realizar un ajuste, no tienes que entenderlo ahora, te lo explicare mas adelante. Siempre en la ventana VBA vamos al menú:
Herramientas/Opciones/Pestaña Editor/Requerir declaración de variables
Este es un check que debes activar, le das aceptar.
Démosle cerrar a la ventana VBA, nos quedamos siempre en la ventana principal de Access en los objetos módulos, pulsemos "Nuevo", nos abre de nuevo la ventana VBA en un modulo nuevo, pulsamos el botón de guardar, le ponemos como nombre "Mis primeras pruebas".
En el modulo que acabas de crear te aparecen dos líneas inicialmente:
Option Compare Database
Option Explicit
En este momento no les hagas caso, lo explicaremos mas adelante. Los procedimientos que se crean en el modulo deben quedar abajo de estas líneas.
Ahora escribamos nuestro primer procedimiento, copia y pega el procedimiento siguiente:
Sub MiMensaje()
MsgBox "Este es mi primer mensaje, voy muy bien!"
End Sub
Corre el procedimiento como lo hiciste con el anterior... ¿Que tal?,
La instrucción MsgBox le dice al sistema que nos muestre un mensaje
Aquí seguro que ya viste una diferencia, en el primer procedimiento lo declarábamos así:
Function EmitirSonido()
Y ahora lo estamos haciendo así:
Sub MiMensaje()
Exacto, existen dos tipos de procedimientos, Sub y Function. Con los dos podemos escribir cualquier tipo de líneas de código (instrucciones), una de las diferencias es que los procedimientos Function además nos pueden devolver un valor (mas adelante profundizaremos en el tema de devolución de valores).
Seguimos con las pruebas, copia y pega estos procedimientos:
Function TextoDelMensaje()
TextoDelMensaje = "Yo soy el texto"
End Function
Sub MostrarMensaje()
Msgbox TextoDelMensaje
End Sub
(Recuerda que para correr un procedimiento primero debes hacer clic sobre cualquiera de sus líneas para que el sistema sepa cual es el que estas seleccionando)
Corre el procedimiento Function TextoDelMensaje()... parece que no pasa nada.
Ahora corre el procedimiento Sub MostrarMensaje()... nos muestra un mensaje con el texto que esta escrito dentro del otro procedimiento Function.
¿Que es lo que esta pasando?
Si ves el cuerpo del procedimiento Function, el procedimiento se esta asignando a si mismo un valor de texto, ahora solo hay que recoger este valor y hacer algo con el. Esta la forma en que los procedimientos Function devuelven un valor.
En el cuerpo del procedimiento Sub:
Msgbox TextoDelMensaje
Primero le decimos al sistema que queremos que nos muestre un mensaje con la instrucción MsgBox, inmediatamente después la instrucción nos pide una cadena de texto para mostrar en el mensaje, como cadena de texto estamos escribiendo el nombre de la Function, porque sabemos que esta nos esta devolviendo una cadena de texto. Cuando corrimos por primera vez la Function si realizo algo, se asigno su valor, pero ya hubo no nada más.
Esto que acabamos de ver es lo mas básico y elemental en procedimientos, debes saberlo de memoria, igual que sabes cuanto es 1+1
Antes de continuar debemos aprender como usar la ventana de "Inmediato", que también nos sirve para realizar pruebas.
Usando La Ventana Inmediato
Estando siempre dentro de la ventana de VBA, podemos ver la ventana de inmediato con cualquiera de estas opciones:
1. Ir al menú Ver/Ventana Inmediato
2. Pulsar la combinación de teclas Ctrl+G
La ventana de Inmediato nos aparece en la parte inferior de la ventana VBA.
Empecemos a utilizarla, en el procedimiento que escribimos anteriormente (el primero del modulo):
Sub MiMensaje()
MsgBox "Este es mi primer mensaje, voy muy bien!"
End Sub
Ahora cambiaremos MsgBox por Debug.Print, nos quedara así:
Sub MiMensaje()
Debug.Print "Este es mi primer mensaje, voy muy bien!"
End Sub
Corremos el procedimiento y podemos ver en la ventana de inmediato que allí se escribió el mensaje. Ahora intentemos esto, directamente en la ventana de inmediato escribamos:
Debug.Print 5 + 5
Y presionamos Enter, nos imprime (muestra en la ventana inmediato) el valor 10
Ahora escribamos:
Debug.Print TextoDelMensaje
Y presionamos Enter
Ahora escribamos:
? 5 + 5
Y presionamos Enter, nos volvió a imprimir el 10. El signo de interrogación es lo mismo que escribir Debug.Print, lo único es que puedes usarlo solo directamente en la Ventana Inmediato, no funciona dentro del código
Por ultimo escribamos:
MostrarMensaje
Y presionamos Enter
Te pudiste dar cuenta que esta es otra forma de correr un procedimiento.
¿Todo Correcto?, ¿Fácil no?
Puedes borrar el texto de la ventana inmediato como has borrado cualquier texto, en cualquier momento, en el momento que gustes
Utilizando Variables
Las variables nos sirven para abrir un espacio de memoria donde podemos guardar algún valor que utilizaremos después.
Copia y pega los dos procedimientos siguientes, correlos y analiza lo que esta pasando:
Sub PruebaVariableUno ()
Dim MiTotal 'declaración de la variable, siempre inicia con "Dim" mas el nombre de la variable
MiTotal = 10 * 10 'Aquí le estamos asignando un valor de 100 a la variable
Debug.Print MiTotal 'Mostramos el valor de la variable en la ventana inmediato
MiTotal = 50 + 3 'Le estamos cambiando el valor a la variable
Debug.Print MiTotal
MiTotal = MiTotal + 10 'El valor de la variable es igual al valor que ya tiene, mas 10
Debug.Print MiTotal
End Sub
Sub PruebaVariableDos()
Dim MiTotal 'declaración de la variable, siempre inicia con "Dim" mas el nombre de la variable
Dim UnNumero
MiTotal = 5 + 5
UnNumero = 5 + 5
Debug.Print MiTotal + UnNumero
Debug.Print MiTotal * UnNumero
Debug.Print MiTotal - UnNumero
Debug.Print MiTotal / UnNumero
End Sub
Tipos De Variables
Los diferentes tipos de variables abren diferentes espacios en memoria, algunas consumen más memoria que otras, por lo que para hacer más eficiente tu aplicación debes ir aplicando a tus variables el tipo necesario. Entre los tipos de variables tenemos:
Boolean (Falso/Verdadero)
Byte (Bite)
Integer (Entero)
Long (Entero Largo)
Currency (Moneda, acepta hasta 4 decimales)
Single (Simple, acepta más decimales que el tipo Currency)
Double (Doble, acepta mas decimales que el tipo Single)
Date (Fecha y Hora)
String (Cadena, Texto)
Object (Objeto)
Variant (Variante, acepta cualquier tipo de valor)
Para conocer los rangos exactos de los valores que acepta cada tipo de variable consulta después la Ayuda de Access.
Tomemos por ejemplo el tipo Byte, que acepta solo números enteros entre 0 y 255:
Sub MisPosiblesNietos()
Dim MiNumeroDeHijos As Byte 'Así declaramos la variable con su tipo especifico
MiNumeroDeHijos = 5
Debug.Print "Mis posibles nietos: " & MiNumeroDeHijos * 3
End Sub
En el procedimiento anterior declaramos la variable "MiNumeroDeHijos" como tipo Byte porque creo que nadie puede tener mas de 255 hijos, esta variable también la pudimos declarar como tipo Integer, Long, Currency, Single, Double o Variant y funcionaria bien, pero seria un desperdicio de recursos del sistema
Si en la variable anterior hicieras esto:
Dim MiNumeroDeHijos As Byte
MiNumeroDeHijos = 100 * 3
Te Daria un error de desbordamiento, porque la variable tipo Byte solo aguanta valores hasta 255, si en realidad necesitaras hacer eso, debes declarar la variable con otro tipo, el que le sigue es el Entero (Integer):
Dim MiNumeroDeHijos As Integer
El tipo de variable Variant es muy especial, este tipo puede contener cualquier tipo de valor, numérico, texto u objetos. Si se declara una variable y no se especifica el tipo, el sistema la asume como tipo Variant.
Dim UnaVariable 'Así queda como tipo Variant
Es fácil no declarar cada variable con un tipo especifico y que queden todas como Variant (porque acepta cualquier valor), pero como dijimos, es un desperdicio de recursos del sistema. Un buen programador declara bien todas sus variables, es mas, todos lo hacen y todos debemos hacerlo.
Nombres De Las Variables
Las variables te aceptan cualquier nombre siempre y cuando no se ingresen espacios intermedios, el nombre es muy importante porque puede ayudarte a entender tu propio código y te puede evitar poner demasiadas notas. En un procedimiento corto es fácil seguir a las variables, pero cuando tienes procedimientos muy largos y con muchas variables entonces ves la diferencia. Una regla general es que los primeros 3 caracteres del nombre te indique el tipo con el que esta declarada:
Dim strDireccion as String 'tipo texto
Dim lngCambios as Long 'tipo entero largo
Veamos un ejemplo para que veas de lo que hablamos, ¿Cual de estos dos procedimientos entiendes mejor?
Sub PruebaVariables()
Dim c as String
Dim d as String
c = "PL0400"
d = "Wire 800400"
Debug.Print c & " " & d
End Sub
Sub PruebaVariables()
Dim strCodigo as String
Dim strDescripcion as String
strCodigo = "PL0400"
strDescripcion = "Wire 800400"
Debug.Print strCodigo & " " & strDescripcion
End Sub
¿Ves la diferencia?
Estas reglas para nombrar variables también se aplican para los nombres de procedimientos.
Tampoco vallas a caer en nombres muy largos y muy descriptivos, porque cargas mucho visualmente tu código, te será más difícil a ti como programador estar escribiendo nombres largos y no se ve muy estético:
Dim sngPorcentajeDeDescuentoParaAplicarleAlProducto as Single
Podría ser:
Dim sngPorcDesc as Single
Declarando Procedimientos Function (Funciones)
Al igual que como vimos con las variables, los procedimientos Function que nos van a devolver un valor debemos declararlos con un tipo especifico de datos. ¿Recuerdas el primer procedimiento Function que escribimos y que nos devolvía un texto?, iba de esta manera:
Function TextoDelMensaje() 'No le estamos indicando el tipo, así que toma el tipo Variant
TextoDelMensaje = "Yo soy el texto"
End Function
Como esta Function nos devuelve un texto, lo correcto es que la declaremos así:
Function TextoDelMensaje() As String 'Aquí le indicamos que tipo de valor nos va a devolver
TextoDelMensaje = "Yo soy el texto"
End Function
Function TuEdad() As Byte 'Aquí le indicamos que tipo de valor nos va a devolver
TuEdad = 25
End Function
Y así con cada Function dependiendo del valor que nos devolverá...
Valores Iniciales De Las Variables Y De Los Procedimientos Function (Funciones)
Las Variables y procedimientos Function nacen con un valor predeterminado, este valor se los asigna el sistema en el momento que las crea en memoria. El valor inicial depende del tipo con el que han sido declarados:
Tipo String (Texto), inicializan como una cadena vacía, igual a ""
Tipo Numéricas, inicializan como cero
Tipo Boolean, inicializan como Falso (False)
Tipo Variant, inicializan como Empty (adelante entraremos en detalles)
Tipo Object, inicializan como Nothing (adelante entraremos en detalles)
Si deseas conocer si una variable de tipo Variant se ha inicializado puedes hacer:
Dim varVar As Variant
If IsEmpty(varVar) Then
Debug.Print "La Variable Variant no a sido inicializada"
End If
Si deseas conocer si una variable de tipo Object (Objeto) se ha inicializado puedes hacer:
Dim obj As Object
If obj Is Nothing Then
Debug.Print "El objeto no a sido inicializado"
End If
Parte II
Para continuar es necesario que tengas bien comprendida la Parte I, de no ser así puede ser que vallas a confundirte, repasa lo que sea necesario
Como ya estas bien claro con la Parte I... continuamos
Procedimientos Con Parámetros
Los parámetros son valores que nos piden los procedimientos para su correcto funcionamiento. Veamos un ejemplo (copia y pega):
Sub LanzarMensaje(strMensaje As String)
MsgBox strMensaje
End Sub
El parámetro aquí es "strMensaje" que como puedes ver, es como una variable que se encuentra dentro del paréntesis de declaración del procedimiento, se le debe especificar de que tipo será y para declararla NO usamos la palabra Dim.
Para que este procedimiento pueda funcionar espera que le pasemos un valor de tipo texto en el parámetro ("strMensaje"), porque este texto será el que se mostrara en el mensaje. Llamemos a este procedimiento desde otro:
Este procedimiento seria bueno que no lo copies y lo pegues, escríbelo a mano para que puedas ver como es que al ir llamando al otro procedimiento te va pidiendo su parámetro
Sub PruebaMensaje()
LanzarMensaje "Este es una prueba de mensaje"
LanzarMensaje "Ya estoy entendiendo lo de parámetro de texto"
LanzarMensaje "Con este texto ya es suficiente"
End Sub
Corre el procedimiento Sub PruebaMensaje()...
Si llamáramos al procedimiento y no le pasamos el valor al parámetro así:
Sub PruebaMensaje()
LanzarMensaje
End Sub
Recibiríamos un error que nos dice "El argumento no es opcional", lo cual quiere decir que obligatoriamente debemos especificar un valor para el parámetro o no se puede continuar
Un procedimiento puede tener cualquier cantidad de parámetros, todos los que sean necesarios, solo deben declararse separados por coma:
Sub UnProc (strAlgo As String, lngNumero As Long, intValor As Integer)
...
End Sub
Parámetros Opcionales
Estos son un tipo de parámetro que puede o no ser llenado porque es opcional, el procedimiento correrá de todas formas. Lo correcto es que al declarar una variable como opcional le asignemos de una vez el valor que tomara al no recibir un valor (copia y pega):
Sub ImprimirTexto(Optional ElTexto As String = "No me ingresaron, soy una cadena automatica")
Debug.Print ElTexto
End Sub
Ahora ve a la ventana Inmediato y escribe:
ImprimirTexto "Esta cadena yo la escribí"
Y pulsa enter.
Ahora llamemos al mismo procedimiento pero no ingresemos valor en el parámetro, escribamos en la ventana Inmediato:
ImprimirTexto
Y pulsas enter, ¿Viste?
A los parámetros declarados como opcionales se les coloca la palabra Optional al inicio de la declaración, un procedimiento puede tener varios parámetros, los parámetros opcionales siempre deben ser colocados de último