You are on page 1of 31

Aprender cdigo VBA en unas horas

Introduccin

Manual de VBA (Visual Basic para Aplicaciones) para Microsoft Access
Con este artculo pretendo que las personas puedan inicializarse en la programacin con cdigo VBA y que
aunque sean principiantes puedan interpretar cualquier cdigo que se les presente. Para ello intentare usar el
lenguaje ms sencillo posible para que sea mas claro para todos.
No pretendo ensear 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 artculo?
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
estn 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 bsica, para que tengas el concepto general y puedas relacionarlo con los dems temas, de
esta manera lograras entender todo sin complicaciones. Luego de terminar este articulo y haberlo
comprendido, ya podrs especializarte en cualquier tema o quiz ya empieces a generar tus cdigos, y
conforme vas avanzando se te irn 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 diseo
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, lneas de cdigo o instrucciones que el programa
seguir y ejecutara.

Cual es el lmite 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 (lneas de cdigo o instrucciones),
tendremos a disposicin 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 atrs, las macros casi pasan
al olvido porque te parecern 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 Cdigo
Como mencionbamos antes, las macros son en realidad procedimientos de cdigo, estos procedimientos se
escriben en los objetos llamados "Mdulos".
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 accin que escogimos).
Ahora dmosle un clic secundario a la macro, en el men contextual que se nos desplega escogemos la
opcin "Guardar como", nos aparecer un formulario, all le ponemos el nuevo nombre, pongmosle
"Procedimiento de la macro Bip", el cuadro combinado de abajo que tiene como nombre "Como", lo
desplegamos y escogemos la opcin "Mdulo", le damos Aceptar, ahora nos aparece un formulario con dos
checks, desmarca los dos y pulsamos el botn "Convertir".
Si se quedo en la ventana VBA vaca, dale cerrar (arriba en la "X")

En la ventana principal de Access nos aparecen los diferentes objetos (Tablas, Consultas, Formularios,
Informes, Pginas, Macros y Mdulos), vamos a los objetos "Mdulos" 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 lneas inician con un apostrofe ( ' ), esto le indica al sistema que no son lneas para ejecutar,
simplemente son notas o apuntes que podemos utilizar para dar alguna descripcin de lo que har el
procedimiento o notas personales, si las borrramos no pasara nada, no influyen en la ejecucin del
procedimiento. Estas notas las podemos colocar en cualquier lugar, fuera o dentro del procedimiento. Las
reconocemos fcilmente porque aparecen en el cdigo en color verde

El procedimiento en si contiene las 3 lneas:

Lnea 1: Function Bip()
Es la declaracin 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 parntesis, todos los procedimientos deben terminar con parntesis.
Hagamos lo siguiente, cambimosle el nombre al procedimiento, cambiemos la palabra "Bip" por
"EmitirSonido"

Lnea 2: Beep
Es el cuerpo del procedimiento o las instrucciones (en realidad la palabra Beep es una instruccin que le
ordena al sistema que emita un sonido), en este caso el cuerpo del procedimiento es de solo una lnea, pero
puede ser cualquier cantidad

Lnea 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 lneas, 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/Pestaa Editor/Requerir declaracin de variables
Este es un check que debes activar, le das aceptar.
Dmosle cerrar a la ventana VBA, nos quedamos siempre en la ventana principal de Access en los objetos
mdulos, pulsemos "Nuevo", nos abre de nuevo la ventana VBA en un modulo nuevo, pulsamos el botn de
guardar, le ponemos como nombre "Mis primeras pruebas".
En el modulo que acabas de crear te aparecen dos lneas 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 lneas.

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 instruccin MsgBox le dice al sistema que nos muestre un mensaje

Aqu seguro que ya viste una diferencia, en el primer procedimiento lo declarbamos 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
lneas de cdigo (instrucciones), una de las diferencias es que los procedimientos Function adems nos
pueden devolver un valor (mas adelante profundizaremos en el tema de devolucin 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 lneas 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 instruccin MsgBox,
inmediatamente despus la instruccin 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 ms.

Esto que acabamos de ver es lo mas bsico 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 tambin 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 combinacin 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 interrogacin es lo mismo que escribir
Debug.Print, lo nico es que puedes usarlo solo directamente en la Ventana Inmediato, no funciona dentro
del cdigo

Por ultimo escribamos:

MostrarMensaje
Y presionamos Enter
Te pudiste dar cuenta que esta es otra forma de correr un procedimiento.

Todo Correcto?, Fcil 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 algn valor que
utilizaremos despus.
Copia y pega los dos procedimientos siguientes, correlos y analiza lo que esta pasando:

Sub PruebaVariableUno ()
Dim MiTotal 'declaracin 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 'declaracin 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 ms memoria que
otras, por lo que para hacer ms eficiente tu aplicacin 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 ms 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 despus la Ayuda
de Access.

Tomemos por ejemplo el tipo Byte, que acepta solo nmeros 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 tambin 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, numrico, 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 fcil 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 cdigo y te puede evitar poner demasiadas
notas. En un procedimiento corto es fcil 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 tambin se aplican para los nombres de procedimientos.

Tampoco vallas a caer en nombres muy largos y muy descriptivos, porque cargas mucho visualmente tu
cdigo, te ser ms difcil a ti como programador estar escribiendo nombres largos y no se ve muy esttico:

Dim sngPorcentajeDeDescuentoParaAplicarleAlProducto as Single

Podra 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 devolva 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 vaca, igual a ""
Tipo Numricas, 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 Parmetros
Los parmetros 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 parmetro aqu es "strMensaje" que como puedes ver, es como una variable que se encuentra dentro del
parntesis de declaracin 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 parmetro
("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, escrbelo a mano para que puedas ver como es
que al ir llamando al otro procedimiento te va pidiendo su parmetro

Sub PruebaMensaje()
LanzarMensaje "Este es una prueba de mensaje"
LanzarMensaje "Ya estoy entendiendo lo de parmetro de texto"
LanzarMensaje "Con este texto ya es suficiente"
End Sub

Corre el procedimiento Sub PruebaMensaje()...

Si llamramos al procedimiento y no le pasamos el valor al parmetro as:

Sub PruebaMensaje()
LanzarMensaje
End Sub

Recibiramos un error que nos dice "El argumento no es opcional", lo cual quiere decir que obligatoriamente
debemos especificar un valor para el parmetro o no se puede continuar

Un procedimiento puede tener cualquier cantidad de parmetros, todos los que sean necesarios, solo deben
declararse separados por coma:

Sub UnProc (strAlgo As String, lngNumero As Long, intValor As Integer)
...
End Sub


Parmetros Opcionales
Estos son un tipo de parmetro 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 parmetro, escribamos en la
ventana Inmediato:

ImprimirTexto
Y pulsas enter, Viste?

A los parmetros declarados como opcionales se les coloca la palabra Optional al inicio de la declaracin, un
procedimiento puede tener varios parmetros, los parmetros opcionales siempre deben ser colocados de
ltimo


Recepcin De Valores En Los Parmetros
Cuando llamamos a un procedimiento que nos pide un valor en un parmetro, podemos pasarle como valor
el contenido de una variable. Veamos el ejemplo siguiente para que se vea mas claro:
Copia-pega los siguientes procedimientos y analzalos:

Sub ImprimirElMensaje(TextoMensaje As String)
'Imprimir el texto que viene en el parmetro
Debug.Print TextoMensaje
End Sub


Sub Probando_ImprimirElMensaje()
Dim strTexto As String

'Le cargamos un valor a la variable
strTexto = "Texto original"

'Llamamos al primer procedimiento, pasndole como parmetro la variable
ImprimirElMensaje strTexto

'Imprimir el valor de la variable
Debug.Print strTexto
End Sub

Corre el procedimiento "Probando_ImprimirElMensaje" y sin ningn problema nos imprimi el texto en la
ventana de inmediato:

Texto original
Texto original

Aqu viene lo bonito, ten mucho ojo con lo que vamos a realizar porque es muy importante.
Ahora vamos a realizar una modificacin al primer procedimiento, vamos a agregarle un par de lneas. Nos
quedara as (Puedes borrar el procedimiento y sustituirlo por este):

Sub ImprimirElMensaje(TextoMensaje As String)
'Imprimir el texto que viene en el parmetro
Debug.Print TextoMensaje

'Cambiando el valor del parmetro 'Cambio 1, Lnea agregada
TextoMensaje = "YO NO SOY EL TEXTO ORIGINAL!!!" 'Cambio 1, Lnea agregada
End Sub

Ahora corremos el procedimiento "Probando_ImprimirElMensaje" y nos imprime en la ventana Inmediato:

Texto original
YO NO SOY EL TEXTO ORIGINAL!!!

Te diste cuenta de lo que paso?,
Lo que paso es que al cambiar el valor del parmetro en el procedimiento "ImprimirElMensaje" (lo hace las
lneas que agregamos), cambiamos directamente el valor de la variable "strTexto" que se encuentra dentro
del otro procedimiento "Probando_ImprimirElMensaje", variable que nos fue pasada como parmetro.
A esto se le llama recibir un parmetro por Referencia, donde lo que estamos recibiendo es un acceso directo
hacia la variable original, por lo que cualquier cambio que se realice al parmetro se esta realizando en la
variable misma.

Nota:
Repasa este ejemplo tantas veces como sea necesario para que te quede claro


Continuamos...
Para declarar un parmetro por Referencia, debemos anteponerle ByRef:

Sub ImprimirElMensaje(ByRef TextoMensaje As String)
End Sub

En el ejemplo anterior se puede notar que en ningn momento declaramos el parmetro con ByRef, esto es
porque al no colocarle nada, el sistema predeterminadamente toma/asume el parmetro por Referencia

El otro tipo de parmetro que podemos definir es ByVal, que quiere decir "Por Valor":

Sub ImprimirElMensaje(ByVal TextoMensaje As String)
End Sub

Esto indica al sistema que solo recibimos el valor que viene en el parmetro, no la referencia. Si hacemos un
cambio en el parmetro no afectar al origen desde donde nos envan el valor.

Probemos...
Hagamos de nuevo una modificacin en el primer procedimiento, declaremos el parmetro como ByVal, nos
quedara as:

Sub ImprimirElMensaje(ByVal TextoMensaje As String) 'Cambio 2, declaracin del parmetro como ByVal
'Imprimir el texto que viene en el parmetro
Debug.Print TextoMensaje

'Cambiando el valor del parmetro 'Cambio 1, Lnea agregada
TextoMensaje = "YO NO SOY EL TEXTO ORIGINAL!!!" 'Cambio 1, Lnea agregada
End Sub

Ahora corremos el procedimiento "Probando_ImprimirElMensaje" y nos imprime en la ventana Inmediato:

Texto original
Texto original

Viste?, el valor de la variable "strTexto" permaneci intacto, no se tuvo acceso a ella.


Procedimientos Que Devuelven Muchos Valores Aprovechado Los Parmetros Por Referencia
Los parmetros por Referencia tambin los podemos usar para obtener muchos valores desde un
procedimiento. Copia y pega los siguientes procedimientos:

Sub DevolverNombres(ByRef Padre As String, ByRef Madre As String, ByRef CantHermanos As Byte)
'Procedimiento que cargara valores a las variables que recibiremos como parmetros
Padre = "Pepe"
Madre = "Mara"
CantHermanos = 5
End Sub


Sub ImprimirNombres()
Dim strNombrePadre As String
Dim strNombreMadre As String
Dim bytNumeroHermanos As Byte

'llamar a la funcin que nos llenara los nombres en las variables
'que pasemos como parmetros
DevolverNombres strNombrePadre, strNombreMadre, bytNumeroHermanos

'Imprimir los valores de las variables
Debug.Print "Padre: " & strNombrePadre
Debug.Print "Madre: " & strNombreMadre
Debug.Print "Numero de hermanos: " & bytNumeroHermanos
End Sub

Ahora corre el procedimiento "ImprimirNombres" y mira el resultado en la ventana Inmediato.
Todo claro verdad?

Tambin podemos recibir como parmetros a matrices y objetos, estos los explicaremos mas adelante.


Llamando A Los Procedimientos Function (Funciones)
Tenemos algunas opciones para llamar a funciones, todo depende de que es lo que necesitamos y como esta
planteada la funcin. Copia y pega la siguiente funcin:

Function NotaAprobada(ByVal bytNota As Byte) As Boolean
'Si la nota es mayor a 69 entonces la funcin devolver Verdadero, de lo contrario Falso
If bytNota > 69 Then
NotaAprobada = True
End If
End Function

Nota: Como tip en esta funcin puedes ver que si la nota no cumple la condicin en ningn momento se le
asigna el valor Falso, esto es porque la funcin ya nace con el valor predeterminado Falso, y volvrselo a
asignar seria redundante.

Para llamar a esta funcin a continuacin unas opciones:

Recogiendo el valor de la funcin en una variable:

Dim blnAprobada As Boolean
blnAprobada = NotaAprobada(85)
If blnAprobada Then
MsgBox "La nota fue aprobada"
Else
MsgBox "Nota perdida"
End If

En esta opcin podemos notar que para que funcione, los parmetros de la funcin deben quedar encerrados
entre los parntesis, si existen muchos parmetros quedara as:

NombreVariable = NombreFuncion(UnParametro, OtroParametro, TercerParametro)

Esta opcin nos sirve si el valor devuelto por la funcin va ha servirnos despus (por eso guardamos el valor
en una variable). Si solo usaremos una vez el valor devuelto por la funcin, podemos procesar de una vez el
resultado:

If NotaAprobada(85) Then
MsgBox "La nota fue aprobada!"
Else
MsgBox "Nota perdida"
End If

En ocasiones tenemos que escribir procedimientos muy largos y no necesitamos que nos devuelva un valor,
solo necesitamos que se realicen muchas acciones, como no hay valor para devolver podemos declarar el
procedimiento como Sub.
Algo muy comn en programacin es que estos procedimientos largos sean declarados como Function y que
devuelvan un valor Boolean, el valor de verdadero se lo asignamos en la ultima lnea (ultima instruccin) y
as sabremos que todo se ejecuto correctamente:

Function UnProcedimientoLargo(lngNumero As Long) as Boolean
'aqu muchas lneas, seguramente tambin abran muchas validaciones...
If NoSeCumpleUnaValidacion then
Exit Function 'Esta instruccin sirve para parar el procedimiento, ya no corren las dems lneas
'Saliendo desde aqu la funcin devolver Falso, que es el valor con que se inicializo
End If
'...aqu mas lneas y validaciones
'la ultima lnea:
UnProcedimientoLargo = True
End Function

Como el procedimiento lleva muchas lneas, en el transcurso de la mismas se van realizando validaciones, si
no se cumple alguna validacin mejor se decide terminar el proceso antes de que termine, lo cual dejara la
funcin con el valor falso. La funcin solo tomara el valor verdadero si se llego al final, lo cual quiere decir
que todo termino correcto. Sabiendo esto podemos llama a la funcin de esta manera:

If UnProcedimientoLargo("valor parmetro") then
'Aqu entramos porque la funcin devolvi Verdadero, nos quedamos tranquilos y realizamos lo que sea
necesario...
Else
'Aqu entramos porque alguna validacin fallo o puede ser que haya ocurrido un error. Realizamos lo que
sea necesario...
End If

Esto como comentaba es muy comn y seguro lo has encontrado o lo encontraras

Si tienes una funcin como la anterior pero no te interesa saber el valor que esta devolviendo, puedes usar
Call para llamar al procedimiento, esta instruccin funciona tanto para Sub y Function:

Call UnProcedimientoLargo("Valor del parmetro")
Call MostrarMensaje


Funciones tiles y Predeterminadas
Existen muchas funciones que ya nos da el sistema, funciones que regularmente necesitamos todos. Como
ya sabes como obtener datos de las funciones, ya puedes usar todas las que quieras, solo te falta conocer o
investigar cuales tienes disponibles. Como ejemplo te doy algunas:

Ucase: Convierte una cadena a Maysculas
Left: Te devuelve un nmero de caracteres de una cadena, desde la izquierda
Split: Te convierte una cadena en una matriz
InStr: Te encuentra un texto dentro de otro texto
etc....


Parte III

Tipos De Mdulos
Existen 3 tipos de mdulos:
-Asociados
-Estndar
-De Clase

Mdulo Asociado
Es aquel que esta ligado a un formulario, pertenece al formulario, se encuentra asociado. Cuando intentamos
escribir cdigo por primera vez a un formulario se crea automticamente

Mdulo Estndar
Mdulo independiente, lo creamos nosotros mismos cuando vamos a los objetos de Access/Mdulos/Nuevo.
El modulo que hemos estado usando para los ejemplos es un modulo estndar

Mdulo De Clase
Mdulo independiente que nos sirve para crear nuestros propios objetos. Veremos mas detalles cuando
veamos objetos


Alcance De Las Variables
Las variable pueden tener alcances diferentes, esto quiere decir que podemos tener acceso a ellas solo desde
el procedimiento que las contiene, desde todos los procedimientos de un mismo modulo o desde todos los
mdulos.

Si tu variable solo va a ser usada desde un procedimiento, entonces se declara dentro del procedimiento
(como lo hemos estado haciendo):

Dim strVariable As String

Si deseas que otros procedimientos del mismo modulo tengan acceso a la variable, entonces tendrs que
declararla en la parte de arriba del modulo:

Option Compare Database
Option Explicit

Dim strVariable As String

Procedimientos...

Las primeras dos lneas las puse solo para que se identifique la parte de arriba del modulo


Para que se pueda tener acceso a una variable desde cualquier lugar, debes declarar la variable en un
"Mdulo estndar" y tienes que anteponer al nombre de la variable la palabra Public:

Option Compare Database
Option Explicit

Public strVariable As String
Private strOtraVariable As String

Procedimientos...

Puedes ver que tambin se ha declarado una variable como "Private", al ser declarada de esta manera la
variable solo estar disponible para los procedimientos del mismo modulo


Alcance De Los Procedimientos
Al igual que las variables, los procedimientos pueden ser declarados como Private y como Public:

Si quieres que tu procedimiento solo pueda correrse desde el mismo modulo lo podemos declarar as:

Private Sub UnProceimiento()
Private Function UnProcedimiento() As Tipo

Si deseas que tu procedimiento pueda llamarse desde cualquier lugar de tu aplicacin debes declararlo en un
"Mdulo Estandar" as:

Public Sub UnProcedimiento()
Public Function UnProcedimiento() as Tipo

El sistema tambin toma como pblicos los procedimientos a los que no se les ha indicado su alcance (como
lo hemos venido haciendo):

Sub UnProcedimiento()
Function UnProcedimiento() as Tipo

Nota:
En los "Mdulos Asociados", aunque declares variables o procedimientos como Public (Pblicos), siempre
tendrn alcance solo para el modulo que los contiene


Procedimientos De Evento
Los procedimientos de evento van ligados a objetos como formularios o controles, se ejecutaran
automticamente cuando ocurre el momento que estn esperando, el momento para el que fueron creados.
Tomemos por ejemplo un Botn en un formulario, a este botn le podemos agregar el evento "Al hacer clic"
esto quiere decir que cada vez que el usuario le haga clic en el botn, se correr este procedimiento. Que
acciones realizara?, pues las que tu quieras, las que tu le especifiques.

Los procedimientos de evento se escriben en ingles. Para el evento "Al hacer clic" de un botn llamado
"btnAbrirFormulario" seria:

Private Sub btnAbrirFormulario_Click()
'Aqu todas las instrucciones que quieras que se realice...
MsgBox "Acabas de hacerme clic"...
End Sub

Estos procedimientos estn disponibles solo para el modulo (como ya vimos anteriormente) y los puedes
llamar desde cualquier otro evento del mismo modulo si es necesario, lo llamara como lo haces
normalmente con los procedimientos:

Call btnAbrirFormulario_Click()

Algunos procedimientos de evento solicitan parmetros o tienen parmetros donde vienen datos que
podemos usar. Lo mas fcil y recomendable para crear estos eventos es de la forma que haremos esta
prueba:
Crea un nuevo formulario en la vista de diseo, dale guardar y ponle cualquier nombre. Crea un nuevo
control de Botn, si te sale el asistente dale cancelar, no necesitaremos al asistente porque nosotros mismos
crearemos eventos. Si el cuadro de propiedades no esta abierto dale doble clic al botn para que aparezca, si
la propiedades ya estn abiertas solo dale un clic al botn para seleccionarlo, en el cuadro de propiedades ve
a la pestaa "Eventos", busca por el evento "Al hacer clic / On clic", pon el puntero del Mouse justo en el
evento, ahora te aparece un pequeo botn a la derecha, este pequeo botn tiene 3 puntos como titulo (...),
dale un clic y te llevara a la ventana VBA, con la novedad de que te agrego automticamente el
procedimiento de evento:

Sub NombreBoton_Click().

End Sub

Ahora puedes agregarle las lneas que desees, le agregaremos estas (agrgaselas manualmente):

Sub NombreBoton_Click().
MsgBox "Procedimiento Al Hacer Clic. " & "Me llamo: " & NombreBoton.Name
MsgBox "Fecha y hora actual: " & Now()
End Sub

Revisa bien el "NombreBoton".
Dale guardar, cierra la ventana VBA, cierra el formulario. Ahora abre tu formulario normalmente con un
doble clic y prueba el botn.

Como pudiste ver en el cuadro de propiedades, existen muchos eventos para el botn. Los tipos de eventos
pueden variar dependiendo del tipo de control, pero hay eventos comunes en los diferentes controles.

Cuando finalices todo este articulo te queda una buena tarea, revisar que otros procedimientos de evento
puedes aplicarle a tus controles, y en que momento se ejecutan.


Estructuras Type
Las estructuras Type son un tipo de variable creada por el programador (tu), son como un grupo de variables
que se manejan juntas:

Public Type typMiFamilia
strNombrePersona As String
strNombrePadre As String
strNombreMadre As String
lngNumeroHermanos As Long
End Type

Estas solo se pueden declarar a nivel de modulo (en la parte superior de modulo) y tambin pueden ser
Private o Public (Si no se le coloca se asumen Public)

Un ejemplo de uso, copia y pega la estructura type typMiFamilia, luego escribe este procedimiento
manualmente:

Sub Prueba_EstructuraType()
Dim UnaFamilia As typMiFamilia 'declaracin de la variable

'llenar los datos de la estructura
UnaFamilia.strNombrePersona = "Mario Hernandez"
UnaFamilia.strNombreMadre = "Mara"
UnaFamilia.strNombrePadre = "Pepe"
UnaFamilia.lngNumeroHermanos = 3

'imprimir los datos de la estructura
Debug.Print UnaFamilia.strNombrePersona
Debug.Print UnaFamilia.strNombreMadre
Debug.Print UnaFamilia.strNombrePadre
Debug.Print UnaFamilia.lngNumeroHermanos
End Sub

Tambin podemos pedir a estas estructuras Type en parmetros de procedimientos, con lo que nos
ahorraramos espacio en la declaracin. En vez de poner muchas variables solo colocamos una variable de
tipo estructura Type


A este punto, para que te sea mas fcil el manejo de esta estructura y muchas cosas que veremos adelante,
tienes que aprender a usar el With


With (Con)
Nos sirve para "agarrar" un objeto y poder trabajar con sus elementos. Como ejemplo vamos a escribir el
mismo ejemplo de arriba de las Estructuras Type, escrbelo a mano:

Sub Prueba_EstructuraType_ConWith()
Dim UnaFamilia As typMiFamilia 'declaracin de la variable

'llenar los datos de la estructura
With UnaFamilia
.strNombrePersona = "Mario Hernandez"
.strNombreMadre = "Mara"
.strNombrePadre = "Pepe"
.lngNumeroHermanos = 3
'imprimir los datos de la estructura
Debug.Print .strNombrePersona
Debug.Print .strNombreMadre
Debug.Print .strNombrePadre
Debug.Print .lngNumeroHermanos
End With
End Sub

Usando la instruccin With podemos ahorrarnos bastante escritura y el cdigo se ve mas limpio.


Matrices
Las matrices son un tipo de variable que te aceptan varios datos, puedes pensar en ellas como filas y
columnas en una hoja de Excel. En las matrices tambin se aplican las mismas reglas de nombres y alcances
de las dems variables, la diferencia es en como se declaran, que despus del nombre se les colocan
parntesis, dentro de los cuales se escribe el tamao que tendr la matriz:

Dim, Private o Public NombreMatriz(NumeroDeFilas, NumeroDeColumnas) As TipoDeDatos

Si tu matriz solo contendra una columna puedes declararla as:

Dim mtzProductos(3) As String 'Aqu solo estamos indicando el nmero de filas, el sistema asume que es de
solo 1 columna

La clave para manejar las matrices es saber que la primera fila o columna es la numero cero. En la
declaracin anterior en realidad hay 4 filas. Veamos un ejemplo:

Sub PruebaMatriz()
Dim mtzProductos(3) As String 'declaracin de la matriz (4 filas)
'cargar datos a la matriz
mtzProductos(0) = "Producto1"
mtzProductos(1) = "Producto2"
mtzProductos(2) = "Producto3"
mtzProductos(3) = "Producto4"
'Imprimir los datos de la matriz
Debug.Print mtzProductos(0)
Debug.Print mtzProductos(1)
Debug.Print mtzProductos(2)
Debug.Print mtzProductos(3)
End Sub

Se podra dar el caso que no conozcamos desde el inicio el tamao que contendr la matriz porque ser
resultado de algo que todava hay que calcular. En este caso podemos declarar una matriz de longitud
variable y en el camino la dimensionamos con la instruccin ReDim. Ejemplo:

Sub PruebaMatrizDos()
Dim mtzProductos() As String 'declaracin de la matriz con longitud variable (no se especifico un tamao)

'Dimensionar el tamao de la matriz
ReDim mtzProductos(3)
'cargar datos a la matriz
mtzProductos(0) = "Producto1"
mtzProductos(1) = "Producto2"
mtzProductos(2) = "Producto3"
mtzProductos(3) = "Producto4"
Debug.Print mtzProductos(0)
Debug.Print mtzProductos(1)
Debug.Print mtzProductos(2)
Debug.Print mtzProductos(3)
End Sub

En algunas ocasiones nos pueden venir matrices llenas desde alguna funcin, en estos casos no conocemos
que tamao tiene, para conocer el limite podemos usar la funcin Ubound
Dim intLimite As Integer
intLimite = Ubound(mtzProductos)

Esta funcin tambin es til cuando trabajamos con bucles, los cuales hacen mas fcil el llenado de datos a
la matriz, haremos un ejemplo de esto cuando aclaremos que son los bucles


<<Anterior Siguiente>>

Aprender cdigo VBA en unas horas 3
Pginas de este artculo: 1 2 3
Objetos
Por fin los objetos... auque parezca que este va ser un tema complicado en realidad es muy sencillo.

Los objetos son los culpables de que veamos el cdigo "complicado" y que muchas personas se
"decepcionen" al ver tantas lneas, pero todo esta en la perspectiva con la que miramos.
Los objetos estn diseados para facilitarnos la vida, realizarnos muchas acciones o proporcionarnos datos.

Si alguien te pasa una fecha, con ella podemos devolver varios datos (En este momento se me ocurren):
-Sacar los das transcurridos hasta el da de hoy
-Sacar los meses
-Sacar los aos
-Cuantos domingos han transcurrido
-Que da fue esa fecha
Etc., etc., seguro a ti se te ocurren muchos mas datos para devolver, todo esto lo podemos realizar con
clculos.
Entonces, nosotros podemos crear un objeto que, pasndole la Fecha deseada, nos devuelva los datos
anteriores. Todos los datos dependen de dicha fecha, si no proporcionamos la fecha al objeto no
obtendremos nada porque no hay punto de partida para realizar los clculos.

En general eso son los objetos, estructuras que nos piden uno o mas datos que le sirven como partida para
saber que es lo que nos interesa, y con eso desencadenan una serie de acciones y clculos que nosotros
podemos aprovechar. Existen miles y miles de objetos y nadie puede conocerlos todos, lo nico que
sabemos es que un objeto nos pedir ciertos datos y con esto le podemos ordenar que ejecute acciones o que
nos devuelva datos.

Que acciones y que datos nos proporciona un objeto?
Eso es especficamente diferente en cada objeto, depende de para que fue diseado.

Quieres saber que hace un objeto?
Busca ayuda sobre el, solo as sabrs que puedes sacarle. Adelante veremos como podemos investigarlos

En general eso es mucho de lo que es la programacin, usar objetos segn nuestra necesidad.
Quieres manejar los registros/datos de una tabla? Usa el objeto Recordset
Quieres manejar formularios? Usa el objeto Form
Quieres manejar controles? Usa el objeto Control
Etc., etc....
El que puedas hacer muchas cosas por cdigo depende de que tantos Objetos conozcas y que tan a fondo los
hayas usado, porque hay objetos que tienen una cantidad muy grande de cosas que se pueden realizar,
incluso hay objetos que contienen sub objetos, y estos pueden tener otros sub objetos, etc.


Utilizar Los Objetos
Vamos a utilizar el ejemplo de la fecha que dimos anteriormente, asumamos que creamos un objeto segn
las especificaciones que dimos, el objeto que creamos se llama "DatosDeFecha"

Para trabajar con el objeto, primero se debe declarar una variable como el tipo de objeto:

Dim objFecha as DatosDeFecha

Con esto el sistema ya sabe que es lo que va a contener tu variable, ahora, para empezar a utilizarla debemos
de "Alistarla", esto se hace regularmente con la instruccin SET, esto es mas o menos como sacarle una
copia al objeto, esta copia es la variable y es con la que trabajaremos:

Set objFecha = DatosDeFecha

'Ingresando los datos necesarios
objFecha.FechaDeseada = #01/01/1975#

'Imprimiendo los datos
Debug.Print objFecha.DiasTranascurridos
Debug.Print objFecha.MesesTranscurridos
Debug.Print objFecha.AosTranscurridos
Debug.Print objFecha.CantidadDomingos
Debug.Print objFecha.NombreDia

'Al terminar de usarlo siempre hay que destruirlo
objFecha = Nothing

Para facilitar la escritura podemos trabajar el objeto con With (ya lo vimos), podra haber sido as:

With objFecha
'Ingresando los datos necesarios
.FechaDeseada = #01/01/1975#

'Imprimiendo los datos
Debug.Print .DiasTranascurridos
Debug.Print .MesesTranscurridos
Debug.Print .AosTranscurridos
Debug.Print .CantidadDomingos
Debug.Print .NombreDia
End With

Los nombres pudieron haber estado en ingles (si fue un objeto elaborado en ingles), y al ver el cdigo nos
hubieran parecido lneas raras, pero ahora sabemos que solo son datos que estamos solicitando/obteniendo.

Nota: Si copias lo anterior obtendrs error porque en tu sistema no existe ningn objeto llamado
"DatosDeFecha", solo lo estamos suponiendo para ver como es que se usa.

Cuando escribes el nombre del objeto, mejor dicho, la variable declarada como el tipo de objeto y despus
escribes el punto (.), se te desplegara la lista de propiedades y mtodos que contiene el objeto

Para dar un ejemplo con un objeto real, veamos un objeto Recordset, con el cual se pueden manejar los
registros de una tabla:

Sub PruebaObjetoRecordset()
'Declaracion de la variable...
'El Recordset es un objeto que esta contenido dentro de un objeto mayor que se llama DAO
Dim rst As DAO.Recordset
'La declaracin tambin se pudo haber hecho as:
'Dim rst As Recordset
'Pero tambin existe el objeto ADO.Recordset, en algunas ocasiones necesitamos
'trabajar con ambos Recordset, Como sabe el sistema con cual es con el que deseamos trabajar?
'Por eso la declaracin como la que realizamos

'Abrir el objeto,
'Donde estn los datos que deseamos manejar?
'manejaremos la tabla clientes, solo le especificamos esto y el objeto se trae los registros...
Set rst = CurrentDb.TableDefs("Clientes")
'Aqu tambin puedes ver que hay una sucesin de objetos
'CurrenteDb = Base de datos, esta contiene al objeto:
'TablaDefs = Coleccin de todas las tablas
'le especificamos que tome la tabla "Clientes"

'Con el objeto ya disponible, realizamos acciones con sus propiedades y mtodos
rst.MoveLast 'ir al ultimo registro
rst.MoveFirst 'ir al primer registro
rst.AddNew 'iniciar un nuevo registro
rst!IdCliente = "CRZTUL" 'ingresando datos en un campo
rst.Update 'grabar el registro
rst.Close 'este objeto requiere que lo cerremos
Set rst = Nothing 'destruyendo el objeto
End Sub

Aunque parece un procedimiento largo y complicado, segn lo que hemos explicado, se puede ver que el
objeto lo manejamos en general con:

Dim rst As DAO.Recordset 'declarar la variable
Set rst = CurrentDb.TableDefs("Clientes") 'Inicializar la variable de objeto
...
Set rst = Nothing 'destruir el objeto

Todo lo dems en el medio son puras propiedades y mtodos propios del objeto

Entendiste?, Difcil?, O ya lo ves diferente?

Hay que tener claro que no todos los objetos se inicializan de la misma manera, hay que investigar como se
inicializa cada objeto, el objeto que te interesa.

En este ejemplo se crea un objeto nuevo, mas bien se crea una "Copia nueva" de un objeto DAO.Recordset,
que es la que se encuentra en la variable y es con la que trabajamos

Otra forma para un Recordset:

Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT * FROM Clientes;")
...
Set rst = Nothing

No todos los objetos tienen que crearse como nuevos, algunos podemos obtenerlos por referencia, pero para
hacer esto se necesita que el objeto se encuentre abierto:

Un formulario:

Dim frm As Form
Set frm = Forms("Nombre formulario")
'Otra forma:
'Set frm = Forms!NombreFormulario
'Otra forma:
'Set frm = [Forms]![NombreFormulario]
...
Set frm = Nothing

Cuando tomamos un objeto por referencia, al destruirlo con:

Set frm = Nothing

Realmente no estamos destruyendo el objeto abierto, solo destruimos la variable con la que estamos
teniendo acceso directo a el (referencia)

Un Control:

Dim ctr As Control
Set ctr = Forms!NombreFormulario!NombreControl
...
Set ctr = Nothing

Para usar un control Treeview (rbol) es necesario que primero se inserte el objeto ActiveX en el formulario
luego haces:

Dim objArbol As TreeView
Set objArbol = NombreDelControDeArbolInsertadoEnElFormulario.Object

Etc.,...


Bucles
Los bucles nos sirven para realizan una misma rutina un determinado numero de veces. La mas simple es
For..Next, copia-pega y corre el procedimiento siguiente:

Sub PruebaForNext()
'variable que nos servir para el bucle
Dim i As Long

'Aqu le estamos diciendo:
'A la variable "i", inciela con el valor 1, termine el bucle cuando valga 5
'la variable que le asignamos predeterminadamente aumentara en 1 unidad en cada vuelta (en este caso la
variable i)
For i = 1 To 5
'imprimir el valor de la variable
Debug.Print "Valor de la variable: " & i
Next i 'indica dar la siguiente vuelta al bucle
End Sub

Tambin tenemos otros tipos de bucles, en los cuales el objetivo no es ir cambiando de valor a la variable
como el For Next, el objetivo es cumplir con alguna condicin, y hasta que se cumpla deja de correr el
bucle, veamos este ejemplo (copia-pega y corre):

Sub PruebaBucleConCondicion()
Dim i As Long 'variable para el bucle

'Esta es la condicin:
'Mientras i sea menor a 10, siga con el bucle
While i < 10
'imprimir el valor de la variable
Debug.Print "Valor de la variable: " & i
'Este tipo de bucle no aumenta predeterminadamente ningn valor a la variable,
'solo se esta preocupando por cumplir la condicin inicial.
'Aqu nosotros le vamos a aumentar el valor a la variable, que ser
'igual al valor que ya tiene mas uno. De esta manera conseguiremos que en cada vuelta
'del bucle la variable aumentara de valor en 1 unidad
i = i + 1
'IMPORTANTE:
'Si no le aumentramos esta unidad, la variable i se quedara en cada
'vuelta con el valor inicial de cero (su valor de inicio), entonces
'nunca se cumplira la condicin inicial y el bucle correra eternamente...
'trabara el sistema, esto es lo que hay que cuidar con los bucles con condiciones
Wend
End Sub

Lo prometido es deuda, aqu les pongo un bucle para llenar datos de a una matriz:

Sub PuebaMatrizConBucle()
Dim mtzNumeracion(9) As String 'matriz de 10 filas
Dim i As Long 'variable para correr el bucle

'Cargar los datos de la matriz...
'vamos desde 0 hasta el limite de la matriz
'Porque desde cero?, porque el primer elemento de las matrices es cero
For i = 0 To UBound(mtzNumeracion)
'cargar el numero
mtzNumeracion(i) = "Elemento numero: " & i
Next i
'Imprimir los datos de la matriz
For i = 0 To UBound(mtzNumeracion)
'imprimir en la ventana Inmediato
Debug.Print mtzNumeracion(i)
Next i
End Sub

Existen varios tipos de bucles (aqu solo vimos dos), donde se pueden definir diferentes criterios para que el
bucle siga dando vueltas en la misma rutina.


Colecciones
Las colecciones son objetos que podemos comparar con matrices de una sola columna, la ventaja es que son
mas flexibles para agregar y consultar datos, podemos ingresarles elementos antes o despus de alguna fila
existente, tambin le podemos dar un cdigo de identificacin y acceder a los elementos por este cdigo, y
no solo por el numero de fila como las matrices. La primera fila inicia en uno.
Veamos un ejemplo (copia, pega y corre):

Sub PruebaColeccion()
Dim colPrueba As Collection
Dim strCodigo As String
Dim i As Long

'Inicializamos la variable para el objeto Collection
Set colPrueba = New Collection
'llenaremos 5 elementos por bucle
For i = 1 To 5
'El cdigo en cada elemento es opcional pero se lo agregaremos para este ejemplo
strCodigo = "Cdigo" & i
'Si solo agregamos elementos sin especificar la posicin, el elemento se crea al final
colPrueba.Add "Elemento por bucle numero: " & i, strCodigo
Next
'ahora vamos a agregar un nuevo elemento, se lo agregaremos al inicio
colPrueba.Add "Agregado despus del bucle", "CodigoDiferente", 1

'Imprimir los datos
'vamos desde el primer elemento hasta el ultimo contenido
For i = 1 To colPrueba.Count 'total de elementos contenidos
Debug.Print "Elemento nmero " & i & " = " & colPrueba(i)
Next i
'Imprimir un elemento llamndolo por el cdigo
Debug.Print "Elemento llamado por su cdigo (CodigoDiferente) = " & colPrueba("CodigoDiferente")

Set colPrueba = Nothing 'destruyendo el objeto
End Sub


Instrucciones De Condicin
Con estas instrucciones podemos ordenarle al sistema que evale resultados, y dependiendo de lo que se
obtenga que haga una cosa u otra. Entre estas tenemos:


IF... THEN... ELSE
Que mas o menos quiere decir:

SI (Esta condicin es verdadero) ENTONCES (Haga esto) SI NO SE CUMPLIO (Haga esto)

Lo usaramos as:

SI (Esta condicin es verdadero) ENTONCES
(Haga esto)
SI NO SE CUMPLIO
(Haga esto)
TERMINAR SI

Ya en lneas de cdigo:

IF (Esta condicin es verdadero) THEN
'aqu lo que quieres que se ejecute si la condicin es verdadera
ELSE
'aqu lo que quieres que se ejecute si la condicin es falsa
END IF


Sub PruebaIF()
If 10 > 8 Then
Debug.Print "La condicin SI se cumple"
'aqu tambin se pueden meter otros IF si fuera necesario
Else
Debug.Print "La condicin NO se cumple"
'aqu tambin se pueden meter otros IF si fuera necesario
End If
End Sub

Hay ocasiones en deseamos hacer un anlisis a un dato, y deseamos actuar de diferente manera segn sea el
valor. Para esto podemos usar:

SELECT CASE

Un ejemplo lo muestra mas claro:

Sub PruebaSelectCase()
Dim bytPrecio As Byte

bytPrecio = 15 'este valor lo puedes ir variando para hacer pruebas

'Segun el valor del precio imprimiremos una nota...

'Analizar el valor contenido en la variable "bytPrecio"
Select Case bytPrecio
Case 0 'si el precio es cero
Debug.Print "Es regalada"
Case 1 'si es igual a uno
Debug.Print "Es casi regalado"
Case 2, 3, 4 'si es igual a 2, 3 o 4
Debug.Print "Esta a buen precio"
Case Is < 10 'si es menor a 10
Debug.Print "Un precio justo"
Case Else 'cualquier otra posibilidad
Debug.Print "Precio fuera de rango, no compres"
End Select
End Sub


Enumerados
Un enumerado nos sirve para mostrar una lista que se nos desplega mientras estamos escribiendo, esta lista
tiene varias opciones donde debemos seleccionar solo un elemento, esto nos facilita la escritura del cdigo y
nos limita las opciones a escoger a solo valores validos. Hagamos esta prueba, escribamos a mano en la
ventana de inmediato:

docmd.selectobject acForm

Esta es una instruccin que le dice al sistema que seleccione un objeto de Access.

Te pudiste dar cuenta que cuando escribiste el espacio (despus de docmd.selectobject) te despleg un lista
donde aparecan los nombres de los objetos que podemos seleccionar, eso es un enumerado, una lista que
nos permite ver que opciones tenemos con nombre y escoger el elemento que nos interesa.
Un enumerado debe crearse a nivel de modulo. Creemos este enumerado:

'Las primeras dos lneas estn puestas solo para que se vea que el enumerado esta a nivel de modulo
Option Compare Database
Option Explicit

Enum enuMensaje
mBajo
mMedio
mAlto
End Enum

El primer elemento del enumerado toma el valor cero, el siguiente toma el valor del elemento anterior +1 (en
este caso seria uno), etc. Estos valores son predeterminados, pero si nosotros deseamos podemos cambiarles
el valor, lo haramos as:

Enum enuMensaje
mBajo = -1
mMedio = 10
mAlto = 20
End Enum

Con esto ya podemos crear una variable y declararla como tipo "enuMensaje" en donde necesitemos. Copia
y pega este procedimiento:

Sub PruebaEnumerado(TipoMensaje As enuMensaje)
'Metemos al Select la variable del parmetro y hacemos algo
'segn sea el valor que venga
Select Case TipoMensaje
Case mBajo
Debug.Print "sin importancia"
Case mMedio
Debug.Print "Tomar en cuenta"
Case mAlto
Debug.Print "MENSAJE CRITICO!"
End Select
End Sub

Ahora escribe a mano esto en la ventana Inmediato:

PruebaEnumerado mBajo
Pulsas enter...

Prueba con las 3 opciones...


Control De Errores
Hay varias razones por las que puede ocurrir un error en un procedimiento, olvidamos poner un valor
necesario, asignamos valores que no corresponden, manejamos mal un objeto, etc.
Cuando ocurre un error, el sistema predeterminadamente se detiene, abre la ventana VBA y nos lleva a la
lnea donde ocurri el error, dicha lnea tambin la pinta de amarrillo, de esta manera podemos realizar los
cambios que sean necesarios. Pero que pasa si el error ocurre en una aplicacin que has hecho para otras
personas?, ellos no tienen porque ver el cdigo.
Para evitar esto podemos controlar los errores con algunas rutinas, all nosotros le diremos que es lo que
queremos que el sistema haga cuando ocurra un error.
Las rutinas de errores son muy importantes porque los errores pueden ser inesperados, puede ser que en tu
computadora corra un procedimiento sin problemas, pero al llevar tu base de datos a otra computadora con
otras propiedades ocurra algn error, por el sistema operativo de otra versin, Office de otra versin,
libreras, dll, etc.

Empecemos por pasos,

GoTo (Ir Hacia) y Etiquetas De Lnea

GoTo (Ir Hacia): Le indica al sistema que salte hacia una Etiqueta de Lnea
Etiqueta De Lnea: Es un nombre cualquiera finalizado con dos puntos (:)

Veamos un ejemplo, copia, pega y prueba este procedimiento:

Sub PruebaSaltoPorEtiquetas()
GoTo SoyEtiquetaDeLinea 'Ir hacia la etiqueta especificada

MsgBox "Mostrando el Primer mensaje"

SoyEtiquetaDeLinea: 'Etiqueta, puede tener cualquier nombre
MsgBox "Mostrando el Segundo mensaje"
End Sub

Como te pudiste dar cuenta al correr el procedimiento, el primer mensaje nunca se mostr, esto es porque en
la primera lnea del procedimiento se le esta indicando con GoTo que se valla a la etiqueta
"SoyEtiquetaDeLinea" y con esto se esta saltando el primer mensaje

Claro?, veamos un segundo ejemplo, copia-pega y prueba el siguiente procedimiento, sigue la secuencia de
saltos de lnea:

Sub PruebaSaltoPorEtiquetasDos()
'Saltar hacia la etiqueta que esta al final del procedimiento
GoTo Etiqueta_Del_Final


Etiqueta_Del_Inicio:
MsgBox "Mostrando el Primer mensaje"
'Salir de procedimiento
Exit Sub


Etiqueta_Del_Final:
MsgBox "Mostrando el Segundo mensaje"
'Saltar/regresar hacia la etiqueta que se encuentra al inicio
GoTo Etiqueta_Del_Inicio
End Sub

En este procedimiento podemos observar que en la primera lnea se salta hacia una etiqueta al final, de all
se hace otro salto hacia una etiqueta que se encuentra al inicio.
Importante:
Hay que tener mucho cuidado en los saltos hacia atrs, si te das cuenta en el ejemplo, al hacer el salto hacia
atrs hay un "Exit Sub" que sirve para salir del procedimiento, si no existiera, el procedimiento correra
infinitamente porque cada vez que llega al final vuelve a saltar hacia el inicio


Objeto Err (Error)
Existe un objeto llamado Err (Error) que siempre esta presente, este objeto tienes varias propiedades que
predeterminadamente se encuentran vacas, cuando ocurre cualquier error el sistema llena estas propiedades
para que nosotros podamos consultarlas y saber que es lo que ha ocurrido. Hagamos esta prueba, en la
ventana Inmediato escribe:

? Err.Number
Pulsamos Enter, nos imprime el valor cero. Este valor quiere decir que no hay ningn error disponible, no a
ocurrido ningn error.
Todos los errores estn identificados con un valor que es un numero entero.


Activar Una Rutina De Errores
Una rutina de error se activa con la sentencia OnError. Hay varias formas de manejar las rutinas de error,
vamos a analizar una de las mas comunes (si creas un control con el asistente Access automticamente te
crea una rutina de error como esta):

Copia-pega y analiza este procedimiento,

Sub ComprendiendoUnaRutinaDeErrorComun()
'Las palabras "On Error" activan la rutina de error, la siguiente lnea dice:
'Al ocurrir un error (en cualquier lugar) saltar a la etiqueta "Tratamiento_Error"
On Error GoTo Tratamiento_Error

'Aqu el cuerpo de procedimiento...


Salir_Del_Procedimiento:
'Si no ocurre ningn error llegamos a esta etiqueta limpiamente y salimos del procedimiento (con Exit
Sub), esto
'porque no necesitamos llegar a la parte donde se trata el error

'Al ocurrir un error, el sistema pasara a las lneas del tratamiento del error, desde all se regresara
'a este punto (con la instruccin Resume)
'Podemos aprovechar este espacio para realizar algunas cosas como desvincular variables o cerrar objetos,
'porque esas son cosas que necesitamos hacer antes de cerrar un procedimiento, haya error o no

'Aqu la lneas para resolver cualquier cosa antes de salir, porque siempre se pasara por este punto...
Exit Sub

Tratamiento_Error:
'Aqu se llega solo si ha ocurrido un error...
'Desplegar un mensaje con la descripcin del error
MsgBox Err.Description
'La palabra Resume hace dos cosas:
'Elimina el error y hacer un salto hacia la etiqueta especificada
Resume Salir_Del_Procedimiento
End Sub

Otro metodo comun de manejar errores es con:

On Error Resume Next

Que es como decirle al sistema "Cuando ocurra un error, siga la ejecucin del procedimiento en la lnea
siguiente de donde se origino el error". Muy til cuando trabajamos con objetos.

Con la primer rutina al ocurrir un error el sistema va hacia la rutina del error luego se sale del
procedimiento, pero a veces necesitamos que aunque ocurra un error el sistema siga ejecutando las dems
lneas del procedimiento, es cuando podemos usar "On Error Resume Next"

Haremos un ejemplo, vamos a probar dos procedimientos que tienen un cuerpo idntico pero con diferente
manejo de errores, copia-pega y corre:

Sub PruebaOnErrorGoTo()
On Error GoTo Tratamiento_Error

Dim rst As DAO.Recordset 'variable para manejar los datos/registros de una tabla

'Asignamos la tabla de donde agarraremos los datos/registros
'Aqu se originara un error porque la tabla de nombre "Inexistente" no existe
Set rst = CurrentDb.TableDefs("Inexistente")

MsgBox "Este mensaje esta puesto despus del error"

Salir_Del_Procedimiento:
Set rst = Nothing 'desvincular variable
Exit Sub

Tratamiento_Error:
MsgBox "Error ocurrido: " & Err.Description
Resume Salir_Del_Procedimiento
End Sub

Sub PruebaOnErrorResumeNext()
On Error Resume Next

Dim rst As DAO.Recordset 'variable para manejar los datos/registros de una tabla

'Asignamos la tabla de donde agarraremos los datos/registros
'Aqu se originara un error porque la tabla de nombre "Inexistente" no existe
Set rst = CurrentDb.TableDefs("Inexistente")

MsgBox "Este mensaje esta puesto despus del error"

Set rst = Nothing 'desvincular variable
End Sub

Corriendo el primer procedimiento nos lanza un mensaje, el mensaje que indica el error que acaba de
ocurrir, este mensaje esta puesto en las lneas donde se trata el error.

Corriendo el segundo procedimiento, se genera el mismo error pero el sistema no se detiene y sigue con las
lneas de cdigo y nos muestra el mensaje que esta puesto en la lnea debajo de donde se origino el error.


Algunos Tips

Continuar Lneas Largas En La Siguiente Lnea
Algunas lneas son tan largas que se salen del rea de pantalla, para tenerlo todo a la vista puedes cortar una
lnea escribiendo un espacio seguido de un guin bajo ( _):

Sub PruebaContinuandoLineas()
'Una lnea larga:
'Aqu se encuentra una lnea que puede llegar a salirse de la pantalla porque al autor se le ocurrio que deba
hacer muchos comentarios para dejar bien claro lo que tenia que decir

'La misma lnea larga:
'Aqu se encuentra una lnea que puede llegar a salirse de la _
pantalla porque al autor se le ocurri que deba hacer muchos _
comentarios para dejar bien claro lo que tenia que decir

MsgBox _
"Este es un mensaje donde se muestra como cortar lneas"
End Sub

De esta manera lo puedes hacer con cualquier lnea, en cualquier parte de la lnea, media vez no cortes
ninguna palabra por el medio porque as no funcionaria


Juntar Varias Lneas En Una Lnea
Se puede juntar dos o mas lneas aunque no tengan ninguna relacin, solo debes colocar dos puntos ( : ) al
final de la lnea:

Sub PruebaJuntandoLineas()
'Normal
Debug.Print "Mensaje Uno"
Debug.Print "Mensaje Dos"
MsgBox "Mensaje Tres"

Debug.Print "-------------------"

'Juntando lneas
Debug.Print "Mensaje Uno": Debug.Print "Mensaje Dos": MsgBox "Mensaje Tres"
End Sub


Objeto DoCmd
Esta es una objeto exclusivo de Access que te permite realizar muchas acciones. Haz esta prueba, escribe:

Docmd.

Al escribir el punto te aparece una lista larga con cosas que puedes realizar, all tienes un bonito tema para
explorar. Si usas por ejemplo:

DoCmd.RunCommand "Parmetro"

Esta opcin te permite realizar cualquier accin de los mens, como que dieras un clic en algn elemento.
En el parmetro opcin te aparecer un enumerado con todas las acciones de los mens


ME (Palabra para referirse al formulario del Mdulo Asociado Actual)
Me es una palabra que solo puedes usar en los Mdulos Asociados (Mdulos que estn ligados a los
formularios), e indica que vas a usar explcitamente el objeto formulario al que pertenece el modulo
asociado en el que estas actualmente.
Para usar un objeto de formulario (como vimos antes) haras:

Dim frm as Form
Set frm = Forms!UnFormulario
frm.UnControl.Visible = True

Al escribir frm. se te desplega el listado de propiedades, mtodos y sub objetos para el objeto frm (Un objeto
de tipo formulario)

Si estas en un modulo asociado y deseas trabajar con el objeto formulario al que pertenece haras:

Me.UnControl.Visible = True

Que seria como decir:

Con este formulario.UnControl.Visible = True

Estas haciendo referencia a un objeto formulario, el formulario actual.


Usar La Ayuda De Manera Fcil y Directa
Si estas observando un cdigo y tienes alguna duda sobre algo que ves, solo haz clic en la palabra, pulsas la
tecla F1 y se mostrara automticamente la ayuda para ese tema, para la palabra que seleccionaste con un
clic. Haz la prueba, haz clic por ejemplo sobre la palabra MsbBox (despus pulsas F1)
Viste?, as podrs especializarte en el cualquier tema de los que hemos tocado aqu o en el que desees,
ahora que ya llegaste a esta parte, Eres libre para explorar!, bienvenid@ al mundo de la programacin...


Finalizando
El unico "Pero" de escribir artculos como este es que casi siempre se le ha ido por alto algn tema y hay que
estar actualizando... si alguien se da cuenta de algo por favor me comunica, as ayudamos a todos

En este articulo iba a explicar como se crea un objeto con un modulo de clase, pero al final me pareci que
esto ya seria un tema muy especifico, as que lo voy a escribir pero en un articulo diferente

Saludos, Byron


<<Anterior

You might also like