Você está na página 1de 37

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


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

Você também pode gostar