Jueves, 27-Abr-17, 0:05 AM
Le saludo Visitante | RSS
Menú del sitio
Búsqueda

byronlcl, Access y algunas cosillas...

Aprender código VBA en unas horas 2

Páginas de este artículo:  1  2  3

Recepción De Valores En Los Parámetros
Cuando llamamos a un procedimiento que nos pide un valor en un parámetro, 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 analízalos:
 
Sub ImprimirElMensaje(TextoMensaje As String)
   'Imprimir el texto que viene en el parámetro
   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, pasándole como parámetro la variable
   ImprimirElMensaje strTexto
 
   'Imprimir el valor de la variable
   Debug.Print strTexto
End Sub
 
Corre el procedimiento "Probando_ImprimirElMensaje" y sin ningún 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 modificación al primer procedimiento, vamos a agregarle un par de líneas. Nos quedaría así (Puedes borrar el procedimiento y sustituirlo por este):
 
Sub ImprimirElMensaje(TextoMensaje As String)
   'Imprimir el texto que viene en el parámetro
   Debug.Print TextoMensaje
 
   'Cambiando el valor del parámetro 'Cambio 1, Línea agregada
   TextoMensaje = "YO NO SOY EL TEXTO ORIGINAL!!!" 'Cambio 1, Línea 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 parámetro en el procedimiento "ImprimirElMensaje" (lo hace las líneas 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 parámetro.
A esto se le llama recibir un parámetro por Referencia, donde lo que estamos recibiendo es un acceso directo hacia la variable original, por lo que cualquier cambio que se realice al parámetro 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 parámetro por Referencia, debemos anteponerle ByRef:
 
Sub ImprimirElMensaje(ByRef TextoMensaje As String)
End Sub
 
En el ejemplo anterior se puede notar que en ningún momento declaramos el parámetro con ByRef, esto es porque al no colocarle nada, el sistema predeterminadamente toma/asume el parámetro por Referencia
 
El otro tipo de parámetro 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 parámetro, no la referencia. Si hacemos un cambio en el parámetro no afectará al origen desde donde nos envían el valor.
 
Probemos...
Hagamos de nuevo una modificación en el primer procedimiento, declaremos el parámetro como ByVal, nos quedaría así:
 
Sub ImprimirElMensaje(ByVal TextoMensaje As String) 'Cambio 2, declaración del parámetro como ByVal
   'Imprimir el texto que viene en el parámetro
   Debug.Print TextoMensaje
 
   'Cambiando el valor del parámetro 'Cambio 1, Línea agregada
   TextoMensaje = "YO NO SOY EL TEXTO ORIGINAL!!!" 'Cambio 1, Línea 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 Parámetros Por Referencia
Los parámetros por Referencia también 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 parámetros
   Padre = "Pepe"
   Madre = "María"
   CantHermanos = 5
End Sub
 
 
Sub ImprimirNombres()
Dim strNombrePadre As String
Dim strNombreMadre As String
Dim bytNumeroHermanos As Byte
 
   'llamar a la función que nos llenara los nombres en las variables
   'que pasemos como parámetros
   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?
 
También podemos recibir como parámetros 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 función. Copia y pega la siguiente función:
 
Function NotaAprobada(ByVal bytNota As Byte) As Boolean
'Si la nota es mayor a 69 entonces la función devolverá Verdadero, de lo contrario Falso
   If bytNota > 69 Then
      NotaAprobada = True
   End If
End Function
 
Nota: Como tip en esta función puedes ver que si la nota no cumple la condición en ningún momento se le asigna el valor Falso, esto es porque la función ya nace con el valor predeterminado Falso, y volvérselo a asignar seria redundante.
 
Para llamar a esta función a continuación unas opciones:
 
Recogiendo el valor de la función 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 opción podemos notar que para que funcione, los parámetros de la función deben quedar encerrados entre los paréntesis, si existen muchos parámetros quedaría así:
 
NombreVariable = NombreFuncion(UnParametro, OtroParametro, TercerParametro)
 
Esta opción nos sirve si el valor devuelto por la función va ha servirnos después (por eso guardamos el valor en una variable). Si solo usaremos una vez el valor devuelto por la función, 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 común en programación 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 línea (ultima instrucción) y así sabremos que todo se ejecuto correctamente:
 
Function UnProcedimientoLargo(lngNumero As Long) as Boolean
   'aquí muchas líneas, seguramente también abran muchas validaciones...
   If NoSeCumpleUnaValidacion then
   Exit Function 'Esta instrucción sirve para parar el procedimiento, ya no corren las demás líneas
   'Saliendo desde aquí la función devolverá Falso, que es el valor con que se inicializo
   End If
   '...aquí mas líneas y validaciones
   'la ultima línea:
   UnProcedimientoLargo = True
End Function
 
Como el procedimiento lleva muchas líneas, en el transcurso de la mismas se van realizando validaciones, si no se cumple alguna validación mejor se decide terminar el proceso antes de que termine, lo cual dejaría la función con el valor falso. La función solo tomara el valor verdadero si se llego al final, lo cual quiere decir que todo termino correcto. Sabiendo esto podemos llama a la función de esta manera:
 
If UnProcedimientoLargo("valor parámetro") then
   'Aquí entramos porque la función devolvió Verdadero, nos quedamos tranquilos y realizamos lo que sea necesario...
Else
   'Aquí entramos porque alguna validación fallo o puede ser que haya ocurrido un error. Realizamos lo que sea necesario...
End If
 
Esto como comentaba es muy común y seguro lo has encontrado o lo encontraras
 
Si tienes una función como la anterior pero no te interesa saber el valor que esta devolviendo, puedes usar Call para llamar al procedimiento, esta instrucción funciona tanto para Sub y Function:
 
Call UnProcedimientoLargo("Valor del parámetro")
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 Mayúsculas
Left: Te devuelve un número 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 Módulos
Existen 3 tipos de módulos:
-Asociados
-Estándar
-De Clase
 
Módulo Asociado
Es aquel que esta ligado a un formulario, pertenece al formulario, se encuentra asociado. Cuando intentamos escribir código por primera vez a un formulario se crea automáticamente
 
Módulo Estándar
Módulo independiente, lo creamos nosotros mismos cuando vamos a los objetos de Access/Módulos/Nuevo. El modulo que hemos estado usando para los ejemplos es un modulo estándar
 
Módulo De Clase
Módulo 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 módulos.
 
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 tendrás que declararla en la parte de arriba del modulo:
 
Option Compare Database
Option Explicit
 
Dim strVariable As String
 
Procedimientos...
 
Las primeras dos líneas 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 "Módulo estándar" 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 también 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 aplicación debes declararlo en un "Módulo Estandar" así:
 
Public Sub UnProcedimiento()
Public Function UnProcedimiento() as Tipo
 
El sistema también toma como públicos 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 "Módulos Asociados", aunque declares variables o procedimientos como Public (Públicos), siempre tendrán 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 automáticamente cuando ocurre el momento que están esperando, el momento para el que fueron creados.
Tomemos por ejemplo un Botón en un formulario, a este botón le podemos agregar el evento "Al hacer clic" esto quiere decir que cada vez que el usuario le haga clic en el botón, 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 botón 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 están disponibles solo para el modulo (como ya vimos anteriormente) y los puedes llamar desde cualquier otro evento del mismo modulo si es necesario, lo llamaría como lo haces normalmente con los procedimientos:
 
Call btnAbrirFormulario_Click()
 
Algunos procedimientos de evento solicitan parámetros o tienen parámetros donde vienen datos que podemos usar. Lo mas fácil y recomendable para crear estos eventos es de la forma que haremos esta prueba:
Crea un nuevo formulario en la vista de diseño, dale guardar y ponle cualquier nombre. Crea un nuevo control de Botón, 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 botón para que aparezca, si la propiedades ya están abiertas solo dale un clic al botón para seleccionarlo, en el cuadro de propiedades ve a la pestaña "Eventos", busca por el evento "Al hacer clic / On clic", pon el puntero del Mouse justo en el evento, ahora te aparece un pequeño botón a la derecha, este pequeño botón tiene 3 puntos como titulo (...), dale un clic y te llevara a la ventana VBA, con la novedad de que te agrego automáticamente el procedimiento de evento:
 
Sub NombreBoton_Click().
 
End Sub
 
Ahora puedes agregarle las líneas que desees, le agregaremos estas (agrégaselas 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 botón.
 
Como pudiste ver en el cuadro de propiedades, existen muchos eventos para el botón. 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 también 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 'declaración de la variable
 
   'llenar los datos de la estructura
   UnaFamilia.strNombrePersona = "Mario Hernandez"
   UnaFamilia.strNombreMadre = "María"
   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
 
También podemos pedir a estas estructuras Type en parámetros de procedimientos, con lo que nos ahorraríamos espacio en la declaración. En vez de poner muchas variables solo colocamos una variable de tipo estructura Type
 
 
A este punto, para que te sea mas fácil 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, escríbelo a mano:
 
Sub Prueba_EstructuraType_ConWith()
Dim UnaFamilia As typMiFamilia 'declaración de la variable
 
   'llenar los datos de la estructura
   With UnaFamilia
      .strNombrePersona = "Mario Hernandez"
      .strNombreMadre = "María"
      .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 instrucción With podemos ahorrarnos bastante escritura y el código 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 también se aplican las mismas reglas de nombres y alcances de las demás variables, la diferencia es en como se declaran, que después del nombre se les colocan paréntesis, dentro de los cuales se escribe el tamaño 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 número 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 declaración anterior en realidad hay 4 filas. Veamos un ejemplo:
 
Sub PruebaMatriz()
Dim mtzProductos(3) As String 'declaración 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 podría dar el caso que no conozcamos desde el inicio el tamaño que contendrá la matriz porque será resultado de algo que todavía hay que calcular. En este caso podemos declarar una matriz de longitud variable y en el camino la dimensionamos con la instrucción ReDim. Ejemplo:
 
Sub PruebaMatrizDos()
Dim mtzProductos() As String 'declaración de la matriz con longitud variable (no se especifico un tamaño)
 
   'Dimensionar el tamaño 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 función, en estos casos no conocemos que tamaño tiene, para conocer el limite podemos usar la función Ubound
Dim intLimite As Integer
   intLimite = Ubound(mtzProductos)
 
Esta función también es útil cuando trabajamos con bucles, los cuales hacen mas fácil el llenado de datos a la matriz, haremos un ejemplo de esto cuando aclaremos que son los bucles