Libro ANAYA Visual Basic 6 0
Libro ANAYA Visual Basic 6 0
Libro ANAYA Visual Basic 6 0
Curso
Captulo 1
Si sientes inters por una seccin de programacin es porque no te conformas con utilizar tu PC como si se tratase de una videoconsola, una mquina de escribir o un reproductor MP3. Lo que os caracteriza a todos los que ahora os adentris en el fascinante mundo de la programacin es que queris sacarle todo el jugo posible a vuestra mquina y, por supuesto, a vuestra cabeza. Con esta nueva seccin os ayudaremos a dar vuestros primeros pasos de una manera sencilla, prctica y amena.
Sin entrar en demasiados detalles diremos que un procesador es capaz de realizar una serie de operaciones bsicas como sumar o restar dos nmeros enteros, leer o escribir un dato en la memoria, comparar si una cantidad es igual, mayor o menor que otra, etc. Teniendo en cuenta que el ordenador trabaja en binario (slo distingue entre 1 y 0), podemos imaginarnos lo complicado que es transmitir las rdenes complejas. Aparece entonces la necesidad
Visual Basic 6.0 3
de utilizar un tipo de herramientas que, a partir del lenguaje humano, genere rdenes que pueda comprender la mquina. Las herramientas de ese tipo son los denominados compiladores. El problema es que un compilador no interpreta directamente el lenguaje coloquial, sino una mezcla de comandos en ingls, nombres, operaciones matemticas y smbolos lgicos. Existe multitud de lenguajes de programacin de alto nivel. En un principio, el cdigo de un programa se escriba en unas tarjetas perforadas del tamao de un folio que se introducan a modo de disquetes en una computadora enorme. Despus aparecieron los primeros en los que se escriba el cdigo en un determinado lenguaje de programacin dentro de un fichero de texto. Despus se ejecutaba el compilador que generaba el archivo ejecutable. Con la llegada a la informtica personal del entorno de ventanas con sus mltiples controles, surgi la necesidad de trabajar con un software que facilitase la insercin de dichos controles. De esta manera apareci la denominada programacin visual, donde destacan Delphi, Visual Basic o Visual C++. Dentro de los entornos de programacin visual, el ms apropiado para aprender es Visual Basic, por su sencillez integracin en todas las versiones de Windows, si bien Delphi es una estupenda alternativa para los que hayan trabajado con Pascal. Para realizar las explicaciones y los ejemplos utilizaremos Microsoft Visual Basic 6.0, aunque posiblemente con versiones anteriores no encontris demasiadas diferencias.
Configurar el formulario
Lo primero que debemos hacer es ejecutar Microsoft Visual Basic. Despus seleccionamos EXE estndar en la pestaa Nuevo de la ventana Nuevo Proyecto y pulsamos el botn Abrir. Aparece entonces un documento en blanco, que es el proyecto que posteriormente generar el programa. Dentro de
4 Curso
l aparece un formulario al que, desde la ventana Propiedades, vamos a cambiar algunos registros. Siempre que vayamos a modificar el registro de propiedad de algn control o formulario, debemos asegurarnos de que tenemos seleccionado el objeto correcto. En este caso no hay ninguna duda, pues tan slo tenemos un formulario. De todos modos, en el ttulo de la ventana Propiedades aparece el nombre del objeto activo. Con el formulario seleccionado modificamos los registros de las propiedades Nombre y Caption (las modificaciones se realizan en la columna de la derecha) con los valores fmrMoneda y Cambio de Moneda respectivamente (de ahora en adelante incluiremos un prefijo Reddick delante del nombre de cada objeto). El nombre que demos a un objeto ser aquel con el que nos referiremos a l a lo largo del programa, mientras que el valor de la propiedad Caption se muestra sobre el objeto.
Etiquetas
Con el formulario configurado procedemos a incluir los objetos en l. En la parte superior del formulario incluiremos dos etiquetas (Label). Para ello, seleccionamos la herramienta correspondiente en el Cuadro de Herramientas y con ella dibujamos un pequeo rectngulo en la parte superior izquierda del formulario (no debe preocuparnos demasiado el tamao o la situacin que tenga un objeto dentro del formulario ya que ambos aspectos
Visual Basic 6.0 5
son fcilmente modificables). Despus insertamos, del mismo modo, una etiqueta similar a la derecha de la primera. Tambin debemos cambiar algunas propiedades de las etiquetas. Concretamente pondremos lblPts en el registro Nombre de la primera y lblEuros en el de la segunda; Pesetas en el registro Caption de la primera y Euros en el de la segunda y, en el registro Font de ambas indicaremos una fuente Times New Roman negrita de 12 puntos en la ventana Fuente (que se despliega al pulsar sobre el botn que aparece en la celda del registro de la propiedad).
Cuadros de texto
Debajo de las etiquetas y del mismo modo que se insertaron stas, se dibujan, con la herramienta TexBox, los dos cuadros de texto. Despus se les cambia el registro de la propiedad Nombre con los valores txtPts para el primero y txtEuros para el segundo. Para ambos cuadros indicaremos el valor 1Right Justify en la propiedad Alignment (para alinear los nmeros a la derecha), y el tipo Times New Roman normal de 12 puntos para el registro Font. Tambin en los dos cuadro de texto dejaremos vaco el registro de la propiedad Text (equivalente a Caption), para lo que tan slo hay que borrar el texto que tiene por defecto. Por ltimo, cambiaremos el valor de la propiedad Enabled a False del cuadro de texto txtEuros para impedir la insercin de datos, pues de momento tan slo debe mostrar un resultado.
Botones de comando
Ahora slo nos queda insertar un par de botones de comando en la parte inferior del formulario. El primero har que se produzca la conversin y el segundo que podamos salir del programa (realmente este segundo botn no es demasiado importante porque la pantalla en la que se ejecutar el programa incluir en la barra de ttulo el clsico botn de cerrar). Dibujamos pues, ambos botones (con la herramienta CommandButton) en la parte inferior del formulario. Al primero lo llamaremos cmdConvertir y cmdSalir al se6 Curso
gundo (propiedad Nombre). Los valores correspondientes a la propiedad Caption sern Convertir y Salir respectivamente. Por ltimo, para asociar la tecla Intro del teclado al primer botn, slo hay que poner el registro de su propiedad Default como True. Del mismo modo, para asociar la tecla Esc al segundo, activaremos (pasando a True su registro) la propiedad Cancel del mismo. Tambin se les puede cambiar la propiedad Font para resaltar el texto.
Insertar cdigo
Hasta ahora slo hemos hecho el diseo del formulario o, lo que es lo mismo, de la pantalla del programa. Una vez terminado este proceso es el momento de incluir unas lneas de cdigo, es decir, un poco de programacin. Para programar el botn de cambio (cmdConvertir) haremos doble clic sobre l. Se despliega entonces la pantalla
Visual Basic 6.0 7
de cdigo del proyecto. En el mismo punto de insercin donde se encuentra el cursor escribimos las lneas: txtEuros = txtPts / 166.386 txtEuros = Format(txtEuros,#,##0.00) Despus se cierra la ventana y se hace doble clic sobre el botn cmdSalir. Igual que con el primer botn, escribimos la lnea: End
Guardar y ejecutar
Con el proyecto terminado lo ms indicado es guardar el trabajo realizado. El proceso es el mismo que el utilizado para guardar cualquier otro documento: pulsando sobre Guardar proyecto como en el men Archivo se abre la ventana Guardar archivo como, utilizada por multitud de programas. Primero se guarda el formulario y posteriormente el proyecto. Para evitar complicaciones diremos que no. Despus, para ejecutar el programa pulsamos el botn Iniciar de la barra de herramientas estndar o la tecla F5 del teclado.
Curso
Captulo 2
El captulo anterior empezamos el curso de programacin con la creacin de un sencillo programa que converta cantidades de pesetas a euros. El objetivo de este segundo captulo es completar la funcionalidad de la aplicacin, mejorar su interfaz y explicar las dudas que puedan ir apareciendo.
En el captulo anterior, diseamos una aplicacin por medio de controles a los que bamos aplicando diferentes propiedades. Una vez diseado el formulario, habamos incluido unas lneas de cdigo, que no explicamos, para
Visual Basic 6.0 9
programar el botn que ejecutaba el cambio. Lo primero que haremos hoy ser explicar brevemente el porqu de aquellas instrucciones. Como recordaris, al hacer doble clic sobre el botn al que llamamos cmdConvertir, se desplegaba la Ventana de Cdigo que ya inclua algunas lneas escritas: Private Sub cmdConvertir_Click() End Sub Estas lneas vienen a marcar el principio y el fin de un procedimiento que se activa al producirse un evento. Siempre que se abre la ventana de cdigo con un doble clic sobre un control, Visual Basic prepara el procedimiento (para ese control) del evento por defecto de ese tipo de controles. Para el caso de los botones de comando, el evento por defecto es Click, es decir pulsar sobre l con el botn izquierdo del ratn. As pues, el nombre del procedimiento (cmdConvertir_Click) viene a expresar un evento (Click) sobre un control (cmdConvertir). Las palabras resaltadas en azul son palabras reservadas de Visual Basic. En este caso indican el inicio de un procedimiento privado (Private Sub) y el fin del mismo (End Sub). Todo lo que introduzcamos entre ambas lneas sern las instrucciones que se ejecutarn al producirse el evento que invoca al procedimiento. Lo siguiente que hicimos fue insertar el cdigo del procedimiento. Para ello habamos escrito las siguientes instrucciones: txtEuros = txtPts / 166.386 txtEuros = Format(txtEuros,#,##0.00) La primera expresin es lo que se denomina una asignacin, es decir se asigna al trmino a la izquierda del = (cuadro de texto txtEuros) el valor de la derecha (el contenido de txtPts dividido entre 166,386). La segunda expresin es similar, salvo que el valor asignado a txtEuros es el valor que devuelve la funcin Format, propia de Visual Basic. Esta funcin necesita dos parmetros: un texto (en nuestro caso el contenido en txtEuros) y un tipo de formato entre comillas (con la coma entre las almohadillas indicamos el separador de miles, y con el punto seguido de 2 ceros indicamos 2 posiciones decimales) que debe ser en formato americano, justo al revs que el europeo (puntos en lugar de comas y comas en lugar de puntos). Los par10 Curso
metros de las funciones y procedimientos siempre van separados por comas. Podramos haber resumido ambas lneas en la siguiente: txtEuros = Format(txtPts / 166.386, #,##0.00) donde indicaramos que habra que asignar directamente a txtEuros el valor de txtPts dividido por 166,386 pero con el formato mencionado. El cdigo introducido en el botn cmdSalir es, sencillamente, el de finalizacin del programa. Novedades de esta versin En esta ocasin vamos a aadir la posibilidad de cambiar cantidades de pesetas a euros indistintamente. Para ello, el formulario debe incluir la opcin de seleccionar el tipo de cambio a realizar. Con los controles bsicos, la manera ms sencilla de hacer este tipo de selecciones es utilizando los controles CheckBox (casilla de verificacin) u OptionButton (botn de opcin). En nuestro caso, partiremos de dos opciones para el tipo de cambio (pesetas a euros o euros a peVisual Basic 6.0 11
setas) donde necesariamente debe haber una, y slo una, seleccionada. Para este tipo de casos lo mejor es utilizar los botones de opcin. Una pequea pega de este tipo de botones es precisamente que son excluyentes unos de otros, es decir, si est marcada una de las opciones el resto no pueden estarlo. Por otro lado, existe la posibilidad de que necesitemos rellenar un mismo formulario con varias cuestiones de este tipo, pero debido a la naturaleza de estos controles, tan slo podramos tener un botn seleccionado. Parece necesario entonces aislar cada uno de los grupos de botones de opcin dentro de su propio contexto. Para ello debemos insertar, previamente, un marco que englobe a todos los botones de opcin referentes a un mismo contexto. Para insertar dichos marcos, Visual Basic dispone del control Frame. Dichos marcos contendrn todos los controles que deban ser aislados. Otro detalle a tener en cuenta es la necesidad de incluir en esta versin los ramificadores condicionales en el cdigo del botn cmdCambio. Los ramificadores que incluiremos sern las estructuras If ... Else ... EndIf. El esquema de estas estructuras es el siguiente: If (condicin) Then (instrucciones si se produce condicin) Else (instrucciones si no se produce condicin) End If De esta manera podremos realizar determinadas operaciones segn se cumpla o no la condicin (que en nuestro caso depender del botn de opcin seleccionado por el usuario). Por otro lado, en esta segunda versin del programa, tendremos que modificar algunas propiedades en tiempo de ejecucin (habilitar o deshabilitar los cuadros de texto dependiendo del tipo de cambio seleccionado) as como invocar al mtodo SetFocus de los cuadros de texto (para situar el puntero en el cuadro de texto correspondiente). Para que todo quede ms claro, en esta versin incluiremos comentarios de todos los aspectos que vayamos programando (Visual Basic interpreta por comentario todo el texto comprendido entre una comilla simple y un salto de lnea, y lo resalta en co12 Curso
lor verde). El esquema de modificacin del registro de la propiedad de un control en tiempo de ejecucin es como sigue: nombre_control.propiedad = nuevo valor
Modificar formulario
Empezaremos por realizar unas pequeas modificaciones en el formulario para adaptarlo a nuestras necesidades. Lo primero que haremos ser eliminar los botones Minimizar y Maximizar o Restaurar de la parte derecha de la barra de herramientas. Para ello debemos cambiar el registro de la
Visual Basic 6.0 13
propiedad BorderStile del formulario al valor 1-Fixed Single. Posteriormente atribuiremos un icono al formulario que se mostrar en la parte superior izquierda del mismo (en la barra de ttulo). Para ello, tan slo debemos acceder al registro de la propiedad Icon del formulario y en l, a partir del explorador desplegado, seleccionar el icono correspondiente (en la pgina web de la revista podris encontrar una coleccin de iconos relacionados con el tema). Por ser el nico formulario de la aplicacin, el icono que atribuyamos al formulario ser el icono por defecto de la misma de modo que al generar el archivo ejecutable ste llevar relacionado ese mismo icono.
Mover controles
Lo siguiente ser realizar las modificaciones grficas pertinentes. Dado que vamos a aadir nuevos elementos a nuestro formulario, parece aconsejable aumentar el tamao del mismo, de manera que los controles no queden muy condensados. Para ello, recordemos, se selecciona el formulario y se estira desde los tiradores hasta alcanzar el tamao deseado o bien se escribe directamente el tamao en los registros de las propiedades Height (altura) y Widht (anchura). En nuestro caso resulta bastante apropiado un tamao aproximado de 7.515 x 4.020 twips. Siguiendo este mtodo podramos aplicar la siguiente tabla para aplicar un tamao y posicin (propiedades Left y Top para la distancia del vrtice superior izquierdo del control respecto a los bordes izquierdo y superior del formulario respectivamente) a todos los controles del formulario: CONTROL lblPts
14
2520, 240 480, 840 2520, 840 5400, 1680 5400, 2640
1095 x 375 1575 x 375 1575 x 375 1335 x 615 1335 x 615
Aadir imagen
Para dar un aspecto ms atractivo a la aplicacin podemos insertar una imagen relacionada con el tema de los euros en la parte superior derecha del formulario. Para ello necesitamos disponer de dicha imagen en nuestro ordenador en formato BMP, JPG, GIF, etc. Una vez dispongamos de la imagen deseada, el modo de insertarla en el formulario es por medio del control Image (tambin podra utilizarse el control PictureBox, aunque este segundo control es ms apropiado para los casos en los que la imagen cambia en tiempo de ejecucin). Seleccionamos, por tanto, el control Image en el Cuadro de Herramientas y dibujamos un rectngulo en la parte superior derecha del formulario sin preocuparnos por el tamao, ya que este control, que har las veces de contenedor, adaptar automticamente sus medidas al tamao de la imagen que contenga. Por ltimo modificamos el registro de la propiedad Nombre del nuevo control con el valor imgEuro y, en la propiedad Picture, abrimos, por medio del explorador de archivos desplegado, la imagen que vayamos a insertar. Si observamos que la imagen no tiene el tamao apropiado, podemos modificar sus proporciones utilizando los tiradores sin ms que cambiar previamente el registro de su propiedad Stretch a True. Para desplazar la imagen por el formulario, como para desplazar cualquier otro control, pulsamos sobre ella con el botn izquierdo del ratn y, sin soltar, arrastramos hasta el lugar deseado.
Insertar macro
15
La parte inferior izquierda del formulario estar dedicada a la seleccin del tipo de cambio a realizar, para lo cual necesitaremos dos botones de opcin. Para crear un contexto aislado para los botones de opcin dibujaremos un marco, con el control Frame seleccionado, en la parte inferior izquierda del formulario con una posicin 480,1.680 y un tamao de 3.255 x 1.455 twips. Despus modificamos el registro de su propiedad Nombre con el valor fmrCambio, el de la propiedad Caption con Tipo de cambio y el de la propiedad Font con un tipo de letra Times New Roman negrita de 12 puntos.
Botones de opcin
Ahora ya podemos insertar los botones de opcin en nuestro formulario. Seleccionamos, pues, el control OptionButton en el cuadro de herramientas y dibujamos, dentro del nuevo marco, dos botones de opcin en las posiciones 240,480 y 240,960 respectivamente (estas posiciones estn referidas al vrtice superior izquierdo del marco que las contiene, no del formulario), ambos con un tamao de 2.055 x 255 twips. Al primero de ello lo llamaremos optPtsEuros y optEurosPts al segundo (propiedad Nombre). En el registro de la propiedad Caption indicaremos los textos Pesetas a Euros para el primero y Euros a Pesetas para el segundo. A ambos les aplicaremos un tipo de letra MS Sans Serif normal de 10 puntos y, en el registro de la propiedad Value del primero (optPtsEuros) indicaremos el valor True para hacer de esta opcin la opcin por defecto.
Reprogramar botones
16 Curso
Con el aspecto del formulario preparado pasamos a revisar el cdigo del programa. Para desplegar la Ventana de Cdigo pulsamos sobre el comando Cdigo en el men Ver de la barra de herramientas estndar. Lo primero que haremos una vez desplegado el formulario es reprogramar el botn cmdConvertir con el siguiente cdigo:
17
Generar ejecutables
Si el cdigo est correctamente escrito, la nueva versin est lista para ser ejecutada (F5). Hay que tener en cuenta que, a pesar de las mejoras, el pro18 Curso
grama an tiene algunos fallos que pasaremos a depurar en el prximo captulo (concretamente el hecho de que a la hora de convertir, si el cuadro de texto activo est vaco o posee caracteres no numricos, se produzca un error). Aun as generaremos, a partir de esta versin, el primer archivo ejecutable (con extensin .exe). Para ello pulsamos sobre el men Archivo en la barra de herramientas y, a continuacin, sobre Generar Proyecto.exe. Despus seleccionamos el nombre (sin extensin) y la ubicacin del ejecutable y confirmamos. El programa se ejecuta con un doble clic.
19
20
Curso
Captulo 3
En el primer captulo del curso de programacin vimos el modo de crear un conversor de pesetas a euros. En el segundo, mejoramos la interfaz grfica del programa y aadimos la posibilidad de convertir indistintamente de pesetas a euros y de euros a pesetas. En esta ocasin los objetivos sern redisear el formulario de manera que resulte lo ms prctico posible y depurar la aplicacin para evitar que se produzcan errores.
En la programacin de las versiones anteriores del conversor de euros hemos tratado con diferentes tipos de datos. Llegados a este punto es conveniente profundizar un poco en este aspecto. Para empezar, podemos decir que aunque Visual Basic no es (todava) un lenguaje de programacin orientada a objetos (POO), s que es, por necesidad, un lenguaje de programacin basado en objetos. Para nosotros, un objeto es, por ejemplo, un formulario, un cuadro de texto o un botn de comando. Cada uno de estos objetos posee sus propios mtodos, propiedades y eventos dependiendo de su naturaleza. Por si esto no queda suficientemente claro, vamos a hacer una semejanza con el mundo real. Supongamos que tenemos un objeto de tipo coche. Las propiedades de nuestro objeto seran, por ejemplo: cilindrada, ABS, color, etc. Ejemplos de eventos podran ser: entrar en coche, salir de coche, tocar coche, etc. Como mtodos asociados podramos indicar: subir ventanillas, frenar, tocar claxon, etc. El uso principal de los eventos es programar acciones referidas al suceso de dicho eventos sobre el objeto. De este modo, y siguiendo con el ejemplo, podra programarse la ejecucin del mtodo subir ventanillas al producirse el evento salir en un objeto coche de nombre MiCoche: Private sub MiCoche_Salir() MiCoche.SubirVentanillas
Visual Basic 6.0 21
End Sub Del mismo modo, para atribuirle un color determinado al objeto MiCoche del tipo coche en un punto determinado del programa podramos incluir: MiCoche.Color = Verde Tipos de datos Centrndonos en las propiedades de los objetos podemos observar que todas ellas son algo as como contenedores de informacin. La cuestin es si todos los datos (ya sean variables, constantes o registros de propiedades) son del mismo tipo. Volviendo al ejemplo, nos damos cuenta de que la inclusin o no de ABS en un objeto de tipo coche se resuelve con un s o un no, mientras que la cilindrada ser un nmero entero positivo de hasta 4 dgitos y el color una cadena de letras. Nos encontramos, pues, con que los datos son de tipos diferentes. En la siguiente tabla se muestran los principales tipos de datos utilizados para trabajar en Visual Basic:
Tipo de datos Byte Integer Long Single Clase Nmeros enteros Nmeros enteros Nmeros enteros Nmeros reales Rango de valores 0255 -3276832767 -2147483648 2147483647 -3,4383,438 (aprox.); precisin mxima 1-45 -1,83081,8308 (aprox); precisin mxima 1-324 15 dgitos para la parte entera y 4 para la decimal True (verdadero) o False (falso) Desde 1/1/100 hasta 31/12/9999 Hasta 2000 millones de caracteres Dependiendo del Tamao en memoria 1 byte 2 bytes 4 bytes 4 bytes
Double
Nmeros reales
8 bytes
Currency
Cantidades monetarias Valores lgicos Fechas Cadenas de caracteres (texto) Cualquier tipo de
8 bytes
los anteriores
tipo
carcter
Profundizando en los cuadros de textos Una de las propiedades ms importantes de las que hemos visto hasta ahora es la propiedad Text de los cuadros de texto. Esta propiedad, cuyo registro es de tipo String, es la propiedad por defecto para esta clase de controles (del mismo modo que, por ejemplo, Value es la propiedad por defecto para los botones de opcin), por lo que podemos referirnos a ella utilizando tan slo el nombre del objeto. As se explica que la instruccin: txtPts = Format (txtEuros * 166.386, #,##0) modifique el texto del cuadro de texto txtPts del mismo modo que lo hara: txtPts.Text = Format(txtEuros.Text * 166,386, #,##0) Por otro lado, y como novedad en esta versin, veremos dos nuevos eventos correspondientes a los cuadros de texto (entre otros controles). El primero es el evento gotfocus, producido al situar el enfoque sobre el control correspondiente. En nuestro programa utilizaremos este evento para seleccionar el texto que aparece por defecto al seleccionar un tipo de cambio. Para realizar dicha seleccin utilizaremos tambin la propiedad de lectura y escritura SelLength. El otro evento, keypress, se produce al pulsar una tecla con el cuadro de texto activo, y a nosotros nos servir para filtrar las teclas que pulsa el usuario. Como es lgico, el procedimiento que utilicemos para programar la ocurrencia de este evento necesitar como parmetro algn tipo de informacin sobre la tecla pulsada (un entero con su cdigo ASCII). Acerca de los string Si alguno de los tipos de datos predeterminados (tanto en Visual Basic como en cualquier otro lenguaje de programacin) merece una mencin especial, sin duda se trata de cadenas de caracteres. Para empezar, Visual Basic slo reconoce como cadenas de caracteres aquel texto comprendido entre comillas dobles (). As se explica, por ejemplo, que cuando el mes pasado queramos borrar los registros de la propiedad Text de los cuadros de texto, hicisemos las asignaciones:
Visual Basic 6.0 23
txtEuros.Text = txtPtx.Text = En referencia a los string, terminaremos indicando las funciones (propias de Visual Basic) que utilizaremos en esta versin: Nombre Len Parmetros necesarios Una cadena de caracteres Valor devuelto Un entero (Long) que indica el nmero de caracteres de la cadena Una cadena de caracteres con el formato especificado Un entero (Long) que indica la posicin de la primera aparicin de la segunda cadena en la primera. Si no se encontraron apariciones devuelve 0
Format InStr
Caracteres Como ya hemos mencionado, un string es una cadena de caracteres. Existen varios tipos de caracteres y varias maneras de representarse (existe un carcter relacionado con la tecla supr que borra el carcter a la derecha del cursor, otro relacionado con la barra espaciadora que deja un espacio en blanco, etc.), aunque el concepto ms importante es que el ordenador utiliza un nico cdigo para representar cada carcter. Teniendo en cuenta que Visual Basic (como cualquier otro lenguaje de programacin) utiliza un Byte (8 bits) para codificar (cdigo ASCII extendido) cada carcter, nos encontramos con que trabajamos con 256 (28) caracteres distintos. Desde luego no es necesario conocer el cdigo ASCII de cada carcter, aunque s es conveniente tener presentes algunos conceptos: Las letras minsculas se codifican de manera distinta a las maysculas (b) ( B) Las vocales acentuadas tienen su propio cdigo ASCII (a) ( )
24
Curso
Los cdigos de los dgitos (0-9) son consecutivos. Lo mismo ocurre con las maysculas (A-Z) y las minsculas (a-z), aunque las vocales acentuadas, el carcter y el carcter no se incluyen en esos rangos.
De todos modos, y para facilitar las cosas, Visual Basic dispone de una serie de constantes con las que trabajaremos sin problemas. En esta versin utilizaremos: vbKey0 (contiene el cdigo ASCII del carcter 0) vbKey9 (contiene el cdigo ASCII del carcter 9) vbKeyClear (contiene el cdigo ASCII asociado a la tecla supr) vbKeyBack (contiene el cdigo ASCII asociado a la tecla de borrado) En esta versin tambin utilizaremos las siguientes funciones para pasar de un cdigo ASCII a carcter y viceversa: Nombre Chr Asc Parmetros necesarios Un entero entre 0 y 255 Un string Valor devuelto Un string de un carcter cuyo cdigo ASCII coincide con el entero Un entero que indica el cdigo ASCII del primer carcter de la caneda
Modificar controles
Para poder modificar el tamao del formulario, previamente hemos de modificar los controles. Para empezar, indicaremos, en el registro de la propiedad Font de las etiquetas (lblPts y lblEuros) y del marco (fmrCambio), un tipo de letra MS Sans Serif en negrita de 8 puntos. Despus se modifica la misma propiedad de los dos cuadros de texto (txtPts y txtEuros) y de los botones de opcin (optPtsEuros y optEurosPts) indicando un tipo de letra MS Sans Serif normal de 8 puntos. Por ltimo modi26 Curso
Mover controles
En este punto nos encontramos con un tamao de formulario desproporcionado con respecto al de los controles. Para solucionarlo indicaremos los siguientes valores para el tamao y ubicacin de los controles:
Despus se cambia el tamao del formulario con los valores 3975 (twips) en el registro de su propiedad Width y 1770 en el de la propiedad Height.
Introducir cdigo
Para terminar, abrimos la ventana de cdigo (Ver/Cdigo), borramos el texto de la versin anterior y tecleamos el siguiente cdigo: Private Sub Form_Load() txtPts = 0 poner pesetas a 0 End Sub Private Sub optEurosPts_Click() txtEuros.Enabled = True habilitar
Visual Basic 6.0 27
txtEuros txtPts.Enabled = False deshabilitar txtPts txtEuros = 0 poner euros a 0 txtEuros.SetFocus situar cursor en txtEuros End Sub Private Sub optPtsEuros_Click() txtPts.Enabled = True habilitar txtPts txtEuros.Enabled = False deshabilitar txtEuros txtPts = 0 poner pesetas a 0 txtEuros = 0,00 poner euros a 0 txtPts.SetFocus situar cursor en txtPts End Sub Private Sub txtEuros_Change() If txtEuros.Enabled = True Then si txtEuros habilitado If Len(txtEuros) = 0 Then si txtEuros se vaca txtEuros = 0 poner euros a 0 txtEuros.SelLength = 1 seleccionar el 0 End If txtPts = Format(txtEuros * 166.386, #,##0) End If End Sub Private Sub txtPts_Change() If txtPts.Enabled = True Then si txtPts habilitado If Len(txtPts) = 0 Then si txtPts se vaca txtPts = 0 poner pesetas a 0 txtPts.SelLength = 1 seleccionar el 0 End If txtEuros = Format(txtPts / 166.386, #,##0.00) End If End Sub Private Sub txtPts_gotfocus() txtPts.SelLength = 1 seleccionar el 0 al mover el cursor End Sub
28 Curso
Private Sub txteuros_gotfocus() txtEuros.SelLength = 1 seleccionar el 0 al mover el cursor End Sub Private Sub txtpts_keypress(tecla As Integer) If ((tecla vbKeyBack) And _ (tecla vbKeyClear) And _ (tecla <> vbKeyClear) And _ ((tecla < vbKey0) Or (tecla > vbKey9))) Then con espacio seguido de guin bajo al final de la lnea contina en siguiente lnea si la tecla no es borrar y tampoco es suprimir y tampoco es un carcter numrico entonces tecla = Empty tecla vaca Beep emitir sonido End If End Sub Private Sub txteuros_keypress(tecla As Integer) habilitar la tecla . para introducir decimales If (tecla = Asc(.)) Then tecla = Asc(,) End If validar caracteres If ((tecla >= vbKey0) And (tecla <= vbKey9)) Then si la tecla es un nmero If InStr(txtEuros.Text, ,) Or (txtEuros.SelLenght <> 0 Then si hay decimales If (InStr(txtEuros.Text, ,) = (Len(txtEuros.Text) - 2)) Then si hay dos decimales tecla = Empty Beep End If End If ElseIf (Chr(tecla) = ,) Then si la tecla no es nmero pero es , If (InStr(txtEuros.Text, ,) <> 0) Or (txtEuros.SelLength <> 0) Then
Visual Basic 6.0 29
si ya hay dos decimales tecla = Empty Beep End If ElseIf (tecla <> vbKeyClear) And (tecla <> vbKeyBack) Then si la tecla no es nmero ni , ni borrar ni suprimir tecla = Empty Beep End If End Sub
Compilacin
Si el cdigo est correctamente escrito, podemos ejecutar el programa (F5) para comprobar que todo funciona correctamente o bien generar un archivo ejecutable (Archivo/Generar ...... .exe).
30
Curso
Captulo 4
En este captulo del curso de programacin, trataremos de aclarar todo lo referente a las condiciones, conoceremos el trabajo con bucles y variables y realizaremos un sencillo programa donde practicaremos todos estos aspectos.
Operadores lgicos y de comparacin Para trabajar con estructuras condicionales (que ya utilizamos en captulos anteriores) se utilizan las expresiones lgicas como condicin. Dichas expresiones pueden ser sencillas (If optPtsEuros = True then) o expresiones mucho ms complejas (como las utilizadas en el cdigo del captulo anterior). El nico requisito es que la expresin lgica responda con un True (verdadero) o False (falso). Para realizar comparaciones sencillas utilizaremos los operadores de comparacin de la siguiente manera: expresin1 operadordecomparacin expresin2 Los operadores de comparacin bsicos son: Para componer las expresiones complejas a partir de expresiones ms simples se utilizan los operadores lgicos de manera similar a los operadores de comparacin: expresin1 sin2 operadorlgico espre-
31
Tambin existe un operador lgico unario (Not) que devuelve el valor contrario de la expresin lgica a la que precede y se denota: Not expresin1 Con el uso de parntesis se pueden asociar expresiones y operadores para formar expresiones ms complejas. Tambin es muy recomendable utilizar parntesis para aislar unas expresiones de otras (aunque no resulte estrictamente necesario) ya que dan mucha claridad al cdigo del programa. Visto esto, analizaremos, como ejemplo, la condicin de filtrado de tecla del cuadro de texto txtPts que utilizamos el captulo anterior: ((tecla <> vbKeyBack) And (tecla <> vbKeClear) And ((tecla < vbKey0) Or (tecla > vbKey9))) Esta expresin est compuesta a su vez por 3 expresiones ms sencillas unidas por el operador lgico And, lo cual quiere decir que basta con que una de las expresiones devuelva el valor False para que el valor de la expresin final sea False. Estas tres expresiones son:
32
De estas tres expresiones, las dos primeras son bsicas, ya que estn formadas por la comparacin directa de dos valores (una variable y una constante) por medio de un operador de comparacin. El valor que devuelve cada una de ellas es obvio: si tecla es distinta de la tecla de borrar en el primer caso, o tecla es distinta de la tecla suprimir en el segundo, el valor de la expresin es True; en caso contrario el valor es False. La tercera expresin vuelve a ser una composicin de expresiones ms sencillas, aunque en este caso unidas por el operador Or, por lo que bastara con que una de las expresiones que forman esta expresin fuese verdadera para hacer verdadera a toda la expresin. Instrucciones If anidadas Otro aspecto que pudo no quedar demasiado claro en el ltimo captulo del curso es la anidacin de los ramificadores. Haciendo memoria, en el segundo captulo del curso indicbamos que la estructura bsica de este tipo de instrucciones era: If (condicin) Then (instrucciones si se produce condicin) Else (instrucciones si no se produce condicin) End If De este modo, para que se ejecuten las instrucciones del If anidado, debe producirse la condicin 2 sin que se produzca la condicin 1. Para estos casos puede utilizarse la palabra reservada ElseIf de la siguiente manera: If (condicin 1) Then (instrucciones si se produce condicin 1) ElseIf (condicin 2) Then (instrucciones se produce condicin 2) End If
Visual Basic 6.0 33
End If Al trabajar con las estructuras If anidadas, hay que tener presente que hasta que no se cierra una estructura If con la instruccin End If no se vuelve al If que contena al primero (de ah la importancia de hacer un buen sangrado a las lneas de cdigo). Variables Visual Basic, por medio de las propiedades de sus controles, permite tener almacenada muchsima informacin. A pesar de ello, en la mayora de los programas esa informacin no resultar suficiente. Ser entonces cuando tengamos que utilizar estructuras de almacenamiento auxiliares, es decir, variables. Los aspectos ms importantes de las variables son los siguientes: Nombre: cada variable debe tener un nombre nico dentro de su mbito. Tipo: cada variable debe estar orientada a contener un tipo de datos especfico. Podran declararse todas como Variant pero estaramos malgastando innecesariamente los recursos de la mquina. mbito: la vida til de la variable equivale a la vida til del programa, funcin o procedimiento donde es declarada. Al finalizar dicho cdigo, el espacio de memoria utilizado por esa variable es liberado.
Visual Basic permite utilizar variables que no han sido declaradas anteriormente (declaracin implcita), lo cual puede resultar tanto una ventaja como un inconveniente, ya que a pesar de ahorrarnos algunas lneas de cdigo, en el supuesto de que al teclear nos equivocsemos y escribisemos mal el nombre de una variable se creara una nueva variable con ese nombre. Para evitar estos problemas, que aumentan proporcionalmente al tamao del programa, se utiliza la declaracin explcita con la que, si Visual Basic encuentra una variable que no ha sido declarada previamente muestra un mensaje de error. El modo ms sencillo de forzar la declaracin explcita es incluir la instruccin Option Explicit al comienzo del cdigo del formulario o mdulo.
34 Curso
La sintaxis de la declaracin de variables es la siguiente: Dim NombredeVariable [As TipodeDato] Es decir, se utiliza la palabra reservada Dim para indicar que se va a declarar una variable de mbito local (por el momento, y salvo que sea estrictamente necesario, prescindiremos del uso de variables globales), despus se indica el nombre de la variable (que debe comenzar por una letra, no puede contener smbolos de puntuacin, no puede superar los 255 caracteres y, por supuesto, no puede tener por nombre ninguna de las palabras reservadas por Visual Basic) y, opcionalmente (cuando utilicemos este tipo de sintaxis, todo lo que vaya entre corchetes [ ] ser opcional) el tipo de dato que, por defecto (si no se pone nada), ser de tipo Variant. Como es lgico, la variable debe ser declarada antes de su primera utilizacin. Adems, al leer un programa, resulta muy cmodo tener declaradas todas las variables al comienzo del programa o subprograma. Bucles Los bucles son estructuras de programacin que permiten repetir la misma tarea un nmero condicionado de veces. Por ejemplo, y adelantndonos al paso a paso de este captulo, imaginemos que dado un nmero natural (mayor o igual que 1) llamado n, queremos calcular la suma de todos los naturales hasta ese n. En este caso tendramos que llevar una variable contador, llammosla i, que, partiendo de 1 y sin pasar de n, se ira incrementando en una unidad y se ira sumando a otra variable llamada resultado. As pues, las instrucciones que iran dentro de este bucle seran: i=i+1 resultado=resultado+i y la condicin de salida del bucle dependera de la estructura seleccionada. Las estructuras ms utilizadas son: Do While condicin instrucciones Loop
Visual Basic 6.0 35
Este bucle evala la condicin. Si no se cumple, contina con las instrucciones que siguen a Loop. Si se cumple ejecuta las instrucciones del bucle y vuelve a evaluar. Es un bucle de los denominados de 0 ms repeticiones. Do instrucciones Loop While condicin En este caso, lo que cambia es que se ejecuta al menos una vez, ya que la condicin se evala despus de ejecutar las instrucciones. Es una estructura de bucle de 1 ms repeticiones. Do Until condicin instrucciones Loop Esta estructura, tambin de 0 ms repeticiones, cambia con respecto a la primera en que se sale del bucle si se cumple la condicin. Do instrucciones Loop Until condicin Esta estructura es la variante de 1 ms repeticiones de la estructura anterior. Ninguna de todas estas estructuras es imprescindible, ya que, por ejemplo, se puede cambiar la palabra While por Until (o viceversa) y aadir el operador lgico Not al inicio de la condicin y el comportamiento del bucle sera el mismo. Otro tipo de estructura de bucles, muy til cuando se conoce el nmero de repeticiones, es el tipo For. Estos bucles, adems, incrementan o disminuyen el contador en cada repeticin. Su sintaxis es la siguiente:
36 Curso
For contador = inicio To fin [Step incremento] instrucciones Next donde contador es una variable e inicio, fin e incremento son valores numricos (constantes o variables). El bucle inicializa contador al valor de inicio, comprueba si inicio es menor o igual que fin antes de cada iteracin (menor o igual en caso de que se indique un incremento negativo). En caso afirmativo se ejecutan las instrucciones (si es mayor se sale del bucle) e incrementa, en cada iteracin, la variable contador con el valor especificado en incremento (1 por defecto).
37
Controles
A continuacin podemos incluir el cuadro de texto.
y el botn de comando
38
Curso
Valor del registro cmdCalcular &Calcular 120 1560 375 1455 Ms Sans Serif, negrita de 8 puntos
Del valor del registro de la propiedad Caption destaca &: antepuesto a un carcter alfanumrico, asocia la tecla correspondiente al evento Click del control.
Opciones
Como indicbamos en el paso Propiedades del formulario, la aplicacin debe ofrecer la posibilidad de elegir entre tres opciones. Utilizaremos botones de opcin en un marco. Modificaremos estos registros:
En este marco, debemos insertar 3 botones de opcin, a los que modificar los registros de algunas propiedades:
39
Bucles
Qu controles programar? Slo programaremos el evento Clic del botn cmdCalcular. Segn la opcin seleccionada el programa realizar una u otra operacin (ramificadores If). En la solucin utilizamos tres estructuras diferentes. Por otro lado, utilizaremos el operador Mod, que devuelve el resto de la divisin del valor numrico a su izquierda por el de su derecha.
Next End If End If lblResultado.Caption = Format(resultado, #,##0) mostrar el resultado con formato End Sub
41
42
Curso
Captulo 5
Funciones, procedimientos y libreras
Una vez que ya sabemos cmo funciona el control del flujo de datos en la programacin con Visual Basic, cmo deben utilizarse las variables y algunos de los controles que se manejan de forma habitual, debemos ir pensando en cmo archivaremos el cdigo de los programas a medida que el nmero de lneas vaya aumentando.
Modularidad Las aplicaciones informticas que se utilizan hoy en da, incluso aquellas diseadas de forma personal, cuentan en su implementacin con miles de lneas de cdigo. Teniendo en cuenta que el cdigo de toda aplicacin debe ser revisado en multitud de ocasiones antes de alcanzar su plena funcionalidad, da la sensacin de que una buena documentacin de todas esas instrucciones no resulta suficiente para localizar aquellos errores que se vayan detectando. Es entonces cuando toma fuerza el uso de la modularidad o, lo que es lo mismo, la divisin de un programa muy grande en programas ms sencillos y manejables. Estos mdulos se denominan funciones, procedimientos, subrutinas, etc., dependiendo del lenguaje de programacin utilizado. Los habituales de esta seccin recordarn que ya hemos usado la modularidad cuando programbamos los eventos de los controles. Uso y ventajas de la modularidad Que debemos echar mano de la modularidad en nuestros programas es un hecho, pero tenemos que saber exactamente cundo hay que abstraer un mdulo del programa principal. Esta respuesta no es sencilla y queda a criterio del programador que, a medida que va adquiriendo experiencia, utiliza este recurso sin apenas darse cuenta. De todos modos, existen algunos casos donde el uso de un subprograma resulta idneo:
43
Un fragmento del programa tiene una misin concreta. El cdigo se mantiene dentro de un tamao manejable. El cdigo puede ser invocado varias veces a lo largo del programa o incluso puede ser reutilizado por otros programas.
Practicando la modularidad a partir de estos criterios, nos encontraremos con las siguientes ventajas: 1. Cada subprograma puede ser desarrollado y comprobado de manera independiente. Se produce un ahorro de memoria al ejecutar el programa debido a la reduccin del nmero de lneas de cdigo. Por el mismo motivo, se ahorra tiempo de desarrollo. Se consigue una independencia de datos que evita que las modificaciones en otras zonas de cdigo afecten a la funcionalidad del subprograma.
2.
3. 4.
Como conclusin, podemos afirmar que el uso de subprogramas resulta beneficioso incluso en programas de pequeo tamao. Funciones y procedimientos Visual Basic, a diferencia de otros lenguajes de programacin, distingue entre funciones y procedimientos. Como ya explicamos en captulos anteriores, la principal diferencia entre un procedimiento y una funcin radica en que esta ltima se puede utilizar dentro de una expresin (por ejemplo, la funcin format), ya que retorna un valor (recordad que la funcin format retornaba una cadena de caracteres con un determinado formato). Por el contrario, los pro44 Curso
cedimientos son segmentos de cdigo independiente que, una vez invocados, ejecutan una serie de instrucciones sin retornar ningn valor al programa que los invoc (aunque puede modificar los argumentos). Un ejemplo de llamada a un procedimiento es la sentencia beep que utilizbamos en el cdigo de la calculadora de euros para emitir un sonido. Funciones
La sintaxis de las funciones es la siguiente: [Public] [Private] Function nombre_funcin ([parmetros]) As tipo [sentencias] nombre_funcin=expresin End Function Con la palabra reservada Public o Private indicamos el alcance de la funcin, es decir, desde dnde se le puede invocar. Utilizando la palabra Public, nos aseguramos de que se puede invocar a la funcin desde cualquier
Visual Basic 6.0 45
parte del programa (el mismo formulario, otro formulario, un mdulo, etc.). Por el contrario, al utilizar la palabra Private acotamos el alcance de la funcin al formulario o mdulo en el que se encuentra. Si no se utiliza ninguna de las dos palabras, Visual Basic entiende que se trata de una funcin pblica. La palabra reservada function indica la naturaleza de la subrutina y nombre_funcin es el nombre que utilizaremos para referirnos a dicha funcin. Cuando utilicemos funciones o procedimientos de mbito pblico debemos asegurarnos de no asignar el mismo nombre a dos subprogramas diferentes. Los parmetros son los argumentos que son pasados cuando se llama a la funcin (en el caso de la funcin format, se pasa una cantidad de tipo variant y un string que indica el formato de salida). Desde el punto de vista del subprograma, los parmetros sern variables con un valor inicial (el correspondiente a la variable, constante o expresin utilizada en la llamada). A la hora de implementar la funcin, esos parmetros se especifican indicando un nombre (que no tiene por qu coincidir con el de la variable utilizada en la llamada) y un tipo. En caso de necesitar ms de un argumento, stos se separan por comas y el orden que ocupen en las llamadas debe corresponder con el orden que ocupan en la definicin. Para especificar el tipo de valor retornado por la funcin se utiliza la palabra reservada As seguida del tipo de dato que devolver el subprograma. Por ltimo, es imprescindible asegurarse de que la funcin retornar el valor deseado, para lo que asigna al nombre de la funcin el valor de retorno (justo antes de salir o durante el transcurso del subprograma) como si de una variable convencional se tratase. Las llamadas a las funciones no tienen un esquema definido, pero puede resumirse su uso diciendo que una llamada a una funcin puede ocupar el mismo lugar que un dato del tipo retornado por la funcin. Procedimientos o subrutinas La sintaxis de los procedimientos en Visual Basic se corresponde con el siguiente esquema: [public] [private] Sub nombre_prodedimiento ([parmetros])
46 Curso
[sentencias] End Sub La explicacin del esquema es similar al de las funciones, si bien cabe destacar que para distinguir el tipo de subprograma del que se trata se utiliza otra palabra reservada por Visual Basic, Sub en este caso. ? Ejemplo de un procedimiento que obtiene la suma de los n primeros nmeros. Por otro lado, y dado que no retorna ningn valor, no debe indicarse ningn tipo de dato devuelto ni hay que asignar ningn valor de retorno. Por ello, la llamada a un procedimiento difiere de la llamada a una funcin, ya que no se espera ningn valor. El esquema de estas llamadas es: call nombre_procedimiento (argumentos) o nombre_procedimiento argumentos Argumentos por referencia y por valor Como venimos explicando a lo largo de este tema, existe una correspondencia entre los valores que se pasan al llamar a un subprograma y los parmetros que ste utiliza. La duda surge al preguntarse si las modificaciones de los parmetros se ven reflejadas en las variables correspondientes en la llamada al subprograma o si, por el contrario, unos datos y otros son independientes. La respuesta es que depende del modo en que los parmetros se especificaron durante la implementacin, en la cabecera del subprograma. Concretamente, Visual Basic reserva la palabra byVal, que se coloca en la cabecera de la especificacin de los subprogramas delante de cada parmetro que se pasa por valor, para indicar que dicho subprograma no modifica el valor de la variable asociada en los argumentos de la llamada. Si no se
Visual Basic 6.0 47
utiliza esta palabra, el argumento se pasa por referencia, es decir, los cambios que sufra el parmetro asociado dentro del subprograma tambin afectan a la variable asociada en la llamada al mismo. ? Ejemplo similar al anterior que no modifica el argumento de la llamada asociado a n.
Libreras
Una de las ventajas del uso de los subprogramas que destacbamos al hablar de la modularidad era la reutilizacin de cdigo. Para facilitar esta labor, Visual Basic cuenta con unos archivos externos (archivos basic .BAS), a los que denomina Mdulos, destinados a contener subprogramas que posteriormente pueden ser exportados y reutilizados. Desde cualquier parte de un proyecto (formulario o mdulo) se puede acceder a cualquier subprograma de cualquier mdulo siempre que dicho subprograma est declarado como pblico. Con la funcin Agregar Mdulo del men Proyecto de la barra de herramientas se puede insertar un mdulo en el proyecto. En el dilogo desplegado puede seleccionarse si se quiere insertar un mdulo nuevo, sin cdigo, o bien reutilizar alguno ya existente, seleccionndolo por medio del explorador que aparece en la pestaa Existente de dicho dilogo. Para salvar un mdulo con el fin de reutilizarlo en otro proyecto, se pulsa con el botn derecho del ratn sobre el mdulo correspondiente en la Ventana de Proyecto y, del men desplegado, se presiona sobre la opcin Guardar Mdulo.Bas. Mdulos matemticos
48 Curso
Como ejemplo, vamos a implementar unos subprogramas bsicos de la didctica de algoritmos dedicados a operaciones matemticas tpicas. Para empezar, modularizaremos el ejemplo del captulo anterior, la suma de los n primeros nmeros naturales. Lo primero que debemos hacer es pararnos a meditar qu tipo de subprograma debemos utilizar. Podemos pensar que utilizar un procedimiento que directamente lea de un cuadro de texto y escriba en otro utilizando un procedimiento para implementarlo puede ser una buena idea, pero la verdad es que se pierde generalidad, pues posiblemente nos encontremos con casos en los que el resultado devuelto no deba ser mostrado por pantalla. Lo idneo es utilizar una funcin que devuelva el valor (de tipo Long para soportar cantidades mayores) al punto de llamada o bien un procedimiento que reciba un parmetro Resultado por referencia. El algoritmo que calcula el factorial de un nmero entero n (el producto de ese nmero y todos los enteros anteriores) es similar al caso anterior, aunque de mayor utilidad. Puede utilizarse un valor devuelto de tipo Single o Double, con lo que se conseguira trabajar con cantidades mayores pero se perdera precisin. En ambos casos sera conveniente especificar un paso por variable para el dato que se pasa como argumento, para evitar una modificacin del mismo y permitir que se pasen variables o constantes indistintamente. Tambin sera conveniente asegurarse de que los valores de n se mueven entre los lmites mnimo y mximo, si procede.
pectos del formulario: Propiedad Nombre Caption Valor del registro FmrMatemticas Funciones Matemticas
Lo siguiente es modificar las propiedades de algunos controles. Por ejemplo, podemos ampliar el tamao del control lblResultado para adaptarlo a cantidades mayores: Propiedad Width Valor del registro 1575
Despus, se elimina el control optSumarImpares seleccionndolo y pulsando la tecla Supr del teclado. A continuacin se modifican las siguientes propiedades de los otros botones de opcin: optSumarTodo Valor del registro optSumatorio Sumar n primeros naturales 970 2200 optSumarPares Valor del registro optFactorial Factorial de n (n!)
Tambin se adapta el marco que contiene los botones de opcin (fmrOpcion) a la nueva aplicacin: Propiedad Height Caption Valor del registro 1095 Seleccionar opcin
A continuacin se inserta un nuevo mdulo dentro del proyecto (Proyecto/Agregar Mdulo) y se teclea el cdigo de las funciones:
50
Curso
Option Explicit Public Function SumaNNaturales(ByVal n As Integer) As Long n se pasa por variable Dim resultado As Long variable auxiliar resultado = 0 inicializacin de resultado If n > 0 Then confirmar que n > 0 sino no entra en el bucle y retorna 0 Do resultado = resultado + n n=n-1 Loop While n > 0 End If SumaNNaturales = resultado asignacin de valor devuelto End Function Public Function Factorial(ByVal n As Integer) As Double n se pasa por variable Dim resultado As Double variable auxiliar resultado = 1 inicializacin de resultado If n > 0 Then confirmar que n > 0 sino no entra en el bucle y retorna 1 Do resultado = resultado * n n=n-1 Loop While n > 0 End If Factorial = resultado asignacin de valor devuelto End Function
51
Para acabar este captulo, se borra el cdigo del formulario del captulo anterior y se escriben las nuevas instrucciones, basadas en llamadas a las funciones: Option Explicit forzar declaracin explcita de variables Private Sub cmdCalcular_Click() If optFactorial.Value = True Then lblResultado = Format(Factorial(txtDatos), #,##0) Else lblResultado = SumaNNaturales(txtDatos) End If End Sub Como podemos observar, la llamada a una funcin (Factorial) se puede producir dentro de la llamada a otra funcin (Format). Por ltimo, se guarda el nuevo formulario con un nombre nuevo con la funcin Archivo/Guardar fmrSumador.fmr como. Tambin se guarda el proyecto, preferiblemente en la misma carpeta que el formulario, con la funcin Archivo/Guardar proyecto como y se le asigna un nombre o ruta distinta al proyecto original para conservar una copia de cada uno.
52
Curso
Captulo 6
Arrays de variables
Hasta ahora, cuando trabajbamos con variables, siempre eran de un nico valor. En ocasiones, debemos trabajar con un elevado nmero de valores del mismo tipo y otorgar un nombre a cada uno de ellos para despus hacerles referencia lo que puede resultar un trabajo tedioso.
Con el fin de facilitar la labor en estos casos, los lenguajes de programacin de alto nivel ponen al servicio de los programadores un tipo de datos denominado array. Los arrays, tambin llamados vectores, son colecciones ordenadas de variables del mismo tipo que comparten el mismo nombre. Dentro de estas colecciones, los elementos se distinguen unos de otros por medio de ndices (generalmente nmeros enteros) que indican la posicin que el elemento ocupa en el vector. La declaracin de arrays se realiza de manera similar a la declaracin de variables de tipos predefinidos pero indicando adems los ndices entre los que se mueven la variables de tipo base o indicando tan slo el ndice superior con un nmero entero (en estos casos los ndices van de 0 al nmero especificado). Veamos unos ejemplos: Dim VectorEnteros (1 To 10) as Integer vector de 10 enteros Dim VectorFechas (10) as Date vector de 11 fechas Un ejemplo de acceso a los datos de los vectores podra ser: VectorEnteros (5) = VectorEnteros (3) * 5 el 5 elto del vector pasa a valer 5 veces el valor del tercero Arrays de controles
53
Una variante especialmente til de los arrays de variables son lo arrays de controles. Como ya explicamos al hablar de los vectores, todos los elementos del array deben ser del mismo tipo, por lo que un array de controles ser un array de cuadros de texto, o un array de cuadros combinados, etc. pero nunca un array de varios tipos de controles. El modo ms sencillo de crear un array de controles en tiempo de diseo es copiar y pegar un control dentro del mismo formulario tantas veces como elementos sean necesarios en el vector. Otra posibilidad es, una vez insertados todos los elementos en el formulario, unificarlos en un vector dndoles a todos el mismo nombre y configurando el valor de su propiedad Index (que es la que indica la posicin que el control ocupa en el formulario). Con el ejemplo de este captulo veremos como un trabajo conjunto de bucles, arrays y subprogramas facilita enormemente la implementacin de una aplicacin. ? La funcin marcad corresponde al cuadro combinado (Combobox) Cuadros combinados Tambin como novedad en el paso a paso de este captulo trabajaremos con un nuevo tipo de controles, los llamados ComboBox o cuadros combinados. Su nombre se debe a que son una combinacin de los cuadros de listas y los cuadros de texto. Seguramente, aunque nunca hayamos programado en ningn lenguaje de programacin visual, en multitud de ocasiones habremos utilizado estos cuadros combinados. Su aspecto en estado inactivo es similar al del cuadro de texto aunque suele llevar un botn desplegable a su derecha que, al ser pulsado, muestra el contenido de la lista. Los elementos de dicha lista puede aadirse y eliminarse en tiempo de diseo (con la propiedad ItemData) y en tiempo de ejecucin (lo ms recomendado, con los eventos AddItem, que necesita un valor para aadir una nueva entrada a la lista en la ltima posicin, y Clear para borrar la lista). Adems, y como veremos en el paso a paso, con la propiedad ListIndex hacemos referencia a la posicin activa de la lista. Al modificar el valor activo de un
54 Curso
cuadro combinado con el ratn o los cursores del teclado se produce su evento Click. Algunas funciones necesarias Para entender el cdigo de este captulo del curso es necesario que comentemos algunas funciones con las que trabajaremos: Year (Fecha): retorna un entero equivalente al ao del valor pasado como argumento, de tipo Date. Month (Fecha): retorna un entero equivalente al mes del valor pasado como argumento, de tipo Date. Date: Retorna la fecha que marca el reloj del sistema. RGB (Rojo,Verde,Azul): retorna un entero correspondiente al color resultante de mezclar las cantidades de rojo, verde y azul especificadas por los argumentos que han de ser enteros con valores entre 0 y 255. Cdate (Expresin): retorna un valor de tipo Date correspondiente a lo especificado en Expresin. Str (Cantidad): Devuelve un String con la cantidad indicada. Weekday (Fecha,Criterio): Devuelve el da de la semana en que cay o caer el da especificado en Fecha, de tipo Date, siguiendo el Criterio, que es un entero que, de valer 2, indica que el primer da de la semana es el lunes (criterio espaol).
Estructura with end winth En el trabajo con objetos, ms an cuando se modifican sus propiedades en tiempo de ejecucin, es necesario que dichas modificaciones se realicen de un modo rpido, ntido y sencillo. Con ese objetivo, Visual Basic 6 ofrece a los programadores la estructura With End Whith que sigue la siguiente estructura:
Visual Basic 6.0 55
With objeto . propiedad1 = Nuevo_Valor . propiedad2 = Nuevo_Valor . propiedadn = Nuevo_Valor End With De este modo modificaramos n propiedades del mismo objeto sin necesidad de escribir n veces su nombre. El hecho de que en el paso a paso de este captulo, objeto sea ARRdias(i) significa que las propiedades se refieren a la etiqueta que ocupa la posicin i-sima del vector de controles ARRdias.
Posteriormente insertaremos dos cuadros combinados con sus respectivas etiquetas. Primero, activando la funcin ComboBox de la barra de herramientas, dibujamos los dos cuadros de texto, a los que indicaremos los siguientes valores para los registros de propiedades:
56 Curso
Despus, con la funcin Label, insertamos sus respectivas etiquetas: Propiedad Nombre Caption Left Top Height Width Etiqueta de Aos Valor lblAnio Ao 360 240 255 615 Etiqueta de Meses Valor lblMes Mes 2400 240 255 615
Para ambas etiquetas indicamos una fuente (propiedad Font) MS Sans Serif, negrita de 12 puntos. Ahora vamos a crear un array de etiquetas, cada una de las cuales contendr (o no, segn el caso) un da del mes. En esta ocasin (no siempre ocurre lo mismo) lo ms prctico ser crear el vector a partir de una etiqueta con unos determinados valores para los registros de sus propiedades haciendo copias de esa etiqueta y ubicndolas en distintos puntos del formulario. Para los registros de las propiedades de la etiqueta original especificamos los siguientes valores: Propiedad Nombre Caption
Visual Basic 6.0
Valor ARRDias
57
A continuacin copiamos la etiqueta en el portapapeles (Edicin/Copiar) y la pegamos sobre el formulario (Edicin/Pegar). En ese momento, Visual Basic nos preguntar si deseamos crear una matriz de controles, a lo que debemos contestar afirmativamente. Debemos repetir este proceso hasta contar con 37 etiquetas iguales (36 copias), colocando cada una en el formulario antes de pegar la siguiente. Es muy importante tener en cuenta el orden que cada una de ellas ocupa en el array, porque su posicin en el formulario depender de ese ndice. Teniendo en cuenta que la primera etiqueta adquiere por defecto el ndice 0 y que ya est ubicada en el formulario, las dems etiquetas ocuparn, segn su ndice (propiedad Index), las siguientes posiciones (las posiciones estn pensadas para que se puedan colocar de manera sencilla pulsando y arrastrando con el ratn):
Prop. Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 58 Prop. Left 240 1200 2160 3120 4080 5040 6000 240 1200 2160 3120 4080 5040 6000 240 1200 2160 Prop. Top 1680 1680 1680 1680 1680 1680 1680 2640 2640 2640 2640 2640 2640 2640 3600 3600 3600 Prop. Index 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Prop. Left 5040 6000 240 1200 2160 3120 4080 5040 600 240 1200 2160 3120 4080 5040 6000 240 Prop. Top 3600 3600 4560 4560 4560 4560 4560 4560 4560 5520 5520 5520 5520 5520 5520 5520 6480 Curso
17 18
3120 4080
3600 3600
36
1200
6480
Los nicos controles que ahora quedan por aadir son los ttulos de los das de la semana. Para ello utilizaremos 7 etiquetas con rtulos (propiedad caption) LUN, MAR, MIE, JUE, VIE, SAB, DOM, de tamao 615 x 255 twips, fuente MS Sans Serif negrita de 12 puntos y las siguientes coordenadas:
Lo siguiente que debemos hacer es insertar el cdigo del formulario (Ver/Cdigo) donde inicializaremos los valores de los cuadros combinados al cargarse el formulario (evento form_load) y programaremos los eventos de cambio de valor de los cuadros combinados (evento click). Para simplificar el cdigo, utilizaremos la modularidad (explicada en el captulo anterior del curso) creando los procedimientos Redibujar (que hace el proceso de refresco de datos), BorrarFormulario (subprocedimiento del anterior, que borra los datos antes de que se dibujen los nuevos) y RedibujarFechas (tambin subprocedimiento de Redibujar que inserta los nuevos datos). El cdigo es el siguiente: Option Explicit
59
Private Sub cmbAnio_Click() Redibujar End Sub Private Sub cmbMes_click() Redibujar End Sub Private Sub form_load() Inicializar valores en tiempo de ejecucin Dim i As Integer RELLENAR EL COMBO DE MESES cmbMes.AddItem Enero cmbMes.AddItem Febrero cmbMes.AddItem Marzo cmbMes.AddItem Abril cmbMes.AddItem Mayo cmbMes.AddItem Junio cmbMes.AddItem Julio cmbMes.AddItem Agosto cmbMes.AddItem Septiembre cmbMes.AddItem Octubre cmbMes.AddItem Noviembre cmbMes.AddItem Diciembre RELLENAR EL COMBO DE AOS For i = 1900 To 2100 cmbAnio.AddItem i Next INICIALIZAR COMBOS CON FECHA ACTUAL cmbAnio.Text = Year(Date) establecer ao actual como valor inicial de cmbAnio cmbMes.ListIndex = Month(Date) - 1 establecer mes actual como valor inicial de cmbMes CAMBIAR COLORES A LOS TTULOS DE SBADO Y DOMINGO lblSabado.ForeColor = RGB(0, 0, 255) lblDomingo.ForeColor = RGB(255, 0, 0) End Sub
60 Curso
Private Sub Redibujar() Dibuja el nuevo calendario Dim diasmes As Integer Dim fecha As Date BorrarFormulario diasmes = NumDiasMes(cmbMes.ListIndex + 1, cmbAnio.Text) fecha = CDate(1/ + Str(cmbMes.ListIndex + 1) + / + cmbAnio.Text) con el smbolo entre strings se produce concatenacin Call RedibujarFechas(Weekday(fecha, 2), diasmes) End Sub Private Sub BorrarFormulario() Borra el formulario Dim i As Integer For i = 0 To 36 With ARRdias(i) .Appearance = 1 Fondo blanco .Caption = .Font = Arial .FontBold = True Negrita .FontSize = 26 .Alignment = 2 Centrado End With Next End Sub Private Sub RedibujarFechas(ByVal dia1mes As Integer, _ ByVal diasmes As Integer) Dim i As Integer For i = dia1mes To (diasmes + dia1mes - 1) ARRdias(i - 1).Appearance = 0 If (i Mod 7 = 6) Then si es sbado ARRdias(i - 1).ForeColor = RGB(0, 0, 255) Else If (i Mod 7 = 0) Then si es domingo ARRdias(i - 1).ForeColor = RGB(255, 0, 0) Else ARRdias(i - 1).ForeColor = RGB(0, 0, 0) End If End If
Visual Basic 6.0 61
ARRdias(i - 1).Caption = i - dia1mes + 1 Next End Sub Por ltimo, debemos crear la funcin NumDiasMes, que devuelve el nmero de das de un mes segn el mes y el ao (exclusivamente para febrero). El criterio utilizado para calcular el nmero de das de un mes de febrero es el siguiente: Un ao es bisiesto (y por consiguiente su mes de febrero tiene 29 das) si dicho ao es divisible por 4 (al dividir el nmero de ao por 4 su resto es 0). Como excepcin estn los aos mltiplos de 100 (el ao 1900, por ejemplo), que no son bisiestos, salvo los mltiplos de 400 (por ejemplo el ao 2000) que s que lo son. Como esta funcin puede tener utilidad en algn otro programa, es conveniente ubicarla en un mdulo externo (Proyecto/Agregar Mdulo/Nuevo). Siguiendo el criterio anterior, el cdigo de la funcin NumDiasMes ser el siguiente: Public Function NumDiasMes(mes As Integer, anio As Integer) If mes = 2 Then If ((anio Mod 4 = 0) And (anio Mod 100<>0)) Or _ ((anio Mod 4 = 0) And (anio Mod 100 = 0) And _ (anio Mod 400 = 0)) Then NumDiasMes = 29 Else NumDiasMes = 28 End If Else If (mes = 1) Or (mes = 3) Or (mes = 5) Or _ (mes = 7) Or (mes = 8) Or (mes = 10) Or _ (mes = 12) Then NumDiasMes = 31 Else NumDiasMes = 30 End If End If End Function
62
Curso
Captulo 7
Interfaz aplicacin-usuario
Seguramente, a todos los que aprendimos a programar con entornos de programacin no visuales (Pascal, Cobol, Basic, C, Fortran, ) lo que ms nos fascin de la programacin visual fue su tremenda potencia a la hora de disear la interfaz de las aplicaciones, gracias a una amplia gama de controles con los que nos permite trabajar.
63
Como hemos ido viendo a lo largo del curso, Visual Basic ofrece una extenssima gama de controles (de los que tan slo conocemos una nfima porcin) que permiten realizar, esencialmente, intercambio de informacin entre la mquina y el usuario. Posiblemente debido a toda esta gama de posibilidades, gran parte del tiempo dedicado al desarrollo de una aplicacin se destina al diseo de la interfaz. Al respecto del diseo de interfaces hay multitud de teoras. De hecho, cada diseador puede tener su propio estilo, pero existen unas premisas bsicas que debemos tener en cuenta antes de empezar a insertar controles en los formularios. Sin profundizar en el buen gusto de cada uno a la hora de elegir colores, fuentes y dems, toda aplicacin que presuma de ser prctica y tener una interfaz bien diseada debe resultar al mismo tiempo: Simple: una interfaz no debe sobrecargarse con controles dedicados a mostrar datos intrascendentes. Completa: la aplicacin debe mostrar todos los datos necesarios. En caso de tener que mostrar o recopilar muchos datos, es preferible utilizar varios formularios que concentrar demasiada informacin en uno mismo. Concreta: en caso de utilizar mltiples formularios en el proyecto, conviene tratar de contextualizar la informacin, dedicando, si es posible, cada formulario a una funcin en concreto. Intuitiva: debe tenderse a desarrollar proyectos donde el usuario se sienta familiarizado con el entorno.
Editor de mens Uno de los elementos ms utilizados a la hora de desarrollar aplicaciones para entornos de ventanas es la barra de mens. Los mens se suelen aadir en la parte superior de los formularios y su funcin es facilitar al usuario el acceso a todas las funciones del programa. Adems, respetando las cualidades anteriormente mencionadas, los desarrolladores de aplicaciones ofimticas tienden a disear la barra de mens siguiendo un estndar: el men Archivo contiene las funciones operativas del documento, Edicin rene, entre
64 Curso
otras, las funciones de trabajo con el portapapeles, Formato se destina a reunir las posibilidades de formato especficas de la aplicacin, Ayuda contiene los ficheros informativos del programa, etc. Visual Basic 6 ofrece una estupenda funcin que nos ayudar en gran medida a la hora de elaborar las barras de men de nuestras aplicaciones. Esta herramienta es el denominado Editor de mens. El Editor de mens se presenta con un formulario dividido en dos zonas. La superior est destinada a configurar cada uno de los nodos del rbol de men mientras que la inferior nos muestra la estructura de dicho rbol. Como el resto de objetos con los que trabaja Visual Basic, los nodos del rbol de men tienen una serie de propiedades que es necesario conocer: Name: es la cadena de caracteres con la que nos referiremos al nodo a lo largo del diseo del programa. Siguiendo el convenio Redclick utilizado desde el principio del curso, todos los nodos del men llevarn en su nombre el prefijo mnu. Caption: es el texto que la aplicacin mostrar en el men como representacin grfica del nodo. Anteponiendo a una de las letras del texto el carcter &, esa letra queda asociada al nodo dentro del submen donde se encuentre. Lgicamente, en cada uno de los submens no puede haber dos nodos con la misma letra asociada. Grficamente, la letra aparecer subrayada. Shortcut: combinacin de teclas con las que, en tiempo de ejecucin, se invoca directamente el evento Click del nodo. La diferencia entre esta asignacin y la anterior es que esta se realiza desde cualquier punto del programa y la asociacin por medio de la propiedad Caption se realiza durante la navegacin por el men. Checked: con esta propiedad (de tipo boolean) activada, aparece una verificacin junto al nodo en el men. Enabled: habilita o deshabilita el nodo (y sus hijos si los tuviera). Visible: muestra u oculta el nodo (y sus hijos si los tuviera).
65
Los separadores son unos nodos especiales. Se utilizan para separar funciones dentro de un mismo men y no llevan programacin. Para aadirlos al men basta con poner un guin - en su propiedad Name. Para diferenciar los distintos niveles del rbol se utilizan las flechas de derecha e izquierda del centro del formulario. La primera hace descender un nivel al nodo seleccionado y la segunda se lo aumenta. Tambin es muy importante el orden en que se ordenan los nodos dentro del rbol, pues dependiendo de este orden los nodos sern padres o hijos de unos nodos u otros. Con las flechas arriba y abajo (en el centro del formulario) se modifica la posicin del nodo seleccionado. Para eliminar un nodo de la estructura se selecciona el nodo en concreto y se pulsa el botn Eliminar del formulario. Para pasar de un nodo a otro se puede seleccionar directamente el nodo objetivo con el ratn o bien utilizar el botn Siguiente para pasar al sucesor del nodo actual.
66
Curso
A continuacin pulsamos la tecla Enter (o el botn Insertar del formulario) para validar la entrada. Como a continuacin vamos a aadir los nodos hijo de archivo, indicamos una bajada de nivel con la flecha derecha del formulario. Al nombre de todos los hijos de Archivo le aadiremos el prefijo del nombre de su padre:
Validamos la entrada (Enter) y aadimos los siguientes nodos (asegurndonos de insertar uno antes de pasar al siguiente):
67
En este punto es conveniente aadir un separador, ya que el prximo nodo programable ser Salir y, por su naturaleza, podra aislarse de los 3 nodos anteriores:
Validamos y queda terminado el men Archivo. Para continuar con el men Edicin lo primero que debemos hacer es subir el nivel (con la flecha izquierda del formulario) para igualarlo al nivel de Archivo. A continuacin aadimos la entrada de dicho nodo:
68
Curso
Despus bajamos de nivel (con la flecha derecha) y aadimos los hijos de Edicin con las siguientes propiedades:
Despus de validar la entrada de estos nuevos nodos, subimos de nuevo de nivel (flecha izquierda del formulario) para aadir el modo Formato.
Bajamos de nivel (flecha derecha del formulario) e insertamos sus correspondientes hijos:
69
Terminada la edicin del men, confirmamos con el botn Aceptar. Despus guardamos el proyecto (Archivo/Guardar proyecto como) para poder retomarlo ms adelante en este mismo punto.
70
Curso
Captulo 8
Barras de estado y barras de herramientas
Aprovechando la creacin del editor de textos en la que nos encontramos sumidos desde el captulo anterior, en esta ocasin, vamos a conocer el manejo de algunos de los llamados controles comunes de Microsoft, algo ms complejos que los controles estndar pero de una alta funcionalidad.
Todas las aplicaciones de trabajo con archivos (diseo, ofimtica, etc.) cuentan con unos controles, de los que an no hemos hablado. De hecho, paralelamente a la barra de mens, estos programas ofrecen una barra de herramientas donde agrupan las principales funciones del men (abrir, guardar, copiar, pegar, etc.). Tambin es muy comn en las aplicaciones donde el teclado tiene un peso importante, incluir una barra de estado en la parte inferior de la pantalla. Esa barra, de uso generalmente informativo, muestra el estado del bloqueo de las maysculas o el teclado numrico, la fecha, la hora, o informacin propia del programa. Del resto de los controles comunes de Microsoft, hoy hablaremos de las listas de imgenes, ya que su utilizacin es imprescindible para poder asociar iconos a los botones de la barra de herramientas. Control ImageList El control ImageList tiene una utilidad diferente a los dems controles con los que hemos trabajado hasta el momento. El fin de casi todos los controles ms comunes de Visual Basic es intercambiar informacin con el usuario (ya sea un simple clic del usuario sobre un botn de comando para desencadenar un procedimiento, mostrar un ttulo sobre una etiqueta u ofrecer una serie de opciones con un cuadro combinado). En cambio, la funcin de una lista de imgenes es servir de contenedor de imgenes (iconos, cursores, mapas de bits, etc.) que posteriormente sern utilizarlas por otros controles. La insercin de las imgenes en la lista puede hacerse por medio de cdigo, en tiempo de ejecucin, o bien en tiempo de diseo a partir de un dilogo que har las veces de asistente. Dentro de la lista, cada imagen tendr un nVisual Basic 6.0 71
dice para diferenciarse del resto. Para que otro control pueda despus utilizar esas imgenes, primero debemos crear un enlace a la lista y despus, por medio de esos ndices, hacer referencia a las distinta imgenes. Barras de herramientas Para crear las barras de herramientas con Visual Basic, se utiliza el control Toolbar (hasta ahora desconocido) que contiene a su vez una serie de controles. Todo el mundo est acostumbrado a utilizar las barras de herramientas en multitud de programas, por lo que incluirlas en nuestras aplicaciones resultar, al menos en concepto, bastante sencillo. El control Toolbar se inserta en el formulario en tiempo de diseo (siempre en la parte superior de la pantalla, bajo la barra de men). La configuracin de las propiedades de este control es tremendamente sencilla, ya que cuenta con un asistente que nos ayudar durante el proceso. Dentro de este dilogo, tambin podemos insertar los botones que habilitaremos para que los usuarios interacten con nuestra aplicacin, si bien los iconos que etiqueten a estos botones deben estar previamente insertados en una lista de imgenes. Dependiendo del tamao de las imgenes y de la insercin o no de texto en los botones de la barra de herramientas, el tamao del control ser mayor o menor. Una alternativa a etiquetar con texto el botn (propiedad Caption), es aadir un texto a la propiedad ToolTipText para que la etiqueta se despliegue al situar el puntero del ratn sobre el botn. Barras de estado Las barras de estado, tambin muy extendidas entre las aplicaciones actuales, estn formadas por uno o varios paneles informativos. Estos paneles pueden mostrar la hora, la fecha, informacin sobre la pulsacin o no de teclas especiales (Bloq Mays, Insert, etc.) o informacin especfica de la aplicacin. En Visual Basic, para insertar barras de estado en las aplicacio72 Curso
nes, se utiliza el control StatusBar. Este tipo de controles, al igual que las barras de estado, poseen un asistente para su configuracin con el fin de evitarle al programador algunas lneas de cdigo. Las barras de estado tambin pueden contener iconos en sus paneles, pero en este caso no es necesario que dichos iconos estn previamente insertados en un control ImageList.
Lo primero que debemos hacer para poder utilizar los nuevos controles, es insertarlos en el cuadro de herramientas. Para ello, pulsamos sobre un rea en blanco del cuadro de herramientas y, del men contextual desplegado, pulsamos sobre la funcin Componentes Se despliega entonces el dilogo Componentes, donde debemos pulsar sobre la pestaa Controles (si no es la lengeta activa). Dentro de la lista de controles, buscamos la entrada MicroVisual Basic 6.0 73
soft Windows Common Controls 6.0 (SP4) y marcamos la casilla de verificacin adjunta. Despus, al pulsar sobre el botn de comando Aceptar, veremos que un conjunto de nuevos controles aparecen en nuestro cuadro de herramientas. Ya estamos en disposicin de insertar los nuevos controles, si bien, como indicbamos anteriormente, es necesario tener creada la lista de imgenes para poder insertar las imgenes en la barra de herramientas. Para aadir un control ImageList a nuestro formulario, basta con hacer un doble clic sobre su icono en el cuadro de herramientas. Una vez tenemos el control ImageList sobre el formulario, pulsamos sobre l para activarlo y establecemos como imlIcono el registro de su propiedad Nombre. A continuacin, pulsamos sobre el control en el formulario con el botn derecho del ratn y, en el men contextual, pulsamos sobre Propiedades. En el dilogo General, indicamos un tamao de los iconos de 16 x 16 puntos y, en Imgenes, insertamos, respetando este orden, las imgenes de los siguientes iconos: nuevo, abrir, guardar, cortar, copiar, pegar, negrita, cursiva y subrayado. Para insertar un icono se pulsa sobre Insertar imagen, se localiza con el explorador desplegado y se pulsa sobre Abrir. Una vez insertadas todas las imgenes, se pulsa sobre el botn Aceptar y la lista queda definida. Ahora insertamos el control ToolBar que contendr la barra de herramientas. Para ello, nuevamente, hacemos doble clic sobre la funcin correspondiente del cuadro de herramientas. Despus actualizamos el nombre del nuevo control (indicamos el valor tbrOfimatica en su propiedad Nombre) y llamamos al asistente de las propiedades del mismo modo que lo
74 Curso
hacamos en el paso anterior con el de la lista de imgenes. En la pestaa general aceptamos los valores por defecto, salvo en el del cuadro combinado ImageList, donde buscaremos la entrada imlIconos correspondiente a la lista recin creada, y pasamos a la pestaa Botones. A partir de este dilogo crearemos los botones que se mostrarn en la barra de herramientas. Existen varios tipos de botones, pero para este proyecto utilizaremos tan slo los botones comunes o tbrDefault (similares a los CommandButton) y los separadores o tbrSeparator. Dentro de la barra de herramientas, los botones vienen a ser elementos de un array de controles. Dicho esto, y teniendo siempre en consideracin el valor del ndice (campo index) del botn, estableceremos los siguientes valores para los 11 botones de la barra de herramientas (para insertar un nuevo botn se pulsa el botn de comando Insertar botn):
El resto de valores se dejan con su valor por defecto. Despus confirmamos pulsando el botn Aceptar.
Visual Basic 6.0 75
De un modo muy similar al utilizado para crear la barra de herramientas, insertaremos en el formulario una barra de estado. Con un doble clic sobre el icono correspondiente el cuadro de herramientas de Visual Basic, aadimos el control StatusBar al formulario, al que llamaremos sbrEstado. A continuacin invocamos al formulario de sus propiedades. Accedemos al dilogo de Paneles pulsando sobre su pestaa correspondiente y, una vez all, insertamos los siguientes paneles:
De nuevo, dejamos el resto de campos con su valor por defecto. Por ltimo, guardamos el proyecto para continuar trabajando en l en los prximos captulos del curso. Si queremos conservar las distintas versiones del proyecto, es preferible hacer una copia de todos los archivos que se generan en una sesin antes de editar los documentos, ya que en ocasiones los proyectos originales pueden verse modificados.
76
Curso
Captulo 9
Cuadros de dilogo comunes
Insertados casi todos los controles en el formulario del editor de textos, ha llegado la hora de empezar a programar, pero antes debemos aadir al proyecto los ltimos objetos necesarios para dotar al editor de toda su funcionalidad.
Con la insercin de las barras de herramientas y estado del captulo anterior del curso, la parte de diseo de la interfaz de nuestro editor qued prcticamente completada. Curiosamente, hemos dejado para el final la parte ms importante, que es el cuadro de texto que contendr todos los caracteres de nuestros documentos. Para el trabajo con archivos, adems, necesitaremos utilizar los tpicos cuadros de dilogo Abrir y Guardar como, para lo que necesitaremos insertar el control CommonDialog. Por ltimo, empezaremos a programar el motor de la aplicacin, teniendo siempre en cuenta el paralelismo entre las funciones de la barra de mens y la barra de herramientas. Introduccin al trabajo con ficheros Como avanzbamos, utilizaremos el control CommonDialog de Visual Basic para trabajar con los cuadros de dilogo usuales en el trabajo con documentos. Adems, en este aspecto, necesitaremos empezar a conocer el funcionamiento del trabajo con ficheros, de modo que seamos capaces de abrir o crear nuevos documentos donde guardar u obtener informacin (texto en el ejemplo que nos compete). Aunque con el Paso a Paso quedar todo mucho ms claro, la idea general es que con un cuadro de dilogo (independientemente de que se trate del destinado a abrir o guardar documentos), obtendremos el nombre, el tipo (con la propiedad Filter de los CommonDialog podemos especificar un filtro para localizar un tipo especfico de archivos) y la ubicacin de un fichero (al salvar los datos,
Visual Basic 6.0 77
si no existe ese fichero, se crea uno nuevo), que posteriormente abriremos para leer o escribir el texto con la instruccin Open de Visual Basic: Open rutaacceso [For modo] As #nmeroarchivo donde rutaacceso es el nombre con la ruta completa del fichero (que automticamente se guarda en el registro de la propiedad FileName de los cuadros de dilogo), modo es el tipo de apertura (Output al guardar e Input al cargar) y nmeroarchivo, siempre precedido de #, el nmero entero que har las veces de alias del fichero. Para recuperar el texto de un documento, tras la llamada al cuadro de dilogo Abrir (mtodo ShowOpen de los CommonDialog) y la apertura del archivo, volcamos el contenido del fichero al editor con la funcin Input, que recibe como parmetros la longitud del texto (que podemos obtener a su vez con la funcin FileLen) y el alias del fichero. Por su parte, para volcar a disco el texto del editor una vez seleccionado y abierto el fichero de destino, utilizaremos el procedimiento Print de Visual Basic, que necesita como parmetros el alias del fichero y el origen del contenido. Sea cual sea la operacin realizada, despus de haber abierto un fichero y trabajado con l, es imprescindible cerrarlo por medio del procedimiento Close (que necesita como parmetro el alias del fichero, que en ese momento queda liberado). Programar las funciones del editor Otro aspecto muy importante del trabajo con el editor, es la programacin de sus funciones. Teniendo en cuenta el paralelismo existente entre las funciones de la barra de herramientas y de la barra de mens, trataremos de modularizar lo ms posible la aplicacin. Por ejemplo, en lugar de escribir el mismo cdigo en el evento Click del botn de men mnuArchivoGuardar que en el caso de pulsar el tercer botn de la barra de herramientas, crearemos un procedimiento llamado Guardar al que invocaremos con una sola lnea de cdigo en ambos casos (tambin incluiremos llamadas al procedimiento Guardar, que perfeccionaremos ms adelante, desde el cdigo de los procedimientos Abrir y Nuevo cuando se hayan producido modificaciones en el documento). Del mismo modo, tambin incluiremos la habilitacin y
78 Curso
deshabilitacin de los botones de ambas barras en sendos procedimientos, a los que invocaremos desde los puntos en los que proceda. Evento ButtonClick de la barra de herramientas Para gestionar la pulsacin de los botones de la barra de herramientas que, a diferencia de los de la barra de mens que tenan un nombre nico cada uno, se distinguen entre ellos por la propiedad index de la barra de men, Visual Basic utiliza un procedimiento asociado al evento ButtonClick sobre la barra de herramientas, que pasa como parmetro una copia del botn pulsado. Con una estructura de seleccin se analiza la posicin en la barra del botn recibido como argumento (con la propiedad index en nuestro caso) y se acta en consecuencia.
79
A continuacin, debemos insertar el control CommonDialog que utilizaremos para no tener que reprogramar los dilogos Guardar como y Abrir. Para poder insertar este control en el formulario, previamente debemos insertar un nuevo componente en el proyecto. Con este fin, pulsamos sobre la funcin Componentes del men Proyecto. En el dilogo desplegado, seleccionamos la pestaa Controles y activamos la entrada Microsoft Common Dialog Control 6.0. Pulsamos el botn Aceptar, y la funcin CommonDialog aparecer al final de nuestra barra de herramientas. Con un doble clic sobre ella, insertamos el control en el formulario, al que especificaremos el nombre cdlDialogo. Por ltimo, abrimos la ventana Cdigo (Ver/Cdigo) y escribimos las siguientes lneas: Private Sub DesactivarFunciones() mnuArchivoGuardar.Enabled = False mnuEdicionCortar.Enabled = False mnuEdicionCopiar.Enabled = False mnuEdicionPegar.Enabled = False mnuEdicionCortar.Enabled = False mnuFormatoNegrita.Enabled = False mnuFormatoCursiva.Enabled = False mnuFormatoSubrayado.Enabled = False With tbrOfimatica .Buttons(3).Enabled = False .Buttons(5).Enabled = False .Buttons(6).Enabled = False .Buttons(7).Enabled = False .Buttons(9).Enabled = False .Buttons(10).Enabled = False .Buttons(11).Enabled = False End With End Sub
80 Curso
Private Sub ActivarFunciones() mnuArchivoGuardar.Enabled = True mnuFormatoNegrita.Enabled = True mnuFormatoCursiva.Enabled = True mnuFormatoSubrayado.Enabled = True With tbrOfimatica .Buttons(3).Enabled = True .Buttons(9).Enabled = True .Buttons(10).Enabled = True .Buttons(11).Enabled = True End With End Sub Private Sub Form_Load() txtTexto.Height = ScaleHeight - _ (tbrOfimatica.Height + sbrEstado.Height) txtTexto.Width = ScaleWidth txtTexto.Left = 0 txtTexto.Top = tbrOfimatica.Height End Sub Private Sub Form_Resize() txtTexto.Height = ScaleHeight (tbrOfimatica.Height + sbrEstado.Height) txtTexto.Width = ScaleWidth End Sub Private Sub mnuArchivoGuardar_Click() Call Guardar End Sub Private Sub tbrOfimatica_ButtonClick(ByVal Button As MSComctlLib.Button) Select Case Button.Index Case 1 Nuevo documento Nuevo Case 2 Abrir documento Abrir Case 3 Guardar documento
Visual Basic 6.0 81
Guardar End Select End Sub Private Sub txtTexto_Change() If txtTexto.Text Then ActivarFunciones End If End Sub Private Sub Guardar() Tipos de archivos que se pueden guardar cdlDialogo.Filter = Archivos de texto (*.txt)|*.txt Mostrar cuadro de dilogo Guardar Como cdlDialogo.showsave Comprobar que no se cancel la accin If cdlDialogo.FileName Then Abrir el archivo para escritura Open cdlDialogo.FileName For Output As #1 Print #1, txtTexto.Text volcado a disco del texto Close #1 cierre del fichero mnuArchivoGuardar.Enabled = False tbrOfimatica.Buttons(3).Enabled = False End If En caso contrario no hacer nada End Sub Private Sub Abrir() If mnuArchivoGuardar.Enabled Then Guardar End If Tipos de archivos que se pueden abrir cdlDialogo.Filter = Archivos de texto (*.txt)|*.txt Mostrar cuadro de dilogo Abrir cdlDialogo.ShowOpen Comprobar que no se cancel la accin If cdlDialogo.FileName Then Abrir el archivo para lectura Open cdlDialogo.FileName For Input As #1 txtTexto.Text = Input(FileLen(cdlDialogo.File82 Curso
Name), #1) Close #1 mnuArchivoGuardar.Enabled = False tbrOfimatica.Buttons(3).Enabled = False End If End Sub Private Sub Nuevo() If mnuArchivoGuardar.Enabled = True Then Guardar End If Borrar texto txtTexto.Text = Desactivar botones DesactivarFunciones End Sub
83
84
Curso
Captulo 10
Introduccin al portapapeles de Windows
Para finalizar la programacin del editor de textos, en este captulo del curso tendremos que trabajar con el portapapeles de Windows con el fin de poder programar las funciones de cortado, copiado y pegado de texto. Adems, para perfeccionar las aperturas y salvados de documentos, utilizaremos los MsgBox, otro tipo de cuadros de dilogo.
A lo largo de los captulos hemos ido diseando y programando un editor de textos que pese a su sencillez, una vez terminado ser perfectamente operativo. Durante este proceso hemos podido conocer el uso de las barras de herramientas, los mens, las barras de estado y los cuadros de dilogo comunes (con los que programamos las funciones de abrir y guardar archivos de un modo muy sencillo). En esta ocasin, perfeccionaremos estas funciones (con unos dilogos previos) utilizando la funcin MsgBox de Visual Basic. Adems, programaremos modularizadamente el resto de opciones que propusimos al disear la herramienta, para lo que tendremos que intercambiar informacin con el portapapeles del sistema operativo. Cuadros de mensaje Los cuadros de mensaje, o MsgBox, son unos pequeos dilogos que los programadores suelen utilizar como recurso cuando han de hacer una consulta simple al usuario, ofrecindole las respuestas bsicas: Aceptar; Aceptar y Cancelar; Anular, Reintentar e Ignorar, etctera. Para facilitar este tipo de intercambios de informacin entre el programa y el usuario, Visual Basic ofrece la funcin MsgBox que tiene,
Visual Basic 6.0 85
bsicamente, la siguiente sintaxis: MsgBox(texo,botones,ttulo) donde texto es una cadena de caracteres con la informacin o la pregunta que se le realiza al usuario, botones es una expresin numrica en la que se especifica el icono y los botones que debe presentar el dilogo, y ttulo es el ttulo del cuadro a desplegar. En el editor, utilizaremos cuadros de mensaje para preguntar al usuario si desea salvar los cambios antes de abrir un archivo (nuevo o existente) y antes de finalizar la aplicacin con la opcin Cerrar del men Archivo. De cualquier modo, conviene tener presente que el subprograma MsgBox es una funcin, es decir, que devuelve un valor. En este caso se trata de un nmero entero que corresponde al cdigo del botn pulsado por el usuario. Dependiendo de cul sea ese valor devuelto el programa debe responder de una u otra forma. De todos modos, existen unas constantes en Visual Basic con las que resulta ms sencillo el trabajo con esta funcin:
Cortar, copiar y pegar Las funciones del men Edicin tambin quedaron pendientes del captulo anterior del curso. Para poder utilizar las funciones Cortar y Pegar debemos tener seleccionado un fragmento de texto (al menos un carcter), por lo que, en caso contrario, las opciones correspondientes a estas dos funciones tanto en el men como en la barra de herramientas deben presentarse deshabilitadas. Del mismo modo, en caso de que en el portapapeles no se encuentre ningn texto, las opciones de Pegar en ambos controles tampoco se presentarn activas. Si con un texto seleccionado se invoca a la copia, dicho texto ha de pasar al portapapeles, al igual que si la opcin elegida es Cortar, en cuyo caso, adems, se debe eli86 Curso
minar ese fragmento del texto total. Por el contrario, si un texto ya copiado (en esta aplicacin o en cualquier otra, ya que el portapapeles es un objeto general del sistema operativo) hemos de pegarlo en el documento, debemos insertar dicho texto en el punto del documento donde se encuentre el cursor. Para facilitar las cosas, Visual Basic ofrece el objeto Clipboard con el que podemos acceder al portapapeles del sistema. Por medio de los mtodos GetText (sin argumentos) y SetText (al que debemos pasar una cadena de caracteres, en nuestro caso el texto seleccionado del TextBox) de dicho objeto, podremos tomar el texto del portapapeles o volcarlo a su interior (respectivamente) segn proceda en cada caso. Formato del texto Por ltimo, tambin debemos programar las funciones del men Edicin. Dado que el editor trabajar con texto sin formato, las funciones destinadas a este efecto deben afectar a todo el texto del editor, independientemente de que un fragmento del mismo se encuentre seleccionado. De esto modo, lo nico que debe hacer la aplicacin al invocar a una de estas funciones es cambiar la propiedad correspondiente (Bold, Italic o Underline para la negrita, cursiva y subrayado respectivamente) del objeto Font que, a su vez, es objeto del cuadro de texto. ltimos toques del editor de textos Con este captulo pondremos fin a la creacin del editor de textos. Lo primero que haremos ser eliminar la posibilidad de minimizar el formulario, evento que provoca un error en el programa. Para ello, con el proyecto abierto por el punto en el que lo dejamos el captulo anterior y con el formulario fmrEditor seleccionado en la pantalla de diseo de Visual Basic, indicamos un valor False en su propiedad MinButton. Adems, y para evitar ese mismo fallo producido al reducir en exceso el tamao del formulario, modificamos el siguiente procedimiento, ya escrito en el captulo anterior. Private Sub Form_Resize() txtTexto.Height = ScaleHeight - _ (tbrOfimatica.Height + sbrEstado.Height) txtTexto.Width = ScaleWidth
Visual Basic 6.0 87
Establecer un tamao mnimo del formulario If fmrEditor.Height < 4000 Then fmrEditor.Height = 4000 End If If fmrEditor.Width < 5800 Then fmrEditor.Width = 5800 End If End Sub A continuacin escribimos, detrs del cdigo ya existente, las instrucciones correspondientes a los procedimientos del men Edicin: Private Sub Cortar() Enviar el texto seleccionado al portapapeles Clipboard.SetText (txtTexto.SelText) Borrar el texto seleccionado del documento txtTexto.SelText = Habilitar y deshabilitar botones mnuEdicionPegar.Enabled = True tbrOfimatica.Buttons(7).Enabled = True mnuEdicionCortar.Enabled = False mnuEdicionCopiar.Enabled = False tbrOfimatica.Buttons(5).Enabled = False tbrOfimatica.Buttons(6).Enabled = False End Sub Private Sub Copiar() Enviar el texto seleccionado al portapapeles Clipboard.SetText (txtTexto.SelText) Habilitar botones de pegado mnuEdicionPegar.Enabled = True tbrOfimatica.Buttons(7).Enabled = True End Sub Private Sub Pegar() Pegar el texto del portapapeles txtTexto.SelText = Clipboard.GetText End Sub
88 Curso
Despus programamos dos nuevos eventos asociados al cuadro de texto y encargados de habilitar y deshabilitar los botones del men y la barra de herramientas correspondientes a las funciones Cortar y Copiar. Con el evento Click trataremos la seleccin del texto por medio del ratn, mientras que con el evento KeyUp contemplaremos la posibilidad de que la seleccin se realice a travs del teclado: Private Sub txtTexto_Click() If txtTexto.SelLength > 0 Then mnuEdicionCopiar.Enabled = True mnuEdicionCortar.Enabled = True tbrOfimatica.Buttons(5).Enabled = True tbrOfimatica.Buttons(6).Enabled = True Else mnuEdicionCopiar.Enabled = False mnuEdicionCortar.Enabled = False tbrOfimatica.Buttons(5).Enabled = False tbrOfimatica.Buttons(6).Enabled = False End If End Sub Private Sub txtTexto_KeyUp(KeyCode As Integer, _ Shift As Integer) If txtTexto.SelLength > 0 Then mnuEdicionCopiar.Enabled = True mnuEdicionCortar.Enabled = True tbrOfimatica.Buttons(5).Enabled = True tbrOfimatica.Buttons(6).Enabled = True Else mnuEdicionCopiar.Enabled = False mnuEdicionCortar.Enabled = False tbrOfimatica.Buttons(5).Enabled = False tbrOfimatica.Buttons(6).Enabled = False End If End Sub Debido a que es posible aadir texto al portapapeles desde fuera de la aplicacin, necesitamos estudiar la activacin de los botones asociados al pegado de texto al margen de la ya definida tras el envo de texto al portapapeles
Visual Basic 6.0 89
a travs de la propia aplicacin. Para ello, aadiremos unas lneas de cdigo al procedimiento asociado al evento Load del formulario (ya existente del captulo anterior) y crearemos un nuevo procedimiento, tambin asociado a un evento del formulario (GotFocus), aunque en este caso correspondiente a una vuelta del foco sobre la aplicacin (se supone que para poder aadir texto al portapapeles desde otra aplicacin, sta debe tomar el foco en detrimento del editor): Private Sub Form_GotFocus() Dim aux As String Comprobar el contenido del portapapeles aux = Clipboard.GetText Si no est vaco, habilitar pegado If aux <> Then mnuEdicionPegar.Enabled = True tbrOfimatica.Buttons(7).Enabled = True Else deshabilitar pegado mnuEdicionPegar.Enabled = False tbrOfimatica.Buttons(7).Enabled = False End If End Sub Tambin debemos programar las funciones correspondientes al formato del texto. Para ello crearemos tres nuevos procedimientos que, aunque son muy sencillos, encajan en el concepto de modularidad. En todos los casos, utilizaremos la funcin lgica Not con la que negaremos el valor actual de la propiedad correspondiente (de modo que si tena valor True pasar a tomar valor False y viceversa). Private Sub Negrita() txtTexto.Font.Bold = Not (txtTexto.Font.Bold) End Sub Private Sub Cursiva() txtTexto.Font.Italic = Not (txtTexto.Font.Italic) End Sub Private Sub Subrayado() txtTexto.Font.Underline = Not (txtTexto.Font.Underline)
90 Curso
End Sub Del mismo modo, debemos insertar las llamadas correspondientes en el procedimiento asociado al evento ButtonClick de la barra de herramientas. Como este procedimiento ya lo empezamos el pasado captulo para contemplar las llamadas a las funciones de trabajo con archivos, tan slo debemos aadir las nuevas lneas: Private Sub tbrOfimatica_ButtonClick _ (ByVal Button As MSComctlLib.Button) Select Case Button.Index Case 1 Nuevo documento Nuevo Case 2 Abrir documento Abrir Case 3 Guardar documento Guardar Case 5 Cortar Cortar Case 6 Copiar Copiar Case 7 Pegar Pegar Case 9 Negrita Negrita Case 10 Cursiva Cursiva Case 11 Subrayado Subrayado End Select End Sub Igualmente debemos programar los procedimientos asociados al pulsado de las distintas opciones de los mens Edicin y Formato: Private Sub mnuEdicionCopiar_Click() Copiar End Sub
Visual Basic 6.0 91
Private Sub mnuEdicionCortar_Click() Cortar End Sub Private Sub mnuEdicionPegar_Click() Pegar End Sub Private Sub mnuFormatoNegrita_Click() Negrita End Sub Private Sub mnuFormatoCursiva_Click() Cursiva End Sub Private Sub mnuFormatoSubrayado_Click() Subrayado End Sub Con respecto a los cuadros de mensaje (MsgBox), tambin debemos hacer una modificacin en los procedimientos Abrir y Nuevo creados en el captulo anterior del curso. Dicha modificacin se basa en la insercin de un aserto que condiciona la llamada al procedimiento Guardar. Dicho aserto es una pregunta de confirmacin al usuario al respecto de su intencin de salvar los cambios que se realiza por medio de un cuadro de mensaje. El resultado, tras las modificaciones en dichos procedimientos sera el siguiente: Private Sub Abrir() If mnuArchivoGuardar.Enabled = True Then Preguntar al usuario si quiere salvar If MsgBox(Guardar los cambios?, _ 36, Abrir documento) = vbYes Then Guardar End If End If Tipos de archivos que se pueden abrir cdlDialogo.Filter = Archivos de texto (*.txt)|*.txt Mostrar cuadro de dilogo Abrir
92 Curso
cdlDialogo.ShowOpen Comprobar que no se cancel la accin If cdlDialogo.FileName <> Then Abrir el archivo para lectura Open cdlDialogo.FileName For Input As #1 txtTexto.Text = Input(FileLen(cdlDialogo.FileName), #1) Close #1 mnuArchivoGuardar.Enabled = False tbrOfimatica.Buttons(3).Enabled = False End If End Sub Private Sub Nuevo() If mnuArchivoGuardar.Enabled = True Then Preguntar al usuario si quiere salvar If MsgBox(Guardar los cambios?, _ 36, Nuevo documento) = vbYes Then Guardar End If End If Borrar texto txtTexto.Text = Desactivar botones DesactivarFunciones End Sub Asimismo, y para terminar, debemos programar (en esta ocasin desde cero) la salida del programa por medio de la opcin Cerrar del men Archivo. En esta ocasin, y si procede, tambin preguntaremos al usuario si desea salvar los cambios antes de salir, del mismo modo que lo hacamos en los casos anteriores. Fin del proyecto Aprovecharemos el fin de la creacin del editor de textos para dar un nuevo enfoque a la seccin de programacin. Con el fin de profundizar en las posibilidades de Visual Basic en la informtica domstica y evitar los problemas de adquisicin del compilador por parte de algunos lectores, a partir del
Visual Basic 6.0 93
prximo captulo nos centraremos en la programacin de macros para las herramientas de Microsoft Office. Para seguir esta nueva temtica del curso no necesitaremos un compilador, ya que el cdigo de las macros lo interpreta directamente la aplicacin (Excel, Word, Access, etc.) de modo que bastar con que contemos con la propia aplicacin (que ya cuenta con su propio editor de Visual Basic).
94
Curso
Captulo 11
Macros en Microsoft Excel
Como avanzbamos en el captulo anterior, a partir de este captulo daremos un nuevo enfoque a la seccin de programacin, centrndonos concretamente en el campo de las macros para las herramientas ofimticas de Microsoft.
Qu son las macros?
Si en su da elegimos Visual Basic para la realizacin de este curso, desde luego no lo hicimos por tratarse del lenguaje de programacin ms potente del mercado ya que, al menos hasta el reciente lanzamiento de Visual Basic .NET no poda compararse a los lenguajes de programacin orientados a obVisual Basic 6.0 95
jetos (C++ o Delphi, por ejemplo) en este aspecto. Lo que ofreca Visual Basic en detrimento del resto de lenguajes era su sencillez didctica por un lado y, principalmente, su aplicabilidad en la informtica domstica por otro. Centrndonos en este segundo aspecto, aquellos que hayan seguido el curso de manera regular se encuentran en disposicin de empezar a programar instrucciones sobre documentos de los principales programas de Microsoft Office con el fin de automatizar los procesos que nos resulten ms tediosos. Las macros son, a fin de cuentas, procedimientos (realizados en Visual Basic) donde deben concentrarse estas instrucciones. El objeto Worksheet Una de las principales novedades con las que nos encontraremos al trabajar con las macros de Excel es el objeto Worksheet. Este objeto no es ms que una hoja de clculo del total de las hojas que forman el documento XLS (el libro). Para soportar el trabajo con varias hojas utilizaremos el array Worksheets, formado por la coleccin total de hojas del libro. Para acceder a cada una de esas hojas, usaremos un ndice numrico, correspondiente a la posicin que ocupa la hoja dentro del libro (siguiendo el orden establecido por las pestaas). Como ya os habris dado cuenta, aunque necesitaremos este objeto como base de la programacin de las hojas de clculo, necesitaremos precisar un poco este concepto para trabajar con ms precisin. Por ello, cada objeto Worksheet est formado a su vez por otros objetos y un conjunto de mtodos y propiedades. As, para referirnos a una o varias celdas de la hoja, utilizaremos el objeto Range, que necesita como parmetros un String (recordad que si pasamos directamente el argumento, sin utilizar una variable, la cadena debe ir entre comillas) con las coordenadas de la seleccin. A su vez, este objeto cuenta con otra serie de mtodos y propiedades (Offset, por ejemplo, que devuelve un nuevo rango desplazando un nmero de filas y columnas que se pasan por referencia). A medida que vayamos profundizando en las macros a travs de ejercicios prcticos, iremos conociendo el uso de estos y otros objetos. que se pasan por referencia). A medida que vayamos profundizando en las macros a travs de ejercicios prcticos, iremos conociendo el uso de estos y otros objetos. Trabajando con los colores
96
Curso
Al margen de estos aspectos, propios de las hojas de clculo de Microsoft Excel y sus macros, el lenguaje de programacin seguir siendo Visual Basic a todos los efectos. As por ejemplo, para facilitar el trabajo con los colores, Visual Basic cuenta con la funcin RGB (Red, Green, Blue) que necesita como parmetros tres nmeros enteros entre 0 y 255, correspondientes a la intensidad de color del rojo, verde y azul respectivamente. La funcin devuelve un valor de tipo Long que Visual Basic puede trabajar. De este modo, para aplicar el color azul al texto de una celda referenciada a partir de la celda A1 con el mtodo Offset, se utilizara el siguiente cdigo: Worksheets(1).Range("a1").Offset(PosMax, 0).Font.Color = RGB(0, 0, 256)
Nivel de seguridad Dado que, como decamos, con las macros de Microsoft Office se puede hacer casi cualquier tarea de programacin, es necesario que, antes de abrir un documento contenedor de macros con cualquiera de las herramientas del paquete ofimtico, de algn modo se nos advierta de los peligros que podemos correr al permitir la ejecucin de esas instrucciones en nuestro PC, ya que algunas instrucciones podran contener accesos a partes delicadas de nuestro sistema (los archiconocidos virus) o, por estar incorrectamente programadas, ejecutar bucles infinitos que podran bloquear nuestra mquina. Sobre este aspecto, la solucin ofrecida por Microsoft es bastante complaciente (polticamente hablando) ya que ofrece opciones para todos los gustos. Para los ms precavidos, la solucin es utilizar un nivel de confianza alto, asegurndose as de que tan slo se ejecutarn las macros que procedan de fuentes de confianza (definidas en una lista especfica), deshabilitando
Visual Basic 6.0 97
las del resto de documentos. Para los despreocupados, o aquellos que slo abran documentos propios o de fuentes fiables, el nivel de seguridad ms aparente es el bajo, que acepta automticamente todas las macros, independientemente del autor de las mismas. Por ltimo, el nivel de seguridad recomendado desde estas lneas y ms acorde con la mayora de los usuarios, es el medio, alertando al usuario, antes de abrir el documento, de la presencia de macros en el mismo, de modo que en cada caso se pueda elegir entre la habilitacin o inhabilitacin de las macros del archivo. Para acceder al dilogo de modificacin de las propiedades, pulsamos sobre el men Herramientas y, a continuacin, sobre Opciones. En la pantalla desplegada, pulsamos sobre la pestaa Seguridad y posteriormente sobre el botn de comando Seguridad de macros, tras lo que se despliega el formulario de seleccin del nivel de seguridad.
98
Curso
A continuacin escribimos el cdigo de la macro, que buscar las celdas de la hoja donde se encuentran los valores mnimo y mximo en la primera columna, almacenando en sendas variables (PosMin y PosMax respectivamente) el nmero de filas por debajo de la celda a1 (primer parmetro del mtodo Offset) donde se encuentran esos valores para posteriormente ser coloreados (en rojo el mnimo y en azul el mximo). Antes de realizar estas instrucciones, durante el proceso de bsqueda de los valores y sus posiciones, se vuelve a especificar el color negro para cada una de las celdas con el fin de evitar que, tras modificaciones relevantes de la serie, puedan aparecer varios resultados sealados. El cdigo de la macro podra ser el siguiente: Sub maxymin() Dim i As Integer Dim PosMin As Integer Dim PosMax As Integer 'inicializar variables PosMin = 0 PosMax = 0 i=1 'inicializar el color del texto de la 'primera celda Worksheets(1).Range("a1").Font.Color = RGB(0, 0, 0) 'buscar la posicin de los valores 'mximos y mnimos 'y restaurar el color de las celdas Do Until IsEmpty(Worksheets(1).Range("a1").Offset(i, 0)) Worksheets(1).Range("a1").Offset(i, 0).Font.Color = RGB(0, 0, 0) If Worksheets(1).Range("a1").Offset(i, 0).Value < _ Worksheets(1).Range("a1").Offset(PosMin, 0).Value Then PosMin = i Else 'No pueden darse los dos casos If Worksheets(1).Range("a1").Offset(i, 0).Value > _ Worksheets(1).Range("a1").Offset(PosMax, 0).Value Then PosMax = i End If End If i=i+1
Visual Basic 6.0 99
Loop 'resaltar los valores mximos y mnimos Worksheets(1).Range("a1").Offset(PosMin, 0).Font.Color = RGB(256, 0, 0) Worksheets(1).Range("a1").Offset(PosMax, 0).Font.Color = RGB(0, 0, 256) End Sub Una vez creado el procedimiento, podemos ejecutarlo cuantas veces queramos invocando a la macro a travs del dilogo Macro de Microsoft Excel o bien con el comando Ejecutar (o con la tecla F5 del teclado) en el propio editor. En el primero de los casos, con la secuencia de men Herramientas/Macro/Macros accedemos al dilogo Macro donde aparece un listado con todos los procedimientos disponibles en el documento en curso. Tan slo tenemos que seleccionar aquel que queremos ejecutar y las instrucciones sern interpretadas (a diferencia de los programas convencionales ya compilados, las macros se interpretan instruccin a instruccin durante la ejecucin, de modo que localiza todos los errores en tiempo de ejecucin ya que no existe el proceso de compilacin). Para ejecutar la macro a travs del editor, debemos tener presente que el procedimiento que se ejecutar ser aquel que est activo en la ventana de cdigo.
100
Curso
Captulo 12
Bsqueda y ordenacin (1 parte)
Con este captulo del curso nos introduciremos en uno de los temas ms apasionantes del aprendizaje de programacin: bsqueda y ordenacin de listas. Para ello, utilizaremos la programacin de macros de Visual Basic.
Todo programador que se precie ha tenido que vrselas alguna vez con una lista (entendiendo por lista una coleccin lineal de elementos de un mismo tipo) en la que deba hacer una bsqueda, una insercin respetando un orden o una ordenacin completa. Para aprender a solucionar estos problemas y, lo que es ms, para hacerlo de la forma ms eficiente posible, os recomendamos seguir atentamente este captulo del curso de programacin. Eficiencia Antes de empezar a hablar de la bsqueda de elementos y la ordenacin de listas, es recomendable detenerse un instante ante el concepto de eficiencia. Informticamente hablando, la eficiencia de un algoritmo es una medida de su calidad desde el punto de vista de la implementacin. A primera vista, podra decirse que la eficiencia de un algoritmo es algo as como su velocidad de ejecucin, de modo que un algoritmo es ms eficiente si, bajo las mismas condiciones, se ejecuta en un menor espacio de tiempo que otro algoritmo diseado para realizar la misma funcin. A poco experimentado que se sea en el mundo de la informtica, todo el mundo sabe que el tiempo real que una aplicacin tarda en ejecutar alguna de sus partes vara en funcin de muchos parmetros: caractersticas de la mquina en que se ejecuta (procesador, memoria, r.p.m. del disco duro, etctera), sistema operativo instalado en el equipo, cantidad de memoria RAM disponible en ese momento y un interminable nmero de variables ms. Por ello, la eficiencia se mide en funcin del diseo del algoritmo y no en funcin del tiempo real de ejecucin.
Visual Basic 6.0 101
Bsquedas en listas ordenadas Todo el mundo, programador o no, sabe lo que es una bsqueda en una lista. De hecho, todos los das realizamos bsquedas de este tipo, ya sea para localizar los apuntes en una carpeta o una pgina de un libro. La diferencia entre estas dos bsquedas (al menos en mi caso) es que mientras los apuntes se encuentran distribuidos aleatoriamente en mi carpeta, las pginas de los libros se ordenan de menor a mayor, de modo que resulta muy sencillo localizar cualquier pgina del libro. Para terminar de entender el concepto de eficiencia podramos plantear el ejemplo de la bsqueda de una pgina concreta en un libro: una bsqueda sera eficiente si, partiendo de una pgina que localizar, se abriese el libro por la mitad y, en funcin de que el nmero de pgina buscado fuese menor o mayor (la posibilidad de que fuese igual debera contemplarse en alguno de los casos) que el nmero de pgina desplegado, se repetira la apertura en la primera o la segunda mitad respectivamente, y as sucesivamente hasta localizar la pgina objetivo; la bsqueda no sera eficiente si, partiendo de la primera hoja del libro se pasase a la siguiente hoja hasta encontrar la pgina objetivo. En la siguiente tabla podemos observar el nmero exacto de operaciones que realizar en el primer caso y el nmero aproximado en el segundo, en funcin del nmero de pginas del libro: Despus de este ejemplo, resulta ms fcil entender la importancia de programar pensando no slo en nuestra comodidad, sino tambin en lo ms beneficioso para nuestro programa, ya que, si un algoritmo mal programado puede pasar desapercibido en un programa, un cmulo de ineficiencias (a mayor nmero de lneas de cdigo, mayor probabilidad de introducir errores) puede provocar una ejecucin deficiente de la aplicacin. Como es fcil entender, la nica manera de localizar un elemento en una lista no ordenada es recorrer toda la lista de manera secuencial (un elemento tras otro) hasta encontrar el objetivo.
102
Curso
Ordenacin de listas Si ya resulta de por s importante prestar una especial atencin a la hora de programar las bsquedas, ni qu decir tiene lo delicado que resulta disear un algoritmo eficiente para la ordenacin de los elementos de una lista. De hecho, algunas de las tcnicas de ordenacin de listas se basan en algoritmos de bsqueda. Por poner un ejemplo, una tcnica consiste en, entendiendo que el primer elemento de la lista est ordenado, coger el primer elemento de la parte no ordenada, buscar su posicin idnea en la parte ordenada, insertar el elemento en esa posicin y repetir el proceso hasta que toda la coleccin quede ordenada. Otro de los algoritmos ms conocidos utiliza la permutacin de elementos contiguos, si procede, hasta llegar a ordenar toda la lista.
de ellos corresponde a la insercin independiente de una celda en la posicin en la que se encuentre la celda activa en la que se inserta un valor, que se pasa como parmetro. Como novedad en este subprograma, se utiliza el objeto Selection, correspondiente en la hoja a la seleccin actual de celdas (normalmente la celda activa) y su mtodo Insert (al que se le pasa como parmetro el tipo de desplazamiento de las celdas afectadas) para poder realizar la insercin de una nueva celda. El cdigo de este procedimiento es el siguiente: Private Sub Insertar(Valor As Variant) Insertar celda en la posicin actual y desplazar hacia abajo Selection.Insert shift:=xlDown Insertar Valor en la nueva celda ActiveCell.Value = Valor End Sub La bsqueda, en esta ocasin, la realizaremos de forma secuencial para facilitar la comprensin del cdigo. En este mismo mdulo insertamos la subrutina BusquedaSecuencial, que tambin necesita el valor que buscar como parmetro. Este procedimiento, tambin de carcter privado, tiene un modo especial de realizar el rastreo de las celdas: en lugar de utilizar una referencia (mtodo Offset) a una celda anclada, compara la celda activa y, en cada iteracin, activa la celda inferior a la actual. Despus, una vez localizada la posicin en la que debe insertarse el valor, se invoca al procedimiento Insertar. El cdigo de esta subrutina es el siguiente: Private Sub BusquedaSecuencial(Valor As Variant) Definir variable booleana Dim Encontrado As Boolean Activar al celda B1 ActiveSheet.Range(b1).Activate Inicializar variable booleana Encontrado = False Mientras la celda activa no est vaca y no se ha encontrado la posicin Do While Not (IsEmpty(ActiveCell)) _ And (Not Encontrado)
104 Curso
Si encontramos la posicin If ActiveCell.Value >= Valor Then Llamada a procedimiento Valor Insertar (Valor) Sealar que se ha encontrado la posicin para el valor Encontrado = True Si no se ha encontrado la posicin Else Activar la celda inferior ActiveCell.Offset(1, 0).Activate End If Loop Si se sale del bucle sin encontrar la posicin es porque el valor es mayor que todos los de la segunda columna If (Not Encontrado) Then Insertar el valor al final Insertar (Valor) End If End Sub Por ltimo, insertamos el procedimiento principal de la aplicacin. Para que este procedimiento pueda ser llamado desde el men de macros del documento de Excel, es necesario que lo declaremos como pblico. Lo nico que hace este procedimiento es recorrer la primera columna de la hoja de clculo (hasta encontrar un hueco), mientras que para cada uno de los valores de la columna se realiza una llamada a la subrutina de bsqueda. Con el fin de estandarizar, en la medida de lo posible, esta prctica, hemos definido el parmetro Valor de todos los procedimientos como tipo Variant, si bien conviene comparar valores del mismo tipo. Como es lgico, el recorrido de esta columna se hace referencialmente, pues si utilizase la activacin de celdas hara que este procedimiento entrase en conflicto con el de bsquedas. Con todo esto, el cdigo final de este procedimiento, que tambin ira insertado en el nuevo mdulo, sera el siguiente: Public Sub Ordenar() Definir variable contador de filas
Visual Basic 6.0 105
Dim Fila As Integer Iniciar variables Fila = 0 Mientras haya datos en la primera columna Do Until IsEmpty(ActiveSheet. _ Range(a1).Offset(Fila, 0)) Llamar a BusquedaSecuencial con el valor de la celda correspondiente BusquedaSecuencial (ActiveSheet. _ Range(a1).Offset(Fila, 0).Value) Incrementar la variable De no hacerlo entraramos en un bucle infinito Fila = Fila + 1 Loop End Sub El ltimo paso de esta prctica sera pensar el modo de mejorar la eficiencia del procedimiento BusquedaSecuencial. La solucin es la bsqueda dicotmica, explicada anteriormente, consistente en dividir la bsqueda a la mitad en cada iteracin. En el prximo captulo del curso daremos la solucin basada en este tipo de bsqueda.
106
Curso
Captulo 13
Bsqueda y ordenacin (2 parte)
Para finalizar la parte del curso correspondiente a la bsqueda, ordenacin e introduccin a la eficiencia, completaremos la explicacin iniciada en captulo anterior y en la parte prctica, realizaremos un programa relacionado.
En el captulo anterior del curso de programacin realizamos un sencillo subprograma que generaba en la columna B de la hoja de clculo una copia ordenada de la primera columna. Adems, propusimos que vosotros mismos trataseis de buscar una manera ms eficiente de realizar esa misma funcin. En este captulo daremos una solucin a esa proposicin y explicaremos todos aquellos detalles que, a raz de ello, puedan ir apareciendo. Realizamos un sencillo subprograma Algoritmo de bsqueda binaria o dicotmica Aquellos que hayan realizado el paso a paso del captulo anterior, habrn podido comprobar que para ordenar una columna con el algoritmo propuesto, el ordenador necesita emplear una gran cantidad de tiempo que aumenta exponencialmente a medida que crece el nmero de elementos a ordenar (pues debe buscar entre ms elementos). Obviamente, el tiempo empleado tambin aumentar si las caractersticas del equipo son sensiblemente inferiores. De todos modos, y como ya avanzamos en el pasado captulo, el modo en que programamos dicha ordenacin no es, ni mucho menos, el idneo, ya que existen otros algoritmos muchsimo ms eficientes. Unos de esos algoritmos, de los ms utilizados, es el algoritmo de bsqueda binaria (tambin denominado de bsqueda dicotmica) que en cada iteracin divide en 2 el tamao de la lista. Es por eso que, frente a la reduccin de tan slo un elemento (tcnica utilizada en la bsqueda secuencial) el tiempo empleado en este tipo de bsqueda se reducir sustancialmente. As, a la hora de programar la bsqueda dicotmica debemos tener en cuenta, principalmente, en qu mitad de la lista hemos de seguir buscando, para lo que utilizareVisual Basic 6.0 107
mos 3 variables con las que apuntaremos a los extremos del segmento de lista en el que buscamos, as como el punto central. En el momento que ambos extremos coincidan nos encontraremos exactamente en la posicin donde debemos insertar el elemento.
Valores aleatorios Otra de las funciones que veremos en la parte prctica de este captulo del curso es la generacin de valores aleatorios. Lo ms lgico al hablar de mquinas es dudar de su capacidad de generar valores equiprobables, puesto que sea como sea, siempre han de basarse en un dato real de la mquina. Para solucionar este inconveniente, Visual Basic, al igual que la inmensa mayora de los lenguajes de programacin, hace una lectura del reloj de la mquina para tomar el valor semilla sobre el que se trabajar. Para ello, es necesario realizar una llamada a la instruccin Randomize de Visual Basic. Una vez hecho esto, ya podemos obtener nmeros aleatorios por medio de la funcin Rnd. Esta funcin no requiere argumentos (si bien es opcional para casos especficos) y devuelve un nmero de tipo single siempre menor que 1 y mayor o igual que 0. De este modo, si lo que queremos es generar nmero enteros aleatorios, para cada uno debemos utilizar una expresin como la siguiente:
108 Curso
CInt((Lmite_superior - lmite_inferior + 1) * Rnd + lmite_inferior) donde lmite inferior es el menor entero esperado y lmite superior el mayor posible. Por otro lado, la funcin CInt devuelve un nmero entero en funcin del argumento. Trabajando con cadenas de caracteres En el paso a paso que realizaremos a continuacin haremos el clculo de unos tiempos que despus deberemos mostrar al usuario. Como ya hicimos con el editor de textos, estos datos los mostraremos utilizando un cuadro de mensaje (MsgBox). Para refrescar conceptos, recordaremos la frmula de la funcin MsgBox: MsgBox(texo,botones,ttulo) donde tanto texto como ttulo son cadenas de caracteres. En el caso que nos ocupa, los resultados que mostraremos son tiempos almacenados en variables de tipo Date que hemos de convertir en un string. De manera similar a lo que ocurra con la conversin a enteros, Visual Basic dispone de la funcin CStr que convierte cualquier tipo de dato en una cadena de caracteres. Posteriormente, para unir varias cadenas de caracteres en una nica expresin, utilizaremos el operador binario +, que concatena ambos string en una nica expresin. Como se puede observar, en el cuadro de mensaje utilizado en el siguiente paso a paso utilizamos la constante VbCrLf para insertar un retorno de carro y la correspondiente ubicacin del puntero al inicio de lnea (equivalente a pulsar la tecla Intro del teclado) como un string ms. Conclusin El objetivo de esta leccin del curso va ms all de la mera exposicin de los tipos de bsqueda ms utilizados en programacin. La moraleja que debe quedarnos de estas lneas es que, tan importante como conseguir que el programa resuelva un problema, es que lo haga de una manera eficiente.
Activar la celda inferior ActiveCell.Offset(1, 0).Activate End If Loop Si se sale del bucle sin encontrar la posicin es porque el valor es mayor que todos los de la segunda columna If (Not Encontrado) Then Insertar el valor al final Insertar (Valor) End If End Sub Public Sub Ordenar() Definir variable contador de filas Dim Fila As Integer Iniciar variables Fila = 0 Mientras haya datos en la primera columna Do Until IsEmpty(ActiveSheet. _ Range(a1).Offset(Fila, 0)) Llamar a BusquedaSecuencial con el valor de la celda correspondiente BusquedaSecuencial (ActiveSheet. _ Range(a1).Offset(Fila, 0).Value) Incrementar la variable De no hacerlo entraramos en un bucle infinito Fila = Fila + 1 Loop End Sub Private Sub BusquedaDicotomica _ (Valor As Variant, ByVal Superior As Integer) La variable Superior indica el nmero de eltos ordenados de la lista Dim Inferior As Integer
Visual Basic 6.0 111
Dim Aux As Variant Dim Central As Integer Entendemos que el primer elto tiene la posicin 0 Inferior = 0 Mientras Superior > Inferior Do While Superior > Inferior Asignamos a Central el pto medio de la parte actual de la lista Central = CInt(Superior + Inferior) / 2 Aux toma el valor de la posicin Central Aux = ActiveSheet.Range(c1).Offset(Central, 0).Value Si Valor>Aux tomamos la mitad superior If Aux < Valor Then Inferior = Central + 1 Else Si Valor<Aux tomamos la mitad inferior If Aux > Valor Then Superior = Central - 1 Si coinciden terminamos Else Superior = Central Inferior = Central End If End If Loop ActiveSheet.Range(c1).Offset(Inferior, 0).Activate Si el valor buscado ha de ir en la celda activa insertamos el valor en ese punto If (Valor <= ActiveCell.Value) Or _ IsEmpty(ActiveCell) Then Insertar (Valor) Sino lo insertamos en el siguiente Else ActiveCell.Offset(1, 0).Activate Insertar (Valor) End If End Sub
112 Curso
Public Sub Ordenar2() Definir variable contador de filas Dim Fila As Integer Iniciar variables Fila = 1 ActiveSheet.Range(c1).Value = ActiveSheet.Range(a1).Value Mientras haya datos en la primera columna Do Until IsEmpty(ActiveSheet. _ Range(a1).Offset(Fila, 0)) Llamar a BusquedaSecuencial con el valor de la celda correspondiente Call BusquedaDicotomica(ActiveSheet. _ Range(a1).Offset(Fila, 0).Value, Fila - 1) Incrementar la variable De no hacerlo entraramos en un bucle infinito Fila = Fila + 1 Loop End Sub Public Sub RellenoAleatorio() Dim i As Integer Inicializar la aleatoriedad Randomize Para insertar 500 valores For i = 0 To 500 ActiveSheet.Range(a1).Offset(i, 0).Value = _ CInt(500 * Rnd) Next End Sub Public Sub ComparacionAlgoritmos()
Visual Basic 6.0 113
Dim TiempoSecuencial As Date Dim TiempoDicotomica As Date Dim Resultado As Integer Rellenar datos RellenoAleatorio Tomar instante de inicio de procedimiento TiempoSecuencial = Time Realizar la ordenacin secuencial Ordenar Calcular el tiempo empleado TiempoSecuencial = Time - TiempoSecuencial Tomar instante de inicio de procedimiento TiempoDicotomica = Time Realizar la ordenacin dicotmica Ordenar2 Calcular el tiempo empleado TiempoDicotomica = Time - TiempoDicotomica Mostrar el resultado con un cuadro de mensaje Resultado = MsgBox(Secuencial= + CStr(TiempoSecuencial) _ + vbCrLf + Dicotmica= + CStr(TiempoDicotomica), vbOKOnly, _ Tiempos empleados) End Sub Para realizar la comparacin de tiempos, es necesario que las tres primeras columnas de la hoja de clculo se encuentren completamente vacas para posteriormente ejecutar el procedimiento (Herramientas/Macro/Macros) Comparacin/Algoritmos.
114
Curso
Captulo 14
Controles y formularios en las hojas de clculo
Como lenguaje de programacin visual que es, Visual Basic nos va a permitir insertar controles y formularios en las hojas de clculo para hacer visualmente ms atractivas nuestras macros.
Nadie discutir que, por muy eficaz que sea, todo programa resulta muchsimo ms atractivo con un buen diseo. Basndonos en los criterios para hacer ms efectivos nuestros formularios que ya explicamos en los primeros captulos del curso, nos ha llegado la hora de aprender a insertar los controles ms comunes en los documentos de Excel para hacer que nuestras macros sean an ms efectivas. Con lo visto a lo largo del curso, todos los controles que utilizbamos iban insertados en formularios. Esto ocurra, entre otras cosas, porque no contbamos con otros objetos que fuesen capaces de contener dichos controles. En esta ocasin, veremos que las hojas de clculo pueden contener controles al igual que ocurra con los formularios, si bien, en muchas ocasiones, resultar ms cmodo seguir utilizando formularios para realizar algunas de las tareas ms cotidianas.
Apellidos en la B2, y Entidad, Oficina, Control y Nmero de cuenta en las celdas C2, D2, E2 y F2 respectivamente; despus, combinamos y centramos las celdas A1 y B1 por un lado y C1, D1, E1 y F1 por otro. Para finalizar la preparacin del documento, podemos modificar el tamao de las columnas que ubicarn cada uno de los campos, cambiar el formato del texto, aadir lneas y bordes, etc. Despus de esto, para que nos resulte ms cmodo el trabajo con controles, lo ms recomendable es mostrar las barras de herramientas relacionadas con el trabajo que nos ocupa. Para ello, activamos las entradas Cuadro de controles y Visual Basic de submen Barras de herramientas en el men Ver. La primera de ellas contiene una coleccin de controles bsicos de Visual Basic con los que nos resultar ms sencillo aadir funcionalidad a la hoja de clculo, as como un botn que nos muestra u oculta las propiedades del control activo y otro para entrar y salir del Modo de Diseo (aquel en el que podemos insertar y modificar los controles sobre la hoja de clculo). Hasta ahora, para poder ejecutar una macro, tenamos que acudir al dilogo Macro, donde seleccionbamos aquella que queramos activar. En esta ocasin, lo que haremos, ser insertar un botn de comando en la propia hoja de clculo que, al ser pulsado, cargar el formulario que utilizaremos para insertar los datos. Para ello, lo primero que debemos hacer es pasar a Modo Diseo (a travs del botn correspondiente de cualquiera de las dos nuevas barras de herramientas). Ya en modo de diseo, seleccionamos el botn de comando de la barra de controles y dibujamos un botn en la hoja de clculo (fuera del rea de datos). Una vez dibujado, cambiamos a nuestro criterio sus propiedades con la nica condicin de que el nombre que reciba el botn sea
116 Curso
cmdTomarDatos. Estando en modo de diseo, con un doble clic sobre el control pasamos a la ventana de Microsoft Visual Basic (concretamente al cdigo de la hoja 1 del libro) donde tendremos que aadir la sentencia fmrTomarDatos.Show al cdigo del procedimiento asociado al evento Click del botn. Dicho procedimiento ha de quedar del siguiente modo: Private Sub cmdTomarDatos_Click() Al pulsar el botn mostrar el formulario frmTomarDatos.Show End Sub Ahora debemos insertar un formulario en el proyecto, aadirle los controles necesarios y programarlos correctamente. Para ello, debemos acudir a la ventana de Microsoft Visual Basic (si nos encontramos ante la hoja de clculo pulsamos el botn Editor de Visual Basic de la barra de herramientas Visual Basic). Una vez all, aadimos el formulario con la funcin UserForm del men Insertar. Para mostrar la ventana de propiedades de los formularios y los controles, basta con pulsar la tecla F4. En dicha ventana, adjudicamos al nuevo formulario el nombre frmTomarDatos. Dentro del nuevo formulario hemos de insertar una serie de controles a los que cada uno puede dar su toque personal. Para que el cdigo propuesto funcione correctamente es imprescindible insertar 6 cuadros de texto con los nombres txtNombre, txtApellidos, txtEntidad, txtOficina, txtControl y txtCuenta. Es recomendable utilizar etiquetas para que el usuario pueda distinguirlos. Tambin es necesario aadir 2 botones de comando con los nombres cmdAceptar y cmdTerminar. Para que la movilidad por el formulario sea ptima, es recomendable utilizar el siguiente orden de tabulacin: Por ltimo, tan slo tenemos que aadir el cdigo del formulario que, como podris observar, interacta continuamente con la hoja de clculo: Forzamos la declaracin de variables Option Explicit
Visual Basic 6.0 117
Private Sub UserForm_Activate() Activamos la primera celda susceptible de contener datos ActiveSheet.Range(a3).Activate Buscamos la primera fila sin datos en la columna nombre Do While Not IsEmpty(ActiveCell) ActiveCell.Offset(1, 0).Activate Loop End Sub Private Sub cmdAceptar_Click() Antes de ingresar los datos comprobamos que sean correctos ValidarCampos End Sub Private Sub cmdTerminar_Click() Descargamos el formulario Unload frmTomarDatos End Sub Private Sub txtEntidad_Change() Al escribir los 4 dgitos de la entidad pasamos al siguiente campo If Len(txtEntidad.Text) = 4 Then txtOficina.SetFocus End If End Sub Private Sub txtOficina_Change() Al escribir los 4 dgitos de la oficina pasamos al siguiente paso If Len(txtOficina.Text) = 4 Then txtControl.SetFocus End If End Sub Private Sub txtControl_Change()
118 Curso
Al escribir los 2 dgitos de control pasamos al siguiente campo If Len(txtControl.Text) = 2 Then txtCuenta.SetFocus End If End Sub Private Sub txtCuenta_Change() Al escribir los 10 dgitos del nmero de cuenta situamos el foco sobre el botn cmdAceptar If Len(txtCuenta.Text) = 10 Then cmdAceptar.SetFocus End If End Sub Private Sub ValidarCampos() Declaramos el procedimiento como privado porque es especfico del formulario Declaramos una variable de tipo String Dim Error As String Dim ValorMensaje As Integer Inicializamos el valor del mensaje de error Error = Error en los datos del formulario Si el campo Nombre est vaco If Len(txtNombre.Text) = 0 Then Mostramos mensaje de error ValorMensaje = MsgBox(El campo Nombre est vaco, _ vbOKOnly, Error) Situamos el foco sobre el campo Nombre txtNombre.SetFocus Else Si el campo Apellidos est vaco If Len(txtApellidos.Text) = 0 Then Mostramos el mensaje de error ValorMensaje = MsgBox _ (El campo Apellidos est vaco, vbOKOnly,
Visual Basic 6.0 119
Error) Situamos el foco sobre el campo Apellidos txtApellidos.SetFocus Else Si no hubo fallos insertamos With ActiveCell Sobre la celda activa el Nombre .Value = txtNombre Sobre la de la columna siguiente los apellidos .Offset(0, 1).Value = txtApellidos 2 columnas despus de la activa el cdigo de la entidad .Offset(0, 2).Value = txtEntidad 3 columnas despus de la activa el cdigo de la oficina .Offset(0, 3).Value = txtOficina a continuacin el de control .Offset(0, 4).Value = txtControl y por ltimo el de la cuenta .Offset(0, 5).Value = txtCuenta End With Pasamos a la siguiente fila por si se ingresan ms datos ActiveCell.Offset(1, 0).Activate Borramos el formulario BorrarFormulario End If End If End Sub Private Sub BorrarFormulario() Ponemos la cadena vaca a todos los campos txtNombre.Text = txtApellidos.Text = txtEntidad.Text = txtOficina.Text = txtControl.Text = txtCuenta.Text = Situamos el foco en el campo Nombre txtNombre.SetFocus
120 Curso
End Sub Propuesta Como objetivo antes del prximo captulo del curso, deberemos tratar de validar los 4 campos numricos de la cuenta, de modo que si el usuario escribe un carcter no numrico en cualquiera de ellos el ordenador emita un sonido y desprecie dicho carcter. Tambin habr que controlar el tamao de los campos de modo que los 4 numricos estn vacos o contengan los 20 nmeros de la cuenta correctamente repartidos. Como ayuda, si recordis, algo parecido a la primera parte de la propuesta ya lo resolvimos en la calculadora de euros. Por ltimo, debemos tener en cuenta que para que el botn de comando cmdTomarDatos sea operativo hemos de salir del modo de diseo.
121
122
Curso
Captulo 15
Controles y formularios (2)
A pesar de lo atractivos que resultan los complementos grficos en los programas, la obligacin de un programador es prestar especial atencin a la funcionalidad. En el programa que empezamos a elaborar el pasado captulo, qued pendiente la validacin de los campos numricos, tarea que trataremos de solucionar a continuacin.
Lo que haremos en este paso a paso ser presentar una posible solucin a la propuesta realizada en el captulo anterior del curso, que consista en validar los 4 campos numricos del Cdigo Cuenta Cliente. Antes de nada, debemos plantearnos en qu momento debe realizarse esa validacin, ya que cabra la posibilidad de asociarla a diferentes eventos de varios controles. Este aspecto pierde importancia si aadimos el cdigo correspondiente a la validacin de los campos numricos directamente en el subprograma ValidarCampos ya existente desde la versin anterior, independientemente del punto del programa principal desde el que se invoque a este procedimiento. Adems, a la hora de reutilizar cdigo modularizado, debemos tratar de que el nmero de lneas de cdigo en un nico subprograma no sea excesivo, por lo que, llegado el momento, podemos crear un nuevo subprograma. As, si partimos del cdigo del proyecto del pasado captulo, lo primero que haremos ser pasar a un nuevo procedimiento el cdigo que insertaba los datos validados en la hoja de clculo. Dicho procedimiento, que podemos incluir a continuacin del cdigo ya existente, quedara: Private Sub InsertarDatos() With ActiveCell
Visual Basic 6.0 123
Sobre la celda activa el Nombre .Value = txtNombre Sobre la de la columna siguiente los apellidos .Offset(0, 1).Value = txtApellidos 2 columnas despus de la activa el cdigo de la entidad .Offset(0, 2).Value = txtEntidad 3 columnas despus de la activa el cdigo de la oficina .Offset(0, 3).Value = txtOficina a continuacin el de control .Offset(0, 4).Value = txtControl y por ltimo el de la cuenta .Offset(0, 5).Value = txtCuenta End With Pasamos a la siguiente fila por si se ingresan ms datos ActiveCell.Offset(1, 0).Activate Borramos el formulario BorrarFormulario End Sub Obviamente, todo este cdigo deberamos sustituirlo en el procedimiento ValidarCampos por una llamada al nuevo procedimiento. Adems y ya concretando la solucin a la propuesta, podemos crear un nuevo subprograma que nos sirva para validar todos los datos numricos. Dicho subprograma podra devolver un valor lgico que indicase si el campo analizado es correcto o contiene errores. Lo que debera analizar sera si el texto de los cuadros de texto contiene slo nmeros y si su longitud es la adecuada. Aceptando estas premisas, el nuevo subprograma ha de ser una funcin (porque devuelve un valor) a la que debemos pasar 2 parmetros: un string correspondiente al texto introducido por el usuario y un entero que indique el nmero de caracteres que dicho campo debe contener. Teniendo esto claro, y a la espera de realizar ese nuevo subprograma, podramos aadir las llamadas a esa nueva funcin, a la que llamaremos NumeroValido, en el procedimiento ValidarCampos. As, un posible resultado final para el cdigo de ValidarCampos podra ser:
124 Curso
Private Sub ValidarCampos() Declaramos el procedimiento como privado porque es especfico del formulario Declaramos una variable de tipo String Dim Error As String Dim ValorMensaje As Integer Inicializamos el valor del mensaje de error Error = Error en los datos del formulario Si el campo Nombre est vaco If Len(txtNombre.Text) = 0 Then Mostramos mensaje de error ValorMensaje = MsgBox(El campo Nombre est vaco, _ vbOKOnly, Error) Situamos el foco sobre el campo Nombre txtNombre.SetFocus Else Si el campo Apellidos est vaco If Len(txtApellidos.Text) = 0 Then Mostramos el mensaje de error ValorMensaje = MsgBox _ (El campo Apellidos est vaco, vbOKOnly, Error) Situamos el foco sobre el campo Apellidos txtApellidos.SetFocus Else Comprobamos que los datos del nmero de cuenta sean correctos If Not NumeroValido(txtEntidad.Text, 4) Then Mostramos el mensaje de error ValorMensaje = MsgBox _ (El valor del campo Entidad no es correcto, vbOKOnly, Error) Situamos el foco sobre el campo Entidad txtEntidad.SetFocus ElseIf Not NumeroValido(txtOficina.Text, 4) Then Mostramos el mensaje de error ValorMensaje = MsgBox _ (El valor del campo Oficina no es correcto, vbOKOnly, Error) Situamos el foco sobre el campo Oficina txtOficina.SetFocus ElseIf Not NumeroValido(txtControl.Text, 2) Then
Visual Basic 6.0 125
Mostramos el mensaje de error ValorMensaje = MsgBox _ (El valor del campo Control no es correcto, vbOKOnly, Error) Situamos el foco sobre el campo Control txtControl.SetFocus ElseIf Not NumeroValido(txtCuenta.Text, 10) Then Mostramos el mensaje de error ValorMensaje = MsgBox _ (El valor del campo Numero de cuenta no es correcto, vbOKOnly, Error) Situamos el foco sobre el campo Numero de cuenta txtCuenta.SetFocus Else Si no hubo fallos insertamos InsertarDatos End If End If End If End Sub Del cdigo anterior, cabra destacar que en lugar de utilizar una anidacin natural de ramificadores (If, Else), empleamos el condicional ElseIf, que concatena el fin de una rama con el inicio de la siguiente. Adems, a la hora de finalizar las ramificaciones con End If, una nica instruccin cierra toda la estructura ElseIf. Esta forma de ramificar puede resultar ms sencilla que la convencional, pero conviene tener en cuenta que no todos los lenguajes de programacin permiten utilizar este tipo de estructuras. Para finalizar con la solucin a la propuesta, debemos programar la funcin NumeroValido. Tal y como habamos definido las llamadas a la funcin, la cabecera debera ser similar a la siguiente:
126 Curso
Private Function NumeroValido(ByVal Numero As String, _ ByVal Longitud As Integer) As Boolean Como puede observarse en este ejemplo, las variables se pasan por valor en lugar de por referencia. Esto se debe a que el objetivo de la funcin es analizar los datos, no modificarlos, aunque es cierto que al pasar los datos por valor se crean variables nuevas con los datos duplicados los cuales, mientras permanezca activa la funcin, estarn ocupando memoria. En caso de estar seguros de que el cdigo de la funcin no modificar los datos, podramos pasarlos por referencia, en cuyo caso el subprograma trabajara directamente con los datos originales. En cuanto al mtodo que utilizaremos para validar el cdigo, primero analizaremos si el texto recibido por la funcin (que se corresponde con el contenido de alguno de los cuadros de texto del CCC, ya que a partir de ellos se realiza la llamada) es numrico utilizando la funcin IsNumeric, propia de Visual Basic, que analiza un dato de cualquier tipo (la cadena Numero en este caso) y devuelve el valor True si encaja en un formato numrico y False en otro caso. Si el texto pasa esta primera criba, debemos asegurarnos de que el nmero sea entero (examinando que no contenga puntos ni comas con la funcin InStr, ya comentada en entregas anteriores) natural (contemplando la posibilidad de que contenga el signo -). Por ltimo, si Numero cumple todos los requisitos anteriores, tan slo tenemos que comprobar que su longitud coincida con el valor de la variable Longitud, para lo que utilizaremos la funcin Len, propia del lenguaje y que tambin comentamos en su momento. Un ejemplo del cdigo de la funcin NumeroValido podra ser: Private Function NumeroValido(ByVal Numero As String, _ ByVal Longitud As Integer) As Boolean Suponemos que el campo est correctamente rellenado NumeroValido = True Comprobamos que el string pasado sea numrico If Not IsNumeric(Numero) Then NumeroValido = False Else Si es un nmero nos aseguramos de que sea entero buscando comas y puntos y natural buscando el signo If (InStr(Numero, ,) 0) Or _
Visual Basic 6.0 127
(InStr(Numero, -)) Or _ (InStr(Numero, .) 0) Then NumeroValido = False Else Comprobamos la longitud del campo If Len(Numero) Longitud Then NumeroValido = False End If End If End If End Function Con el objetivo de mejorar el aspecto del formulario, podemos utilizar, entre otras opciones, los controles grficos que vimos en captulos anteriores. Una posibilidad es incluir un control de tipo imagen y asociarle un icono o un clipart relacionado. Para ello bastara con aumentar el tamao del formulario, elegir la opcin Imagen del cuadro de herramientas y dibujar un nuevo control. A este nuevo control le asociaremos la imagen en tiempo de diseo a travs de su propiedad Picture. El resto de opciones grficas quedar a gusto del diseador.
128
Curso
Captulo 16
Formato de bordes
Poco a poco, a lo largo del curso hemos ido conociendo los principios bsicos de programacin junto con algunos importantes conceptos ms avanzados (modularidad y eficiencia, por ejemplo). Con este captulo del curso de programacin, profundizaremos algo ms en el formato de las hojas de clculo.
129
La parte de cdigo reutilizable del proceso de seleccin y aplicacin de formato al conjunto de la tabla, consta de las instrucciones correspondientes a la seleccin de la tabla por proximidad con la celda activa, el borrado de todos los bordes anteriores y la aplicacin, a toda la tabla, de unos bordes simples. El subprograma utilizado debera ser un procedimiento (ya que no devuelve ningn valor) que, por ejemplo, requiera de 2 parmetros correspondientes a las coordenadas (hoja y celda) de la celda original (si bien podra prescindirse de estos parmetros y utilizar para esta tarea la celda activa). Una posible forma de programar este procedimiento, que debera escribirse en el nuevo mdulo, podra ser: Procedimiento que genera los bordes Public Sub Bordes(Hoja As Integer, casilla As String) Activar la hoja y la casilla pasadas como parmetros Worksheets(Hoja).Activate ActiveSheet.Range(casilla).Activate Seleccionar toda la regin adyacente a la celda activa ActiveCell.CurrentRegion.Select Para toda la seleccin eliminar bordes With Selection .Borders(xlDiagonalDown).LineStyle = xlNone .Borders(xlDiagonalUp).LineStyle = xlNone .Borders(xlEdgeLeft).LineStyle = xlNone .Borders(xlEdgeRight).LineStyle = xlNone .Borders(xlEdgeTop).LineStyle = xlNone .Borders(xlEdgeBottom).LineStyle = xlNone
130 Curso
.Borders(xlInsideVertical).LineStyle = xlNone .Borders(xlInsideHorizontal).LineStyle = xlNone End With Para el borde exterior izquierdo de la seleccin aplicamos una lnea fina continua de color negro With Selection.Borders(xlEdgeLeft) .LineStyle = xlContinuous .Weight = xlMedium .ColorIndex = xlAutomatic End With Para el borde exterior superior de la seleccin aplicamos una lnea fina continua de color negro With Selection.Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlMedium .ColorIndex = xlAutomatic End With Para el borde exterior inferior de la seleccin aplicamos una lnea fina continua de color negro With Selection.Borders(xlEdgeBottom) .LineStyle = xlContinuous .Weight = xlMedium .ColorIndex = xlAutomatic End With Para el borde exterior derecho de la seleccin aplicamos una lnea fina continua de color negro With Selection.Borders(xlEdgeRight) .LineStyle = xlContinuous .Weight = xlMedium .ColorIndex = xlAutomatic End With
Visual Basic 6.0 131
Si la seleccin est compuesta por ms de una columna aplicamos una lnea fina continua para separarlas If Selection.Columns.Count > 1 Then With Selection.Borders(xlInsideVertical) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With End If End Sub Una vez que hemos abstrado parte del cdigo, debemos plantearnos desde qu punto del programa debe realizarse la aplicacin del nuevo formato. Una posibilidad sera aadir un nuevo botn de comando en la hoja de clculo o en el formulario existente, a travs del cual se invocase al cdigo encargado de aplicar el formato. Como lo que parece ms lgico es aplicar el formato a los bordes de la tabla cada vez que esta se modifica, otra posibilidad, por la que apostamos desde aqu, es realizar esta tarea automticamente cada vez que se aadan nuevas entradas a la tabla, de modo que, salvo cuando el formulario se encuentre operativo, la tabla siempre se presente en perfectas condiciones. Para ello, al final del cdigo del formulario fmrTomarDatos aadimos un nuevo procedimiento (asociado al evento Terminate del mismo, que se produce en el momento de cerrarlo) que contenga la llamada al procedimiento Bordes (al que hemos de pasar las coordenadas de cualquier celda perteneciente a la tabla, aunque preferiblemente de una de las del ttulo) y a continuacin, el cdigo especfico a la aplicacin de la tabla con la que trabajamos. El cdigo utilizado podra ser la siguiente: Private Sub UserForm_Terminate() Justo al cerrar el formulario llamar al procedimiento Bordes al que pasamos como parmetros la hoja 1 del
132 Curso
libro y la casilla A1 Call Bordes(1, a1) APLICAR FORMATO ESPECIAL A LAS 2 PRIMERAS FILAS Seleccionamos las 2 primeras filas de las que ya conocemos sus coordenadas exactas Range(a1:f2).Select Para el borde exterior izquierdo de la seleccin aplicamos una lnea gruesa doble de color negro With Selection.Borders(xlEdgeLeft) .LineStyle = xlDouble .Weight = xlThick .ColorIndex = xlAutomatic End With Para el borde exterior derecho de la seleccin aplicamos una lnea gruesa doble de color negro With Selection.Borders(xlEdgeRight) .LineStyle = xlDouble .Weight = xlThick .ColorIndex = xlAutomatic End With Para el borde exterior superior de la seleccin aplicamos una lnea gruesa doble de color negro With Selection.Borders(xlEdgeTop) .LineStyle = xlDouble .Weight = xlThick .ColorIndex = xlAutomatic End With Para el borde exterior inferior de la seleccin aplicamos una lnea
Visual Basic 6.0 133
gruesa doble de color negro With Selection.Borders(xlEdgeBottom) .LineStyle = xlDouble .Weight = xlThick .ColorIndex = xlAutomatic End With Interiormente aadimos una lnea gruesa continua de color negro como divisin entre ambas filas With Selection.Borders(xlInsideHorizontal) .LineStyle = xlContinuous .Weight = xlThick .ColorIndex = xlAutomatic End With Coloreamos las celdas de la primera fila Range(a1:f1).Cells.Interior.Color = RGB(100, 200, 200) Con otro color coloreamos las de la segunda Range(a2:f2).Cells.Interior.Color = RGB(150, 250, 250) Activamos la celda A1 Worksheets(1).Range(a3).Activate End Sub Despus de esto, podemos dar por finalizado el proyecto de la tabla CCC. Antes de probar los resultados, es conveniente salvar los cambios (en un nuevo documento preferiblemente). De todos modos, lo ms recomendable es que cada uno pruebe por su cuenta a modificar distintas partes del cdigo para comprobar en qu medida puede personalizar los resultados y sobre todo, poner en prctica todos los conocimientos adquiridos en aquellos documentos que, por su similitud con los vistos hasta el momento, nos resulten ms sencillos de programar.
134
Curso
Del mismo modo que ocurre con el trabajo a nivel de usuario, para aplicar un borde a una tabla formada por una matriz de celdas de Excel con una macro lo ms recomendable es seleccionar previamente toda la tabla. Para facilitar este trabajo, Visual Basic dispone del objeto CurrentRegion, que forma parte de las celdas y hace referencia a todo el rango de celdas no vacas adyacentes a la celda original. Dicho objeto cuenta, a su vez, con el mtodo Select, que selecciona todo ese rango. Haciendo referencia a dicha seleccin con el objeto Selection, podremos realizar ms fcilmente la aplicacin de formatos a los bordes. El conjunto de todos los bordes puede tratarse a su vez como un objeto parte de Selection al que hay que especificar, por medio de un parmetro, un borde en concreto. Despus, se indica a travs de sus propiedades LineStyle, Wight y ColorIndex el estilo, el grosor y el color de la lnea respectivamente, utilizando para ello constantes exclusivas de Excel.
135
136
Curso
Captulo 17
Grficas
En nuestro afn por conocer de qu forma podemos programar las tareas triviales de Excel, no podamos dejarnos por el camino el trabajo con las grficas. Seguro que a los usuarios habituales del editor de hojas de clculo de Microsoft, este captulo del curso de programacin les resultar realmente interesante. Una de las mejores aplicaciones prcticas que los usuarios de Excel pueden encontrar a las macros es la actualizacin automtica de las series de datos de las grficas creadas con anterioridad ya que, a pesar de que Excel cuenta con una alta capacidad de actualizacin de valores gracias a la interrelacin de celdas por medio de frmulas y rangos, no presenta la posibilidad de aadir valores a una serie de datos de una grfica de forma, si no automtica, al menos trivial. Objetos ChartObjects Cada uno de los objetos grficos que se encuentran en una hoja de clculo de un libro de trabajo (WorkSheets) son, para Visual Basic, ChartObjects. Adems, cada uno de estos grficos toma un nmero dentro de la hoja (del mismo modo que cada hoja toma un nmero dentro del libro) a los que se accede a travs de un ndice vectorial. Por ejemplo, para referirnos al cuarto grfico de la tercera hoja del libro de trabajo, deberamos escribir: Worksheets(3).ChartObjects(4) Del mismo modo, una grfica cuenta, a su vez, con una serie de objetos, mtodos y propiedades. Uno de esos objetos es la propia rea del grfico, que se denomina Chart. Entre los objetos que nuevamente forman parte del rea del grfico, resultan especialmente tiles (para posteriores actualizaciones) las series de datos, a las que Visual Basic nombra como SeriesCollection, que tambin se enVisual Basic 6.0 137
cuentran vectorizadas. Para acceder, por ejemplo, a la primera de las series de datos de la grfica anterior, deberamos escribir: Worksheets(3).ChartObjects(4).Chart.SeriesCollection(1) En lo que a las series se refiere, stas cuentan con varios campos, entre los que cabe destacar dos especialmente: Values, que corresponde a los valores numricos de la grfica, y Xvalues, que son los ttulos del eje de las abcisas. El contenido de ambas propiedades son rangos, por lo que, en caso de querer aplicar un nuevo valor a alguna de ellas, deberamos pasar un String que cumpla las caractersticas de rango o un rango directamente. Concatenacin de cadenas de caracteres Como veremos en el ejemplo del paso a paso, puede resultar muy til actualizar dinmicamente los rangos de las grficas con el fin de no tener que dibujarlas de nuevo tras la insercin de nuevos valores al final de la misma. Para realizar esta tarea es posible que nos veamos en la necesidad de concatenar varias expresiones para poder conseguir un rango vlido. Una posibilidad, la seguida en el paso a paso, es utilizar el operador & como concatenador.
el nmero de concursantes que se presentarn, de modo que se descarta la opcin de formatear la hoja antes de realizar las anotaciones. Qu solucin podramos aportar? Ante esta situacin, la mejor opcin es aprovechar nuestros conocimientos sobre Visual Basic y las macros de Microsoft automatizando tanto la toma de datos como la actualizacin de la grfica con los nuevos valores que se vayan insertando. Para ello, lo primero que debemos hacer es preparar la hoja de cara a la recepcin de los datos. Una posibilidad, sobre la que trabajaremos en la realizacin de este paso a paso, sera combinar las celdas A1 y B1 (seleccionando ambas y pulsando posteriormente el botn Combinar y centrar de la barra de herramientas Formato). Despus escribimos el texto CONCURSO en la celda resultante y CONCURSANTE y TOQUES en las celdas A2 y B2, respectivamente. Aunque podra insertarse la grfica dinmicamente desde una macro, como ste no es el objetivo de la prctica de este captulo, la insertaremos utilizando el asistente. Para facilitar ms an el proceso, podemos insertar unos datos inventados en las celdas A3, B3, A4 y B4. Despus, seleccionamos esos 4 valores y pulsamos el botn Asistente para grficos de la barra de herramientas Estndar. Seleccionamos una grfica de columnas y pulsamos el botn Finalizar (despus cada uno podr dar a la grfica la apariencia que desee). A continuacin, situamos la grfica a la derecha del lugar que ocupar la lista a medida que aumente su tamao. En este punto, debemos plantearnos empezar a programar. Como es lgico, debemos abstraer las diferentes funciones que debe realizar el programa para poder realizar los subprogramas necesarios. Una posibilidad (aunque no
Visual Basic 6.0 139
la nica), es realizar una funcin que busque el lugar donde deben ir los nuevos datos. Una vez localizada la primera celda vaca, el programa debe escribir los valores del siguiente concursante, tarea sta que puede realizarse desde la misma funcin. Para simplificar, utilizaremos dos InputBoxes (uno para tomar el nombre y otro para la puntuacin), que escribirn directamente sobre la hoja de clculo. El cdigo de esta funcin podra ser el siguiente (que escribiramos sobre la propia hoja de clculo, sin necesidad de utilizar mdulos): Funcin con la que obtendremos las coordenadas del nuevo dato y con la que anotaremos los valores en la hoja de clculo Private Function NuevaFila() As Integer Inicializamos el comienzo de la cuenta en la fila 3 porque las 2 primeras estn dedicadas a los ttulos NuevaFila = 3 Buscamos el primer hueco tras la lista actual Do While Not IsEmpty(Worksheets(1).Range(a1). _ Offset(NuevaFila - 1, 0)) NuevaFila = NuevaFila + 1 Loop Insertamos el nombre del nuevo concursante a travs de un InputBox Worksheets(1).Range(a1).Offset(NuevaFila - 1, 0) = _ InputBox(Concursante:, Nuevo Dato) Insertamos la puntuacin del nuevo concursante a travs de un InputBox Worksheets(1).Range(B1).Offset(NuevaFila - 1, 0) = _ InputBox(N de toques:, Nuevo Dato) End Function
140
Curso
Ahora debemos plantearnos de qu forma se utilizar el dato recibido para recalcular los valores de la serie. La operacin es tan sencilla como asignar dicho valor a una nueva variable que despus se asignar como el nmero de fila del segundo valor del cdigo del rango utilizando para ello la concatenacin de cadenas de caracteres. Una posibilidad es la siguiente: Procedimiento al que ligaremos el botn de comando Public Sub Record() Declaramos la variable fila en la que guardaremos el nmero de fila correspondiente a la nueva entrada Dim Fila As Integer Asignamos a la variable Fila el valor devuelto por la funcin NuevaFila Fila = NuevaFila Para la hoja de trabajo 1 entre su coleccin de grficas la 1 para su primera serie de datos With Worksheets(1).ChartObjects(1).Chart.SeriesCollection(1) El rango de valores se corresponde con la el rango b3:bFila de la primera hoja de trabajo .Values = Worksheets(1).Range(b3:b & CStr(Fila)) El rango de ttulos se corresponde con la el rango a3:aFila de la primera hoja de trabajo .XValues = Worksheets(1).Range(a3:a & CStr(Fila)) End With End Sub Con el motor preparado para realizar las operaciones pertinentes, tan slo nos queda realizar los ltimos toques de apariencia y accesibilidad de la hoja de clculo. Lo primero que haremos ser borrar los datos inventados de
Visual Basic 6.0 141
la hoja de clculo para dejarla preparada para empezar a insertar los reales. Despus debemos insertar un botn de comando bajo la grfica, a travs del cual invocaremos al procedimiento Record. Para poder insertar controles en el formulario, lo primero que debemos hacer es mostrar la barra de herramientas Formularios (Ver/Barras de herramientas/Formularios). Despus, pulsando sobre el comando Botn de dicha barra estaremos en disposicin de dibujar el control en la propia hoja de clculo. Dependiendo de la versin de Excel con la que estemos trabajando, es posible que, al terminar de dibujar el botn de comando, el ordenador nos pregunte si queremos relacionar el evento Clic del ratn sobre dicho botn a alguna de las macros existentes. De ocurrir esto, tan slo tenemos que seleccionar el procedimiento Record de la lista de macros y pulsar el botn Aceptar. Una vez terminado nuestro trabajo, la localidad donde tendra lugar el concurso de toques de baln dispondra de una hoja de clculo adaptada a sus necesidades. Cada vez que uno de los concursantes terminase su participacin, los jueces no tendran ms que pulsar el botn de comando (al que podemos cambiar algunas propiedades, Caption por ejemplo, para hacerlo ms atractivo) y a travs de sendos dilogos, introducir el nombre y la puntuacin del concursante. Automticamente, esos valores se aadiran a la lista y se actualizara la grfica correspondiente.
142
Curso
Captulo 18
Grficas (2 de 2)
Despus de que en el anterior captulo viramos de qu forma se modifican las series de datos de las grficas de Excel por medio de la programacin de macros, en ste, conoceremos los distintos tipos de grficas con los que podremos trabajar en este proceso.
Si alguna conclusin hemos debido sacar a lo largo de la segunda parte del curso de programacin en Visual Basic (la dedicada a explicar la programacin de macros sobre Microsoft Excel) es que la posibilidad de automatizar todo tipo de tareas que nos ofrecen las aplicaciones de Microsoft Office hace que podamos complementar nuestros documentos. Se volvern no slo ms operativos, sino tambin mucho ms atractivos para el usuario. En esta lnea va enfocado el ltimo captulo de la parte del curso de programacin dedicada a las macros, ya que trataremos de presentar la gama de posibles grficas que utilizar y el modo de cambiar de estilo las grficas de nuestros documentos en tiempo de ejecucin, de modo que los datos se puedan presentar a gusto del usuario sin necesidad de que ste conozca los pormenores de las propiedades de las grficas. Tipos de grficas Para referirnos al tipo de grfica de un ChartObject, hemos de acceder a la propiedad ChartType del subobjeto Chart correspondiente. Como ya vimos en el captulo anterior del curso, para hacer referencia a cada uno de los grficos de una hoja hemos de pasar previamente por el objeto WorkSheet correspondiente a la hoja de trabajo en cuestin.
Visual Basic 6.0 143
As, para modificar el tipo de grfica del primer grfico de la primera hoja de trabajo del libro la expresin correspondiente podra escribir: Worksheets(1).ChartObjects(1).Chart.ChartType = <I>Constante<P> donde Constante es un valor constante de tipo XlChartType. En la siguiente tabla podemos observar toda la coleccin de valores de este tipo de constantes, si bien es preciso tener en cuenta que no siempre es posible cambiar de tipo de grfica sin modificar algunas otras propiedades del objeto: xlLine xlLineMarkersStacked xlLineStacked xlPie xlPieOfPie xlPyramidBarStacked xlPyramidCol xlPyramidColClustered xlPyramidStacked xlPyramidColStacked100 xlRadar xlRadarFilled xlRadarMarkers xlStockHLC xlStockOHLC xlStockVHLC xlSurface xlSurfaceTopView xlSurfaceTopViewWireframe xlSurfaceWireframe xlXYScatter xlXYScatterLines xlXYScatterLinesNoMarkers xlXYScatterSmooth xlXYScatterSmoothNoMarkers xl3DArea xl3DAreaStacked
144
Lnea Lnea apilada con marcadores Lnea apilada Circular Circular con subgrfico circular Barra piramidal apilada Columna piramidal 3D Columna piramidal agrupada Columna piramidal apilada Columna piramidal apilada 100% Radial Radial relleno Radial con marcadores de datos Mximos, mnimos. cierre Apretura, mximos, mnimos, cierre Volumen, mximos, mnimos, cierre Superficie 3D Superficie (vista superior) Superficie (vista superior de la trama) Superficie 3D (trama) Dispersin Dispersin con lneas Dispersin con lneas y sin marcadores de datos Dispersin con lneas suavizadas Dispersin con lneas suavizadas y sin marcadores de datos rea 3D rea 3D apilada
Curso
xl3DAreaStacked100 xl3DBarClustered xl3DBarStacked xl3DBarStacked100 xl3DColumn xl3DColumnClustered xl3DColumnStacked xl3DColumnStacked100 xl3DLine xl3DPie xl3DExploded xlArea xlAreaStacked xlAreaStacked100 xlBarClustered xlBarOfPie xlBarStacked xlBarStacked100 xlBubble xlBubble3DEffect xlColumnClustered xlColumnStacked xlColumnStacked100 xlConeBarClustered xlConeBarStacked xlConeBarStacked100 xlConeCol xlConeColClustered xlCloneColStacked xlCloneColStacked100 xlClylinderBarClustered xlCylinderBarStacked xlCylinderBarStacked100 xlCylinderCol xlCylinderColClustered xlCylinderColStacked xlCylinderColStacked100 xlDoughnut xlDoughnutExploded
Visual Basic 6.0
rea apilada 100 % Barra 3D agrupada Barra 3D apilada Barra 3D apilada 100 % Columna 3D Columna 3D agrupada Columna 3D apilada Columna 3D apilada 100 % Lnea 3D Circular 3D Circular seccionado 3D rea rea apilada rea apilada 100 % Barra agrupada Circular con subgrfico de barras Barra apilada Barra apilada 100 % Burbuja Burbuja con efectos 3D Columna agrupada Columna apilada Columna apilada 100 % Barra cnica agrupada Barra cnica apilada Barra cnica apilada 100 % Columna cnica 3D Columna cnica agrupada Columna cnica apilada Columna cnica apilada 100% Barra cilndrica agrupada Barra cilndrica apilada Barra cilndrica apilada 100 % Columna cilndrica 3D Columna cnica agrupada Columna cnica apilada Columna cnica apilada 100 % Anillos Anillos seccionado
145
Lnea con marcadores Lnea apilada 100 % con marcadores Lnea apilada 100 % Circular seccionado Barra piramidal agrupada Barra piramidal apilada 100 %
Como es fcil entender, cada una de las propiedades que se definen al utilizar el Asistente para grficos se pueden modificar igualmente por medio de programacin, de modo que las limitaciones que existen a la hora de automatizar los documentos de Microsoft Excel radican, principalmente, en nosotros mismos.
Inmediatamente despus, pasamos a programar el evento Open del libro de trabajo, ya que cada vez que se abra el documento ha de rellenarse la lista de valores del cuadro combinado. En realidad, lo nico que haremos en esta subrutina ser llamar al procedimiento InicializarComboGrficas que escribiremos a continuacin en el cdigo de la hoja 1 del documento. As, tras acceder a la ventana de cdigo de Microsoft Visual Basic (Herramientas/Macro/Editor de Visual Basic), abrimos la ventana de cdigo del libro de trabajo haciendo un doble clic con el ratn sobre el objeto ThisWorkbook en el rbol de la ventana Proyecto. Una vez all, escribimos la llamada al procedimiento que rellenar el cuadro combinado y la inicializacin del mismo para cada ejecucin: Private Sub Workbook_Open() 'Al abrir el libro de trabajo llamamos al 'procedimiento InicializarComboGraficas 'que se encuentra en la hoja 1 del libro de 'trabajo y que rellena el cuadro combinado 'con una serie de valores Worksheets(1).InicializarComboGraficas 'Despus especificamos un estilo de barras 2D, 'que ocupa la primera posicin (0) de la lista, 'a la grfica como valor predeterminado Worksheets(1).cmbEstiloGrafica.ListIndex = 0 End Sub Finalmente, escribimos el cdigo del procedimiento InicializarComboGraficas y el de la subrutina asociada al evento de cambio de valor del cuadro combinado (Change) tras el cdigo escrito en la versin anterior en el la Hoja 1. Esencialmente, lo que haremos en la subrutina InicializarComboGraficas ser rellenar el cuadro combinado con valores correspondientes a diferentes tipos de grficas compatibles (barras y columnas). Esos valores sern el nombre descriptivo del tipo de grfica, ya que al programar el evento Change del combo asociaremos esas descripciones al valor real de la
Visual Basic 6.0 147
constante correspondiente por medio de una estructura Select Case. Una posibilidad para codificar ambos procedimientos podra ser la siguiente: Public Sub InicializarComboGraficas() 'Procedimiento a travs del cual rellenaremos el 'cuadro combinado de la hoja de clculo con las 'posibles grficas que utilizar 'Primero borramos el "combo" de los valores 'que pudiera guardar de la ltima ejecucin cmbEstiloGrafica.Clear 'Despus, utilizando el mtodo AddItem de los 'cuadros combinados aadimos ttulos a las 'entradas (necesariamente strings) cmbEstiloGrafica.AddItem "Columnas 2D" cmbEstiloGrafica.AddItem "Columnas 3D" cmbEstiloGrafica.AddItem "Barras 2D" cmbEstiloGrafica.AddItem "Barras 3D" 'de todas las posibilidades de grficos ofreceremos 'aquellas de tipo barra que resulten representativas 'de los datos que mostrar End Sub Private Sub cmbEstiloGrafica_Change() 'Al cambiar el valor del "combo" de grficas With Worksheets(1).ChartObjects(1).Chart 'Primero accedemos al rea grfica del primer 'objeto grfico de la primera hoja del libro 'de trabajo Select Case cmbEstiloGrafica.ListIndex 'Analizamos la posicin en la lista del valor 'actual del cuadro combinado Case 0 'Si es Barras 2D ocupa la posicin 0 .ChartType = xlColumnClustered 'Especificamos el valor correspondiente 'a su propiedad ChartType Case 1 'Si es Barras 3D ocupa la posicin 1 .ChartType = xl3DColumn
148 Curso
'Especificamos el valor correspondiente 'a su propiedad ChartType Case 2 'Si es Filas 2D ocupa la posicin 2 .ChartType = xlBarClustered 'Especificamos el valor correspondiente 'a su propiedad ChartType Case 3 'Si es Filas 3D ocupa la posicin 3 .ChartType = xl3DBarClustered 'Especificamos el valor correspondiente 'a su propiedad ChartType End Select End With End Sub
149
150
Curso
Captulo 19
Gestor de CDs
A estas alturas del curso de programacin ha llegado el momento de enfrentarnos a un nuevo reto que resultar de lo ms apasionante: desarrollaremos desde cero una aplicacin de gestin utilizando para ello una base de datos.
Despus de varios captulos conociendo los entresijos de la programacin con Microsoft Visual Basic, ha llegado el momento de dar el que puede ser el paso ms importante en lo que al desarrollo de aplicaciones se refiere; esto es, la conexin de una aplicacin con una base de datos. Para ello, durante los prximos captulos del curso programaremos ntegramente una aplicacin que nos permita gestionar tanto nuestra coleccin de CDs como los prstamos que realicemos a nuestros amigos. Coleccin de discos El nuevo proyecto, sobre el que trabajaremos durante los prximos captulos, es un gestor de una coleccin de CDs. Este programa, una vez finalizado, ha de permitirnos llevar un control absoluto sobre nuestra coleccin de discos compactos independientemente del tipo que sean. As, y a pesar de que podremos diferenciar perfectamente unos tipos de otros, es posible aadir a la coleccin tanto discos de msica como de datos, juegos o pelculas, llegando a gestionar (con modificaciones, adiciones y eliminaciones) los diferentes gneros de cada uno de los tipos de CD. Del mismo modo, gestionaremos los prstamos de los CDs, de forma que nos resulte sencillo en todo momento tener localizados todos los elementos de la coleccin. Adems, podremos consultar multitud de datos referentes tanto a los propios discos como a los prstamos realizados, as como generar y mostrar completos listados de nuestra coleccin de juegos, msica o pelculas. Tambin posibilitaremos la asociacin de cartulas a cada uno de los discos, para lo cual tan slo tendremos que guardar una imagen asociada a dicha cartula en un directorio concreto y despus, a travs de un formulario, seVisual Basic 6.0 151
leccionar las imgenes correspondientes a cada CD. De este modo, podremos reducir el espacio fsico ocupado por nuestra coleccin sin tener que renunciar a las cartulas que, en ocasiones, tan preciada informacin nos aportan. Adems, para los amantes de la tecnologa, la aplicacin presentar compatibilidad con el trabajo con cdigos de barras que la propia aplicacin generar y que podrn ser ledos por dispositivos compatibles (este aspecto lo comentaremos ms detenidamente cuando llegue el momento de codificarlo). Prstamos En lo que se refiere a los prstamos, mostraremos una especial atencin tanto a la administracin de datos de nuestros contactos como al detalle de los prstamos realizados. Como se puede apreciar en la base de datos que utilizaremos, registraremos tanto la fecha de prstamo de los CDs como la fecha de su devolucin. Asimismo, habilitaremos la posibilidad de que el gestor pueda registrar el estado en que fue devuelto el CD. Adems, ser posible, en todo momento, tener localizados todos los CDs prestados. Conexin con las bases de datos Si nunca hemos conectado una aplicacin o una pgina Web con una base de datos, puede parecer que lo que proponemos en este momento ser realmente difcil de implementar. Pero lo cierto es que, como podremos comprobar a partir del prximo captulo del curso, trabajar con bases de datos resulta, adems de cmodo, realmente sencillo. Dado que una base de datos es imprescindible en cualquier programa de gestin, no podamos seguir avanzando en el curso obviando este aspecto.
Zona de descargas
Cada captulo incluiremos en la Zona de descargas de la revista, dentro de www.computeridea.net, el documento de Access que acompaa los progresos realizados en la seccin base de datos. Toda aplicacin de gestin que se precie debe ir desarrollada a partir de una base de datos. En realidad, es posible que pueda llegar a tener ms importancia la propia base de datos que el programa en s, ya que lo realmente imprescindible en el campo de la gestin son los datos. Por ello, y antes de empezar a disear la aplicacin, debe
152 Curso
quedarnos claro el diseo de la base de datos sobre la que trabajaremos, la cual podis descargar, ya diseada, desde la Web de la revista. Coleccin de CDs Es cierto que la base de datos que proponemos puede resultar un tanto compleja si no estamos acostumbrados a trabajar con bases de datos normalizadas. Sin embargo, desde estas lneas trataremos de aclarar, en la medida de lo posible, el porqu del diseo seleccionado. As, en lo que a la coleccin de CDs se refiere, la base de datos cuenta con una tabla, llamada CDS, en la que se aadirn los datos generales de todos los discos (ttulo, nmero de discos, fecha de alta, ISBN, si se trata de un CD original o de una copia de seguridad y un campo de texto para introducir, si procede, un comentario). Lgicamente, cada CD contar tambin con un identificador autonumrico para que el ordenador pueda trabajar ms fluidamente con los registros. Ese mismo identificador lo heredarn despus las diferentes tablas especficas, una para cada uno de los diferentes tipos de CD. As, la base de datos cuenta con las tablas PELICULAS, JUEGOS, MUSICA, SOFTWARE y DATOS, cada una de las cuales con caractersticas especficas de sus tipos. Por ejemplo, la tabla PELICULAS, adems del identificador que hereda de la tabla CDS, cuenta con campos donde almacenar la duracin, el estado del sonido y la imagen (deficiente en algunas pelculas en formato DivX), el nombre de los protagonistas y el director, si la pelcula ya est visionada, si necesita un cdec especial y el formato y el gnero de la pelcula. Durante el diseo de la base de datos, con el objetivo de evitar que errores ortogrficos pudiesen despus falsear las consultas de datos, decidimos normalizar el formato de las pelculas (tabla FORMATO_PELICULA). En efecto, creamos una nueva tabla donde se especificaran una nica vez los formatos (DivX, VdeoCD, DVD, etctera), a los que despus se acceder al
Visual Basic 6.0 153
introducir los datos de una pelcula que, en lugar de guardar el nombre completo del formato, guardar el identificador numrico del mismo. La misma explicacin tendra la existencia de las tablas GENERO_PELICULA, GENERO_JUEGO, DISPOSITIVO_JUEGO y GENERO_MUSICA. Cartulas Respecto a las cartulas de los CDs, durante la instalacin de la aplicacin se crear una carpeta en la que deberemos guardar, en formato grfico, todas las cartulas que queramos que estn disponibles para el programa. Para gestionar esas imgenes, en un principio, se pens en insertar dos campos en la tabla CDS en los que se almacenasen los nombres de las cartulas delantera y trasera. Sin embargo, al contemplar la posibilidad de que dichos campos pudiesen quedar vacos en un gran nmero de casos y el consiguiente malgasto de recursos que eso implicara (hay que tener en cuenta que si reservamos 50 caracteres para cartulas en cada CD, aunque no se inserte ningn valor, los 50 bytes sern ocupados en la base de datos), se decidi normalizar este aspecto. Esto implic la creacin de una nueva tabla, llamada CARATULAS, que hereda el identificador del CD de la tabla CDS y cuenta, adems, con dos campos de texto donde se almacenarn los nombres que las respectivas cartulas tienen dentro del directorio anteriormente sealado. Amigos Para controlar los prstamos, previamente necesitaremos tener una coleccin de amigos a los que les prestaremos los CDs. Este control lo haremos a travs de la tabla AMIGOS, que cuenta con campos de texto para el nombre, la direccin, el e-mail y dos nmeros de telfono (conviene tener localizados a aquellos amigos que tarden en devolvernos los discos), adems del identificador autonumrico con el que trabajar internamente la base de datos, sobre todo a la hora de relacionar los prstamos con un amigo.
154
Curso
Prstamos La forma en que almacenaremos los datos de los prstamos merecen una especial atencin. La ms sencilla de hacerlo sera introducir una tabla en la que almacensemos el identificador del CD y el identificador del amigo al que se le hace el prstamo. Pero de esta manera no guardaramos una completa relacin de los prstamos en s, sino de los detalles, algo as como si en una venta se registrasen los productos por separado sin relacionarlos en una nica nota.
Para esta versin ms completa necesitamos dos tablas. La primera, llamada PRESTAMOS, almacena, simplemente, el identificador del amigo al que se le prestan los discos y la fecha de dicho prstamo, adems de un identificador autonumrico para cada prstamo. La otra tabla, DETALLE_PRESTAMO, almacena el identificador del pedido y el identificador de un CD como claves principales y tanto la fecha de devolucin del CD como un cuadro de texto donde especificar el estado en que nos devuelven el CD (por si acaso) como datos aadidos. Aunque a primera vista puede sorprender que la fecha de devolucin y la fecha de prstamo del CD se almacenen en tablas diferentes, esto resulta completamente lgico si pensamos que en muchas ocasiones los discos prestados de una vez no se devuelven juntos. Relaciones
155
En lo que a las relaciones utilizadas se refiere, conviene destacar el tipo 1 a 1 presentes entre los identificadores de las tablas correspondientes a los diferentes tipos de CDs y la propia tabla CDS. Estas relaciones, de tipo ISA, se caracterizan por presentar en las tablas derivadas un identificador heredado de la propia tabla original. En lo que a la tabla CARTULAS se refiere, la relacin, tambin 1 a 1, se debe a que un CD tendr, cmo mximo, un juego de cartulas. Por el contrario, dado que un amigo puede realizar varios pedidos de pelculas, la relacin entre las tablas AMIGOS y PRESTAMOS es de 1 a 8 , debido a que un pedido se asigna a un nico amigo mientras que un amigo puede realizar mltiples pedidos. Se produce una relacin similar entre las tablas PRESTAMOS y DETALLE_PRESTAMO porque un detalle pertenece a un prstamo concreto, mientras que un prstamo puede tener mltiples detalles. La misma explicacin tendra la relacin existente entre DETALLE_PRESTAMO y CDS, tambin de 1 a 8 .
156
Curso
Captulo 20
Gestor de CDs
Tras presentar brevemente el captulo anterior lo que ser el gestor de CDs que vamos a desarrollar, en esta ocasin debemos empezar a disear los formularios de la aplicacin. En este captulo del curso nos centraremos en la construccin de la barra de mens y en la introduccin al trabajo con formularios MDI.
El diseo de las barras comunes de trabajo con aplicaciones ya lo realizamos durante el desarrollo del editor de textos. Para esta aplicacin seguiremos un proceso similar, comenzando por la preparacin de la lista de imgenes, aunque debemos hacer una breve introduccin a lo que supone el trabajo con Aplicaciones de Interfaz de Mltiples Documentos (aplicaciones MDI), que suponen una novedad con respecto a los formularios presentados hasta el momento. Aplicaciones de Interfaz de Mltiples Documentos Un proyecto de Visual Basic se compone, esencialmente, de mdulos y formularios. En cuanto a los primeros, est claro que su principal utilidad es la de hospedar cdigo reutilizable, mientras que en los segundos debemos disear la parte operativa de la aplicacin, es decir, los controles que harn las funciones de interfaz entre el usuario y el ordenador. Algunos formularios con los que trabajamos habitualmente, si no como desarrolladores al menos como usuarios, es el tipo de formularios MDI, donde existe un formulario principal dentro del que se hospedan uno o varios formularios secundarios. Las aplicaciones ofimticas suelen utilizar este tipo de formularios ya que, normalmente, en un mismo formulario se pueden abrir mltiples documentos. Caractersticas de los formularios MDI primarios
157
Obviamente, en una aplicacin MDI existen considerables diferencias entre los formularios de carcter primario y los secundarios. Para empezar, como avanzbamos anteriormente, una aplicacin puede tener, como mximo, un nico formulario MDI primario. Adems, este formulario tiene muy limitado el hospedaje de controles, pudiendo albergar, bsicamente, barras de uso general y algn PictureBox. Adems, no se puede utilizar ningn mtodo grfico para mostrar informacin sobre el formulario MDI primario (ni siquiera el mtodo Print). De usarlos, en la barra de tareas de Windows aparecer una nica referencia, correspondiente a este formulario, de modo que de ser minimizado todos aquellos formularios secundarios contenidos en l tambin seran minimizados y, al restaurarlo, todos volveran a su estado anterior. En cuanto a los mens, en este tipo de aplicaciones lo ms comn es definirlos en el formulario principal, ya que podran ser utilizados en toda la aplicacin. Si se define un men para un formulario secundario, ste se mostrara en el principal cuyo men, de existir, desaparecera a favor del secundario. Caractersticas de los formularios MDI secundarios
? Microsoft Photo Editor es un ejemplo de aplicacin MDI
Los formularios MDI secundarios son ms parecidos a los formularios tpicos de Visual Basic, ya que en ellos se ubicarn los controles interactivos de la aplicacin. A pesar de todo, poseen una serie de comportamientos un tanto caractersticos debidos a su dependencia con respecto al formulario principal. As, los formularios MDI secundarios han de aparecer, necesariamente, dentro de los lmites del formulario principal. Adems, cuando se minimiza un formulario secundario, su referencia aparecer dentro de la ventana del formulario principal y no en la barra de tareas de Windows. Cuando se maximiza un formulario secundario, ste pasa a rellenar todo el espacio del formulario principal, aadindose adems el t158 Curso
tulo del hijo a la barra de ttulo del padre. Simultneamente, el resto de formularios secundarios quedan automticamente minimizados. Hay que destacar que, de todos modos, el hecho de que un programa cuente con formularios MDI no implica que no puedan existir formularios convencionales en esa misma aplicacin.
Nombre de proyecto. Por ltimo, eliminamos el formulario inicial Form1 pulsando sobre l con el botn derecho del ratn para despus pulsar sobre la opcin Quitar Form1. A continuacin, pasamos a crear el men de la aplicacin que tambin ubicaremos en el formulario MDI, por lo que debemos asegurarnos de que, antes de nada, se encuentre activo. A travs del editor de mens (Herramientas/Editor de mens) aadimos los mens de la aplicacin. Siguiendo el orden presentado, y teniendo en cuenta que un nivel inferior supone un aumento de la sangra en el dilogo para la entrada correspondiente, el esquema de mens sera el siguiente: Caption &Pelculas &Aadir &Borrar &Modificar Editar &gnero Editar &formato &Consultar &Uno a uno &Listado &Juegos &Aadir &Borrar &Modificar &Editar gnero &Consultar &Uno a uno &Listado &Msica &Aadir &Borrar &Modificar
160
Name mnuPeliculas mnuPeliculasAnadir mnuPeliculasBorrar mnuPeliculasModificar mnuPeliculasGenero mnuPeliculasFormato mnuPeliculasConsultar mnuPeliculasConsultarUno mnuPeliculasConsultarListado mnuJuegos mnuJuegosAnadir mnuJuegosBorrar mnuJuegosModificar mnuJuegosGenero mnuJuegosConsultar mnuJuegosConsultarUno mnuJuegosConsultarListado mnuMusica mnuMusicaAnadir mnuMusicaBorrar mnuMusicaModificar
Nivel Principal Secundario Secundario Secundario Secundario Secundario Secundario Terciario Terciario Principal Secundario Secundario Secundario Secundario Secundario Terciario Terciario Principal Secundario Secundario Secundario
Curso
&Editar gnero &Consultar &Uno a uno &Listado &Software &Aadir &Borrar &Modificar &Consultar &Uno a uno &Listado &Datos &Aadir &Borrar &Modificar &Consultar &Uno a uno &Listado P&rstamos &Prstamo &Devolucin &Consulta &Amigos &Aadir &Borrar &Consultar A&yuda Ayuda Acerca de
mnuMusicaGenero mnuMusicaConsultar mnuMusicaConsultarUno mnuMusicaConsultarListado mnuSoftware mnuSoftwareAnadir mnuSoftwareBorrar mnuSoftwareModificar mnuSoftwareConsultar mnuSoftwareConsultarUno mnuSoftwareConsultarListado mnuDatos mnuDatosAnadir mnuDatosBorrar mnuDatosModificar mnuDatosConsultar mnuDatosConsultarUno mnuDatosConsultarListado mnuPrestamos mnuPrestamosPrestamo mnuPrestamosDevolucion mnuPrestamosConsulta mnuAmigos mnuAmigosAnadir mnuAmigosBorrar mnuAmigosConsultar mnuAyuda mnuAyudaAyuda mnuAyudaAcercade
Secundario Secundario Terciario Terciario Principal Secundario Secundario Secundario Secundario Terciario Terciario Principal Secundario Secundario Secundario Secundario Terciario Terciario Principal Secundario Secundario Secundario Primario Secundario Secundario Secundario Primario Secundario Secundario
Para poder aadir barras de herramientas y de estado al proyecto, es imprescindible que previamente agreguemos los controles comunes de Windows a la barra de herramientas. Para ello, pulsamos sobre la opcin Componentes del men Proyecto y, en el apartado Controles del dilogo, buscamos la entrada Microsoft Windows Common Controls 6.0 y marcamos la casilla de verificacin adyacente. Tras confirmar, con un doble clic sobre el control ImageList, en la barra de herramientas aadiremos un contenedor de imgenes al formulario, imprescindible para posteriormente insertar imgenes a la barra de herramientas. A este control lo llamaremos imlToolBar, escribienVisual Basic 6.0 161
do dicho texto en el registro de su propiedad Nombre. Pulsando sobre l con el botn derecho del ratn, y posteriormente sobre la opcin Propiedades del men desplegado, accedemos a la Pgina de propiedades del control. Puesto que la aplicacin estar optimizada para una resolucin de pantalla 1.024 x 768 pxeles, especificamos un tamao de 32 x 32 puntos.
162
Curso
Captulo 21
Barra de herramientas y barra de estado
El objetivo en este captulo del curso de programacin ser crear una barra de herramientas y una barra de estado en el formulario MDI primario que insertamos en el proyecto el captulo anterior. Con ellas, daremos mayor funcionalidad a la aplicacin al tiempo que mantendremos ms informado al usuario del estado de su coleccin.
La insercin de nuevos controles en un formulario debe llevar un proceso previo de anlisis de la aplicacin en todo su concepto, ya que tan negativo es que un programa carezca de los controles necesarios para hacer fluida la navegacin por sus pantallas como que cuente con un exceso de ellos, lo que suele implicar que el usuario termine perdindose entre la sobrecarga de elementos. En este caso, el objetivo ser determinar cules son las funciones que ms comnmente utilizar el usuario para facilitar su acceso a travs de una barra de herramientas. Adems, incluiremos en la parte inferior del formulario una barra de estado que aporte mayor informacin sobre la situacin de la coleccin de CDs. Barras de herramientas Las aplicaciones actuales dedican mucha atencin a sus barras de herramientas. En la actualidad, cuando un grupo de programadores crea una aplicacin casi se ve obligado a insertar una o varias barras de herramientas. Al tratarse de una tendencia generalizada, los usuarios se estn acostumbrando a contar con ellas sea cual sea la naturaleza de la aplicacin y la
Visual Basic 6.0 163
mxima de este oficio es desarrollar los programas pensando en el usuario final. Con Visual Basic 6 este proceso se realiza de una forma muy sencilla. De hecho, el apartado al que suele dedicarse ms tiempo es a la deduccin de cules son los botones ms convenientes para ser insertados en dicho control. Si somos un poco observadores, podemos apreciar que las herramientas ms populares suelen sacar a la barra de herramientas aquellos comandos que tienen ms probabilidades de ser utilizados de entre todos los existentes en la barra de men. De hecho, gracias a una de las opciones de las barras de herramientas, se puede habilitar la posibilidad de que el usuario inserte o elimine botones en las barras de herramientas casi a su antojo. Una variante de las barras de herramientas tradicionales son las CoolBar, utilizadas en las distintas herramientas de Microsoft Office. Se diferencian de sus antecesoras en que pueden flotar libremente por el formulario, adems del modo de acceso a sus controles. En este caso, hemos llegado a la conclusin de que la mejor opcin es utilizar una barra de herramientas tradicional y fija en la que incluiremos los controles que, a nuestro parecer, sern ms utilizados por los usuarios. El hecho de que uno de los botones con los que contar la barra de herramientas sea de estilo desplegable se debe ms a razones didcticas que a la funcionalidad que aporta al proyecto. Botones utilizados Como ya hemos mencionado anteriormente, si decidimos disear nuestra aplicacin siguiendo los cnones establecidos por los programas ms populares, los botones que incluyamos en las barras de herramientas deben aparecer en alguno de los distintos mens, pues de lo contrario el usuario puede encontrarse un tanto desorientado al utilizar la aplicacin. Siguiendo este convenio, y aadiendo una importante dosis de criterio personal, la barra de herramientas de nuestra aplicacin contendr 9 botones que detallaremos en el siguiente paso a paso. Lo que resulta imprescindible en todo caso es contar con un control ImageList que haga las veces de contenedor de imgenes para que despus puedan ser utilizadas en la barra de herramientas. Dicho control ya se encuentra incluido en el proyecto desde el captulo anterior del curso.
164
Curso
Barra de estado Otro control de los incluidos dentro de los Controles comunes de Microsoft son las barras de estado. stas no tienen tanta importancia como las de herramientas desde un punto de vista interactivo, pero pueden resultar verdaderamente tiles para proporcionar informacin. Las barras de estado, que normalmente se ubican en la parte inferior del formulario aunque pueden ser colocadas en cualquiera de los bordes, se dividen en paneles informativos (aunque tambin puede atriburseles cierta funcionalidad tctil) que se utilizan para aportar datos sobre diferentes aspectos del proyecto. Hay distintos tipos de panel, algunos de los cuales aportan informacin sin necesidad de que el programador tenga que insertar cdigo (como, por ejemplo, la fecha, la hora o el bloqueo de maysculas o nmeros). En nuestro caso insertaremos cuatro paneles, dos de los cuales sern destinados a mostrar informacin sobre el nmero de CDs existentes en la coleccin y de ellos, cuntos se encuentran prestados en el momento de utilizar la herramienta. Los otros dos mostrarn la fecha y la hora, respectivamente.
Crear la interfaz
Si en el captulo anterior insertbamos el control imlToolBar en el formulario MDI principal, en esta ocasin, antes de insertar la barra de herramientas, lo primero que debemos hacer es cargar la lista de imgenes con los iconos que, a continuacin, vamos a utilizar. Los iconos que nosotros hemos seleccionado los podis encontrar en la zona de descarga de la web de la revista, si bien cada uno puede utilizar aquellos que le resulten ms convenientes, sobre todo teniendo en cuenta que no hay que seguir el proceso de creacin del editor al pie de la letra. Para cargar la lista con imgenes, basta con acceder a la Pgina de propiedades del control (con el comando Propiedades que aparece en su men contextual al pulsar con el botn derecho sobre dicho elemento). Una vez all, seleccionamos el tamao que queremos que tengan las imgenes en la barra (32 x 32 puntos en nuestro caso), para despus pulsar la pestaa Imgenes. A travs del botn de comando Insertar
Visual Basic 6.0 165
imagen de este dilogo vamos cargando las imgenes, teniendo en cuenta el ndice (propiedad Index) de cada una para poder referirnos a ellas posteriormente. El orden de insercin utilizado en el proyecto de ejemplo fue: Nuevo CD.ico, Modificar CD.ico, Borrar.ico, Consultas.ico, Prstamo.ico, Devolucin.ico, ConsultaPrestamos.ico, Amigos.ico y Ayuda.ico. En el punto donde dejamos el proyecto el pasado captulo, en el cuadro de herramientas del editor de Visual Basic tendramos que tener un botn que nos permitiese insertar un control Toolbar con un simple doble clic sobre l. Automticamente aparece la barra de herramientas en la parte superior del formulario activo (necesariamente el MDI principal, pues no contamos con otro). Despus accedemos al dilogo de propiedades del control del mismo modo que lo hacamos para la lista de imgenes. En la pestaa General de dicho formulario, lo primero que haremos ser definir el control Imagelist, del que tomaremos las imgenes. En el cuadro combinado correspondiente aparecen todas las listas de imgenes disponibles, una sola (imlToolBar) en este caso, que es la que debemos seleccionar. Despus, en el campo Style, seleccionamos el valor 1 tbrFlat para dar a la barra una apariencia ms integrada en el formulario. A travs de la pestaa Botones iremos insertando todos los que creamos oportunos. En primer lugar, introduciremos el correspondiente a la insercin de un nuevo CD en la coleccin. Para ello, basta con introducir el nmero de la imagen en el campo Image (1 en el caso del ejemplo) y el texto Nuevo CD, que ser emergente en detrimento del fijo por ocupar menos espacio en el formulario, por lo que dicho texto debe introducirse en el campo ToolTipText. Haremos lo propio con los botones Modificar CD y Eliminar CD, a los que atribuiremos las imgenes 2 y 3 respectivamente y que, como en el caso del primer botn, tienen que ser del tipo predeterminado, por lo que el valor de su propiedad Style ha de ser 0 tbrDefault. A continuacin, incluiremos el botn de consulta. Por ser ste de tipo desplegable, debemos establecer el valor de su propiedad Style a 5 tbrDropdown. Despus incluimos un separador (Style como tbrSeparator) para continuar con los botones de
166 Curso
tipo estndar correspondientes a Prstamos, Devoluciones y Consultas de prstamos. De nuevo insertamos un separador y, a continuacin, los botones de Amigos y Ayuda divididos por otro separador. Por ltimo, volvemos al botn nmero 4, desplegable, al que incluiremos 2 botones de men con el botn de comando Insertar ButtonMenu, que han de tener por texto Uno a uno y Listado, respectivamente. Si hemos seguido el ejemplo al pie de la letra, las imgenes deben ser utilizadas respetando esta misma ordenacin. Del mismo modo que insertbamos la barra de herramientas en el formulario, hacemos lo propio con la barra de estado (doble clic sobre el botn StatusBar del cuadro de herramientas del editor). Despus accedemos al dilogo de sus propiedades pulsando la opcin Propiedades de su men contextual. Una vez all, accedemos al dilogo Paneles, donde debemos aadir los 4 que previamente habamos decidido. Aplicaremos a todos ellos una alineacin centrada (estableciendo un valor 1 sbrCenter en su propiedad Alignment) y un valor 1 sbrSpring en el campo Autosize para que se distribuyan el ancho del formulario equitativamente. El estilo de los dos primeros ha de ser de tipo 0 sbrText para que podamos insertar en ellos mensajes de texto libremente, mientras que el tercero debe especificarse como 5 sbrTime y el cuarto como 6 sbrDate si queremos que nos muestren la hora y la fecha, respectivamente.
167
168
Curso
Captulo 22
Diseo de un formulario
Cuando nos decidimos a crear una aplicacin desde el principio, uno de los primeros aspectos que debemos estudiar es el diseo del formulario. En esta ocasin, veremos cmo crear correctamente un formulario a travs del cual insertar y modificar los datos de una pelcula.
Aunque el objetivo de este curso no es hacer una aplicacin estticamente perfecta, sino que sea lo ms funcional posible, tambin conviene prestar un poco de atencin al diseo de los formularios, sobre todo con el fin de facilitar su navegabilidad, pues si seguimos algunos criterios bsicos, conseguiremos que el usuario final se encuentre ms a gusto con la aplicacin. Diseo correcto de un formulario Desde un punto de vista prctico, lo ms recomendable de cara al diseo de los formularios de la aplicacin es que sus controles sean lo ms homogneos posible. En este sentido, hemos de tratar de evitar una mezcla recargada de colores, fuentes o tamaos. As pues, debemos seleccionar un tipo de letra de fcil legibilidad y que vaya en consonancia con el tema de la aplicacin. En cuanto al tamao, no conviene que sea especialmente grande ni pequea, porque podra sobrecargar el formulario o impedir una buena lectura de los textos. Los colores de las fuentes deben destacar sobre los colores del formulario sin ser perjudiciales para la visin. Tambin es conveniente que los controles similares guarden una buena correlacin de proporciones, tanto entre s como con el texto que puedan contener. Reutilizacin de formularios En lo que se refiere al programa en el que estamos trabajando, as como en programas de gestin similares, conviene, en medida de lo posible, facilitar la memorizacin de los formularios al usuario, con el nico objetivo de conVisual Basic 6.0 169
seguir que la asimilacin del uso de la aplicacin sea lo ms rpida posible. Cuando diseemos un formulario para la insercin de datos, podemos plantearnos la posibilidad de reutilizar ese mismo formulario para la edicin o la presentacin de los mismos. Incluso, y como veremos a lo largo de desarrollo de la aplicacin, si diseamos correctamente el formulario, podemos despus aprovechar algunas partes para otros formularios.
cilitan al usuario la comprensin de la estructura de los programas, utilizaremos un diseo muy similar para la adicin y edicin de CDs del resto de tipos (juegos, msica, software y datos). De hecho, muchos de los datos necesarios para las pelculas sern tambin necesarios para el resto de CDs, independientemente del tipo que sean. As, como ya explicamos con el diseo de la base de datos, los campos comunes a todos los CDs son el ttulo, el nmero de CDs, si se trata de un disco original o no, la fecha de alta en la base de datos, el cdigo de barras y un comentario al respecto. Tambin es comn a todos los CDs la posibilidad de tener cartulas. Una buena forma de distribuir los controles en el formulario sera aadir previamente unos marcos donde ir insertndolos segn la tabla de la base de datos a la que hagan referencia. Un primer marco sera el correspondiente a los controles que utilizaremos para aadir o modificar los datos del CD. Teniendo en cuenta las modificaciones que hagis en vuestros proyectos con respecto al nuestro de cara al cdigo posterior, cada uno puede disear sus formularios de la forma que estime oportuno. En nuestro caso, hemos decidido que el ttulo, el nmero de CDs, la fecha de alta del CD y las observaciones sean cuadros de texto. Para los valores booleanos (el campo Original de la base de datos) utilizamos botones de opcin y para el cdigo de barras, puesto que ser generado por la propia aplicacin, hemos optado por una etiqueta con aspecto de cuadro de texto. Junto a ella dos botones de comando: uno para generar el cdigo y otro para imprimirlo. Los datos propios de la pelcula, que sugerimos que sean insertados en un marco diferente, tambin deben ser colocados en un cierto orden lgico que ayuden al usuario a utilizar el programa. En nuestro caso hemos optado por utilizar dos columnas, una de ellas destinada a los datos ms filmogrficos (gnero, director, protagonistas y duracin de la
Visual Basic 6.0 171
pelcula) y en la otra aspectos ms informticos tales como la calidad del vdeo o el audio, el formato grfico o el cdec necesario para su reproduccin (si se trata de un formato de compresin como divX). En esta misma columna hemos incluido los botones de opcin que nos permiten especificar si la pelcula ya se encuentra visionada (podis observar que tendemos a insertar siempre los botones de opcin en un marco destinado explcitamente para ellos). Para facilitar a los usuarios el almacenamiento de cartulas digitales, la aplicacin est pensada para que, a partir de imgenes que se almacenarn en un nico directorio, se pueda asociar a cada CD sus propias cartulas. El marco correspondiente contendr, por tanto, dos controles Image (uno para la cartula frontal y otro para la trasera) y dos botones de comando destinados a seleccionar la imagen correspondiente a cada uno. Si queremos que las imgenes aparezcan de forma proporcionada, debemos tener presente que las dimensiones de las cartulas frontales son de 12 x 12 centmetros y las de la trasera 11,8 x 15 (no es necesario que el tamao en el formulario sea exactamente ese, pero conviene mantener, aproximadamente, la proporcin). En nuestro caso y pensando en una resolucin de pantalla de 1.024 x 768, el tamao utilizado es de 2.520 x 2.520 twips (1/20 de pulgada) para el control Image de la cartula frontal y 3.195 x 2.475 para la trasera (propiedades Height y Width respectivamente). Adems, si queremos forzar a las imgenes que contengan el control a respetar este tamao, debemos poner el registro de la propiedad Stretch a True. A pesar de que cada vez somos menos, algunos coleccionistas de CDs todava queremos tener cada uno con su cartula fsica (ya sea la original o una obtenida a travs de la impresora), por lo que la aplicacin tambin contemplar la posibilidad de que las cartulas asociadas a un CD puedan imprimirse. Para ello, dentro del propio marco de cartulas,
172 Curso
hemos insertado un nuevo marco en el que habilitaremos 3 botones de opcin con los que seleccionaremos qu cartula queremos imprimir (frontal, trasera o ambas). Al lado, un botn de comando con el que dar la instruccin de imprimir. Para finalizar con el diseo del formulario, insertamos dos botones de comando, ya fuera de los marcos, que harn las funciones de confirmar los datos del formulario e insertarlos en la base de datos (botn Aceptar) o salir del formulario sin guardar los cambios (botn Cancelar). Otro aspecto muy importante de cara a la navegacin del usuario por el formulario es el orden de tabulacin de los controles. Especificar este orden de una forma correcta, facilitar al usuario la insercin de datos nicamente con el teclado. Para especificar este orden utilizamos la propiedad TabIndex de cada control, teniendo en cuenta que un nmero menor significa una posicin anterior en el orden de tabulacin.
173
174
Curso
Captulo 23
Conexin DAO con la base de datos
Todo programa de gestin trabaja sobre una base de datos. De hecho, algunas aplicaciones no son ms que una mera interfaz grfica que nos permite aadir, rescatar y modificar los datos. En este captulo del curso aprenderemos a realizar una conexin con la que insertar datos en el archivo.
Para conectar una base de datos con una aplicacin es imprescindible, adems de la base de datos y el programa correspondiente, crear una conexin que nos permita atacar la base de datos desde la aplicacin. Para realizar esas conexiones hay multitud de tecnologas, algunas destinadas a sistemas muy robustos y complejos y otras, muy simples, que se pueden gestionar a base de controles. Para este proyecto utilizaremos DAO (Objetos de Acceso a Datos), lo suficientemente simple y didctica para ser utilizada por usuarios noveles, aunque en la actualidad existen otras tecnologas ms eficientes. Uso de Recordset Una vez que realicemos la conexin con la base de datos, a travs de un objeto Database, necesitaremos especificar qu datos concretos son los que queremos leer, modificar o aadir a la base de datos. Con la conexin slo se crea un vnculo entre el programa y la base de datos. Para acceder a la informacin necesitamos utilizar objetos Recordset que nos permitirn trabajar directamente con los datos almacenados que, a partir de una completa gama de mtodos y propiedades, podremos recorrer y manipular a capricho. Para seleccionar con precisin aquellos datos que necesitemos, tendremos que utilizar consultas en lenguaje SQL en el comando de conexin.
Antes de proceder a programar la insercin de informacin en la base de datos, debemos adaptar nuestro proyecto para que cumpla los requisitos necesarios. Para empezar, dado que vamos a utilizar una tecnologa de Objetos de Acceso a Datos o DAO, debemos aadir al proyecto la referencia pertinente, pues de otro modo nos sera imposible crear objetos Database o Recordset. Para ello, pulsamos sobre la entrada Referencias del men Proyecto del editor de Visual Basic con el proyecto abierto tal y cmo lo dejamos en la ltima entrega (recordad que podis descargar el proyecto en sus diferentes puntos de desarrollo desde la Web de la revista). Se despliega entonces el dilogo Referencias, donde aparecen remarcadas las referencias con las que actualmente cuenta el proyecto. Para aadir una nueva referencia basta con marcar su casilla de verificacin adjunta. En este caso, buscamos Microsoft DAO 3.6 Object Library y activamos la referencia. A continuacin, agregamos un nuevo mdulo al proyecto. En dicho mdulo, guardaremos aquellas funciones y procedimientos que sean comunes a dos o ms formularios. El primer subprograma que aadiremos ser la funcin NuevoCD, al que le pasaremos como parmetro el formulario de trabajo. La funcin recorrer los controles del marco correspondiente a los datos del CD, que ser comn a todos los formularios destinados a dar de alta CDs en cualquiera de sus modalidades (pelculas, juegos, etctera), y aadir en un nuevo registro de la base de datos los valores que el usuario haya escrito en los controles. Adems, devolver el identificador de uso interno para ese CD (el campo ID de la base de datos, que se asigna automticamente) y que despus deberemos utilizar para especificar el CD al que pertenecen las cartulas o los datos especficos segn su naturaleza. Para agregar el mdulo, pulsamos sobre la entrada Agre176 Curso
gar mdulo del men Proyecto y, en el dilogo desplegado, seleccionamos Nuevo y aceptamos. Haciendo un doble clic sobre el mdulo en el Explorador de proyectos, accedemos a su ventana de cdigo, donde debemos escribir el cdigo correspondiente a la funcin explicada anteriormente. Una posibilidad, partiendo del nombre de los controles que utilizamos en nuestro proyecto, sera la siguiente: Forzamos la declaracin de variables Option Explicit Funcin pblica para poder acceder desde cualquier punto del proyecto Public Function NuevoCD(Formulario As Form) As Long Declaramos el Recordset Dim rsNuevoCD As Recordset Declaramos la base de datos Dim dbCDs As Database Declaramos una respuesta para el MsgBox Dim respuesta As Integer Si el CD no tiene ttulo If Formulario.txtTitulo.Text = Then Mostramos mensaje de error respuesta = MsgBox(Es imprescindible indicar & _ un nombre para el CD, vbCritical, Error en los datos) Situamos el foco en el control correspondiente Formulario.txtTitulo.SetFocus
Visual Basic 6.0 177
Ponemos un valor negativo al valor devuelto por la funcin NuevoCD = -1 Else Conectamos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Abrimos el Recordset enlazndolo a la tabla CDs Set rsNuevoCD = dbCDs.OpenRecordset(SELECT * FROM CDS, _ dbOpenDynaset) Con el nuevo recordset With rsNuevoCD Creamos una nueva entrada .AddNew Pasamos el ttulo a maysculas y lo almacenamos !Titulo = UCase(Formulario.txtTitulo.Text) Si el nmero de CDs est especificado If Formulario.txtNumero.Text Then lo almacenamos en el campo correspondiente !NUMCDS = Formulario.txtNumero.Text End If Guardamos el valor de Original en funcin de lo especificado en los botones de opcin !ORIGINAL = Formulario.optOriginalSi.Value Si hay observaciones especificadas If Formulario.txtObservaciones.Text Then Tambin las almacenamos !COMENTARIO = UCase(Formulario.txt Observaciones.Text) End If Si hay fecha especificada If Formulario.txtFecha.Text Then La almacenamos en la base de datos !FECHA_ALTA = Formulario.txtFecha.Text End If Si hay un Cdigo de barras escrito If Formulario.txtISBN.Caption Then Lo guardamos !ISBN = Formulario.txtISBN.Caption
178 Curso
End If Guardamos el valor autonumrico del identificador para utilizarlo despus en las otras tablas NuevoCD = !ID Actualizamos .Update End With Cerramos el recordset rsNuevoCD.Close Cerramos la base de datos dbCDs.Close End If End Function Si queremos probar la eficacia del cdigo escrito, tan slo tenemos que aadir al procedimiento asociado al evento Click del botn de comando destinado a confirmar la entrada de datos una llamada a la nueva funcin. El cdigo, por supuesto no definitivo, del formulario podra ser: Forzamos declaracin de variables Option Explicit Declaramos la variable global en la que se almacenar el ID del CD sobre el que se trabaja Dim ID_CD As Long Private Sub cmdAceptar_Click() LLamamos a la funcin NuevoCD y almacenamos el valor devuelto en la variable global ID_CD = NuevoCD(fmrPeliculas) End Sub De momento, y hasta que seamos capaces de mostrar informacin de la base de datos en nuestra aplicacin, debemos abrir la base de datos para comprobar que, efectivamente, al pulsar sobre el botn se aade una nueva entrada con los datos especificados. La base de datos, tal y como se especifica en la
Visual Basic 6.0 179
conexin, debe encontrarse en el mismo directorio que los archivos de Visual Basic relativos al proyecto.
180
Curso
Captulo 24
Cuadros enlazados a bases de datos
Centrndonos en el proceso de alta de pelculas, explicaremos el uso de los cuadros combinados como representacin de una serie de opciones almacenadas en la base de datos.
A pesar de que existen multitud de controles que podemos utilizar con Visual Basic, cuando nos enfrentamos a un proyecto de una determinada importancia tendremos que echar mano de nuestra imaginacin para poder resolver algunos problemas que se nos van a ir planteando. Lo que nos har sentirnos verdaderos programadores ser utilizar combinaciones de recursos sencillos para resolver problemas un tanto complejos. Un caso de este tipo, al que debemos enfrentarnos inminentemente, es la carga de opciones en un cuadro combinado. Como ya sabemos, si las opciones estn predefinidas, podemos cargarlas en tiempo de diseo directamente en la propiedad List del control. El problema aparece cuando hemos de cargar las opciones a partir de informacin almacenada en una base de datos. As, durante el proceso de alta de una pelcula hemos de sealar su formato y su gnero. El usuario debe seleccionar las opciones a travs de sendos ComboBox que tan solo contienen listas con cadenas de texto. Al guardar los datos, debemos almacenar los identificadores correspondientes al gnero o al formato seleccionado. Para solucionarlo, utilizaremos dos vectores (uno por cada combo) donde almacenaremos los identificadores correspondientes en el momento de cargar las listas. Al guardar, obtendremos el identificador del vector en funcin del lugar que ocupe en la lista la opcin elegida, que guardar una relacin directa con el orden de los identificadores del vector.
181
Tal y como avanzbamos en la introduccin, el objetivo de este paso a paso es comprender y programar la asociacin de una tabla sencilla a un cuadro combinado, buscando que el usuario pueda elegir de entre una serie de opciones existentes en la base de datos aqulla que estime pertinente. En el formulario en el que actualmente estamos trabajando, los cuadros combinados de esta naturaleza son cmbGenero y cmbFormato. Hay que sealar que, debido a que el programa todava no cuenta con funcionalidad suficiente como para que el usuario pueda insertar formatos y gneros a su antojo, estas tablas deben estar previamente inicializadas en la base de datos. As pues, lo primero que debemos hacer es asegurarnos de que las tablas FORMATO_PELICULA y GENERO_PELICULA cuentan, al menos, con un registro cada una. Es cierto que existen cuadros combinados que se pueden enlazar directamente a una tabla o un recordset de una base de datos, lo que ocurre es que para ello es preciso utilizar una serie de controles de acceso a bases de datos muy bsicos y que limitaran bastante nuestras posibilidades de actuacin en el formulario. Tambin se pueden programar cuadros combinados personalizados, pero esta tarea se escapa del enfoque actual de este curso. Nosotros utilizaremos un recurso intermedio, que consiste en utilizar un cuadro combinado convencional y un vector de enteros largos que trabajen de forma paralela. En el comboBox cargaremos los textos y en el vector los identificadores correspondientes de la base de datos. Para poder utilizarlos, declararemos al inicio del formulario fmrPeliculas los vectores GenerosPeliculas y FormatosPeliculas como vectores de tamao variable de enteros largos. As, la cabecera del formulario quedara: Forzamos declaracin de variables Option Explicit Declaramos la variable global en la que se almacenar el ID del CD sobre el que se trabaja Dim ID_CD As Long
182 Curso
Declaramos los vectores en los que se almacenarn los identificadores del gnero y el formato de las pelculas Dim GenerosPeliculas() As Long Dim FormatosPeliculas() As Long En lo que a la programacin se refiere, vamos a crear los procedimientos necesarios para inicializar los dos cuadros combinados. El cdigo para ambos es similar y debe ir programado sobre el propio formulario. De todos modos, de cara al refresco de los valores, cuando habilitemos la posibilidad de que el usuario pueda modificarlos, declararemos los procedimientos de carcter pblico. Nuestra propuesta es la siguiente: Procedimiento que se encarga de cargar en el cuadro combinado cmbGenero los registros existentes en la tabla GENERO_PELICULA Public Sub ActualizarGeneros() Declaramos las variables Dim i As Integer contador Dim rsGeneros As Recordset recordset Dim dbCDs As Database base de datos Vaciamos el combo cmbGenero.Clear Conectamos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Obtenemos los registros de la tabla Set rsGeneros = dbCDs.OpenRecordset _ (SELECT * FROM GENERO_PELICULA ORDER BY DESCRIPCION, dbOpenDynaset) Inicializamos el contador i=1
Visual Basic 6.0 183
Recorremos todos los registros hasta llegar al final Do While Not rsGeneros.EOF Cargamos en el combo el texto almacenado cmbGenero.AddItem rsGeneros!DESCRIPCION Redimensionamos el vector preservando los valores existentes ReDim Preserve GenerosPeliculas(i) Almacenamos en el vector el ID correspondiente al gnero GenerosPeliculas(i) = rsGeneros!ID Incrementamos el contador i=i+1 Pasamos al siguiente registro rsGeneros.MoveNext Loop Al finalizar, activamos el primer registro rsGeneros.Close Cerramos el recordset dbCDs.Close Cerramos la base de datos cmbGenero.ListIndex = 0 Activamos como predeterminado el primero de los gneros existentes End Sub Procedimiento que se encarga de cargar en el cuadro combinado cmbFormato los registros existentes en la tabla FORMATO_PELICULA Public Sub ActualizarFormatos() Declaramos las variables Dim i As Integer Contador Dim rsFormatos As Recordset Recordset Dim dbCDs As Database Base de datos Borramos el combo cmbFormato.Clear Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Seleccionamos los formatos Set rsFormatos = dbCDs.OpenRecordset _ (SELECT * FROM FORMATO_PELICULA ORDER_ BY DESCRIPCION, dbOpenDynaset) Inicializamos el contador
184 Curso
i=1 Recorremos todos los registros Do While Not rsFormatos.EOF Cargamos el texto en el combo cmbFormato.AddItem rsFormatos!DESCRIPCION Redimensionamos el vector respetando los datos existentes ReDim Preserve FormatosPeliculas(i) Guardamos el ID correspondiente en el vector de formatos FormatosPeliculas(i) = rsFormatos!ID Incrementamos el contador i=i+1 Pasamos al siguiente registro rsFormatos.MoveNext Iteramos Loop rsFormatos.Close Cerramos el recordset dbCDs.Close Cerramos la base de datos cmbFormato.ListIndex = 0 Activamos, por defecto, el primero de los registros End Sub Si bien es cierto que ya contamos con el cdigo necesario para inicializar los cuadros combinados, an no contamos con un cdigo que desencadene dicha inicializacin. Tal y como se encuentra el cdigo actualmente, lo ms lgico es que dicho desencadenante sea la propia carga del formulario (lo cual no quiere decir que ste sea el nico punto en el que deba realizarse la llamada a los procedimientos). En el cdigo asociado a este mismo evento, tambin realizaremos la inicializacin de los cuadros combinados estticos cmbCalidadImagen y cmbCalidadSonido. El resultado sera el siguiente: Private Sub Form_Load()
Visual Basic 6.0 185
Actualizamos los gneros ActualizarGeneros Actualizamos los formatos ActualizarFormatos Inicializamos los combos de calidad como Excelente cmbCalidadSonido.Text = cmbCalidadSonido.List(0) cmbCalidadImagen.Text = cmbCalidadImagen.List(0) End Sub Prximo captulo Insercin de datos relacionados en la base de datos. Adicin de los datos propios de las pelculas a la tabla PELICULAS relacionndolos con los de la tabla CDS.
186
Curso
Captulo 25
Creacin de relaciones en la base de datos
Cuando trabajamos con bases de datos relacionales, debemos enlazar registros de unas tablas con otras. Con este captulo del curso de programacin nos acercaremos a la creacin de relaciones directamente desde la aplicacin.
La utilizacin de bases de datos relacionales ofrece una serie de ventajas bastante considerables que iremos conociendo poco a poco a medida que vayamos programando el editor. La principal, que se har evidente a lo largo de la prctica de este captulo del curso, es que sin ms que guardar el identificador de un registro correspondiente a una tabla en otra tabla, nos aseguraremos la posibilidad de consultar posteriormente los datos como si de una sola se tratase. En lo que al caso que nos compete se refiere, tenemos un ejemplo muy significativo en el proceso de alta de una pelcula. Primero hemos de crear un nuevo registro en la tabla CDS, donde se almacenan datos generales, correspondientes al CD en s. Posteriormente, en la tabla PELCULAS, guardamos los datos propios de la pelcula (reparto, director, gnero, etctera) y, finalmente, debemos guardar, si procede, las cartulas asociadas a esa pelcula en la tabla CARTULAS. Tal y como est diseada la base de datos, para mantener todas esas relaciones bastara con especificar en los registros correspondientes de las tablas CARTULAS y PELCU-
187
LAS el campo ID del registro correspondiente en CDS en los campos ID_CD e ID respectivamente. Actualizacin dinmica de los datos Uno de los efectos directos del uso de relaciones es la actualizacin dinmica de los datos de las consultas. El diseo de la aplicacin trata de mostrarnos, como ya comentamos en el captulo anterior del curso, las diferencias entre las distintas alternativas. En el caso concreto de las pelculas, utilizamos tablas independientes para almacenar el gnero y el formato de las pelculas, mientras que el tipo de cdigo de reproduccin es un campo de texto ms. En la prctica, la principal diferencia que encontraremos es que si modificamos un registro de la tabla GENERO_PELCULA, todas aquellas pelculas que tengan asociado ese gnero se mostrarn con los nuevos datos. Por el contrario, si queremos modificar el nombre de un cdigo de reproduccin, tendramos que actualizar cada uno de los registros que contuviesen ese cdigo.
lculas se realizar exclusivamente desde este formulario, no tenemos necesidad de trasladarlo a ningn mdulo. A continuacin proponemos un cdigo que asociar al evento click sobre el botn cmdAceptar: Procedimiento asociado a la pulsacin del botn cmdAceptar Private Sub cmdAceptar_Click() Declaracin de variables Dim dbCDs As Database Base de datos Dim rsNuevaPelicula As Recordset Recordset Dim Respuesta As Integer Almacn de respuesta de los msgbox Preguntamos por la existencia de un CD con el mismo ttulo If ExisteCD(txtTitulo.Text) Then En caso afirmativo informamos al usuario Respuesta = MsgBox(El nombre especificado ya est en uso. _ & vbCrLf & vbCrLf & Prueba con otro, _ vbOKOnly + vbCritical, Nombre de CD ocupado) Situamos el cursor en el ttulo y txtTitulo.SetFocus seleccionamos el texto actual para facilitar los cambios txtTitulo.SelStart = 0 txtTitulo.SelLength = Len(txtTitulo.Text) Else En caso de que el nombre est disponible Pedimos confirmacin al usuario para aadir el nuevo CD If MsgBox(Aadir la pelcula a la coleccin?, _ vbYesNo + vbQuestion, Nuevo CD) = vbYes Then Si confirma, llamamos a la funcin NuevoCD para que inserte en la base de datos aspectos generales ID_CD = NuevoCD(fmrPeliculas) Si no hay problemas en este punto, ID_CD nos indica el identificador del nuevo CD que debemos especificar en la tabla pelculas If ID_CD -1 Then Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Abrimos la tabla Peliculas asociada al recordset Set rsNuevaPelicula = dbCDs.OpenRecordset _ (SELECT * FROM PELICULAS, dbOpenDynaset) Aadimos los datos correspondientes a la pelcula
Visual Basic 6.0 189
With rsNuevaPelicula Nuevo registro .AddNew Especificamos el ID que se le asign al nuevo CD !ID = ID_CD Si el usuario especific duracin lo registramos If txtDuracion.Text Then !DURACION = txtDuracion.Text End If Para la imagen y el sonido slo almacenamos el primer caracter para optimizar el espacio en la base de datos !SONIDO = Left(cmbCalidadSonido.Text, 1) !IMAGEN = Left(cmbCalidadImagen.Text, 1) Si se especific el director se registra If txtDirector.Text Then !DIRECTOR = UCase(txtDirector.Text) End If Hacemos lo mismo con los protagonistas If txtProtagonistas.Text T !PROTAGONISTAS = UCase(txtProtagonistas.Text) End If y con los cdigos If txtCodec.Text Then !CODEC = UCase(txtCodec.Text) End If Guardamos en la base de datos si la pelcula ya est vista !VISIONADA = optVisionadaSi.Value Guardamos los ID de gnero y formato obtenindolos de los vectores correspondientes !ID_GENERO = GenerosPeliculas(cmbGenero.ListIndex + 1) !ID_FORMATO = FormatosPeliculas(cmbFormato.ListIndex + 1) .Update Almacenamos el nuevo registro End With rsNuevaPelicula.Close Cerramos el recordset dbCDs.Close Cerramos la base de datos End If
190 Curso
End If End If End Sub Para que todo esto pueda funcionar, es imprescindible programar la funcin ExisteCD en el mdulo de subprogramas. La opcin que desde aqu elegimos es la siguiente: Funcin pblica que utilizaremos para comprobar que el nombre de un CD no est en uso a la hora de darlo de alta o modificar sus datos Public Function ExisteCD(Nombre As String, Optional ID As Long_ = -1) As Boolean Dim dbCDs As Database Conexin a la base de datos Dim rsDatosCD As Recordset Recordset para recorrer los registros Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Seleccionamos aquellos CDs que coincidan con Nombre Set rsDatosCD = dbCDs.OpenRecordset(SELECT * FROM CDS & _ WHERE TITULO LIKE & UCase(Nombre) & AND ID & _ ID, dbOpenDynaset) Devolvemos el valor correspondiente ExisteCD = Not (rsDatosCD.EOF) rsDatosCD.Close Cerramos el recordset dbCDs.Close Cerramos la base de datos End Function Prximo captulo
Visual Basic 6.0 191
Localizacin y almacenaje de las cartulas relacionadas con los CDs as como el tratamiento de la informacin correspondiente en la base de datos.
192
Curso
Captulo 26
Asignar imgenes a los CDs
A lo largo de este captulo del curso, veremos una forma sencilla pero muy efectiva de asignar cartulas a las pelculas, si bien este mismo sistema ser el que utilicemos posteriormente para el resto de tipos de CDs.
Para ir finalizando el desarrollo de uno de los formularios de alta de CDs (es evidente que, una vez finalizado el de pelculas, el resto de formularios sern prcticamente iguales), hemos de programar la gestin de imgenes, concretamente para poder localizarlas, consultarlas y almacenarlas. Para el apartado de bsqueda, utilizaremos una nica carpeta y un control para dilogos comunes, lo que nos facilitar enormemente la tarea. As pues, antes de asignar una cartula a un CD, la imagen debe encontrarse en dicha carpeta. Controles Image Para mostrar las imgenes correspondientes a las cartulas, utilizaremos controles Image (algunos de los cuales ya se encuentran insertados en el formulario). Este tipo de controles son ideales para la presentacin de imgenes bidimensionales, ya que soportan los formatos ms utilizados: mapas de bits, JPG, GIF, etctera. Adems, con ellos podemos hacer que una imagen se adapte al tamao del control sin ms que especificar su propiedad Stretch a True. Para cargar una imagen, asignaremos a la propiedad Picture del control el valor devuelto por la funcin propia de Visual Basic LoadPicture, la cual necesita el nombre de un archivo que contenga una imagen en un formato soportado. Tambin, necesitaremos una variable de tipo String por cada una de las cartulas que utilicemos para almacenar temporalmente la cadena que posteriormente guardaremos en la base de datos.
193
Lo primero que debemos hacer para poder gestionar las cartulas, si para ello vamos a utilizar Cuadros de dilogo comunes, es insertar un control CommonDialog sobre el formulario frmPeliculas. Previamente, es imprescindible agregar el componente a la barra de herramientas del proyecto. Para ello, accedemos al dilogo Componentes (Proyecto/Componentes) y, una vez all, activamos la entrada Microsoft Common Dialog Control 6.0. Tras aceptar, un nuevo control aparecer en la barra de herramientas. Para agregar un control de este tipo al formulario activo, basta con hacer un doble clic sobre l en la barra de herramientas. A continuacin, modificamos su nombre en la paleta de propiedades especificando, por ejemplo, cdlDialogo. Antes de programar la carga de imgenes en el formulario, debemos aclarar algunos conceptos referentes al mtodo que utilizaremos para guardar los archivos correspondientes. Para empezar, como especificamos en la descripcin del proyecto, todas las imgenes se guardarn en una carpeta llamada cartulas que estar ubicada junto al archivo ejecutable de la aplicacin. Por consiguiente, en la base de datos tan slo almacenaremos el nombre del archivo, ya que, como todos los archivos tendrn la misma ruta (secuencia de carpetas), que adems es conocida, sera redundante guardar para cada uno todo ese texto. El problema es que, si utilizamos el cuadro de dilogo Abrir para seleccionar la imagen, se nos devolver el nombre del archivo junto con la ruta completa. Antes de guardar los datos en la base de datos, necesitamos contar con una variable de mbito local en la que guardaremos el nombre del archivo sin la ruta (tal y como debe ser guardada despus). Para eliminar esa ruta y quedarnos exclusivamente con el nombre del archivo, hemos de crear, en el mdulo de subpro194 Curso
gramas comunes, una funcin a la que llamaremos EliminarRuta y cuyo cdigo podra ser el siguiente: Funcin que recibe un archivo junto con su ruta en Rutacompleta y, tras eliminar la ruta, devuelve slo el nombre del archivo Public Function EliminarRuta(Rutacompleta As String) As String Declaracin de variables Dim i As Integer Almacena donde se encuentra el primer carcter \ EliminarRuta = Rutacompleta Inicializacin i = InStr(EliminarRuta, \) Busca un \ Do While i 0 Mientras encuentre algn \ Elimina la parte izda de la cadena hasta \ EliminarRuta = Right(EliminarRuta, Len(EliminarRuta) - i) Busca un nuevo \ i = InStr(EliminarRuta, \) Loop End Function Tal y como hemos diseado el formulario para las pelculas, al pulsar sobre los botones cmdFrontal y cmdTrasera, deberamos poder seleccionar las cartulas correspondientes a la pelcula en curso y tras confirmar, dicha cartula debera presentarse en los controles imgFrontal e imgTrasera. Antes de nada, hemos de declarar las variables CaratulaFrontal y CaratulaTrasera en el formulario frmPeliculas. As pues, la declaracin de variables, en la parte superior del cdigo del formulario, quedara: Forzamos declaracin de variables Option Explicit Declaramos la variable global en la que se almacenar
Visual Basic 6.0 195
el ID del CD sobre el que se trabaja Dim ID_CD As Long Declaramos los vectores en los que se almacenarn los identificadores de gnero y formato de pelculas Dim GenerosPeliculas() As Long Dim FormatosPeliculas() As Long Declaramos la variables en las que se almacenarn los nombres de los archivos correspondientes a las cartulas antes de guardar en la base de datos Dim CaratulaFrontal As String Dim CaratulaTrasera As String Centrndonos en la cartula frontal, y teniendo en cuenta toda la funcionalidad que podemos delegar en el dilogo Abrir, el cdigo necesario para realizar ese proceso, obviamente asociado a la pulsacin del botn de comando cmdFrontal, podra ser el siguiente: Private Sub cmdFrontal_Click() Variable donde almacenar la respuesta del msgbox Dim Respuesta As Integer Para cdlDialogo With cdlDialogo Especificamos el directorio de inicio .InitDir = .\caratulas Mostramos el dilogo Abrir .ShowOpen Si se seleccion algn archivo If .FileName Then Si el archivo no existe If Dir$(.FileName) = Then Mostramos un mensaje respuesta = MsgBox(La cartula frontal no se & _ encuentra en el directorio de Cartulas., _ vbOKOnly + vbCritical, ERROR al cargar la CARTULA FRONTAL) Especificamos que no hay imagen imgFrontal.Picture = Nothing CaratulaFrontal =
196 Curso
Else Si se encuentra alguna imagen La cargamos en imgFrontal imgFrontal.Picture = LoadPicture(CStr(.FileName)) Guardamos provisionalmente el nombre del archivo CaratulaFrontal = EliminarRuta(CStr(cdlDialogo.FileName)) End If Else Si no se seleccion ningn archivo Especificamos que no hay imagen imgFrontal.Picture = Nothing CaratulaFrontal = End If End With End Sub Exactamente igual, procedemos a programar el botn cmdTrasera: Private Sub cmdTrasera_Click() Variable donde almacenar la respuesta del msgbox Dim Respuesta As Integer Para cdlDialogo With cdlDialogo Especificamos el directorio de inicio .InitDir = .\caratulas Mostramos el dilogo Abrir .ShowOpen Si se seleccion algn archivo If .FileName Then Si el archivo no existe If Dir$(.FileName) = Then Mostramos un mensaje respuesta = MsgBox(La cartula Trasera no se & _ encuentra en el directorio de Cartulas., _ vbOKOnly + vbCritical, ERROR al cargar la CARTULA TRASERA) Especificamos que no hay imagen imgTrasera.Picture = Nothing
Visual Basic 6.0 197
CaratulaTrasera = Else Si se encuentra alguna imagen La cargamos en imgTrasera imgTrasera.Picture = LoadPicture(CStr(.FileName)) Guardamos provisionalmente el nombre del archivo CaratulaTrasera = EliminarRuta(CStr(cdlDialogo.FileName)) End If Else Si no se seleccion ningn archivo Especificamos que no hay imagen imgTrasera.Picture = Nothing CaratulaTrasera = End If End With End Sub Prximo captulo
198
Curso
Poco a poco, nos acercamos ms a la finalizacin de nuestro proyecto. El prximo captulo, veremos la creacin de un formulario donde poder observar las imgenes de las cartulas ampliadas.
199
200
Curso
Captulo 27
Zoom en las cartulas
En este captulo vamos a ver una manera de desarrollar un formulario en el que sea posible ver ampliadas las imgenes de las cartulas de los CDs, ya que, por cuestiones de espacio, las imgenes que aparecen en los formularios principales pueden ser un tanto pequeas.
A pesar de que el proyecto contempla la posibilidad de anotar bastante informacin acerca de cada CD, lo cierto es que las cartulas pueden aportar informacin complementaria, como escenas de un juego, la lista de canciones de un CD de audio o la sinopsis de una pelcula. El problema es que el tamao que est actualmente destinado a albergar las cartulas en el formulario fmrPeliculas es, por necesidad, demasiado pequeo, por lo que sera conveniente habilitar de algn modo la posibilidad de ampliar la imagen a voluntad. Concretamente, lo que desarrollaremos en este captulo del curso es que tras hacer un doble clic sobre la imagen del formulario fmrPeliculas, emerja una nueva ventana en la que la imagen pueda contemplarse con una mayor nitidez. Por tanto, hemos de disear el formulario fmrCaratulaZoom, programarlo para aumentar el tamao de las imgenes dejndolas centradas en l y por ltimo, programar el lanzamiento de la ventana.
su nombre: imgCaratulaZoom y su propiedad Stretch a True, ya que el resto de los parmetros sern especificados en tiempo de ejecucin. En lo referente a la carga de las cartulas en el formulario, puesto que se utilizar el mismo indistintamente para las frontales y para las traseras (que tienen distintas proporciones), hemos de programar que, en funcin del tipo de cartula que se trate, las dimensiones y la situacin del control imgCaratulaZoom se establezcan de forma automtica. Recordando la forma en que cargbamos las imgenes en la entrega anterior del curso, el cdigo del procedimiento CargarCaratula podra ser el siguiente: Procedimiento que muestra la imagen Necesita 2 parmetros: Caratula: contiene el nombre del archivo que contiene la imagen Frontal: informa si la cartula es la frontal o la trasera Public Sub CargarCaratula(Caratula As String, _ Frontal As Boolean) Para imgCaratulaZoom With imgCaratulaZoom Fijamos la altura .Height = 7000 Cargamos la imagen, para lo que concatenamos el directorio de la aplicacin con el nombre del fichero .Picture = LoadPicture(App.Path & _ \caratulas\ & Caratula) Centramos verticalmente la imagen .Top = (fmrCaratulaZoom.ScaleHeight - 7000) / 2 Si la caratula es frontal If Frontal Then Especificamos una anchura de 7000 twips .Width = 7000 Si es trasera Else La anchura es de 8900 .Width = 8900
202 Curso
End If Centramos horizontalmente la imagen .Left = (fmrCaratulaZoom.ScaleWidth - .Width) / 2 Actualizamos .Refresh End With End Sub El siguiente paso consiste en programar la inclusin en la base de datos de las referencias a las imgenes para que al consultar los CDs se mantenga esa informacin. Para ello, empezaremos creando un nuevo procedimiento en el mdulo de subprogramas en el que crearemos los registros correspondientes en la base de datos. El cdigo propuesto es el siguiente: Procedimiento que guarda en la tabla CARATULAS los nombres de los archivos correspondientes a las cartulas dentro de la carpeta destinada a tal efecto Public Sub NuevaCaratula(ID_CD As Long, CaratulaFrontal As String, _ CaratulaTrasera As String) Necesita: ID_CD: Id del CD que preserva la referencia entre tablas CaratulaFrontal: Nombre del archivo que contiene la imagen de la cartula frontal CaratulaTrasera: Nombre del archivo que contiene la imagen de la cartula trasera Dim rsNuevaCaratula As Recordset Dim dbCDs As Database Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Abrimos el recordset con la tabla CARATULAS Set rsNuevaCaratula = dbCDs.OpenRecordset(SELECT *FROM CARATULAS,_ dbOpenDynaset) Con el recordset With rsNuevaCaratula
Visual Basic 6.0 203
Abrimos un nuevo registro .AddNew Almacenamos el ID del CD !ID_CD = ID_CD Si alguna de las cartulas est vaca le asignamos la imagen comodn If CaratulaFrontal = Then !Frontal = ImagenNoDisponible.gif Else !Frontal = CaratulaFrontal End If If CaratulaTrasera = Then !TRASERA = ImagenNoDisponible.gif Else !TRASERA = CaratulaTrasera End If Actualizamos la base de datos para almacenar los cambios .Update End With Cerramos el recordset rsNuevaCaratula.Close Cerramos la base de datos dbCDs.Close End Sub Adems, hemos de modificar el procedimiento asociado a la confirmacin de los datos del CD que se desencadena al pulsar el botn cmdAceptar del formulario fmrPeliculas. Para ser ms concretos, debemos aadir a la secuencia una llamada al procedimiento NuevaCaratula que acabamos de crear. El cdigo final de este procedimiento sera el siguiente: Procedimiento asociado a la pulsacin del botn cmdAceptar Private Sub cmdAceptar_Click() Declaracin de variables
204 Curso
Dim dbCDs As Database Base de datos Dim rsNuevaPelicula As Recordset Recordset Dim Respuesta As Integer Almacn de respuesta de los msgbox
Preguntamos por la existencia de un CD con el mismo ttulo If ExisteCD(txtTitulo.Text) Then En caso afirmativo informamos al usuario Respuesta = MsgBox(El nombre especificado ya est en uso. _ & vbCrLf & vbCrLf & Prueba con otro, _ vbOKOnly + vbCritical, Nombre de CD ocupado) Situamos el cursor en el ttulo y txtTitulo.SetFocus seleccionamos el texto actual para facilitar los cambios txtTitulo.SelStart = 0 txtTitulo.SelLength = Len(txtTitulo.Text) Else En caso de que el nombre est disponible Pedimos confirmacin al usuario para aadir el nuevo CD If MsgBox(Aadir la pelcula a la coleccin?, _ vbYesNo + vbQuestion, Nuevo CD) = vbYes Then Si confirma, llamamos a la funcin NuevoCD para que inserte en la base de datos los aspectos generales ID_CD = NuevoCD(fmrPeliculas) Si no hay problemas en este punto, ID_CD nos indica el identificador del nuevo CD que debemos especificar en la tabla pelculas If ID_CD -1 Then Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Abrimos la tabla Peliculas asociada al recordset Set rsNuevaPelicula = dbCDs.OpenRecordset _ (SELECT * FROM PELICULAS, dbOpenDynaset) Aadimos los datos correspondientes a la pelcula With rsNuevaPelicula Nuevo registro .AddNew Especificamos el ID que se le asign al nuevo CD !ID = ID_CD Si el usuario especific duracin lo registramos If txtDuracion.Text Then !DURACION = txtDuracion.Text End If Para la imagen y el sonido slo almacenamos el
Visual Basic 6.0 205
primer caracter para optimizar el espacio en la base de datos !SONIDO = Left(cmbCalidadSonido.Text, 1) !IMAGEN = Left(cmbCalidadImagen.Text, 1) Si se especific el director se registra If txtDirector.Text Then !DIRECTOR = UCase(txtDirector.Text) End If Hacemos lo mismo con los protagonistas If txtProtagonistas.Text Then !PROTAGONISTAS = UCase(txtProtagonistas.Text) End If y con los cdigos If txtCodec.Text Then !CODEC = UCase(txtCodec.Text) End If Guardamos en la base de datos si la pelcula ya est vista !VISIONADA = optVisionadaSi.Value Guardamos los ID de gnero y formato obtenendolos de los vectores correspondientes !ID_GENERO = GenerosPeliculas(cmbGenero.ListIndex + 1) !ID_FORMATO = FormatosPeliculas(cmbFormato.ListIndex + 1) .Update Almacenamos el nuevo registro End With rsNuevaPelicula.Close Cerramos el recordset dbCDs.Close Cerramos la base de datos Si alguna de las cartulas est especificada If CaratulaFrontal Or CaratulaTrasera Then Las guardamos en la base de datos Call NuevaCaratula(ID_CD, CaratulaFrontal, CaratulaTrasera) End If End If End If End If End Sub
206 Curso
Captulo 28
Gestin de gneros de pelculas (1 de 2)
Cmo gestionar la entrada y modificacin de registros en una tabla utilizada para almacenar un dato de una tabla principal? La solucin ms prctica es crear un nuevo formulario dedicado exclusivamente a tal efecto.
Como recordaris, al disear la base de datos sobre la que trabaja el gestor de CDs, decidimos que la mejor manera de almacenar la informacin sobre los gneros y los formatos de las pelculas (as como otros parmetros de los diferentes tipos de CDs) sera crear tablas donde se guardasen todos los distintos valores utilizados y de entre ellos elegir, en cada caso, el que resultase oportuno, evitando de este modo la duplicacin innecesaria de datos as como la confusin de valores por errores ortogrficos. Para poder trabajar inicialmente, insertamos algunos registros en la base de datos, pero para que la aplicacin sea completamente operativa hemos de habilitar, por medio de la programacin, la posibilidad de que el usuario aada ms entradas a esas mismas tablas. Tambin podra programarse la opcin de eliminar registros, pero en la solucin propuesta desestimaremos esta opcin por el escaso valor operativo que aporta, aunque contemplaremos la posibilidad de modificar registros existentes.
Formulario fmrGeneroPelicula
Lo primero que haremos ser crear el formulario fmrGeneroPelicula, a travs del cual gestionaremos la insercin y modificacin de los registros de la tabla correspondiente. Para ello, pulsamos sobre la opcin Agregar formulario del men Proyecto, y confirmamos la insercin de un nuevo formulario. A continuaVisual Basic 6.0 207
cin cambiamos las propiedades bsicas del formulario: fmrGeneroPelicula para el Nombre; Gneros de pelculas en Caption; la propiedad BorderStyle la establecemos a 3-Fixed Dialog para que no se pueda redimensionar (tambin se eliminan los botones de minimizar y maximizar). En cuanto a las dimensiones del formulario, nuestra propuesta cuenta con 5.670 twips de altura (propiedad Height) y 3.945 de anchura (propiedad Width). Por ltimo podemos especificar un icono representativo a travs de la propiedad Icon. En este momento, hemos de proceder a insertar en el nuevo formulario los controles con los que realizaremos la edicin de gneros de pelculas. Empezaremos insertando un cuadro de lista (ListBox) al que llamaremos lstGeneros en la parte superior del formulario y el cuadro de texto (TextBox), txtGenero, a travs del cual aadiremos y editaremos los distintos gneros de las pelculas. Tambin incluiremos sendas etiquetas (Label) sobre ambos controles con las que indicaremos la funcin de cada uno a travs de su propiedad Caption. Por ltimo, hemos de agregar al formulario dos botones de comando (CommandButton) que utilizaremos para confirmar la adicin de una nueva entrada en la tabla o para modificar un registro ya existente. A dichos controles los llamaremos cmdAceptar y cmdModificar respectivamente. Tambin sera conveniente formatear el texto de los nuevos controles para que exista una similitud con el resto de controles del programa. Con el formulario diseado podemos empezar a programar su funcionamiento. Antes de escribir el cdigo del formulario, vamos a insertar en el mdulo de subprogramas una funcin que nos servir para saber si el registro que estamos aadiendo ya existe en la lista, con lo que evitaremos duplicaciones en la base de datos. La razn principal por la que dicha funcin debe ir en el mdulo se debe a que tambin ser utilizada por otros formularios. Tambin sealar que la bsqueda la realizaremos de forma secuencial puesto que para un nmero reducido de registros (no es muy probable que necesitemos muchos gneros de pelcula) la bsqueda dicotmica no resulta mucho ms eficiente mientras que supone bastante complicacin a la hora de programar. Hacien208 Curso
do doble clic sobre el mdulo en el explorador de proyectos, accedemos al cdigo, al final del cual aadiremos la nueva funcin: Busca el string Cadena en el cuadro de lista Control devuelve true si encuentra algo y false en otro caso Public Function Existe(Cadena As String, Control As ListBox) As Boolean Creamos la variable contador i Dim i As Integer inicializamos i i=1 Mientras no encontremos coincidencia Do While i <= Control.ListCount And Control.List(i - 1) <> Cadena Incrementamos la i i=i+1 Loop Si hemos contado hasta el final devolvemos false En otro caso devolvemos true Para ello comparamos el nmero de elementos de la lista con el valor de i Existe = i <= Control.ListCount End Function Centrndonos en el nuevo formulario, es muy importante tener en cuenta que la tabla de gneros de pelcula cambiar a medida que insertemos o modifiquemos registros y que es conveniente que dichos cambios sean tambin presentados en el formulario. Por ello, las primeras lneas del cdigo las dedicaremos a implementar un procedimiento que refresque el contenido de la lista. Una posible solucin sera la siguiente:
Visual Basic 6.0 209
Procedimiento que borra la lista de gneros para volver a escribirla despus Se invoca tras una insercin o modificacin Private Sub ActualizarLista() Definimos variables Dim dbCDs As Database Base de datos Dim rsGeneros As Recordset Recordset Dim i As Integer Contador Borramos la lista lstGeneros.Clear Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Abrimos la tabla GENEROS_PELICULA Set rsGeneros = dbCDs.OpenRecordset (SELECT * FROM _ GENERO_PELICULA ORDER BY 2, dbOpenDynaset) Inicializamos contador i=1 Recorremos todo el recordset Do While Not rsGeneros.EOF Aadimos a la lista el campo DESCRIPCION del registro lstGeneros.AddItem rsGeneros!DESCRIPCION Redimensionamos el vector de identificadores ReDim Preserve GenerosPeliculas(i) Guardamos en l el ID del registro actual GenerosPeliculas(i) = rsGeneros!ID Incrementamos el contador i=i+1 Pasamos al siguiente registro rsGeneros.MoveNext Loop Cerramos el recordset rsGeneros.Close Cerramos la base de datos dbCDs.Close End Sub Como se puede observar en este procedimiento, es necesario contar con un vector donde almacenar los identificadores de cada uno de los gneros en el
210 Curso
orden en que estos aparecen el la lista. Adems, para evitar la creacin de variables no definidas, debemos aadir la sentencia Option Explicit al principio del documento. As pues, en la parte superior del cdigo del formulario hemos de insertar las siguientes lneas: Option explicit Declaramos un vector en el que guardaremos los ID de los gneros segn aparecen en la base de datos Dim GenerosPeliculas() As Long En cuanto al procedimiento asociado a la pulsacin del botn de comando cmdAceptar, destinado a confirmar una nueva insercin, una posible secuencia de instrucciones podra ser la que sigue: Al pulsar el botn cmdAceptar Private Sub cmdAceptar_Click() Dim dbCDs As Database Base de datos Dim rsGeneros As Recordset Recordset Dim respuesta As Integer Respuesta del MsgBox Comprobamos que no exista ese gnero If Existe(txtGenero.Text, lstGeneros) Then Si existe se lo indicamos al usuario respuesta = MsgBox(Ya existe una entrada con ese nombre _ , vbCritical, Error en el nuevo gnero) Else Sino pedimos confirmacin If MsgBox(Desea aadir el nuevo gnero de pelcula?,vbQuestion + _ vbYesNo, Nuevo gnero de pelcula) = vbYes Then Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & \CDS.mdb) Abrimos la tabla GENERO_PELICULA Set rsGeneros = dbCDs.OpenRecordset (SELECT * FROM _ GENERO_PELICULA ORDER BY 1, dbOpenDynaset)
Visual Basic 6.0 211
Con el recordset abierto With rsGeneros Creamos una nueva entrada .AddNew Guardamos en el campo DESCRIPCION el valor especificado !DESCRIPCION = txtGenero.Text Confirmamos .Update Cerramos el recordset .Close End With Cerramos la base de datos dbCDs.Close Actualizamos la lista ActualizarLista Borramos el cuadro de texto txtGenero.Text = End If End If End Sub Prximo captulo En el prximo captulo del curso de programacin terminaremos de programar el formulario fmrGeneroPelicula.
212
Curso
Captulo 29
Gestin de gneros de pelculas (2 de 2)
Con este captulo del curso de programacin, terminaremos de programar el formulario fmrGeneroPelicula.
Si algo nos est quedando claro con el importante proyecto en el que nos encontramos sumidos desde hace ya unos cuantos meses, es que incluso aquellos detalles que pueden parecer simples en su utilizacin, siempre conllevan un complejo proceso de programacin, ms an si nos esmeramos para conseguir que todo funcione lo ms correctamente posible: que no se produzcan errores inesperados, que los botones se habiliten o deshabiliten en funcin de determinadas circunstancias, que los datos se actualicen en tiempo real, etctera. En esta ocasin, y por primera vez, nos encontramos ante dos formularios idnticos en diseo y muy similares en programacin correspondientes a la edicin del listado de gneros y formatos de pelculas. Durante este captulo del curso veremos cmo rematar el primero y, basndonos en l, debemos ser capaces de implementar completamente el segundo.
Tambin es necesario que, al pulsar sobre un elemento de la lista, y suponiendo que con ello el usuario quiere indicar qu registro pretende modificar, carguemos en el cuadro de texto txtGenero esa cadena con el objetivo de facilitar la edicin de registros de la base de datos. Adems, y tambin para mejorar la utilizacin del formulario, llevaremos el foco al cuadro de texto. Esto mismo, en lenguaje Visual Basic, se traduce como sigue: 'Al hacer Click sobre el listado de gneros Private Sub lstGeneros_Click() 'Comprobamos si el listado est vaco If lstGeneros.ListIndex = -1 Then 'En ese caso deshabilitamos el botn cmdModificar cmdModificar.Enabled = False Else 'En caso contrario 'Habilitamos el botn cmdModificar.Enabled = True 'Rellenamos txtGenero con el texto pulsado txtGenero.Text = lstGeneros.List(lstGeneros.ListIndex) 'Llevamos el foco al cuadro de texto txtGenero.SetFocus End If End Sub Ahora, para evitar que se aadan entradas vacas a la base de datos, hemos de asegurarnos de que el usuario no pueda pulsar el botn de comando cmdAceptar si el cuadro de texto txtGenero est vaco. Para comprobarlo utilizaremos la funcin de Visual Basic Len, que recibe como parmetro un String y devuelve su longitud. En caso de que la longitud de la cadena sea 0, deshabilitaremos el botn de comando y en otro caso lo dejaremos habilitado. No haremos lo mismo con el botn cmdModificar, pues se entiende que lo normal es que el usuario borre el texto anterior antes de realizar la modificacin, de modo que haremos la comprobacin cuando el usuario pulse el botn pero antes de realizar el cambio en la base de datos. En cuanto al evento asociado a la modificacin del contenido en el cuadro de texto, una posible codificacin podra ser la siguiente: 'Al cambiar el texto de txtGenero Private Sub txtGenero_Change() 'Si hay algo escrito
214 Curso
If Len(txtGenero.Text) > 0 Then 'Habilitamos el botn cmdAceptar cmdAceptar.Enabled = True Else 'En caso contrario 'Lo deshabilitamos cmdAceptar.Enabled = False End If End Sub Ahora ya estamos en disposicin de programar la modificacin de los registros de la tabla GENERO_PELICULA, que ser ejecutada al pulsar el botn de comando cmdModificar y consistir en sustituir el valor actual del campo DESCRIPCION correspondiente al ltimo elemento de la lista pulsado por el usuario por el texto especificado en el cuadro de texto txtGenero. Haremos tan slo dos comprobaciones previas: que haya algn texto escrito en dicho cuadro de texto y que no se dupliquen valores en la base de datos con esa modificacin. Adems, pediremos al usuario la confirmacin de la accin para evitar errores inesperados. Con estas premisas, el resultado podra ser el siguiente: Private Sub cmdModificar_Click() 'Declaramos las variables Dim dbCDs As Database 'La base de datos Dim rsGeneros As Recordset 'El recordset Dim Respuesta As Integer 'Si txtGenero est vaco If Len(txtGenero.Text) = 0 Then 'Informamos al usuario con un mensaje de error Respuesta = MsgBox("No se puede insertar una cadena vaca", _ vbCritical, "Error en la edicin") Else 'Si el gnero ya existe If Existe(txtGenero.Text, lstGeneros) Then 'Informamos al usuario con un mensaje de error Respuesta = MsgBox("Ya existe una entrada con ese nombre", _ vbCritical, "Error en la edicin") Else 'Sino 'Pedimos confirmacin
Visual Basic 6.0 215
If MsgBox("Desea modificar el gnero seleccionado?", _ vbQuestion + vbYesNo, "Modificar gnero de pelcula") = vbYes Then 'Si el usuario confirma 'Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & "\CD'S.mdb") 'Asociamos el recordset a la tabla de gneros 'seleccionando concretamente el registro 'asociado a la entrada seleccionada Set rsGeneros = dbCDs.OpenRecordset ("SELECT * FROM " & _ "GENERO_PELICULA WHERE ID=" & _ GenerosPeliculas(lstGeneros.ListIndex + 1), dbOpenDynaset) With rsGeneros .Edit 'Editamos el registro !DESCRIPCION = txtGenero.Text 'Actualizamos la descripcion .Update 'Actualizamos la base de datos .Close 'Cerramos el recordset End With 'Cerramos la base de datos dbCDs.Close 'Actualizamos el listado ActualizarLista 'Deshabilitamos el botn cmdModificar cmdModificar.Enabled = False 'Borramos el texto de txtGenero txtGenero.Text = "" End If End If End If End Sub Un ltimo detalle que debemos tener en cuenta es la necesidad de refrescar el formulario fmrPeliculas para que el cuadro combinado cmbGenero se actualice una vez finalizado el trabajo sobre el formulario fmrGeneroPelicula. Para ello, debemos programar el evento Unload de este mismo formulario para que realice una llamada al procedimiento ActualizarGeneros del formulario fmrPeliculas que ya habamos programado en entregas anteriores. Sencillamente, el cdigo quedara como sigue:
216 Curso
'Al descargar el formulario Private Sub Form_Unload(Cancel As Integer) 'Invocamos al procedimiento ActualizarGeneros 'del formulario de pelculas fmrPeliculas.ActualizarGeneros End Sub Obviamente, el trato que hemos de dar a los formatos de las pelculas debe ser exactamente el mismo que el que hemos utilizado para gestionar los gneros. Por ello, debemos crear el formulario fmrFormatoPelicula, insertar controles similares y programar los eventos correspondientes. En lo que respecta a la base de datos, la tabla que contiene los registros asociados a los formatos se llama FORMATO_PELICULA. La codificacin final de este formulario tambin se incluye en el proyecto que, como cada captulo, puede ser descargado desde la Web de la revista. Por ltimo, y para que los nuevos formularios puedan ser accesibles, hemos de aadir en algn punto del programa una llamada a fmrFormatoPelicula y otra a fmrGeneroPelicula. Como recordaris, al disear el formulario MDI padre fmrPrincipal incluimos una serie de mens. Concretamente en el men Pelculas agregamos dos entradas etiquetadas como Editar gnero y Editar Formato. Para que al pulsar dichos comandos aparezcan los formularios correspondientes hemos de acceder a la ventana de cdigo del formulario fmrPrincipal y programar el evento Clic sobre dichos controles. Adems, para que los formularios estn permanentemente activos hasta que sean cerrados, hemos de aadir el parmetro 1 al mtodo Show relacionado con ellos. De este modo, el cdigo a aadir en el formulario fmrPrincipal sera el siguiente: 'Procedimiento asociado a la pulsacin 'de la entrada mnuPeliculasFormato de los 'mens, que debe mostrar el formulario 'vmrFormatoPelicula y bloquear la aplicacin 'hasta que sea cerrado Private Sub mnuPeliculasFormato_Click() 'Mostrar el formulario correspondiente fmrFormatoPelicula.Show 1 End Sub
Visual Basic 6.0 217
'Procedimiento asociado a la pulsacin 'de la entrada mnuPeliculasGenero de los 'mens, que debe mostrar el formulario 'vmrGeneroPelicula y bloquear la aplicacin 'hasta que sea cerrado Private Sub mnuPeliculasGenero_Click() 'Mostrar el formulario correspondiente fmrGeneroPelicula.Show 1 End Sub
218
Curso
Captulo 30
Gestin de cdigos de barras
Lo primero que debemos hacer para poder imprimir los cdigos de barras es instalar en nuestro equipo (concretamente en el directorio Fonts de la carpeta de instalacin de Windows) el tipo de letra BarCode que incluimos en el proyecto de este captulo y que podemos. Para acceder mediante cdigo a este tipo de letra tendremos que utilizar el nombre interno IDAUTOMATIONHC39M como veremos ms adelante. En cuanto a la generacin del cdigo, lo ms sencillo es aadir al mdulo una funcin llamada GenerarISBN que se invoca al ser pulsado el botn cmdGenerarISBN y cuyo valor devuelto (un string) se escribe directamente en el cuadro de texto txtISBN. El cdigo de la funcin podra ser el siguiente: 'Funcin que genera el cdigo de barras para un CD Public Function GenerarISBN() As String 'Declaracin de variables Dim rsISBN As Recordset 'Recordset Dim dbCDs As Database 'Base de datos Dim i As Integer 'Contador 'Abrimos la base de datos Set dbCDs = OpenDatabase(App.Path & "\CD'S.mdb") 'Abrimos el recordset Set rsISBN = dbCDs.OpenRecordset("SELECT ISBN FROM CDS _ ORDER BY 1", dbOpenDynaset) 'Si recin abierto el rsISBN estamos en el final 'es porque est vaco If rsISBN.EOF Then 'Entonces inicializamos la numeracin GenerarISBN = "0000000" Else 'Sino 'Vamos al ltimo registro rsISBN.MoveLast
Visual Basic 6.0 219
'Pasamos a nmero el texto y sumamos 1 GenerarISBN = CStr (CLng (rsISBN!ISBN) + 1) 'Rellenamos con "0" el string Do While Len(GenerarISBN) < 7 GenerarISBN = "0" + GenerarISBN Loop End If 'Cerramos el recordset y la base de datos rsISBN.Close dbCDs.Close End Function En cuanto la instruccin asociada a la pulsacin del botn de comando cmdGenerarISBN podra ser tan sencilla como la siguiente: Private Sub cmdGenerarISBN_Click() 'Generamos el cdigo de barras txtISBN.Caption = GenerarISBN End Sub Para imprimir los cdigos de barras de los discos utilizaremos hojas de tamao DIN-A4 de pegatinas cortadas. En nuestro caso particular, cada hoja de pegatinas cuenta con 80 unidades (16 filas x 5 columnas) y con un pequeo margen en todo el permetro para que todas las etiquetas sean imprimibles. Despus de realizar distintas pruebas de calibracin, con estas caractersticas el procedimiento que imprimira una etiqueta concreta en la impresora predeterminada del equipo, y que deberamos agregar al mdulo de subprogramas, qued de la siguiente manera: 'Procedimiento que imprime un cdigo de barras en 'una pegatina concreta 'Requiere el ttulo del CD (que se imprime en la parte 'superior de la pegatina), el nmero del cdigo (que 'se imprime en la parte inferior), la fila y la columna 'donde se debe imprimir, siempre contando con una hoja 'de unas caractersticas concretas Public Sub ImprimirISBN(Titulo As String, ISBN As String, Fila As Integer, Columna As Integer)
220 Curso
'Declaracin de variables Const Twip = 567 'N de twips por cm Const AnchoPegatina = 3.8 'En centmetros Const AltoPegatina = 1.7 'En centmetros Const Arriba = 1.2 'Coordenadas en cm para 'la posicin dentro de la pegatina Const Izquierda = 1.1 'Coordenadas en cm para 'la posicin dentro de la pegatina 'Tipo de letra del ttulo Printer.Font = "Comic Sans MS" 'Tamao de letra del ttulo Printer.FontSize = 6 'Posicin de impresin del ttulo Printer.CurrentX = Twip * (AnchoPegatina _ * (Columna - 1) + Izquierda) Printer.CurrentY = Twip * (AltoPegatina * _ (Fila - 1) + Arriba) 'Imprimimos los 20 primeros caracteres del ttulo Printer.Print Left(UCase(Titulo), 20) 'Tipo de letra del cdigo Printer.Font = "IDAUTOMATIONHC39M" 'Tamao del cdigo Printer.FontSize = 10 'Posicin de impresin del cdigo Printer.CurrentX = Twip * (AnchoPegatina * _ (Columna - 1) + Izquierda) Printer.CurrentY = Twip * (AltoPegatina * _ (Fila - 1) + Arriba) + 200 'Imprimimos el cdigo entre asteriscos, requisito 'imprescindible para que pueda ser interpretado por 'el lector Printer.Print "*" & ISBN & "*" End Sub Aunque ms adelante disearemos y programaremos un formulario a travs del cual imprimir mltiples cdigos de barras de diferentes discos de una sola vez, tambin resulta interesante que desde los propios formularios de
Visual Basic 6.0 221
edicin, adicin o consulta se pueda imprimir el cdigo correspondiente al artculo en curso. En este caso, no habr ninguna duda sobre qu cdigo imprimir, pero existir la disyuntiva sobre en qu pegatina hacerlo, pues no siempre estar disponible la de la posicin 1-1 (primera fila y primera columna). Concretamente para que el usuario pueda elegir una pegatina libre, hemos de disear un formulario que, bsicamente, contendr sendos ComboBox correspondientes a la seleccin de la fila y la columna donde se encuentra la pegatina y un par de botones de comando con los que confirmar la impresin o salir sin hacer nada. Los cuadros combinados deben llamarse cmbFila y cmbColumna y cargarse con valores de 1 a 16 y de 1 a 5 respectivamente (lo haremos mediante cdigo). En cuanto a los botones de comando sus nombres han de ser cmdImprimir y cmdSalir. En cuanto al cdigo de este formulario, tan slo cabe destacar que debe contar con dos variables de mbito global (accesibles desde todo el formulario) que han de ser inicializadas desde fuera del formulario (por lo que hay que programar un procedimiento pblico para hacerlo). Esas variables se corresponden con el nombre y el cdigo que deben aparecer en la pegatina. En cuanto a la impresin propiamente dicha, se realizar haciendo una llamada al procedimiento ImprimirISBN que ya tenemos programado. El cdigo del formulario podra ser el siguiente: Option Explicit 'Para forzar la declaracin de variables 'Declaracin de variables de mbito global Dim Titulo As String 'Para almacenar el ttulo Dim ISBN As String 'Para almacenar el cdigo 'Al pulsar el botn cmdImprimir Private Sub cmdImprimir_Click() 'Calidad de impresin alta Printer.PrintQuality = -4 'Llamada al procedimiento ImprimirISBN 'donde pasamos el ttulo, el cdigo, y los nmeros 'que aparecen en los combos Call ImprimirISBN(Titulo, ISBN, _ cmbFila.ListIndex + 1, cmbColumna.ListIndex + 1) 'Imprimir Printer.EndDoc 'Descargar el formulario
222 Curso
Unload fmrImprimirISBN End Sub Private Sub cmdSalir_Click() 'Descargar el formulario Unload fmrImprimirISBN End Sub 'Al cargar el formulario Private Sub Form_Load() Dim i As Integer 'Inicializamos el combo de filas For i = 1 To 16 cmbFila.AddItem i Next 'Lo ponemos a valor 1 cmbFila.ListIndex = 0 'Inicializamos el combo de columnas For i = 1 To 5 cmbColumna.AddItem i Next 'Lo ponemos a valor 1 cmbColumna.ListIndex = 0 End Sub 'Procedimiento pblico con el que cargamos 'el ttulo y el cdigo del CD 'en la variables globales Public Sub ImprimirCodigo(TituloCD As String, ISBNCD As String) Titulo = TituloCD ISBN = ISBNCD End Sub En cuanto al cdigo asociado a la pulsacin del botn cmdImprimirISBN del formulario fmrPeliculas, hay que destacar que pueden evitarse algunos errores o imprecisiones tan slo con comprobar que el CD cuenta con un tVisual Basic 6.0 223
tulo y que su cdigo de barras ha sido generado. Una posible codificacin podra ser: 'Al pulsar cmdImprimirISBN Private Sub cmdImprimirISBN_Click() 'Variable donde guardar la respuesta Dim respuesta As Integer 'Si no hay ttulo especificado If txtTitulo.Text = "" Then 'Mostramos error respuesta = MsgBox("Es necesario especificar un ttulo al CD.", _ vbOKOnly + vbCritical, "Error al imprimir cdigo de barras") Else 'Sino 'Si no hay cdigo de barras generado If txtISBN.Caption = "" Then respuesta = MsgBox("Es necesario generar el cdigo antes de imprimir.", _ vbOKOnly + vbCritical, "Error al imprimir cdigo de barras") Else 'Sino 'Inicializamos las variables globales de fmrImprimirISBN Call fmrImprimirISBN.ImprimirCodigo(txtTitulo.Text, txtISBN.Caption) 'Lanzamos el formulario fmrImprimirISBN.Show 1 End If End If End Sub
224
Curso
Captulo 31
ltimas nociones
Despus de muchos captulos conociendo un lenguaje de programacin tan popular y didctico como Visual Basic, ha llegado el momento de poner punto y final al curso con unas pautas a seguir para finalizar el gestor de CD que estbamos programando ltimamente.
Tras finalizar la programacin del formulario de alta de pelculas, hemos decidido dar por finalizado el Curso de Programacin, no sin antes aportaros algunos consejos para que os resulte ms sencillo terminar con xito el Gestor. Adems, como complemento, hemos puesto a vuestra disposicin en la Web de la revista un proyecto que incluye los formularios ms importantes de la aplicacin. Prximamente, incluiremos en uno de nuestros CDs una versin instalable as como el proyecto completo para que dispongis de la solucin ante problemas puntuales. Por el momento, comentaremos algunos de los aspectos ms destacables de los formularios que incluimos en el proyecto de este captulo.
Aspectos generales
Con el objetivo de disponer del formulario sobre el que estbamos trabajando nada ms iniciar la aplicacin, habamos configurado la apertura de fmrPeliculas junto al formulario MDI principal. Segn avancemos en la programacin de la aplicacin, comprobaremos que una solucin ms eficiente sera no cargar un formulario concreto inicialmente, sino dejar a criterio del usuario la apertura del formulario que estime oportuno. Otro detalle concerniente al formulario fmrPrincipal, es la informacin que, a la hora de disearlo, decidimos incluir en su parte inferior, concretamente en la barra de estado. Esta informacin corresponde, adems de a la fecha y la hora, al nmero de CDs que forman la coleccin y, de ellos, los que se encuentran
Visual Basic 6.0 225
prestados en ese momento. Con respecto a ambos elementos, por tratarse de informacin susceptible de cambiar en tiempo de ejecucin, hemos de controlar todos aquellos puntos en los que los datos deben ser actualizados y proceder en consecuencia. Para ello es recomendable contar con un procedimiento para cada una de las tareas a los que tan slo haya que invocar en el momento preciso.
En cuanto a los formularios del resto de tipos de CD, la forma de programarlos y de cara al usuario, tambin al disearlos, hemos de tratar de que el resultado final sea lo ms parecido posible a los formularios relativos a las pelculas. Pensando en ello, en el momento de distribuir los controles en el formulario fmrPeliculas ya habamos creado tres marcos que actuaban de contenedores de controles y que haban sido distribuidos en funcin de las tablas de la base de datos a las que afectaban: en el marco frmDatosCD colocbamos aquellos controles relacionados con los campos de la tabla CDS; en frmCaratulas los relativos a las cartulas y, slo en el marco frmDatosPelicula estaban incluidos los que afectaban directamente a la tabla PELICU226 Curso
LAS o a las tablas subyacentes. Sera concretamente este marco el que deberamos sustituir por el correspondiente a la tabla involucrada en el formulario a la hora de programar la adicin, edicin o consulta de juegos, programas, etctera. Puesto que la barra de herramientas propuesta cuenta con botones genricos para el trato de CDs mientras que en la prctica existirn formularios concretos en funcin de la naturaleza del compacto, es evidente que de alguna manera el usuario ha de poder seleccionar el tipo de CD a aadir, por ejemplo, despus de pulsar el primero de los botones de la barra tbrPrincipal. Una posibilidad, la que nosotros hemos elegido, es disear un formulario emergente de tamao discreto que cuente con todas las opciones posibles adems de un botn de confirmacin (que adems puede variar en funcin del botn pulsado por el usuario). Con algunas de las opciones de la barra, la seleccin ha de ser distinta. As, si lo que el usuario desea es modificar un CD, ha de bastar con que indique el identificador del CD objetivo (en nuestro caso el cdigo de barras) y, con ese dato, el encargado de mostrar el formulario correspondiente ha de ser el propio programa. En cuanto a los listados de CDs, sera lgico dudar entre crear un nico formulario en el que listarlos todos, independientemente de su tipo, o bien listarlos utilizando formularios especficos. Nosotros hemos optado por esta segunda opcin que, si bien supone un mayor coste en tiempo de programacin, lo cierto es que nos aporta la posibilidad de incluir en los listados informacin propia segn el tipo de CD. Tambin proponemos la utilizacin de controles ListView para crear
Visual Basic 6.0 227
los listados que, aunque no permiten un enlace directo con la base de datos, resultan muy vistosos y operativos (pueden programarse para que, al pulsar sobre la cabecera de una de las columnas, el listado sea ordenado alfabticamente segn su contenido). Tambin sera conveniente aadir a estos formularios, junto a los listados, botones de comando con los que poder aadir, modificar o eliminar elementos de la coleccin (concretamente el elemento seleccionado en el listado). Antes de poder gestionar los prstamos de CDs, hemos de programar todo lo relacionado con los amigos. As, tendremos que poder aadir y modificar amigos de la lista. No conviene poder eliminarlos porque, tal y como se encuentra diseada la base de datos, de hacerlo, se perdera todo el historial de prstamos asociados a esa persona. Crearemos, entonces, el formulario fmrAmigos con el que gestionaremos el alta y las modificaciones de los amigos a los que les prestaremos los CDs, fmrDetallesAmigos con el que consultaremos sus datos personales y fmrLocalizarAmigo en el que mostraremos un listado con todos nuestros contactos para poder trabajar despus con alguno de ellos en los anteriores formularios. Cuando ya contemos con contactos a los que poder prestar nuestros CDs, necesitaremos un formulario a partir del cual anotar la relacin de compactos prestados. En este formulario hemos de poder localizar de la forma ms rpida y sencilla posible los elementos de nuestra coleccin. Para ello, nosotros siempre hemos propuesto la utilizacin de cdigos de barras (aunque no se tenga pistola lectora, siempre se puede introducir el cdigo a mano) pero en la solucin definitiva no hemos descartado la posibilidad de localizar los CDs a travs de su nombre, de modo que hemos
228 Curso
incluido un botn de bsqueda y un listado en el que aparecen las coincidencias. Desde ese listado resulta muy sencillo incluir una referencia en la relacin de elementos prestados. Adems el usuario debe contar con la posibilidad de modificar la fecha, que si bien se entiende que por defecto ha de figurar la del da en el que se anote el prstamo, ha de ser factible anotar prstamos con fecha diferente. Tambin en este mismo formulario se encontrar un listado con todos los contactos donde elegiremos aquel que se llevar temporalmente parte de la coleccin. Una vez confirmado un prstamo, la nica forma de modificarlo es por medio del formulario de devoluciones. A travs de ese formulario, informaremos a la aplicacin cuando alguno de los CDs prestados sea devuelto. Este formulario, al que nosotros hemos llamado fmrDevolucion, debe contener todos los controles necesarios para poder realizar fcilmente este proceso. Para los usuarios que dispongan de lector de cdigo de barras, lo ms prctico es que, una vez tenga el CD en su mano, con slo acceder el formulario y acercar la pistola a la caja, el programa registre la devolucin. Por otro lado, para quienes utilicen un mtodo ms domstico, es conveniente mostrar una lista de los compactos prestados y, sin ms que pulsar sobre aquel que ha sido devuelto todo quede registrado de manera automtica. En lo que a informacin propiamente dicha se refiere, el diseo de la aplicacin exige que contemos con un formulario con el que consultar qu CDs se encuentran prestados y para cada uno de ellos, quin es el amigo que lo tiene en su posesin. Este formulario puede ser programado de muchsimas formas diferentes,
Visual Basic 6.0 229
aunque es imprescindible que nos aporte un mnimo de informacin. Dicha informacin puede ser complementada por otros formularios. Por ejemplo, en el listado de CDs, podemos indicar de alguna manera cules son los que estn prestados e, incluso, quin es el amigo que lo tiene en su poder. Nuestra propuesta es que, en todos los listados, los CDs prestados aparezcan en color rojo y que al ponernos sobre ellos con el puntero del ratn, emerja un rtulo (propiedad ToolTipText) que nos indique a qu amigo se le hemos prestado. Tambin hemos aadido un formulario que, por amigos, nos muestra una relacin detallada de todos los discos que en algn momento le han sido prestados, destacando adems los que an continan en su posesin.
230
Curso
Vocabulario
Array: Conjunto de instancias (variables o controles) de un mismo tipo que comparten el mismo nombre. Base de datos: Conjunto de datos relacionados que se almacenan en tablas cuyos campos se encuentran claramente definidos. Su fin es el almacenaje masivo de datos que puedan ser recuperados de una forma rpida y sencilla en base a determinados criterios. Cdigo de programa: Coleccin de instrucciones en un determinado lenguaje de programacin que indican las tareas que debe realizar la aplicacin. Cdigo mquina: Conjunto de instrucciones a muy bajo nivel que el procesador es capaz de interpretar y ejecutar directamente. Comentarios: Texto dentro del cdigo de un programa que el compilador ignora. Se utiliza para documentar el programa de cara a futuras modificaciones. Compiladores Herramientas que interpretan el cdigo de un programa escrito en un lenguaje de programacin y lo pasan a cdigo mquina. Constantes: Estructuras similares a las variables pero que no cambian de valor durante el programa. Pueden ser declaradas por el usuario o estar predefinidas por el lenguaje utilizado. Controles: Objetos que se pueden manipular en tiempo de diseo o ejecucin para presentar la informacin. Se insertan en los formularios. Cuadros combinados: (ComboBox)Controles bsicos de Windows en todas sus versiones. Son una combinacin de los cuadros de texto simples (TextBox) y los cuadros de lista desplegable (ListBox). Entorno de programacin visual: Entorno de programacin para sistemas operativos de ventanas que facilita el diseo de la apariencia del programa.
Visual Basic 6.0 231
Eventos: Acciones (normalmente realizadas por el usuario) que se producen en tiempo de ejecucin de un programa. Son eventos: mover el ratn, pulsar una tecla, pulsar un botn del ratn, etctera. Formularios: Son la base de la programacin visual; contienen los controles de una aplicacin. ndice de un array: Nmero entero (o elemento perteneciente a un conjunto ordenado) que indica la posicin (relativa al conjunto utilizado) de un elemento en el array. Interfaz: Mecanismo de intercambio de informacin. En informtica existen varios tipos de interfaces: entre software y hardware, entre software y usuario, entre hardware y hardware. Lenguaje de programacin: Lenguaje formado por identificadores, comandos y smbolos (de puntuacin, lgicos u operacionales) con los que se expresan las instrucciones a seguir al ejecutar un programa. Librera: Archivo independiente con informacin potencialmente utilizable por varias aplicaciones. En programacin se usan para reutilizar cdigo. Mtodos: En programacin orientada a objetos, un mtodo es una subrutina asociada a un objeto (o a una clase de objetos). Mdulo: Archivo de cdigo, adjunto a un proyecto que contienen clases, funciones o procedimientos a los que se tiene acceso desde dicho proyecto. Se utilizan a modo de librera. Palabras reservadas: En programacin son aquellas palabras propias del lenguaje utilizado que tienen significado por s mismas y que no pueden ser utilizadas para nombrar controles, variables, constantes, etc. Parmetros: (de funciones y procedimientos) son valores necesarios para la realizacin de las subrutinas. Estos parmetros deben ser de un tipo predeterminado (Visual Basic permite cierta flexibilidad en este aspecto) y pueden ser constantes y/o variables segn el caso.
232
Curso
Parmetros (de funciones y procedimientos:) Son valores necesarios para la realizacin de las subrutinas. Estos parmetros deben ser de un tipo predeterminado y pueden ser constantes y/o variables segn el caso. Prefijo Reddick: Abreviatura de tres letras minsculas que se antepone, por convenio, al nombre de un objeto segn su naturaleza. Aunque al principio resulte confuso, su utilizacin ayuda a medida que crece el tamao del programa. Procedimientos: Tambin llamados subrutinas, son aquellos trozos de programa que son invocados de manera independiente. Si devuelven algn valor al punto donde se invocaron se denominan funciones, aunque algunos lenguajes de programacin (por ejemplo C) no distinguen entre unos y otros. Programacin: Proceso a travs del cul se crea el software. Consiste en escribir el cdigo del programa en un determinado lenguaje de programacin para despus compilarlo. Programacin Orientada a Objetos (POO): Evolucin de los lenguajes estructurados hacia la simplificacin y reutilizacin de cdigo. En la POO, cada objeto (predefinido o definido por el usuario) dispone de sus propias propiedades y mtodos dependiendo de la clase de objetos a la que pertenece. Propiedad: Cada uno de los aspectos caractersticos de un tipo de control o formulario. (p. ejemplo: nombre, caption, etc.) Proyecto: Conjunto de formularios que conforman una aplicacin. Recordset: Objeto de acceso a los datos de una base de datos. Existen diferentes tipos de Rescordset que se utilizan en funcin del trabajo que se vaya a realizar en la base de datos. Registro de una propiedad: Valor que toma la propiedad de un control o formulario. SQL: (Structured Query Language) Estndar en el lenguaje de acceso a bases de datos.
Visual Basic 6.0 233
Tiempo de diseo (de una aplicacin): Periodo de duracin del diseo y programacin de la aplicacin. Tiempo de ejecucin (de una aplicacin): Periodo que transcurre desde que se inicia hasta que finaliza la ejecucin de la aplicacin. Twip: (Twuentleth of a Point) Vigsima parte de un punto. Medida de longitud esencialmente informtica que equivale a 1/20 puntos de impresora, a 1/1440 pulgadas lgicas a 1/567 centmetros lgicos. Variable: Estructura de programacin que contiene datos que pueden variar a lo largo del programa. El usuario otorga un nombre nico a cada variable e indica el tipo de dato que contendr. Mantiene los datos hasta que se le asigna un nuevo valor o hasta que el programa (o subrutina) al que pertenece termina.
234
Curso
ndice
Captulo 1 ................................................................................................... Programar una calculadora de euros .......................................................... Configurar el formulario ............................................................................ Etiquetas ..................................................................................................... Cuadros de texto ......................................................................................... Botones de comando .................................................................................. Modificar tamao y posicin ...................................................................... Insertar cdigo ............................................................................................ Guardar y ejecutar ...................................................................................... 3 4 4 5 6 6 7 7 8
Captulo 2 ................................................................................................... 9 Programar una calculadora de euros ...........................................................13 Abrir antiguo proyecto ............................................................................. 13 Modificar formulario ................................................................................ 13 Mover controles ....................................................................................... 14 Aadir imagen .......................................................................................... 15 Botones de opcin .................................................................................... 16 Reprogramar botones ............................................................................... 16 Programar botones nuevos ....................................................................... 17 Generar ejecutables .................................................................................. 18 Captulo 3 ................................................................................................. Tipos de datos .......................................................................................... Profundizando en los cuadros de texto ..................................................... Acerca de los string .................................................................................. Caracteres ................................................................................................. Programar una calculadora de euros ........................................................ Eliminar controles innecesarios ............................................................... Modificar controles .................................................................................. Mover controles ....................................................................................... Introducir cdigo ...................................................................................... Compilacin ............................................................................................. 21 22 23 23 24 25 26 26 27 27 30
Variables .................................................................................................. 34 Bucles ....................................................................................................... 35 Suma de nmeros decimales .................................................................... 37 Propiedades del formulario .........................................................................37 Controles .................................................................................................. 38 Opciones ................................................................................................... 39 Bucles ....................................................................................................... 40 Cdigo del programa ................................................................................ 40 Captulo 5 ................................................................................................. Funciones, procedimientos y libreras ...................................................... Modularidad ............................................................................................. Uso y ventajas de la modularidad ............................................................ Funciones y procedimientos ..................................................................... Funciones ................................................................................................. Argumentos por referencia y por valor .................................................... Libreras ................................................................................................... Mdulos matemticos .............................................................................. Crear un mdulo matemtico ................................................................... Captulo 6 ................................................................................................. Arrays de variables ................................................................................... Arrays de controles ................................................................................... Cuadros combinados ................................................................................ Algunas funciones necesarias ................................................................... Estructura with end with ..................................................................... Crear un calendario universal ................................................................... Captulo 7 ................................................................................................. Interfaz aplicacin-usuario ....................................................................... Editor de mens ........................................................................................ Creacin del men del editor de textos .................................................... Captulo 8 ................................................................................................. Barras de estado y barras de herramientas ............................................... Barras de herramientas ............................................................................. Barras de estado ....................................................................................... Controles comunes de Microsoft .............................................................
236 Curso
43 43 43 43 44 45 47 48 48 49 53 53 53 54 55 55 56 63 63 64 66 71 71 72 72 73
Captulo 9 ................................................................................................. Cuadros de dilogo comunes .................................................................... Introduccin al trabajo con ficheros ......................................................... Programar las funciones del editor ........................................................... Evento ButtonClick de la barra de herramientas ...................................... Dotar de cuadros de dilogo al editor ...................................................... Captulo 10 ............................................................................................... Cuadros de mensaje .................................................................................. Cortar, copiar y pegar ............................................................................... Formato del texto ..................................................................................... ltimos toques del editor de textos .......................................................... Fin del proyecto ........................................................................................ Captulo 11 ............................................................................................... Macros en Microsoft Excel ...................................................................... Qu son las macros? ............................................................................... El objeto Worksheet ................................................................................. Trabajando con los colores ....................................................................... Nivel de seguridad .................................................................................... Resaltar valores mximos y mnimos ...................................................... Captulo 12 ............................................................................................. Bsqueda y ordenacin (1 parte) ........................................................... Eficiencia ................................................................................................ Bsquedas en listas ordenadas ............................................................... Ordenacin de listas ............................................................................... Ordenar los valores de una hoja de clculo ............................................ Captulo 13 ............................................................................................. Bsqueda y ordenacin (2 parte) ........................................................... Algoritmo de bsqueda binaria o dicotmica ........................................ Valores aleatorios ................................................................................... Trabajando con cadenas de caracteres ................................................... Conclusin .............................................................................................. Comparar algoritmos de bsqueda: ordenar 500 nmeros aleatorios ....
77 77 77 78 79 79 85 85 86 87 87 93 95 95 95 96 96 97 98 101 101 101 102 102 103 107 107 107 108 109 109 109
Captulo 14 ............................................................................................. 115 Controles y formularios en las hojas de clculo ..................................... 115
Visual Basic 6.0 237
Realizar un formulario para adquirir y validad valores .......................... 115 Propuesta ................................................................................................ 121 Captulo 15 ............................................................................................. 123 Controles y formularios (2) .................................................................... 123 Captulo 16 ............................................................................................. Formato de bordes .................................................................................. Aplicar formato a los bordes de la tabla CCC ........................................ Seleccin y aplicacin de bordes ........................................................... Captulo 17 ............................................................................................. Grficas .................................................................................................. Objetos ChartObjects ............................................................................. Concatenacin de cadenas de caracteres ................................................ Actualizar una grfica automticamente ................................................ Captulo 18 ............................................................................................. Grficas (2 de 2) ..................................................................................... Tipos de grficas .................................................................................... Modificar el tipo de grfica en tiempo de ejecucin .............................. Captulo 19 ............................................................................................. Gestor de CDs ........................................................................................ Coleccin de discos ................................................................................ Prstamos ............................................................................................... Conexin con las bases de datos ............................................................ Zona de descargas .................................................................................. Cartulas ................................................................................................. Amigos ................................................................................................... Prstamos ............................................................................................... Relaciones .............................................................................................. Captulo 20 ............................................................................................. Gestor de CDs ........................................................................................ Aplicaciones de interfaz de Mltiples Documentos ............................... Caractersticas de los formularios MDI primarios ................................. Caractersticas de los formularios MDI secundarios .............................. Preparacin del proyecto ........................................................................
238 Curso
129 129 129 129 137 137 137 138 138 143 143 143 146 151 151 151 152 152 152 152 152 153 153 157 157 157 157 158 159
Captulo 21 ............................................................................................. Barra de herramientas y barra de estado ................................................ Barra de herramientas ............................................................................. Botones utilizados .................................................................................. Barra de estado ....................................................................................... Crear la interfaz ...................................................................................... Captulo 22 ............................................................................................. Diseo de un formulario ......................................................................... Diseo correcto de un formulario ........................................................... Reutilizacin de formularios .................................................................. Aadir pelculas al formulario ................................................................ Captulo 23 ............................................................................................. Conexin DAO con la base de datos ...................................................... Uso de Recordset .................................................................................... Insertar una nueva entrada en la tabla CDS ...........................................
163 163 163 164 165 165 169 169 169 169 170 175 175 175 175
Captulo 24 ............................................................................................. 181 Cuadros enlazados a bases de datos ....................................................... 181 Utilizacin de cuadros combinados asociados a tablas de una base de datos .................................................................................................. 181 Captulo 25 ............................................................................................. Creacin de relaciones en la base de datos ............................................ Actualizacin dinmica de los datos ...................................................... Insercin de los datos de la pelcula relacionndolos con la tabla CDS Captulo 26 ............................................................................................. Asignar imgenes a los CDs .................................................................. Controles Image ..................................................................................... Gestionar las cartulas ............................................................................ 187 187 188 188 193 193 193 193
Captulo 27 ............................................................................................. 201 Zoom en las cartulas ............................................................................. 201 Creacin del formulario fmrCaratulasZoom .......................................... 201 Captulo 28 ............................................................................................. 207 Gestin de gneros de pelculas ............................................................. 207
Visual Basic 6.0 239
Formulario fmrGeneroPelicula .............................................................. 207 Captulo 29 ............................................................................................. 213 Gestin de gneros de pelculas (2 de 2) ................................................ 213 Refinando el formulario frmGeneroPelicula .......................................... 213 Captulo 30 ............................................................................................. 219 Gestin de cdigos de barras .................................................................. 219 Captulo 31 ............................................................................................. 225 ltimas nociones .................................................................................... 225 Aspectos generales ................................................................................. 225 Vocabulario ............................................................................................ 235
240
Curso