12.07.2015 Views

Aprenda Visual Basic 6.0 como si estuviera en Primero

Aprenda Visual Basic 6.0 como si estuviera en Primero

Aprenda Visual Basic 6.0 como si estuviera en Primero

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Escuela Superior de Ing<strong>en</strong>ieros Industrialesde San SebastiánUNIVERSIDAD DE NAVARRA<strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong><strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> primeroSan Sebastián, agosto 1999Javier García de Jalón • José Ignacio Rodríguez • Alfonso Brazálezhttp://www.tayuda.com/ayudainf/


<strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong><strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> primeroJavier García de JalónJosé Ignacio RodríguezAlfonso BrazálezPert<strong>en</strong>eci<strong>en</strong>te a la colección : “<strong>Apr<strong>en</strong>da</strong> …, <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> primero”Editada y mant<strong>en</strong>ida por Javier García de Jalón (jgjalon@et<strong>si</strong>i.upm.es)Nuevos títulos y actualizaciones <strong>en</strong>: http://www.tayuda.com/ayudainf/index.htm


Índicepágina iÍNDICE1. Introducción 11.1 Programas secu<strong>en</strong>ciales, interactivos y ori<strong>en</strong>tados a ev<strong>en</strong>tos 11.2 Programas para el <strong>en</strong>torno Windows 21.2.1 Modo de Diseño y Modo de Ejecución 21.2.2 Formularios y Controles 21.2.3 Objetos y Propiedades 21.2.4 Nombres de objetos 31.2.5 Ev<strong>en</strong>tos 41.2.6 Métodos 41.2.7 Proyectos y ficheros 41.3 El <strong>en</strong>torno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> 51.4 El Help de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> 61.5 Ejemplos 61.5.1 Ejemplo 1.1: S<strong>en</strong>cillo programa de colores y po<strong>si</strong>ciones 61.5.2 Ejemplo 1.2: Minicalculadora elem<strong>en</strong>tal 81.5.3 Ejemplo 1.3: Transformación de unidades de temperatura 91.5.4 Ejemplo 1.4: Colores RGB 112. Entorno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> 142.1 Introducción: ¿Qué es <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>? 142.2 El <strong>en</strong>torno de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> 142.2.1 La barra de m<strong>en</strong>ús y las barras de herrami<strong>en</strong>tas 142.2.2 Las herrami<strong>en</strong>tas (toolbox) 162.3 Formularios (forms) y módulos 162.4 La v<strong>en</strong>tana de proyecto (project) 172.5 La v<strong>en</strong>tana de propiedades (Properties) 172.6 Creación de programas ejecutables 182.7 Cómo utilizar el Help 192.8 Utilización del Code Editor 192.9 Utilización del Debugger 212.9.1 Ejecución controlada de un programa 212.9.2 V<strong>en</strong>tanas Immediate, Locals y Watches 222.9.3 Otras po<strong>si</strong>bilidades del Debugger 233. L<strong>en</strong>guaje BASIC 243.1 Introducción 243.2 Com<strong>en</strong>tarios y otras utilidades <strong>en</strong> la programación con visual ba<strong>si</strong>c 243.3 Proyectos y módulos 253.3.1 Ámbito de las variables y los procedimi<strong>en</strong>tos 253.3.1.1 Variables y funciones de ámbito local 253.3.1.2 Variables y funciones de ámbito global 263.4 Variables 273.4.1 Id<strong>en</strong>tificadores 273.4.2 Variables y constantes 283.4.3 Nombres de variables 283.4.4 Tipos de datos 293.4.5 Elección del tipo de una variable 303.4.6 Declaración explícita de variables 303.5 Operadores 313.6 S<strong>en</strong>t<strong>en</strong>cias de control 313.6.1 S<strong>en</strong>t<strong>en</strong>cia IF ... THEN ... ELSE ... 323.6.2 S<strong>en</strong>t<strong>en</strong>cia SELECT CASE 333.6.3 S<strong>en</strong>t<strong>en</strong>cia FOR ... NEXT 343.6.4 S<strong>en</strong>t<strong>en</strong>cia DO ... LOOP 343.6.5 S<strong>en</strong>t<strong>en</strong>cia WHILE … WEND 353.6.6 S<strong>en</strong>t<strong>en</strong>cia FOR EACH ... NEXT 353.7 Algoritmos 363.7.1 Introducción 363.7.2 Repres<strong>en</strong>tación de algoritmos 36


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong>página ii3.8 Funciones y Procedimi<strong>en</strong>tos 373.8.1 Conceptos g<strong>en</strong>erales sobre funciones 373.8.2 Funciones y procedimi<strong>en</strong>tos Sub <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> 373.8.3 Funciones (function) 383.8.4 Procedimi<strong>en</strong>tos Sub 393.8.5 Argum<strong>en</strong>tos por refer<strong>en</strong>cia y por valor 403.8.6 Procedimi<strong>en</strong>tos recur<strong>si</strong>vos 403.8.7 Procedimi<strong>en</strong>tos con argum<strong>en</strong>tos opcionales 413.8.8 Número indeterminado de argum<strong>en</strong>tos 413.8.9 Utilización de argum<strong>en</strong>tos con nombre 413.9 Arrays 413.9.1 Arrays estáticos 423.9.2 Arrays dinámicos 423.10 Estructuras: S<strong>en</strong>t<strong>en</strong>cia Type 433.11 Funciones para manejo de cad<strong>en</strong>as de caracteres 453.12 Funciones matemáticas 464. Ev<strong>en</strong>tos, Propiedades y Controles 484.1 Ev<strong>en</strong>tos 484.1.1 Ev<strong>en</strong>tos g<strong>en</strong>erales 484.1.1.1 Carga y descarga de formularios 484.1.1.2 Paint 504.1.1.3 El foco (focus) 504.1.1.4 KeyPress, KeyUp y KeyDown 514.1.2 Ev<strong>en</strong>tos relacionados con el ratón 514.1.2.1 Click y DblClick 514.1.2.2 MouseDown, MouseUp y MouseMove 524.1.2.3 DragOver y DragDrop 524.2 Algunas propiedades comunes a varios controles 534.3 Controles más usuales 544.3.1 Botón de comando (Command Button) 544.3.2 Botones de opción (Option Button) 554.3.3 Botones de selección (Check Box) 554.3.4 Barras de desplazami<strong>en</strong>to (Scroll Bars) 554.3.5 Etiquetas (Labels) 564.3.6 Cajas de texto (Text Box) 564.3.7 Listas (List Box) 574.3.8 Cajas combinadas (ComboBox) 584.3.9 Controles relacionados con ficheros 584.3.10 Control Timer 584.4 Cajas de diálogo estándar (Controles Common Dialog) 584.4.1 Op<strong>en</strong>/Save Dialog Control 604.4.2 Print Dialog Control 604.4.3 Font Dialog Control 614.4.4 Color Dialog Control 614.5 Formularios múltiples 614.5.1 Apertura de controles <strong>en</strong> forma modal 624.5.2 Formularios MDI (Multiple Docum<strong>en</strong>t Interface) 624.6 Arrays de controles 635. M<strong>en</strong>ús 645.1 Introducción a las po<strong>si</strong>bilidades de los m<strong>en</strong>ús 645.2 El editor de m<strong>en</strong>ús (M<strong>en</strong>u Editor) 655.3 Añadir código a los m<strong>en</strong>ús 665.4 Arrays de m<strong>en</strong>ús 665.5 Ejemplo: M<strong>en</strong>ú para determinar las características de un texto 675.6 M<strong>en</strong>ús contextuales (Popup M<strong>en</strong>u) 686. Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> 696.1 Tratami<strong>en</strong>to del color 696.1.1 Repres<strong>en</strong>tación hexadecimal de los colores 696.1.2 Acceso a los colores del <strong>si</strong>stema 69


Índicepágina iii6.1.3 Función RGB 706.1.4 Paleta de colores 706.2 Formatos gráficos 716.3 Controles gráficos 71Control Line 71Control Shape 726.3.3 Ejemplo 6.1: Uso de los controles Line y Shape 72Control Image 726.3.5 Control PictureBox 746.4 Métodos gráficos 746.4.1 Método Print 756.4.2 Dibujo de puntos: método PSet 756.4.3 Dibujo de líneas y rectángulos: método Line 756.4.4 Dibujo de circunfer<strong>en</strong>cias, arcos y elipses: método Circle 766.4.5 Otros métodos gráficos 776.5 Sistemas de coord<strong>en</strong>adas 776.5.1 Método Scale 786.6 Ev<strong>en</strong>tos y propiedades relacionadas con gráficos 796.6.1 El ev<strong>en</strong>to Paint 796.6.2 La propiedad DrawMode 796.6.3 Planos de dibujo (Layers) 806.6.4 La propiedad AutoRedraw 806.6.5 La propiedad ClipControl 816.7 Ejemplos 816.7.1 Ejemplo 6.1: Gráficos y barras de desplazami<strong>en</strong>to 816.7.2 Ejemplo 6.2: Repres<strong>en</strong>tación gráfica de la solución de la ecuación de segundo grado 836.8 Barras de Herrami<strong>en</strong>tas (Toolbars) 867. Archivos y Entrada/Salida de Datos 877.1 Cajas de diálogo InputBox y MsgBox 877.2 Método Print 887.2.1 Características g<strong>en</strong>erales 887.2.2 Función Format 897.3 Utilización de impresoras 907.3.1 Método PrintForm 907.3.2 Objeto Printer 907.4 Controles FileList, DirList y DriveList 917.5 Tipos de ficheros 927.6 Lectura y escritura <strong>en</strong> ficheros secu<strong>en</strong>ciales 937.6.1 Apertura y cierre de ficheros 937.6.2 Lectura y escritura de datos 937.6.2.1 S<strong>en</strong>t<strong>en</strong>cia Input 937.6.2.2 Función Line Input y función Input 947.6.2.3 Función Print # 947.6.2.4 Función Write # 957.7 Ficheros de acceso aleatorio 957.7.1 Abrir y cerrar archivos de acceso aleatorio 957.7.2 Leer y escribir <strong>en</strong> una archivo de acceso aleatorio. Funciones Get y Put 957.8 Ficheros de acceso binario 968. ANEXO A: Con<strong>si</strong>deraciones adicionales sobre datos y variables 978.1 Caracteres y código ASCII 978.2 Números <strong>en</strong>teros 988.3 Números reales 988.3.1 Variables tipo Single 988.3.2 Variables tipo Double 998.4 Sistema binario, octal, decimal y hexadecimal 99


Capítulo 1: Introducción página 11. INTRODUCCIÓN<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es uno de los l<strong>en</strong>guajes de programación que más <strong>en</strong>tu<strong>si</strong>asmo despiertan <strong>en</strong>tre losprogramadores de PCs, tanto expertos <strong>como</strong> novatos. En el caso de los programadores expertos porla facilidad con la que desarrollan aplicaciones complejas <strong>en</strong> poquí<strong>si</strong>mo tiempo (comparado con loque cuesta programar <strong>en</strong> <strong>Visual</strong> C++, por ejemplo). En el caso de los programadores novatos por elhecho de ver de lo que son capaces a los pocos minutos de empezar su apr<strong>en</strong>dizaje. El precio quehay que pagar por utilizar <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es una m<strong>en</strong>or velocidad o efici<strong>en</strong>cia <strong>en</strong> las aplicaciones.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es un l<strong>en</strong>guaje de programación visual, también llamado l<strong>en</strong>guaje de 4ªg<strong>en</strong>eración. Esto quiere decir que un gran número de tareas se realizan <strong>si</strong>n escribir código,<strong>si</strong>mplem<strong>en</strong>te con operaciones gráficas realizadas con el ratón sobre la pantalla.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es también un programa basado <strong>en</strong> objetos, aunque no ori<strong>en</strong>tado a objetos<strong>como</strong> C++ o Java. La difer<strong>en</strong>cia está <strong>en</strong> que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> utiliza objetos con propiedades ymétodos, pero carece de los mecanismos de her<strong>en</strong>cia y polimorfismo propios de los verdaderosl<strong>en</strong>guajes ori<strong>en</strong>tados a objetos <strong>como</strong> Java y C++.En este primer capítulo se pres<strong>en</strong>tarán las características g<strong>en</strong>erales de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>, juntocon algunos ejemplos s<strong>en</strong>cillos que d<strong>en</strong> idea de la pot<strong>en</strong>cia del l<strong>en</strong>guaje y del modo <strong>en</strong> que seutiliza.1.1 PROGRAMAS SECUENCIALES, INTERACTIVOS Y ORIENTADOS A EVENTOSExist<strong>en</strong> distintos tipos de programas. En los primeros tiempos de los ord<strong>en</strong>adores los programaseran de tipo secu<strong>en</strong>cial (también llamados tipo batch) Un programa secu<strong>en</strong>cial es un programa quese arranca, lee los datos que nece<strong>si</strong>ta, realiza los cálculos e imprime o guarda <strong>en</strong> el disco losresultados. De ordinario, mi<strong>en</strong>tras un programa secu<strong>en</strong>cial está ejecutándose no nece<strong>si</strong>ta ningunainterv<strong>en</strong>ción del usuario. A este tipo de programas se les llama también programas basados uori<strong>en</strong>tados a procedimi<strong>en</strong>tos o a algoritmos (procedural languages). Este tipo de programas <strong>si</strong>gu<strong>en</strong>utilizándose ampliam<strong>en</strong>te <strong>en</strong> la actualidad, pero la difu<strong>si</strong>ón de los PCs ha puesto de actualidad otrostipos de programación.Los programas interactivos exig<strong>en</strong> la interv<strong>en</strong>ción del usuario <strong>en</strong> tiempo de ejecución, bi<strong>en</strong>para suministrar datos, bi<strong>en</strong> para indicar al programa lo que debe hacer por medio de m<strong>en</strong>ús. Losprogramas interactivos limitan y ori<strong>en</strong>tan la acción del usuario. Un ejemplo de programa interactivopodría ser Matlab.Por su parte los programas ori<strong>en</strong>tados a ev<strong>en</strong>tos son los programas típicos de Windows, tales<strong>como</strong> Netscape, Word, Excel y PowerPoint. Cuando uno de estos programas ha arrancado, lo únicoque hace es quedarse a la espera de las acciones del usuario, que <strong>en</strong> este caso son llamadas ev<strong>en</strong>tos.El usuario dice <strong>si</strong> quiere abrir y modificar un fichero exist<strong>en</strong>te, o bi<strong>en</strong> com<strong>en</strong>zar a crear un ficherodesde el principio. Estos programas pasan la mayor parte de su tiempo esperando las acciones delusuario (ev<strong>en</strong>tos) y respondi<strong>en</strong>do a ellas. Las acciones que el usuario puede realizar <strong>en</strong> un mom<strong>en</strong>todeterminado son variadí<strong>si</strong>mas, y exig<strong>en</strong> un tipo especial de programación: la programaciónori<strong>en</strong>tada a ev<strong>en</strong>tos. Este tipo de programación es s<strong>en</strong><strong>si</strong>blem<strong>en</strong>te más complicada que la secu<strong>en</strong>cialy la interactiva, pero <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> la hace especialm<strong>en</strong>te s<strong>en</strong>cilla y agradable.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 21.2 PROGRAMAS PARA EL ENTORNO WINDOWS<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> está ori<strong>en</strong>tado a la realización de programas para Windows, pudi<strong>en</strong>do incorporartodos los elem<strong>en</strong>tos de este <strong>en</strong>torno informático: v<strong>en</strong>tanas, botones, cajas de diálogo y de texto,botones de opción y de selección, barras de desplazami<strong>en</strong>to, gráficos, m<strong>en</strong>ús, etc.Prácticam<strong>en</strong>te todos los elem<strong>en</strong>tos de interacción con el usuario de los que dispone Windows95/98/NT pued<strong>en</strong> ser programados <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> de un modo muy s<strong>en</strong>cillo. En oca<strong>si</strong>onesbastan unas pocas operaciones con el ratón y la introducción a través del teclado de algunass<strong>en</strong>t<strong>en</strong>cias para disponer de aplicaciones con todas las características de Windows 95/98/NT. En los<strong>si</strong>gui<strong>en</strong>tes apartados se introducirán algunos conceptos de este tipo de programación.1.2.1 Modo de Diseño y Modo de EjecuciónLa aplicación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> de Microsoft puede trabajar de dos modos distintos: <strong>en</strong> modo de diseñoy <strong>en</strong> modo de ejecución. En modo de diseño el usuario construye interactivam<strong>en</strong>te la aplicación,colocando controles <strong>en</strong> el formulario, defini<strong>en</strong>do sus propiedades, y desarrollando funciones paragestionar los ev<strong>en</strong>tos.La aplicación se prueba <strong>en</strong> modo de ejecución. En ese caso el usuario actúa sobre el programa(introduce ev<strong>en</strong>tos) y prueba cómo responde el programa. Hay algunas propiedades de los controlesque deb<strong>en</strong> establecerse <strong>en</strong> modo de diseño, pero muchas otras pued<strong>en</strong> cambiarse <strong>en</strong> tiempo deejecución desde el programa escrito <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>, <strong>en</strong> la forma <strong>en</strong> que más adelante se verá.También hay propiedades que sólo pued<strong>en</strong> establecerse <strong>en</strong> modo de ejecución y que no son vi<strong>si</strong>bles<strong>en</strong> modo de diseño.Todos estos conceptos –controles, propiedades, ev<strong>en</strong>tos, etc.- se explican <strong>en</strong> los apartados<strong>si</strong>gui<strong>en</strong>tes.1.2.2 Formularios y ControlesCada uno de los elem<strong>en</strong>tos gráficos que pued<strong>en</strong> formar parte de una aplicación típica de Windows95/98/NT es un tipo de control: los botones, las cajas de diálogo y de texto, las cajas de seleccióndesplegables, los botones de opción y de selección, las barras de desplazami<strong>en</strong>to horizontales yverticales, los gráficos, los m<strong>en</strong>ús, y muchos otros tipos de elem<strong>en</strong>tos son controles para <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>. Cada control debe t<strong>en</strong>er un nombre a través del cual se puede hacer refer<strong>en</strong>cia a él <strong>en</strong> elprograma. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> proporciona nombres por defecto que el usuario puede modificar. En elApartado 1.2.4 se expon<strong>en</strong> algunas reglas para dar nombres a los distintos controles.En la terminología de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se llama formulario (form) a una v<strong>en</strong>tana. Unformulario puede ser con<strong>si</strong>derado <strong>como</strong> una especie de cont<strong>en</strong>edor para los controles. Unaaplicación puede t<strong>en</strong>er varios formularios, pero un único formulario puede ser sufici<strong>en</strong>te para lasaplicaciones más s<strong>en</strong>cillas. Los formularios deb<strong>en</strong> también t<strong>en</strong>er un nombre, que puede crearse<strong>si</strong>gui<strong>en</strong>do las mismas reglas que para los controles.1.2.3 Objetos y PropiedadesLos formularios y los distintos tipos de controles son <strong>en</strong>tidades g<strong>en</strong>éricas de las que puede habervarios ejemplares concretos <strong>en</strong> cada programa. En programación ori<strong>en</strong>tada a objetos (más bi<strong>en</strong>basada <strong>en</strong> objetos, habría que decir) se llama clase a estas <strong>en</strong>tidades g<strong>en</strong>éricas, mi<strong>en</strong>tras que sellama objeto a cada ejemplar de una clase determinada. Por ejemplo, <strong>en</strong> un programa puede haber


Capítulo 1: Introducción página 3varios botones, cada uno de los cuales es un objeto del tipo de control command button, que sería laclase.Cada formulario y cada tipo de control ti<strong>en</strong><strong>en</strong> un conjunto de propiedades que defin<strong>en</strong> suaspecto gráfico (tamaño, color, po<strong>si</strong>ción <strong>en</strong> la v<strong>en</strong>tana, tipo y tamaño de letra, etc.) y su forma deresponder a las acciones del usuario (<strong>si</strong> está activo o no, por ejemplo). Cada propiedad ti<strong>en</strong>e unnombre que vi<strong>en</strong>e ya definido por el l<strong>en</strong>guaje.Por lo g<strong>en</strong>eral, las propiedades de un objeto son datos que ti<strong>en</strong><strong>en</strong> valores lógicos (True, False)o numéricos concretos, propios de ese objeto y distintos de las de otros objetos de su clase. Asípues, cada clase, tipo de objeto o control ti<strong>en</strong>e su conjunto de propiedades, y cada objeto o controlconcreto ti<strong>en</strong>e unos valores determinados para las propiedades de su clase.Ca<strong>si</strong> todas las propiedades de los objetos pued<strong>en</strong> establecerse <strong>en</strong> tiempo de diseño y también-ca<strong>si</strong> <strong>si</strong>empre- <strong>en</strong> tiempo de ejecución. En este segundo caso se accede a sus valores por medio delas s<strong>en</strong>t<strong>en</strong>cias del programa, <strong>en</strong> forma análoga a <strong>como</strong> se accede a cualquier variable <strong>en</strong> un l<strong>en</strong>guajede programación. Para ciertas propiedades ésta es la única forma de acceder a ellas. Por supuesto<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite crear distintos tipos de variables, <strong>como</strong> más adelante se verá.Se puede acceder a una propiedad de un objeto por medio del nombre del objeto a quepert<strong>en</strong>ece, seguido de un punto y el nombre de la propiedad, <strong>como</strong> por ejemplo optColor.objName.En el <strong>si</strong>gui<strong>en</strong>te apartado se estudiarán las reglas para dar nombres a los objetos.1.2.4 Nombres de objetosEn principio cada objeto de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> debe t<strong>en</strong>er un nombre, por medio del cual se hacerefer<strong>en</strong>cia a dicho objeto. El nombre puede ser el que el usuario desee, e incluso <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>proporciona nombres por defecto para los diversos controles. Estos nombres por defecto hac<strong>en</strong>refer<strong>en</strong>cia al tipo de control y van seguidos de un número que se increm<strong>en</strong>ta a medida que se vanintroduci<strong>en</strong>do más controles de ese tipo <strong>en</strong> el formulario (por ejemplo VScroll1, para una barra dedesplazami<strong>en</strong>to -scroll bar- vertical, HScroll1, para una barra horizontal, etc.).Los nombres por defecto no son adecuados porque hac<strong>en</strong> refer<strong>en</strong>cia al tipo de control, perono al uso que de dicho control está haci<strong>en</strong>do el programador. Por ejemplo, <strong>si</strong> se utiliza una barra dedesplazami<strong>en</strong>to para introducir una temperatura, convi<strong>en</strong>e que su nombre haga refer<strong>en</strong>cia a lapalabra temperatura, y así cuando haya que utilizar ese nombre se sabrá exactam<strong>en</strong>te a qué controlcorresponde. Un nombre adecuado sería por ejemplo hsbTemp, donde las tres primeras letra<strong>si</strong>ndican que se trata de una horizontal scroll bar, y las restantes (empezando por una mayúscula) queservirá para definir una temperatura.Existe una conv<strong>en</strong>ción ampliam<strong>en</strong>te aceptada que es la <strong>si</strong>gui<strong>en</strong>te: se utilizan <strong>si</strong>empre tresletras minúsculas que indican el tipo de control, seguidas por otras letras (la primera mayúscula, amodo de separación) librem<strong>en</strong>te escogidas por el usuario, que ti<strong>en</strong><strong>en</strong> que hacer refer<strong>en</strong>cia al usoque se va a dar a ese control. La Tabla 1.1 muestra las abreviaturas de los controles más usuales,junto con la nom<strong>en</strong>clatura inglesa de la que derivan. En este mismo capítulo se verán unos cuantosejemplos de aplicación de estas reglas para construir nombres.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 4Abreviatura Control Abreviatura Controlchk check box cbo combo y drop-list boxcmd command button dir dir list boxdrv drive list box fil file list boxfrm form fra framehsb horizontal scroll bar img imagelbl label lin linelst list mnu m<strong>en</strong>uopt option button pct pictureBoxshp shape txt text edit boxtmr timer vsb vertical scroll barTabla 1.1. Abreviaturas para los controles más usuales.1.2.5 Ev<strong>en</strong>tosYa se ha dicho que las acciones del usuario sobre el programa se llaman ev<strong>en</strong>tos. Son ev<strong>en</strong>tostípicos el clicar sobre un botón, el hacer doble clic sobre el nombre de un fichero para abrirlo, elarrastrar un icono, el pulsar una tecla o combinación de teclas, el elegir una opción de un m<strong>en</strong>ú, elescribir <strong>en</strong> una caja de texto, o <strong>si</strong>mplem<strong>en</strong>te mover el ratón. Más adelante se verán los distintostipos de ev<strong>en</strong>tos reconocidos por Windows 95/98/NT y por <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Cada vez que se produce un ev<strong>en</strong>to sobre un determinado tipo de control, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>arranca una determinada función o procedimi<strong>en</strong>to que realiza la acción programada por el usuariopara ese ev<strong>en</strong>to concreto. Estos procedimi<strong>en</strong>tos se llaman con un nombre que se forma a partir delnombre del objeto y el nombre del ev<strong>en</strong>to, separados por el carácter (_), <strong>como</strong> por ejemplotxtBox_click, que es el nombre del procedimi<strong>en</strong>to que se ocupará de responder al ev<strong>en</strong>to click <strong>en</strong> elobjeto txtBox.1.2.6 MétodosLos métodos son funciones que también son llamadas desde programa, pero a difer<strong>en</strong>cia de losprocedimi<strong>en</strong>tos no son programadas por el usuario, <strong>si</strong>no que vi<strong>en</strong><strong>en</strong> ya pre-programadas con ell<strong>en</strong>guaje. Los métodos realizan tareas típicas, previ<strong>si</strong>bles y comunes para todas las aplicaciones. Deahí que v<strong>en</strong>gan con el l<strong>en</strong>guaje y que se libere al usuario de la tarea de programarlos. Cada tipo deobjeto o de control ti<strong>en</strong>e sus propios métodos.Por ejemplo, los controles gráficos ti<strong>en</strong><strong>en</strong> un método llamado Line que se <strong>en</strong>carga de dibujarlíneas rectas. De la misma forma existe un método llamado Circle que dibuja circunfer<strong>en</strong>cias yarcos de circunfer<strong>en</strong>cia Es obvio que el dibujar líneas rectas o circunfer<strong>en</strong>cias es una tarea comúnpara todos los programadores y que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> da ya resuelta.1.2.7 Proyectos y ficherosCada aplicación que se empieza a desarrollar <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es un nuevo proyecto. Unproyecto compr<strong>en</strong>de otras compon<strong>en</strong>tes más s<strong>en</strong>cillas, <strong>como</strong> por ejemplo los formularios (que sonlas v<strong>en</strong>tanas de la interface de usuario de la nueva aplicación) y los módulos (que son conjuntos defunciones y procedimi<strong>en</strong>tos <strong>si</strong>n interface gráfica de usuario).¿Cómo se guarda un proyecto <strong>en</strong> el disco? Un proyecto se compone <strong>si</strong>empre de variosficheros (al m<strong>en</strong>os de dos) y hay que preocuparse de guardar cada uno de ellos <strong>en</strong> el directorio


Capítulo 1: Introducción página 5adecuado y con el nombre adecuado. Existe <strong>si</strong>empre un fichero con ext<strong>en</strong><strong>si</strong>ón *.vbp (<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>Project) que se crea con el comando File/Save Project As. El fichero del proyecto conti<strong>en</strong>e toda lainformación de conjunto. Además hay que crear un fichero por cada formulario y por cada móduloque t<strong>en</strong>ga el proyecto. Los ficheros de los formularios se crean con File/Save Fil<strong>en</strong>ame As t<strong>en</strong>i<strong>en</strong>do<strong>como</strong> ext<strong>en</strong><strong>si</strong>ón *.frm. Los ficheros de código o módulos se guardan también con el comandoFile/Save Fil<strong>en</strong>ame As y ti<strong>en</strong><strong>en</strong> <strong>como</strong> ext<strong>en</strong><strong>si</strong>ón *.bas <strong>si</strong> se trata de un módulo estándar o *.cls <strong>si</strong>se trata de un módulo de clase (class module).Clicando <strong>en</strong> el botón Save <strong>en</strong> la barra de herrami<strong>en</strong>tas se actualizan todos los ficheros delproyecto. Si no se habían guardado todavía <strong>en</strong> el disco, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> abre cajas de diálogo SaveAs por cada uno de los ficheros que hay que guardar.1.3 EL ENTORNO DE PROGRAMACIÓN VISUAL BASIC <strong>6.0</strong>Cuando se arranca <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>aparece <strong>en</strong> la pantalla una configuración<strong>si</strong>milar a la mostrada <strong>en</strong> la Figura 1.1. Enella se pued<strong>en</strong> distinguir los <strong>si</strong>gui<strong>en</strong>teselem<strong>en</strong>tos:1. La barra de títulos, la barra de m<strong>en</strong>ús yla barra de herrami<strong>en</strong>tas de <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>en</strong> modo Diseño (partesuperior de la pantalla).2. Caja de herrami<strong>en</strong>tas (toolbox) con loscontroles disponibles (a la izquierda dela v<strong>en</strong>tana).3. Formulario (form) <strong>en</strong> gris, <strong>en</strong> que seFigura 1.1. Entorno de programación de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.pued<strong>en</strong> ir <strong>si</strong>tuando los controles (<strong>en</strong> elc<strong>en</strong>tro). Está dotado de una rejilla (grid) para facilitar la alineación de los controles.4. V<strong>en</strong>tana de proyecto, que muestra los formularios y otros módulos de programas que formanparte de la aplicación (arriba a la derecha).5. V<strong>en</strong>tana de Propiedades, <strong>en</strong> la que se pued<strong>en</strong> ver las propiedades del objeto seleccionado o delpropio formulario (<strong>en</strong> el c<strong>en</strong>tro a la derecha). Si esta v<strong>en</strong>tana no aparece, se puede hacer vi<strong>si</strong>blecon la tecla .6. V<strong>en</strong>tana FormLayout, que permite determinar la forma <strong>en</strong> que se abrirá la aplicación cuandocomi<strong>en</strong>ce a ejecutarse (abajo a la derecha).Exist<strong>en</strong> otras v<strong>en</strong>tanas para edición de código (Code Editor) y para ver variables <strong>en</strong> tiempo deejecución con el depurador o Debugger (v<strong>en</strong>tanas Immediate, Locals y Watch). Todo este conjuntode herrami<strong>en</strong>tas y de v<strong>en</strong>tanas es lo que se llama un <strong>en</strong>torno integrado de desarrollo o IDE(Integrated Developm<strong>en</strong>t Environm<strong>en</strong>t).Construir aplicaciones con <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es muy s<strong>en</strong>cillo: basta crear los controles <strong>en</strong> elformulario con ayuda de la toolbox y del ratón, establecer sus propiedades con ayuda de la v<strong>en</strong>tanade propiedades y programar el código que realice las acciones adecuadas <strong>en</strong> respuesta a los ev<strong>en</strong>toso acciones que realice el usuario. A continuación, tras explicar brevem<strong>en</strong>te cómo se utiliza el Helpde <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>, se pres<strong>en</strong>tan algunos ejemplos ilustrativos.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 61.4 EL HELP DE VISUAL BASIC <strong>6.0</strong>El Help de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es de los mejores que exist<strong>en</strong>. Además de que se puede buscarcualquier tipo de información con la función Index, basta seleccionar una propiedad cualquiera <strong>en</strong>la v<strong>en</strong>tana de propiedades o un control cualquiera <strong>en</strong> el formulario (o el propio formulario), para quepulsando la tecla aparezca una v<strong>en</strong>tana de ayuda muy completa. De cada control de muestranlas propiedades, métodos y ev<strong>en</strong>tos que soporta, así <strong>como</strong> ejemplos de aplicación. También semuestra información <strong>si</strong>milar o relacionada.Existe además un breve pero interesante curso introductorio sobre <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> que seactiva con la opción Help/Cont<strong>en</strong>ts, seleccionando luego MSDN Cont<strong>en</strong>ts/<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> Docum<strong>en</strong>tation/<strong>Visual</strong><strong>Ba<strong>si</strong>c</strong> Start Page/Getting Started.1.5 EJEMPLOSEl <strong>en</strong>torno de programación de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ofrece muchas po<strong>si</strong>bilidades de adaptación a losgustos, deseos y prefer<strong>en</strong>cias del usuario. Los usuarios expertos ti<strong>en</strong><strong>en</strong> <strong>si</strong>empre una forma propia dehacer las cosas, pero para los usuarios noveles convi<strong>en</strong>e ofrecer unas ciertas ori<strong>en</strong>taciones alrespecto. Por eso, antes de realizar los ejemplos que <strong>si</strong>gu<strong>en</strong> se recomi<strong>en</strong>da modificar laconfiguración de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> de la <strong>si</strong>gui<strong>en</strong>te forma:1. En el m<strong>en</strong>ú Tools elegir el comando Options; se abre un cuadro de diálogo con 6 solapas.2. En la solapa Environm<strong>en</strong>t elegir “Promp to Save Changes” <strong>en</strong> “Wh<strong>en</strong> a Program Starts” paraque pregunte antes de cada ejecución <strong>si</strong> se desean guardar los cambios realizados. En la soladaEditor elegir también “Require Variable Declaration” <strong>en</strong> “Code Settings” para evitar errores alteclear los nombres de las variables.3. En la solapa Editor, <strong>en</strong> Code Settings, dar a “Tab Width” un valor de 4 y elegir la opción “AutoInd<strong>en</strong>t” (para que ayude a mant<strong>en</strong>er el código legible y ord<strong>en</strong>ado). En Windows Settings elegir“Default to Full Module View” (para ver todo el código de un formulario <strong>en</strong> una mismav<strong>en</strong>tana) y “Procedure Separator” (para que separe cada función de las demás mediante unalínea horizontal).1.5.1 Ejemplo 1.1: S<strong>en</strong>cillo programa de coloresy po<strong>si</strong>cionesEn la Figura 1.2 se muestra el formulario y loscontroles de un ejemplo muy s<strong>en</strong>cillo que permitemover una caja de texto por la pantalla, permiti<strong>en</strong>doa su vez repres<strong>en</strong>tarla con cuatro colores difer<strong>en</strong>tes.En la Tabla 1.2 se describ<strong>en</strong> los controlesutilizados, así <strong>como</strong> algunas de sus propiedades má<strong>si</strong>mportantes (sobre todo las que se separan de losvalores por defecto). Los ficheros de este proyectose llamarán Colores0.vbp y Colores0.frm. Figura 1.2. Formulario y controles del Ejemplo 1.1.


Capítulo 1: Introducción página 7Control Propiedad Valor Control Propiedad ValorfrmColores0 Name frmColores0 optVerde Name optVerdeCaption Colores Caption VerdefraColores Name fraColor fraPo<strong>si</strong>cion Name fraPo<strong>si</strong>cionCaption Colores Caption Po<strong>si</strong>ciónoptAzul Name optAzul optArriba Name optArribaCaption Azul Caption ArribaoptRojo Name optRojo optAbajo Name optAbajoCaption Rojo Caption AbajooptAmarillo Name optAmarillo txtCaja Name txtCajaCaption Amarillo Text “”Tabla 1.2. Objetos y propiedades del ejemplo Colores0.A continuación se muestra el código correspondi<strong>en</strong>te a los procedimi<strong>en</strong>tos de este ejemplo.Option ExplicitPrivate Sub Form_Load()txtCaja.Top = 0End SubPrivate Sub optArriba_Click()txtCaja.Top = 0End SubPrivate Sub optAbajo_Click()txtCaja.Top = frmColores0.ScaleHeight - txtCaja.HeightEnd SubPrivate Sub optAzul_Click()txtCaja.BackColor = vbBlueEnd SubPrivate Sub optRojo_Click()txtCaja.BackColor = vbRedEnd SubPrivate Sub optVerde_Click()txtCaja.BackColor = vbGre<strong>en</strong>End SubPrivate Sub optAmarillo_Click()txtCaja.BackColor = vbYellowEnd SubSobre este primer programa <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se pued<strong>en</strong> hacer algunos com<strong>en</strong>tarios:1. El comando Option Explicit <strong>si</strong>rve para obligar a declarar todas las variables que se utilic<strong>en</strong>.Esto impide el cometer errores <strong>en</strong> los nombres de las variables (confundir masa con mesa, porejemplo). En este ejemplo esto no ti<strong>en</strong>e ninguna importancia, pero es conv<strong>en</strong>i<strong>en</strong>teacostumbrarse a incluir esta opción. Declarar una variable es crearla con un nombre y de untipo determinado antes de utilizarla.2. Cada una de las partes de código que empieza con un Private Sub y termina con un End Subes un procedimi<strong>en</strong>to, esto es, una parte de código indep<strong>en</strong>di<strong>en</strong>te y reutilizable. El nombre deuno de estos procedimi<strong>en</strong>tos, por ejemplo optAzul_Click(), es típico de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>. Laprimera parte es el nombre de un objeto (control); después va un separador que es el carácterde subrayado (_); a continuación el nombre de un ev<strong>en</strong>to -click, <strong>en</strong> este caso-, y finalm<strong>en</strong>teunos parénte<strong>si</strong>s <strong>en</strong>tre los que irían los argum<strong>en</strong>tos, <strong>en</strong> caso de que los hubiera.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 83. Es también interesante ver cómo se accede desde programa a la propiedad backColor de lacaja de texto que se llama txtCaja: se hace utilizando el punto <strong>en</strong> la forma txtCaja.BackColor.Los colores se podrían también introducir con notación hexadecimal (com<strong>en</strong>zando con &H,seguidos por dos dígitos <strong>en</strong>tre 00 y FF (es decir, <strong>en</strong>tre 0 y 255 <strong>en</strong> base 10) para los tres coloresfundam<strong>en</strong>tales, es decir para el Red, Gre<strong>en</strong> y Blue (RGB), de derecha a izquierda. Aquí sehan utilizado las constantes <strong>si</strong>mbólicas predefinidas <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>: vbRed, vbGre<strong>en</strong> yvbBlue (ver Tabla 6.1, <strong>en</strong> la página 69).4. Recuérdese que <strong>si</strong> se desea que el código de todos los ev<strong>en</strong>tos aparezca <strong>en</strong> una misma v<strong>en</strong>tanahay que activar la opción Default to Full Module View <strong>en</strong> la solapa Editor del comandoTools/Options. También puede hacerse directam<strong>en</strong>te <strong>en</strong> la v<strong>en</strong>tana de código con uno de losbotones que aparec<strong>en</strong> <strong>en</strong> la parte inferior izquierda ( ).5. Es muy importante crear primero el control frame y después, estando seleccionado, colocarlos botones de opción <strong>en</strong> su interior. No <strong>si</strong>rve hacerlo a la inversa. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> supone quetodos los botones de opción que están d<strong>en</strong>tro del mismo frame forman parte del mismo grupoy sólo permite que uno esté seleccionado.1.5.2 Ejemplo 1.2: Minicalculadora elem<strong>en</strong>talEn este ejemplo se muestra una calculadora elem<strong>en</strong>talque permite hacer las cuatro operaciones aritméticas(Figura 1.3). Los ficheros de este proyecto se pued<strong>en</strong>llamar minicalc.vbp y minicalc.frm.El usuario introduce los datos y clica sobre elbotón correspondi<strong>en</strong>te a la operación que desearealizar, apareci<strong>en</strong>do inmediatam<strong>en</strong>te el resultado <strong>en</strong> lacaja de texto de la derecha.La Tabla 1.3 muestra los objetos y las propiedadesmás importantes de este ejemplo.Figura 1.3. Minicalculadora elem<strong>en</strong>tal.Control Propiedad Valor Control Propiedad ValorfrmMinicalc Name frmMinicalc lblEqual Name lblEqualCaption Minicalculadora Caption =txtOper1 Name txtOper1 cmdSuma Name cmdSumaText Caption +txtOper2 Name txtOper2 cmdResta Name cmdRestaText Caption -txtResult Name txtResult cmdMulti Name cmdProdText Caption *lblOp Name lblOp cmdDivi Name cmdDivCaption Caption /Tabla 1.3. Objetos y propiedades del ejemplo Minicalculadora.A continuación se muestra el código correspondi<strong>en</strong>te a los procedimi<strong>en</strong>tos que gestionan losev<strong>en</strong>tos de este ejemplo.Option ExplicitPrivate Sub cmdDiv_Click()txtResult.Text = Val(txtOper1.Text) / Val(txtOper2.Text)lblOp.Caption = "/"End Sub


Capítulo 1: Introducción página 9Private Sub cmdProd_Click()txtResult.Text = Val(txtOper1.Text) * Val(txtOper2.Text)lblOp.Caption = "*"End SubPrivate Sub cmdResta_Click()txtResult.Text = Val(txtOper1.Text) - Val(txtOper2.Text)lblOp.Caption = "-"End SubPrivate Sub cmdSuma_Click()txtResult.Text = Val(txtOper1.Text) + Val(txtOper2.Text)lblOp.Caption = "+"End SubEn este ejemplo se ha utilizado repetidam<strong>en</strong>te la función Val() de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>. Esta funciónconvierte una serie de caracteres numéricos (un texto formado por cifras) <strong>en</strong> el número <strong>en</strong>tero o depunto flotante correspondi<strong>en</strong>te. Sin la llamada a la función Val() el operador + aplicado a cad<strong>en</strong>asde caracteres las concat<strong>en</strong>a, y <strong>como</strong> resultado, por ejemplo, “3+4” daría “34”. No es lo mismo loscaracteres “1” y “2” formando la cad<strong>en</strong>a o string “12” que el número 12; la función val() conviertecad<strong>en</strong>as de caracteres numéricos –con los que no se pued<strong>en</strong> realizar operaciones aritméticas- <strong>en</strong> losnúmeros correspondi<strong>en</strong>tes –con los que sí se puede operar matemáticam<strong>en</strong>te-. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>transforma de modo automático números <strong>en</strong> cad<strong>en</strong>as de caracteres y viceversa, pero este es un caso<strong>en</strong> el que dicha transformación no funciona porque el operador “+” ti<strong>en</strong>e s<strong>en</strong>tido tanto con números<strong>como</strong> con cad<strong>en</strong>as.1.5.3 Ejemplo 1.3: Transformación de unidades de temperaturaLa Figura 1.4 muestra un programa s<strong>en</strong>cillo quepermite ver la equival<strong>en</strong>cia <strong>en</strong>tre las escalas detemperaturas <strong>en</strong> grados c<strong>en</strong>tígrados y gradosFahr<strong>en</strong>heit. Los ficheros de este proyecto se pued<strong>en</strong>llamar Temperat.vbp y Temperat.frm.En el c<strong>en</strong>tro del formulario aparece una barrade desplazami<strong>en</strong>to vertical que permite desplazarsecon increm<strong>en</strong>tos pequeños de 1º C y grandes de 10ºC. Como es habitual, también puede cambiarse elvalor arrastrando con el ratón el cursor de la barra.Los valores máximos y mínimo de la barra son 100ºC y -100º C.A ambos lados de la barra aparec<strong>en</strong> dos Figura 1.4. Equival<strong>en</strong>cia de temperaturas.cuadros de texto (color de fondo blanco) dondeaparec<strong>en</strong> los grados correspondi<strong>en</strong>tes a la barra <strong>en</strong> ambas escalas. Encima aparec<strong>en</strong> dos rótulos(labels) que indican la escala de temperaturas correspondi<strong>en</strong>te. Completan la aplicación un botónSalir que termina la ejecución y un m<strong>en</strong>ú File con la única opción Exit, que termina a<strong>si</strong>mismo laejecución del programa.La Tabla 1.4 indica los controles utilizados <strong>en</strong> este ejemplo junto con las propiedades y losvalores correspondi<strong>en</strong>tes.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 10Control Propiedad Valor Control Propiedad ValorfrmTemp Name frmTemp vsbTemp Name vsbTempCaption Conversor deMin 100temperaturasmnuFile Name mnuFile Max -100Caption &File SmallChange 1mnuFileExit Name mnuFileExit LargeChange 10Caption E&xit Value 0cmdSalir Name cmdSalir lblC<strong>en</strong>t Name lblC<strong>en</strong>tCaption Salir Caption Grados C<strong>en</strong>tígradosFont MS Sans Serif, Bold, 14 Font MS Sans Serif, 10txtC<strong>en</strong>t Name txtC<strong>en</strong>t lblFahr Name lblFahrtext 0 Caption Grados Fahr<strong>en</strong>heittxtFahr Name txtFahr Font MS Sans Serif, 10text 32Tabla 1.4. Controles y propiedades del Ejemplo 1.3.Por otra parte, el código con el que este programa responde a los ev<strong>en</strong>tos es el cont<strong>en</strong>ido <strong>en</strong>los <strong>si</strong>gui<strong>en</strong>tes procedimi<strong>en</strong>tos:Option ExplicitPrivate Sub cmbSalir_Click()BeepEndEnd SubPrivate Sub mnuFileExit_Click()EndEnd SubPrivate Sub vsbTemp_Change()txtC<strong>en</strong>t.Text = vsbTemp.ValuetxtFahr.Text = 32 + 1.8 * vsbTemp.ValueEnd SubSobre este tercer ejemplo se puede com<strong>en</strong>tar lo <strong>si</strong>gui<strong>en</strong>te:1. Se ha utilizado la propiedad Value de la barra de desplazami<strong>en</strong>to, la cual da el valor actual dela misma con respecto a los límites inferior y superior, previam<strong>en</strong>te establecidos (-100 y 100).2. Mediante el procedimi<strong>en</strong>to cmdSalir_Click, se cierra el programa, gracias a la instrucciónEnd. El cometido de Beep no es otro que el de emitir un pitido a través del altavoz delord<strong>en</strong>ador, que indicará que <strong>en</strong> efecto se ha salido del programa.3. La función mnuFileExit_Click() y activa desde el m<strong>en</strong>ú y termina la ejecución <strong>si</strong>n emitirningún sonido.4. Finalm<strong>en</strong>te, la función vsbTemp_Change() se activa al cambiar el valor de la barra dedesplazami<strong>en</strong>to; su efecto es modificar el valor de la propiedad text <strong>en</strong> las cajas de texto quemuestran la temperatura <strong>en</strong> cada una de las dos escalas.


Capítulo 1: Introducción página 111.5.4 Ejemplo 1.4: Colores RGBLa Figura 1.5 muestra el formulario y loscontroles del proyecto Colores. Los ficheros deeste proyecto se pued<strong>en</strong> llamar Colores.vbp yColores.frm.En este ejemplo se dispone de tres barras dedesplazami<strong>en</strong>to con las que pued<strong>en</strong> controlarselas compon<strong>en</strong>tes RGB del color del fondo y delcolor del texto de un control label. Dos botonesde opción permit<strong>en</strong> determinar <strong>si</strong> los valores delas barras se aplican al fondo o al texto. Cuandose cambia del texto al fondo o viceversa losvalores de las barras de desplazami<strong>en</strong>to (y lapo<strong>si</strong>ción de los cursores) cambian de modoacorde.Figura 1.5. Colores de fondo y de texto.A la dcha. de las barras de desplazami<strong>en</strong>totres cajas de texto conti<strong>en</strong><strong>en</strong> los valores numéricos de los tres colores (<strong>en</strong>tre 0 y 255). A la izda. treslabels indican los colores de las tres barras. La Tabla 1.5 muestra los controles y las propiedadesutilizadas <strong>en</strong> el este ejemplo.Control Propiedad Valor Control Propiedad ValorfrmColores Name frmColores hsbColor Name hsbColorCaption Colores Min 0lblCuadro Name lblCuadro Max 255Caption INFORMÁTICA 1 SmallChange 1Font MS Sans Serif, Bold, 24 LargeChange 16cmdSalir Name cmdSalir Index 0,1,2Caption Salir Value 0Font MS Sans Serif, Bold, 10 txtColor Name txtColoroptColor Name optColor Text 0Index 0,1 Locked TrueCaption Fondo, Texto Index 0,1,2Font MS Sans Serif, Bold, 10 lblColor Name lblColorCaption Rojo,Verde,AzulIndex 0,1,2Font MS Sans Serif, 10Tabla 1.5. Objetos y propiedades del ejemplo Colores.Una característica importante de este ejemplo es que se han utilizado vectores (arrays) decontroles. Las tres barras se llaman hsbColor y se difer<strong>en</strong>cian por la propiedad Index, que toma losvalores 0, 1 y 2. También las tres cajas de texto, las tres labels y los dos botones de opción sonarrays de controles. Para crear un array de controles basta crear el primero de ellos y luego hacerCopy y Paste tantas veces <strong>como</strong> se desee, respondi<strong>en</strong>do afirmativam<strong>en</strong>te al cuadro de diálogo quepregunta <strong>si</strong> desea crear un array.El procedimi<strong>en</strong>to Sub que conti<strong>en</strong>e el código que gestiona un ev<strong>en</strong>to de un array es único paratodo el array, y recibe <strong>como</strong> argum<strong>en</strong>to la propiedad Index. De este modo que se puede saberexactam<strong>en</strong>te <strong>en</strong> qué control del array se ha producido el ev<strong>en</strong>to. Así pues, una v<strong>en</strong>taja de los arraysde controles es que pued<strong>en</strong> compartir el código de los ev<strong>en</strong>tos y permitir un tratami<strong>en</strong>to conjunto


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 12por medio de bucles for. A continuación se muestra el código correspondi<strong>en</strong>te a los procedimi<strong>en</strong>tosque tratan los ev<strong>en</strong>tos de este ejemplo.Option ExplicitPublic Brojo, Bverde, Bazul As IntegerPublic Frojo, Fverde, Fazul As IntegerPrivate Sub cmdSalir_Click()EndEnd SubPrivate Sub Form_Load()Brojo = 0Bverde = 0Bazul = 0Frojo = 255Fverde = 255Fazul = 255lblCuadro.BackColor = RGB(Brojo, Bverde, Bazul)lblCuadro.ForeColor = RGB(Frojo, Fverde, Fazul)End SubPrivate Sub hsbColor_Change(Index As Integer)If optColor(0).Value = True Th<strong>en</strong>lblCuadro.BackColor = RGB(hsbColor(0).Value, hsbColor(1).Value, _hsbColor(2).Value)Dim i As IntegerFor i = 0 To 2txtColor(i).Text = hsbColor(i).ValueNext iElselblCuadro.ForeColor = RGB(hsbColor(0).Value, hsbColor(1).Value, _hsbColor(2).Value)For i = 0 To 2txtColor(i).Text = hsbColor(i).ValueNext iEnd IfEnd SubPrivate Sub optColor_Click(Index As Integer)If Index = 0 Th<strong>en</strong> ’Se pasa a cambiar el fondoFrojo = hsbColor(0).ValueFverde = hsbColor(1).ValueFazul = hsbColor(2).ValuehsbColor(0).Value = BrojohsbColor(1).Value = BverdehsbColor(2).Value = BazulElse’Se pasa a cambiar el textoBrojo = hsbColor(0).ValueBverde = hsbColor(1).ValueBazul = hsbColor(2).ValuehsbColor(0).Value = FrojohsbColor(1).Value = FverdehsbColor(2).Value = FazulEnd IfEnd SubEl código de este ejemplo es un poco más complicado que el de los ejemplos anteriores yrequiere unas ciertas explicaciones adicionales adelantando cuestiones que se verán posteriorm<strong>en</strong>te:1. La función RGB() crea un código de color a partir de sus argum<strong>en</strong>tos: las compon<strong>en</strong>tes RGB(Red, Gre<strong>en</strong> and Blue). Estas compon<strong>en</strong>tes, cuyo valor se almac<strong>en</strong>a <strong>en</strong> un byte y puede oscilar<strong>en</strong>tre 0 y 255, se determinan por medio de las tres barras de desplazami<strong>en</strong>to.


Capítulo 1: Introducción página 132. El color blanco se obti<strong>en</strong>e con los tres colores fundam<strong>en</strong>tales a su máxima int<strong>en</strong><strong>si</strong>dad. Elcolor negro se obti<strong>en</strong>e con los tres colores RGB a cero. También se pued<strong>en</strong> introducir con lasconstantes predefinidas vbWhite y vbBlack, respectivam<strong>en</strong>te.3. Es importante disponer de unas variables globales que almac<strong>en</strong><strong>en</strong> los colores del fondo y deltexto, y que permitan tanto guardar los valores anteriores de las barras <strong>como</strong> cambiar éstas asus nuevos valores cuando se clica <strong>en</strong> los botones de opción. Las variables globales, definidas<strong>en</strong> la parte de definiciones g<strong>en</strong>erales del código, fuera de cualquier procedimi<strong>en</strong>to, sonvi<strong>si</strong>bles desde cualquier parte del programa. Las variables definidas d<strong>en</strong>tro de una función oprocedimi<strong>en</strong>to sólo son vi<strong>si</strong>bles desde d<strong>en</strong>tro de dicha función o procedimi<strong>en</strong>to (variableslocales).4. La función hsbColor_Change(Index As Integer) se activa cada vez que se cambia el valor <strong>en</strong>una cualquiera de las barras de desplazami<strong>en</strong>to. El argum<strong>en</strong>to Index, que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> defineautomáticam<strong>en</strong>te, indica cuál de las barras del array es la que ha cambiado de valor (la 0, la 1ó la 2). En este ejemplo dicho argum<strong>en</strong>to no se ha utilizado, pero está disponible por <strong>si</strong> sehubiera querido utilizar <strong>en</strong> el código.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 142. ENTORNO DE PROGRAMACIÓN VISUAL BASIC <strong>6.0</strong>2.1 INTRODUCCIÓN: ¿QUÉ ES VISUAL BASIC <strong>6.0</strong>?<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es una excel<strong>en</strong>te herrami<strong>en</strong>ta de programación que permite crear aplicacionespropias (programas) para Windows 95/98 o Windows NT. Con ella se puede crear desde una <strong>si</strong>mplecalculadora hasta una hoja de cálculo de la talla de Excel (<strong>en</strong> sus primeras ver<strong>si</strong>ones...), pasando porun procesador de textos o cualquier otra aplicación que se le ocurra al programador. Susaplicaciones <strong>en</strong> Ing<strong>en</strong>iería son ca<strong>si</strong> ilimitadas: repres<strong>en</strong>tación de movimi<strong>en</strong>tos mecánicos o defunciones matemáticas, gráficas termodinámicas, <strong>si</strong>mulación de circuitos, etc.Este programa permite crear v<strong>en</strong>tanas, botones, m<strong>en</strong>ús y cualquier otro elem<strong>en</strong>to de Windowsde una forma fácil e intuitiva. El l<strong>en</strong>guaje de programación que se utilizará será el <strong>Ba<strong>si</strong>c</strong>, que sedescribirá <strong>en</strong> el <strong>si</strong>gui<strong>en</strong>te capítulo.A continuación se pres<strong>en</strong>tarán algunos aspectos del <strong>en</strong>torno de trabajo de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>:m<strong>en</strong>ús, opciones, herrami<strong>en</strong>tas, propiedades, etc.2.2 EL ENTORNO DE VISUAL BASIC <strong>6.0</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ti<strong>en</strong>e todos los elem<strong>en</strong>tos que caracterizan a los programas de Windows e inclusoalguno m<strong>en</strong>os habitual. En cualquier caso, el <strong>en</strong>torno de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es muy lógico y natural, yademás se puede obt<strong>en</strong>er una descripción de la mayoría de los elem<strong>en</strong>tos clicando <strong>en</strong> ellos paraseleccionarlos y pulsando luego la tecla .2.2.1 La barra de m<strong>en</strong>ús y las barras de herrami<strong>en</strong>tasLa barra de m<strong>en</strong>ús de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> resulta <strong>si</strong>milar a la de cualquier otra aplicación deWindows, tal y <strong>como</strong> aparece <strong>en</strong> la Figura 2.2. Bajo dicha barra aparec<strong>en</strong> las barras deherrami<strong>en</strong>tas, con una serie de botones que permit<strong>en</strong> acceder fácilm<strong>en</strong>te a las opciones má<strong>si</strong>mportantes de los m<strong>en</strong>ús. En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> exist<strong>en</strong> cuatro barras de herrami<strong>en</strong>tas: Debug, Edit,Form Editor y Standard. Por defecto sólo aparece la barra Standard, aunque <strong>en</strong> la Figura 2.2 semuestran las cuatro. Clicando con el botón derecho sobre cualquiera de las barras de herrami<strong>en</strong>tasaparece un m<strong>en</strong>ú contextual con el que se puede hacer aparecer y ocultar cualquiera de las barras. Aligual que <strong>en</strong> otras aplicaciones de Windows 95/98/NT, también pued<strong>en</strong> modificarse las barrasañadi<strong>en</strong>do o eliminando botones (opción Customize).En la barra de herrami<strong>en</strong>tas Standard también se pued<strong>en</strong> ver a laderecha dos recuadros con números, que repres<strong>en</strong>tan cuatro propiedadesdel formulario refer<strong>en</strong>tes a su po<strong>si</strong>ción y tamaño que se verán másadelante: Top y Left, que indican la po<strong>si</strong>ción de la esquina superiorizquierda del formulario, y también Height y Width, que describ<strong>en</strong> eltamaño del mismo <strong>en</strong> unas unidades llamadas twips, que secorrespond<strong>en</strong> con la vigé<strong>si</strong>ma parte de un punto (una pulgada ti<strong>en</strong>e 72puntos y 1440 twips). Las dim<strong>en</strong><strong>si</strong>ones de un control aparec<strong>en</strong> tambiéncuando con el ratón se arrastra sobre el formulario, según se puede verFigura 2.1. Información visualsobre el tamaño de un control.<strong>en</strong> la Figura 2.1. Los botones de la barra de herrami<strong>en</strong>tas Standard respond<strong>en</strong> a las funciones má<strong>si</strong>mportantes: abrir y/o guardar nuevos proyectos, añadir formularios, hacer vi<strong>si</strong>bles las distintasv<strong>en</strong>tanas del <strong>en</strong>torno de desarrollo, etc. Todos los botones ti<strong>en</strong><strong>en</strong> su correspondi<strong>en</strong>te comando <strong>en</strong>


Capítulo 2: El <strong>en</strong>torno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 15alguno de los m<strong>en</strong>ús. Son importantes los botones que permit<strong>en</strong> arrancar y/o parar laejecución de un proyecto, pasando de modo diseño a modo de ejecución y viceversa.Figura 2.2. Barra de m<strong>en</strong>ús y barras de herrami<strong>en</strong>tas de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.El m<strong>en</strong>ú File ti<strong>en</strong>e pocas novedades. Lo más importante es la distinción <strong>en</strong>tre proyectos ytodos los demás ficheros. Como ya se ha dicho, un proyecto reúne y organiza todos los ficheros quecompon<strong>en</strong> el programa o aplicación (hace la función de una carpeta que contuviera apuntes). Estosficheros pued<strong>en</strong> ser formularios, módulos, clases, recursos, etc. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite t<strong>en</strong>er másde un proyecto abierto <strong>si</strong>multáneam<strong>en</strong>te, lo cual puede ser útil <strong>en</strong> oca<strong>si</strong>ones. Con el comandoAddProject se añade un nuevo proyecto <strong>en</strong> la v<strong>en</strong>tana Project Manager. Con los comandos Op<strong>en</strong>Project o New Project se abre o se crea un nuevo proyecto, pero cerrando el o los proyectos que<strong>estuviera</strong>n abiertos previam<strong>en</strong>te. En este m<strong>en</strong>ú está el comando Make ProjectName.exe, quepermite crear ejecutables de los proyectos.Tampoco el m<strong>en</strong>ú Edit aporta cambios importantes sobre lo que es habitual. Por el contrarioel m<strong>en</strong>ú View, g<strong>en</strong>eralm<strong>en</strong>te de poca utilidad, es bastante propio de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>. Este m<strong>en</strong>úpermite hacer aparecer <strong>en</strong> pantalla las distintas v<strong>en</strong>tanas del <strong>en</strong>torno de desarrollo, así <strong>como</strong> accedera un formulario o al código relacionado con un control (que también aparece <strong>si</strong> se clica dos veces <strong>en</strong>dicho control), y manejar funciones y procedimi<strong>en</strong>tos.El m<strong>en</strong>ú Project permite añadir distintos tipos de elem<strong>en</strong>tos a un proyecto (formularios,módulos, etc.). Con Project/Properties se puede elegir el tipo de proyecto y determinar elformulario con el que se arrancará la aplicación (Startup Object). Con el comando Compon<strong>en</strong>ts sepued<strong>en</strong> añadir nuevos controles a la Toolbox que aparece a la izquierda de la pantalla.El m<strong>en</strong>ú Format conti<strong>en</strong>e opciones para controlar el aspecto de la aplicación (alinearcontroles, espaciarlos uniformem<strong>en</strong>te, etc.). Los m<strong>en</strong>ús Debug y Run permit<strong>en</strong> controlar laejecución de las aplicaciones. Con Debug se puede ver <strong>en</strong> detalle cómo funcionan, ejecutando pasoa paso, y<strong>en</strong>do hasta una línea de código determinada, etc. Esto es especialm<strong>en</strong>te útil cuando hayaque <strong>en</strong>contrar algunos errores ejecutando paso a paso, o vi<strong>en</strong>do resultados intermedios.En el m<strong>en</strong>ú Tools se <strong>en</strong>cu<strong>en</strong>tran los comandos para arrancar el M<strong>en</strong>u Editor (para crearm<strong>en</strong>ús, <strong>como</strong> se verá <strong>en</strong> el Apartado 5, a partir de la página 64, dedicado a los M<strong>en</strong>ús) y paraestablecer las opciones del programa. En Tools/Options se <strong>en</strong>cu<strong>en</strong>tran las opciones relativas alproyecto <strong>en</strong> el que se trabaja. La l<strong>en</strong>güeta Environm<strong>en</strong>t determina las propiedades del <strong>en</strong>torno delproyecto, <strong>como</strong> las opciones para actualizar o no los ficheros antes de cada ejecución; <strong>en</strong> G<strong>en</strong>eralse establece lo refer<strong>en</strong>te a la retícula o grid que aparece <strong>en</strong> el formulario; Editor permite establecerla nece<strong>si</strong>dad de declarar todas las variables junto con otras opciones de edición, <strong>como</strong> <strong>si</strong> se quier<strong>en</strong>ver o no todos los procedimi<strong>en</strong>tos juntos <strong>en</strong> la misma v<strong>en</strong>tana, y <strong>si</strong> se quiere ver una líneaseparadora <strong>en</strong>tre procedimi<strong>en</strong>tos; Editor Format permite seleccionar el tipo de letra y los códigosde color con los que aparec<strong>en</strong> los distintos elem<strong>en</strong>tos del código. La opción Advanced hacerefer<strong>en</strong>cia <strong>en</strong>tre otras cosas a la opción de utilizar <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>en</strong> dos formatos SDI (SingleDocum<strong>en</strong>t Interface) y MDI (Multiple Docum<strong>en</strong>t Interface descritos <strong>en</strong> el Apartado 4.5, <strong>en</strong> lapágina 61).


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 16Por último, la ayuda (<strong>si</strong>empre imprescindible y <strong>en</strong> el caso de <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> particularm<strong>en</strong>te bi<strong>en</strong> hecha) que se <strong>en</strong>cu<strong>en</strong>tra <strong>en</strong> el m<strong>en</strong>ú Help, sebasa fundam<strong>en</strong>talm<strong>en</strong>te <strong>en</strong> una cla<strong>si</strong>ficación temática ord<strong>en</strong>ada de lainformación disponible (Cont<strong>en</strong>ts), <strong>en</strong> una cla<strong>si</strong>ficación alfabética de lainformación (Index) y <strong>en</strong> la búsqueda de información sobre algún tema porel nombre (Search). Como ya se ha m<strong>en</strong>cionado, la tecla permite unaayuda directa s<strong>en</strong><strong>si</strong>ble al contexto, esto es dep<strong>en</strong>di<strong>en</strong>te de donde se hayaclicado con el ratón (o de lo que esté seleccionado).2.2.2 Las herrami<strong>en</strong>tas (toolbox)La Figura 2.3 muestra la caja de herrami<strong>en</strong>tas, que incluye los controlescon los que se puede diseñar la pantalla de la aplicación. Estos controlesson por ejemplo botones, etiquetas, cajas de texto, zonas gráficas, etc. Paraintroducir un control <strong>en</strong> el formulario <strong>si</strong>mplem<strong>en</strong>te hay que clicar <strong>en</strong> elicono adecuado de la toolbox y colocarlo <strong>en</strong> el formulario con la po<strong>si</strong>ción yel tamaño deseado, clicando y arrastrando con el ratón. Clicando dos vecessobre el icono de un control aparece éste <strong>en</strong> el c<strong>en</strong>tro del formulario y sepuede modificar su tamaño y/o trasladar con el ratón <strong>como</strong> se desee.El número de controles que pued<strong>en</strong> aparecer <strong>en</strong> esta v<strong>en</strong>tana varía conla configuración del <strong>si</strong>stema. Para introducir nuevos compon<strong>en</strong>tes se utilizael comando Compon<strong>en</strong>ts <strong>en</strong> el m<strong>en</strong>ú Project, con lo cual se abre el cuadrode diálogo mostrado <strong>en</strong> la Figura 2.4.Figura 2.3. Caja decompon<strong>en</strong>tes (Toolbox).2.3 FORMULARIOS (FORMS) Y MÓDULOSLos formularios son las zonas de la pantalla sobrelas que se diseña el programa y sobre las que se<strong>si</strong>túan los controles o herrami<strong>en</strong>tas de la toolbox.Al ejecutar el programa, el form se convertirá <strong>en</strong>la v<strong>en</strong>tana de la aplicación, donde aparecerán losbotones, el texto, los gráficos, etc.Para lograr una mejor pres<strong>en</strong>tación existeuna malla o retícula (grid) que permite alinear loscontroles manualm<strong>en</strong>te de una forma precisa(evitando t<strong>en</strong>er que introducir coord<strong>en</strong>adascontinuam<strong>en</strong>te). Esta malla sólo será vi<strong>si</strong>ble <strong>en</strong> elproceso de diseño del programa; al ejecutarlo nose verá. De cualquier forma, se puede desactivarla malla o cambiar sus características <strong>en</strong> el m<strong>en</strong>ú Figura 2.4. Cuadro de diálogo Compon<strong>en</strong>ts.Tools/Options/G<strong>en</strong>eral, cambiando la opciónAlign Controls to Grid.Exteriorm<strong>en</strong>te, los formularios ti<strong>en</strong><strong>en</strong> una estructura <strong>si</strong>milar a la de cualquier v<strong>en</strong>tana. Sinembargo, también pose<strong>en</strong> un código de programación que estará escrito <strong>en</strong> <strong>Ba<strong>si</strong>c</strong>, y que controlaráalgunos aspectos del formulario, sobre todo <strong>en</strong> la forma de reaccionar ante las acciones del usuario(ev<strong>en</strong>tos). El formulario y los controles <strong>en</strong> él <strong>si</strong>tuados serán el esqueleto o la base del programa. Unaaplicación puede t<strong>en</strong>er varios formularios, pero <strong>si</strong>empre habrá uno con el que arrancará laaplicación; este formulario se determina a partir del m<strong>en</strong>ú Project/Properties, <strong>en</strong> Startup Objects.


Capítulo 2: El <strong>en</strong>torno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 17Resumi<strong>en</strong>do, cuando se vaya a crear un programa <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> habrá que dar dospasos:1. Diseñar y preparar la parte gráfica (formularios, botones, m<strong>en</strong>ús, etc.)2. Realizar la programación que gestione la respuesta del programa ante los distintos ev<strong>en</strong>tos.2.4 LA VENTANA DE PROYECTO (PROJECT)Esta v<strong>en</strong>tana, mostrada <strong>en</strong> la Figura 2.5, permite acceder alos distintos formularios y módulos que compon<strong>en</strong> elproyecto. Desde ella se puede ver el diseño gráfico dedichos formularios (botón View Object ), y tambiénpermite editar el código que conti<strong>en</strong><strong>en</strong> (botón View Code). Estos botones están <strong>si</strong>tuados <strong>en</strong> la parte superior dela v<strong>en</strong>tana, debajo de la barra de títulos.Los módulos estándar (ficheros *.bas) conti<strong>en</strong><strong>en</strong>sólo código que, <strong>en</strong> g<strong>en</strong>eral, puede ser utilizado pordistintos formularios y/o controles del proyecto e inclusopor varios proyectos. Por ejemplo puede prepararse unmódulo estándar de funciones matemáticas que sea deutilidad g<strong>en</strong>eral. Normalm<strong>en</strong>te conti<strong>en</strong><strong>en</strong> <strong>si</strong>empre algunasdeclaraciones de variables globales o Public, que seránacce<strong>si</strong>bles directam<strong>en</strong>te desde todos los formularios.Los módulos de clase (ficheros *.cls) conti<strong>en</strong><strong>en</strong>clases definidas por el usuario. Las clases son <strong>como</strong>formularios o controles complejos, <strong>si</strong>n interface gráfica deusuario.Figura 2.5. V<strong>en</strong>tana de proyecto.2.5 LA VENTANA DE PROPIEDADES (PROPERTIES)Todos los objetos <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ti<strong>en</strong><strong>en</strong> unaspropiedades que los defin<strong>en</strong>: su nombre (Name), suetiqueta o título (Caption), el texto que conti<strong>en</strong>e (Text), sutamaño y po<strong>si</strong>ción, su color, <strong>si</strong> está activo o no (Enabled),etc. La Figura 2.6 muestra parcialm<strong>en</strong>te las propiedadesde un formulario. Todas estas propiedades se almac<strong>en</strong>and<strong>en</strong>tro de cada control o formulario <strong>en</strong> forma deestructura (<strong>si</strong>milar a las del l<strong>en</strong>guaje C). Por tanto, <strong>si</strong> porejemplo <strong>en</strong> algún mom<strong>en</strong>to se quiere modificar el nombrede un botón basta con hacerlo <strong>en</strong> la v<strong>en</strong>tana depropiedades (al diseñar el programa) o <strong>en</strong> el código <strong>en</strong><strong>Ba<strong>si</strong>c</strong> (durante la ejecución), mediante el operador punto(.), <strong>en</strong> la forma:Boton1.Name = "NuevoNombre"Para realizar una modificación de las propiedades deun objeto durante el diseño del programa, se activará lav<strong>en</strong>tana de propiedades (con el m<strong>en</strong>ú, con el botón de laFigura 2.6. V<strong>en</strong>tana de propiedades.Figura 2.7. V<strong>en</strong>tana Form Layout.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 18barra de herrami<strong>en</strong>tas o pulsando ). Esta v<strong>en</strong>tana ti<strong>en</strong>e dos l<strong>en</strong>güetas, que permit<strong>en</strong> ord<strong>en</strong>ar laspropiedades alfabéticam<strong>en</strong>te o por categorías. Utilizando la forma que sea más cómoda selocalizará con ayuda de la barra de desplazami<strong>en</strong>to la propiedad que se quiera modificar. Al clicarsobre ella puede activarse un m<strong>en</strong>ú desplegable con las distintas opciones, o bi<strong>en</strong> puede modificarsedirectam<strong>en</strong>te el valor de la propiedad. Si esta propiedad ti<strong>en</strong>e sólo unos valores fijos (por ejemplo,los colores), puede abrirse un cuadro de diálogo para elegir un color, o el tamaño y tipo de letra quese desee <strong>si</strong> se trata de una propiedad Font.La Figura 2.7 muestra la v<strong>en</strong>tana FormLayout, que permite determinar la po<strong>si</strong>ción <strong>en</strong> la queel formulario aparecerá sobre la pantalla cuando se haga vi<strong>si</strong>ble al ejecutar la aplicación.2.6 CREACIÓN DE PROGRAMAS EJECUTABLESUna vez finalizada la programación de la nueva aplicación, la <strong>si</strong>gui<strong>en</strong>te tarea suele con<strong>si</strong>stir <strong>en</strong> lacreación de un programa ejecutable para su distribución e instalación <strong>en</strong> cuantos ord<strong>en</strong>adores sedesee, incluso aunque <strong>en</strong> ellos no esté instalado <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Para crear un programa ejecutable se utiliza el comando Make nombreProyecto.exe … <strong>en</strong> elm<strong>en</strong>ú File. De esta manera se g<strong>en</strong>erará un fichero cuya ext<strong>en</strong><strong>si</strong>ón será *.exe. Para que este programafuncione <strong>en</strong> un ord<strong>en</strong>ador solam<strong>en</strong>te se nece<strong>si</strong>ta que el fichero MSVBVM60.DLL esté instalado <strong>en</strong>el directorio c:\Windows\System o c:\Winnt\System32. En el caso de proyectos más complejos <strong>en</strong>los que se utilic<strong>en</strong> muchos controles pued<strong>en</strong> ser necesarios más ficheros, la mayoría de ellos conext<strong>en</strong><strong>si</strong>ones *.ocx, *.vbx o *.dll. Para saber <strong>en</strong> cada caso cuáles son los ficheros necesarios se puedeconsultar el fichero *.vbp que conti<strong>en</strong>e la descripción completa del proyecto. Ca<strong>si</strong> todos esosficheros necesarios se instalan automáticam<strong>en</strong>te al instalar el compilador de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>en</strong> elord<strong>en</strong>ador.En el caso de el programa se vaya a utilizar <strong>en</strong> un ord<strong>en</strong>ador <strong>en</strong> el que no esté instalado <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong> o de que <strong>en</strong> el proyecto se hayan utilizado controles comerciales (<strong>como</strong> los Crystal Reportspara la creación de informes, los Sheridan Data Widgets o los True DBGrid de Apex para lagestión de bases de datos, etc.), puede resultar interesante construir unos disquetes de instalaciónque <strong>si</strong>mplifiqu<strong>en</strong> la tarea de instalar el programa <strong>en</strong> cualquier ord<strong>en</strong>ador <strong>si</strong>n t<strong>en</strong>er que ver <strong>en</strong> cadacaso cuáles son los ficheros que faltan. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de un A<strong>si</strong>st<strong>en</strong>te (Wizard) que,interactivam<strong>en</strong>te, <strong>si</strong>mplifica <strong>en</strong>ormem<strong>en</strong>te la tarea de creación de disquetes de instalación. EsteA<strong>si</strong>st<strong>en</strong>te está <strong>en</strong> el mismo grupo de programas que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> y se llama Package andDeployem<strong>en</strong>t Wizard.


Capítulo 2: El <strong>en</strong>torno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 192.7 CÓMO UTILIZAR EL HELP<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de un Helpexcel<strong>en</strong>te, <strong>como</strong> la mayoría de lasaplicaciones de Microsoft. En estanueva ver<strong>si</strong>ón la ayuda se ofrece através de una interface de usuario<strong>si</strong>milar a la de Internet Explorer.Estando seleccionado un control, unapropiedad o un formulario, o estandoseleccionada una palabra clave <strong>en</strong> unav<strong>en</strong>tana de código, esta ayuda sepuede utilizar de modo s<strong>en</strong><strong>si</strong>ble alcontexto pulsando la tecla .También se puede ver toda lainformación disponible de modog<strong>en</strong>eral y ord<strong>en</strong>ado por temas con elFigura 2.8. Ayuda de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.comando Help/Cont<strong>en</strong>ts.Otra forma de acceder a la ayudaes mediante las opciones del m<strong>en</strong>úHelp. Así mediante la opción Index sepuede obt<strong>en</strong>er información sobremuchos términos relacionados con<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Una vez obt<strong>en</strong>ida la ayuda sobreel término solicitado se pued<strong>en</strong><strong>en</strong>contrar temas relacionados con esetérmino <strong>en</strong> la opción See Also. En elcaso de que se haya solicitado ayudasobre un determinado tipo de control(<strong>en</strong> la Figura 2.9 se ha hecho con losbotones de comando), se podríaFigura 2.9. Ayuda sobre el botón de comando.acceder también a la ayuda sobretodos y cada uno de sus propiedades, ev<strong>en</strong>tos y métodos con las opciones Properties, Methods yEv<strong>en</strong>ts, respectivam<strong>en</strong>te.La solapa Cont<strong>en</strong>ts de la v<strong>en</strong>tana de ayuda <strong>si</strong>rve para acceder a una pantalla <strong>en</strong> la que la ayudaestá ord<strong>en</strong>ada por temas, la de Index <strong>si</strong>rve para acceder a una pantalla <strong>en</strong> la que se podrá realizaruna búsqueda a partir de un término introducido por el usuario, <strong>en</strong>tre una gran lista de términosord<strong>en</strong>ados alfabéticam<strong>en</strong>te. Al teclear las primeras letras del término, la lista de palabras se vadesplazando de modo automático <strong>en</strong> busca de la palabra buscada. El botón Back <strong>si</strong>rve para regresara la pantalla desde la que se ha llegado a la actual y con el botón Print se puede imprimir elcont<strong>en</strong>ido de la ayuda.2.8 UTILIZACIÓN DEL CODE EDITOREl editor de código o Code Editor de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es la v<strong>en</strong>tana <strong>en</strong> la cual se escrib<strong>en</strong> lass<strong>en</strong>t<strong>en</strong>cias del programa. Esta v<strong>en</strong>tana pres<strong>en</strong>ta algunas características muy interesantes queconvi<strong>en</strong>e conocer para sacar el máximo partido a la aplicación.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 20Para abrir la v<strong>en</strong>tana del editor de código se elige Code <strong>en</strong> el m<strong>en</strong>ú View. También se abreclicando <strong>en</strong> el botón View Code de la Project Window, o clicando dos veces <strong>en</strong> el formulario o <strong>en</strong>cualquiera de sus controles. Cada formulario, cada módulo de clase y cada módulo estándar ti<strong>en</strong><strong>en</strong>su propia v<strong>en</strong>tana de código. La Figura 2.10 muestra un aspecto típico de la v<strong>en</strong>tana de código.Aunque el aspecto de dicha v<strong>en</strong>tana no ti<strong>en</strong>e nada de particular, el Code Editor de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>ofrece muchas ayudas al usuario que requier<strong>en</strong> una explicación más det<strong>en</strong>ida.En primer lugar, el Code Editor utiliza uncódigo de colores (acce<strong>si</strong>ble y modificable <strong>en</strong>Tools/Options/Editor Format) para destacarcada elem<strong>en</strong>to del programa. Así, el códigoescrito por el usuario aparece <strong>en</strong> negro, laspalabras clave de <strong>Ba<strong>si</strong>c</strong> <strong>en</strong> azul, los com<strong>en</strong>tarios<strong>en</strong> verde, los errores <strong>en</strong> rojo, etc. Esta <strong>si</strong>mpleayuda visual permite detectar y corregirproblemas con más facilidad.En la parte superior de esta v<strong>en</strong>tana aparec<strong>en</strong>dos listas desplegables. La de la izquierdacorresponde a los distintos elem<strong>en</strong>tos delformulario (la parte G<strong>en</strong>eral, que es común atodo el formulario; el propio formulario y losFigura 2.10. V<strong>en</strong>tana del Code Editor.distintos controles que están incluidos <strong>en</strong> él). Lalista desplegable de la derecha muestra los distintos procedimi<strong>en</strong>tos que se correspond<strong>en</strong> con elelem<strong>en</strong>to seleccionado <strong>en</strong> la lista de la izquierda. Por ejemplo, <strong>si</strong> <strong>en</strong> la izquierda está seleccionadoun botón de comando, <strong>en</strong> la lista de la derecha aparecerá la lista de todos los po<strong>si</strong>blesprocedimi<strong>en</strong>tos Sub que pued<strong>en</strong> g<strong>en</strong>erar sus po<strong>si</strong>bles ev<strong>en</strong>tos. Estas dos listas permit<strong>en</strong> localizarfácilm<strong>en</strong>te el código que se desee programar o modificar.El código mostrado <strong>en</strong> la Figura 2.10 conti<strong>en</strong>e <strong>en</strong> la parte superior una serie de declaracionesde variables y la opción de no permitir utilizar variables no declaradas (Option Explicit). Ésta es laparte G<strong>en</strong>eral de código del formulario. En esta parte también se pued<strong>en</strong> definir funciones yprocedimi<strong>en</strong>tos Sub no relacionados con ningún ev<strong>en</strong>to o control <strong>en</strong> particular. A continuaciónaparec<strong>en</strong> dos procedimi<strong>en</strong>tos Sub (el segundo de ellos incompleto) que se correspond<strong>en</strong> con elev<strong>en</strong>to Click del botón cmdSalir y con el ev<strong>en</strong>to Load del formulario. Estos procedimi<strong>en</strong>tos estánseparados por una línea, que se activa con Procedure Separator <strong>en</strong> Tools/Options/Editor.Para ver todos los procedimi<strong>en</strong>tos del formulario y de sus controles <strong>si</strong>multáneam<strong>en</strong>te <strong>en</strong> lamisma v<strong>en</strong>tana (con o <strong>si</strong>n separador) o ver sólo un procedimi<strong>en</strong>to (el seleccionado <strong>en</strong> las listasdesplegables) se pued<strong>en</strong> utilizar los dos pequeños botones que aparec<strong>en</strong> <strong>en</strong> la parte inferiorizquierda de la v<strong>en</strong>tana. El primero de ellos es el Procedure View y el segundo el Full ModuleView. Esta opción está también acce<strong>si</strong>ble <strong>en</strong> Tools/Options/Editor.Otra opción muy interesante es la de completar automáticam<strong>en</strong>te el código (AutomaticCompletion Code). La Figura 2.11 muestra cómo al teclear el punto (o alguna letra inicial de unapropiedad después del punto) detrás del nombre de un objeto, automáticam<strong>en</strong>te se abre una lista conlas propiedades de ese objeto. Pulsando la tecla Tab se introduce el nombre completo de lapropiedad seleccionada. A esta característica se le conoce <strong>como</strong> AutoListMembers.Por otra parte, la opción AutoQuickInfo hace que al com<strong>en</strong>zar a teclear el nombre de unafunción aparezca información sobre esa función: nombre, argum<strong>en</strong>tos y valor de retorno (ver Figura


Capítulo 2: El <strong>en</strong>torno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 212.12). Tanto la opción AutoListMembers <strong>como</strong> la opción AutoQuickInfo se activan <strong>en</strong> el cuadro dediálogo que se abre con Tools/Options/Editor.Figura 2.11. Inserción automática de propiedades.Figura 2.12. Ayuda para inserción de funciones.2.9 UTILIZACIÓN DEL DEBUGGERCualquier programador con un mínimo de experi<strong>en</strong>cia sabe que una parte muy importante (muchasveces la mayor parte) del tiempo destinado a la elaboración de un programa se destina a la deteccióny corrección de errores. Ca<strong>si</strong> todos los <strong>en</strong>tornos de desarrollo dispon<strong>en</strong> hoy <strong>en</strong> día de pot<strong>en</strong>tesherrami<strong>en</strong>tas que facilitan la depuración de los programas realizados. La herrami<strong>en</strong>ta más utilizadapara ello es el Depurador o Debugger. La característica principal del Debugger es que permiteejecutar parcialm<strong>en</strong>te el programa, det<strong>en</strong>i<strong>en</strong>do la ejecución <strong>en</strong> el punto deseado y estudiando <strong>en</strong>cada mom<strong>en</strong>to el valor de cada una de las variables. De esta manera se facilita <strong>en</strong>ormem<strong>en</strong>te eldescubrimi<strong>en</strong>to de las fu<strong>en</strong>tes de errores.2.9.1 Ejecución controlada de un programaPara ejecutar parcialm<strong>en</strong>te un programa se pued<strong>en</strong>utilizar varias formas. Una de ellas con<strong>si</strong>ste <strong>en</strong>incluir breakpoints (puntos de parada de laejecución) <strong>en</strong> determinadas líneas del código. Losbreakpoints se indican con un punto grueso <strong>en</strong> elmarg<strong>en</strong> y un cambio de color de la línea, tal <strong>como</strong>se ve <strong>en</strong> la Figura 2.13. En esta figura se muestratambién la barra de herrami<strong>en</strong>tas Debug. El colocarun breakpoint <strong>en</strong> una línea de código implica que laejecución del programa se det<strong>en</strong>drá al llegar a esaFigura 2.13. Utilización del Debugger.línea. Para insertar un breakpoint <strong>en</strong> una línea delcódigo se utiliza la opción Toggle Breakpoint del m<strong>en</strong>ú Debug, con el botón del mismo nombre( ) o pulsando la tecla , estando el cursor po<strong>si</strong>cionado sobre la línea <strong>en</strong> cuestión. Paraborrarlo se repite esa operación.Cuando la ejecución está det<strong>en</strong>ida <strong>en</strong> una línea aparece una flecha <strong>en</strong> el marg<strong>en</strong> izquierdo, tal<strong>como</strong> puede verse también <strong>en</strong> la Figura 2.13. En ese mom<strong>en</strong>to se puede consultar el valor decualquier variable que sea acce<strong>si</strong>ble desde ese punto <strong>en</strong> la v<strong>en</strong>tana de depuración (Debug Window).Un poco más adelante se verán varias formas de hacer esto.En la Figura 2.13 se puede observar <strong>como</strong> la ejecución del programa está det<strong>en</strong>ida <strong>en</strong> la líneacoloreada o recuadrada, con una flecha <strong>en</strong> el marg<strong>en</strong> izquierdo. Se puede observar también lavariación del color de fondo de la línea anterior debido a que <strong>en</strong> ella hay un breakpoint.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 22De todos modos no es estrictam<strong>en</strong>te necesaria la utilización de breakpoints para la ejecuciónparcial de un programa. Esto se puede hacer también ejecutando el programa paso a paso (o línea alínea). Para hacer esto hay varias opciones: pulsando la tecla , seleccionando la opción StepInto del m<strong>en</strong>ú Run o clicando <strong>en</strong> el botón correspondi<strong>en</strong>te ( ). Esta instrucción hace que seejecute una línea del código. En el caso de que ésta se trate de la llamada a un procedimi<strong>en</strong>to ofunción, la ejecución se trasladará a la primera línea de ese procedimi<strong>en</strong>to o función. En el caso deque se desee ejecutar toda la función <strong>en</strong> un único paso (por ejemplo porque se ti<strong>en</strong>e constancia deque esa función funciona correctam<strong>en</strong>te) se puede hacer mediante la opción Step Over, pulsando lasteclas y <strong>si</strong>multáneam<strong>en</strong>te, o clicando <strong>en</strong> el botón correspondi<strong>en</strong>te ( ). Eneste caso la ejecución se traslada a la línea inmediatam<strong>en</strong>te posterior a la llamada a la función. En elcaso de que la línea a ejecutar no sea la llamada a una función ambas opciones (Step Into y StepOver) operan idénticam<strong>en</strong>te. El comando y botón Step Out ( ) hace que se salga de la función oprocedimi<strong>en</strong>to que se está ejecutando y que la ejecución se det<strong>en</strong>ga <strong>en</strong> la s<strong>en</strong>t<strong>en</strong>cia inmediatam<strong>en</strong>te<strong>si</strong>gui<strong>en</strong>te a la llamada a dicha función o procedimi<strong>en</strong>to.La utilización del Debugger permite también otras opciones muy interesantes <strong>como</strong> la deejecutar el programa hasta la línea <strong>en</strong> la que se <strong>en</strong>cu<strong>en</strong>tre po<strong>si</strong>cionado el cursor (con Step To Cursoro Ctrl+); la de continuar con la ejecución del programa hasta el <strong>si</strong>gui<strong>en</strong>te breakpoint <strong>en</strong> elcaso de que lo haya o hasta el final del mismo <strong>si</strong> no hay ninguno (con Continue, botón o );y la po<strong>si</strong>bilidad de volver a com<strong>en</strong>zar la ejecución (con Restart o Mayúsculas + ). Además delas ya m<strong>en</strong>cionadas, también existe la po<strong>si</strong>bilidad de det<strong>en</strong>er mom<strong>en</strong>táneam<strong>en</strong>te la ejecución delprograma mediante el botón Pause ( ) o la combinación de teclas Ctrl+Pausa.Figura 2.14. V<strong>en</strong>tana Immediate.Figura 2.15. V<strong>en</strong>tana Locals.2.9.2 V<strong>en</strong>tanas Immediate, Locals y WatchesEl Debugger de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de varias formas para consultar el valor de variables ypropiedades, así <strong>como</strong> para ejecutar funciones y procedimi<strong>en</strong>tos comprobando su correctofuncionami<strong>en</strong>to. En ello juegan un papel importante tres tipos de v<strong>en</strong>tanas: Immediate, Locals yWatch.La v<strong>en</strong>tana Immediate (ver Figura 2.14) permite realizar diversas acciones:1. Imprimir el valor de cualquier variable y/o propiedad acce<strong>si</strong>ble la función o procedimi<strong>en</strong>toque se está ejecutando. Esto se puede hacer utilizando el método Print VarName (o suequival<strong>en</strong>te ?VarName) directam<strong>en</strong>te <strong>en</strong> dicha v<strong>en</strong>tana o introduci<strong>en</strong>do <strong>en</strong> el código delprograma s<strong>en</strong>t<strong>en</strong>cias del tipo Debug.Print VarName. En este último caso el valor de lavariable o propiedad se escribe <strong>en</strong> la v<strong>en</strong>tana Immediate <strong>si</strong>n nece<strong>si</strong>dad de parar laejecución del programa. Además esas s<strong>en</strong>t<strong>en</strong>cias se guardan con el formulario y no hayque volver a escribirlas para una nueva ejecución. Cuando se compila el programa paraproducir un ejecutable las s<strong>en</strong>t<strong>en</strong>cias Debug.Print son ignoradas. La utilización delmétodo Print se explica <strong>en</strong> el Apartado 7.2, <strong>en</strong> la página 88.


Capítulo 2: El <strong>en</strong>torno de programación <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 232. A<strong>si</strong>gnar valores a variables y propiedades cuando la ejecución está det<strong>en</strong>ida y proseguir laejecución con los nuevos valores. Sin embargo, no se pued<strong>en</strong> crear nuevas variables.3. Ejecutar expre<strong>si</strong>ones y probar funciones y procedimi<strong>en</strong>tos incluy<strong>en</strong>do <strong>en</strong> la v<strong>en</strong>tanaImmediate la llamada correspondi<strong>en</strong>te.La v<strong>en</strong>tana Locals, mostrada <strong>en</strong> la Figura 2.15, muestra el valor de todas las variables vi<strong>si</strong>bles<strong>en</strong> el procedimi<strong>en</strong>to <strong>en</strong> el que está det<strong>en</strong>ida la ejecución.Otra opción que puede resultar útil es lade conocer perman<strong>en</strong>tem<strong>en</strong>te el valor de unavariable <strong>si</strong>n t<strong>en</strong>er que consultarlo cada vez.Para conocer inmediatam<strong>en</strong>te el valor de unavariable se puede utilizar la v<strong>en</strong>tana QuickWatch, mostrada <strong>en</strong> la Figura 2.16. Paraobservar continuam<strong>en</strong>te el valor de unaFigura 2.16. V<strong>en</strong>tana Quick Watch.variable, o expre<strong>si</strong>ón hay que añadirla a lav<strong>en</strong>tana Watches. Esto se hace con la opciónAdd Watch… del m<strong>en</strong>ú Debug. El valor de lasvariables incluidas <strong>en</strong> la v<strong>en</strong>tana Watches (verFigura 2.18) se actualiza automáticam<strong>en</strong>te,indicándose también cuando no son acce<strong>si</strong>blesdesde el procedimi<strong>en</strong>to que se esté ejecutando(Out of Context).La v<strong>en</strong>tana Add Watch mostrada <strong>en</strong> laFigura 2.17 permite introducir Breaks oparadas del programa condicionales, cuando secumple cierta condición o cuando el valor de lavariable cambia.Figura 2.17. V<strong>en</strong>tana Add Watch.Las capacidades de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> paravigilar el valor de las variables pued<strong>en</strong>activarse desde el m<strong>en</strong>ú Debug o con algunosbotones <strong>en</strong> la barra de herrami<strong>en</strong>tas Debug( ).2.9.3 Otras po<strong>si</strong>bilidades del DebuggerFigura 2.18. V<strong>en</strong>tana Watches.El Debugger de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite nosólo saber qué s<strong>en</strong>t<strong>en</strong>cia va a ser la próxima <strong>en</strong> ejecutarse (con Debug/Show Next Statem<strong>en</strong>t), <strong>si</strong>notambién decidir cuál va a ser dicha s<strong>en</strong>t<strong>en</strong>cia (con Debug/Set Next Statem<strong>en</strong>t), pudi<strong>en</strong>do cambiar deesta forma el curso habitual de la ejecución: saltando s<strong>en</strong>t<strong>en</strong>cias, volvi<strong>en</strong>do a una s<strong>en</strong>t<strong>en</strong>cia yaejecutada, etc.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> puede dar también información sobre las llamadas a funciones yprocedimi<strong>en</strong>tos. Esto se hace con el comando View/Call Stack o con el botón correspondi<strong>en</strong>te de labarra Debug ( ). De esta manera puede conocerse qué función ha llamado a qué función hasta las<strong>en</strong>t<strong>en</strong>cia donde la ejecución está det<strong>en</strong>ida.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 243. LENGUAJE BASIC3.1 INTRODUCCIÓNEn este capítulo se explican los fundam<strong>en</strong>tos del l<strong>en</strong>guaje de programación <strong>Ba<strong>si</strong>c</strong> utilizado <strong>en</strong> el<strong>si</strong>stema de desarrollo para <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> de Microsoft. En este manual se supone que el lector noti<strong>en</strong>e conocimi<strong>en</strong>tos previos de programación.Un programa –<strong>en</strong> s<strong>en</strong>tido informático– está constituido <strong>en</strong> un s<strong>en</strong>tido g<strong>en</strong>eral por variablesque conti<strong>en</strong><strong>en</strong> los datos con los que se trabaja y por algoritmos que son las s<strong>en</strong>t<strong>en</strong>cias que operansobre estos datos. Estos datos y algoritmos suel<strong>en</strong> estar incluidos d<strong>en</strong>tro de funciones oprocedimi<strong>en</strong>tos.Un procesador digital únicam<strong>en</strong>te es capaz de <strong>en</strong>t<strong>en</strong>der aquello que está constituido porconjuntos de unos y ceros. A esto se le llama l<strong>en</strong>guaje de máquina o binario, y es muy difícil demanejar. Por ello, desde ca<strong>si</strong> los primeros años de los ord<strong>en</strong>adores, se com<strong>en</strong>zaron a desarrollar losllamados l<strong>en</strong>guajes de alto nivel (tales <strong>como</strong> el Fortran, el Cobol, etc.), que están mucho más cercadel l<strong>en</strong>guaje natural. Estos l<strong>en</strong>guajes están basados <strong>en</strong> el uso de id<strong>en</strong>tificadores, tanto para los datos<strong>como</strong> para las compon<strong>en</strong>tes elem<strong>en</strong>tales del programa, que <strong>en</strong> algunos l<strong>en</strong>guajes se llaman rutinas,procedimi<strong>en</strong>tos, o funciones. Además, cada l<strong>en</strong>guaje dispone de una <strong>si</strong>ntaxis o conjunto de reglascon las que se indica de modo inequívoco las operaciones que se quiere realizar.Los l<strong>en</strong>guajes de alto nivel son más o m<strong>en</strong>os compr<strong>en</strong><strong>si</strong>bles para el usuario, pero no para elprocesador. Para que éste pueda ejecutarlos es necesario traducirlos a su propio l<strong>en</strong>guaje demáquina. Al paso del l<strong>en</strong>guaje de alto nivel al l<strong>en</strong>guaje de máquina se le d<strong>en</strong>omina compilación. En<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> esta etapa no se aprecia tanto <strong>como</strong> <strong>en</strong> otros l<strong>en</strong>guajes donde el programador ti<strong>en</strong>e queindicar al ord<strong>en</strong>ador explícitam<strong>en</strong>te que realice dicha compilación. Los programas de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>se dice que son interpretados y no compilados ya que el código no se convierte a código máquina<strong>si</strong>no que hay otro programa que durante la ejecución “interpreta” las líneas de código que ha escritoel programador. En g<strong>en</strong>eral durante la ejecución de cualquier programa, el código es cargado por el<strong>si</strong>stema operativo <strong>en</strong> la memoria RAM.3.2 COMENTARIOS Y OTRAS UTILIDADES EN LA PROGRAMACIÓN CON VISUAL BASIC<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> interpreta que todo lo que está a la derecha del carácter (') <strong>en</strong> una línea cualquieradel programa es un com<strong>en</strong>tario y no lo ti<strong>en</strong>e <strong>en</strong> cu<strong>en</strong>ta para nada. El com<strong>en</strong>tario puede empezar alcomi<strong>en</strong>zo de la línea o a continuación de una instrucción que debe ser ejecutada, por ejemplo:’ Esto es un com<strong>en</strong>tarioA = B*x+3.4 ' también esto es un com<strong>en</strong>tarioLos com<strong>en</strong>tarios son trem<strong>en</strong>dam<strong>en</strong>te útiles para poder <strong>en</strong>t<strong>en</strong>der el código utilizado, facilitandode ese modo futuras revi<strong>si</strong>ones y correcciones. En programas que no cont<strong>en</strong>gan muchas líneas decódigo puede no parecer dema<strong>si</strong>ado importante, pero cuando se trata de proyectos realm<strong>en</strong>tecomplejos, o desarrollados por varias personas su importancia es trem<strong>en</strong>da. En el caso de que elcódigo no esté com<strong>en</strong>tado este trabajo de actualización y revi<strong>si</strong>ón puede resultar complicadí<strong>si</strong>mo.Otro aspecto práctico <strong>en</strong> la programación es la po<strong>si</strong>bilidad de escribir una s<strong>en</strong>t<strong>en</strong>cia <strong>en</strong> másde una línea. En el caso de s<strong>en</strong>t<strong>en</strong>cias bastante largas es conv<strong>en</strong>i<strong>en</strong>te cortar la línea para que <strong>en</strong>tre<strong>en</strong> la pantalla. En otro caso la lectura del código se hace mucho más pesada. Para ello es necesariodejar un espacio <strong>en</strong> blanco al final de la línea y escribir el carácter (_) tal y <strong>como</strong> se muestra <strong>en</strong> el<strong>si</strong>gui<strong>en</strong>te ejemplo:


Capítulo 3: L<strong>en</strong>guaje BASIC página 25str1 = "Londres" : str2 = "París"'Se inicializan las variablesFrase = "Me gustaría mucho viajar a " & _str1 & " y a " & str2'El cont<strong>en</strong>ido de Frase sería: "Me gustaría mucho viajar a Londres y a ParísUna limitación a los com<strong>en</strong>tarios <strong>en</strong> el código es que no se pued<strong>en</strong> introducir <strong>en</strong> una línea <strong>en</strong>la que se ha introducido el carácter de continuación (_).La <strong>si</strong>ntaxis de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite también incluir varias s<strong>en</strong>t<strong>en</strong>cias <strong>en</strong> una mismalínea. Para ello las s<strong>en</strong>t<strong>en</strong>cias deb<strong>en</strong> ir separadas por el carácter dos puntos (:). Por ejemplo:m = a : n = b : resto = m Mod n' Tres s<strong>en</strong>t<strong>en</strong>cias <strong>en</strong> una línea3.3 PROYECTOS Y MÓDULOSUn proyecto realizado <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es el conjunto de todos los ficheros o módulosnecesarios para que un programa funcione. La información refer<strong>en</strong>te a esos ficheros se almac<strong>en</strong>a <strong>en</strong>un fichero del tipo ProjectName.vbp. La ext<strong>en</strong><strong>si</strong>ón *.vbp del fichero hace refer<strong>en</strong>cia a <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>Project.Si se edita este fichero con cualquier editor de texto se comprueba que la información quealmac<strong>en</strong>a es la localización <strong>en</strong> los discos de los módulos que conforman ese proyecto, los controlesutilizados (ficheros con ext<strong>en</strong><strong>si</strong>ón .ocx), etc. En el caso más <strong>si</strong>mple un proyecto está formado por unúnico formulario y constará de dos ficheros: el que define el proyecto (*.vbp) y el que define elformulario (*.frm).Los módulos que forman parte de un proyecto pued<strong>en</strong> ser de varios tipos: aquellos que estánasociados a un formulario (*.frm), los que conti<strong>en</strong><strong>en</strong> únicam<strong>en</strong>te líneas de código <strong>Ba<strong>si</strong>c</strong> (*.bas)llamados módulos estándar y los que defin<strong>en</strong> agrupaciones de código y datos d<strong>en</strong>ominadas clases(*.cls), llamados módulos de clase.Un módulo *.frm está constituido por un formulario y toda la información refer<strong>en</strong>te a loscontroles (y a sus propiedades) <strong>en</strong> él cont<strong>en</strong>idos, además de todo el código programado <strong>en</strong> losev<strong>en</strong>tos de esos controles y, <strong>en</strong> el caso de que existan, las funciones y procedimi<strong>en</strong>tos propios deese formulario. En g<strong>en</strong>eral se llama función a una porción de código indep<strong>en</strong>di<strong>en</strong>te que realiza unadeterminada actividad. En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> exist<strong>en</strong> dos tipos de funciones: las llamadas function, quese caracterizan por t<strong>en</strong>er valor de retorno, y los procedimi<strong>en</strong>tos o procedures, que no lo ti<strong>en</strong><strong>en</strong>. Enotros l<strong>en</strong>guajes, <strong>como</strong> C/C++/Java, las function realizan los dos papeles.Un módulo de código estándar *.bas cont<strong>en</strong>drá una o varias funciones y/o procedimi<strong>en</strong>tos,además de las variables que se desee, a los que se podrá acceder desde cualquiera de los módulosque forman el proyecto.3.3.1 Ámbito de las variables y los procedimi<strong>en</strong>tosSe <strong>en</strong>ti<strong>en</strong>de por ámbito de una variable (ver Apartado 3.3.1, <strong>en</strong> la página 25) la parte de laaplicación donde la variable es vi<strong>si</strong>ble (acce<strong>si</strong>ble) y por lo tanto puede ser utilizada <strong>en</strong> cualquierexpre<strong>si</strong>ón.3.3.1.1 Variables y funciones de ámbito localUn módulo puede cont<strong>en</strong>er variables y procedimi<strong>en</strong>tos o funciones públicos y privados. Lospúblicos son aquellos a los que se puede acceder librem<strong>en</strong>te desde cualquier punto del proyecto.Para definir una variable, un procedimi<strong>en</strong>to o una función <strong>como</strong> público es necesario preceder a ladefinición de la palabra Public, <strong>como</strong> por ejemplo:


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 26Public Variable1 As IntegerPublic Sub Procedimi<strong>en</strong>to1 (Parametro1 As Integer, …)Public Function Funcion1 (Parametro1 As Integer, …) As IntegerPara utilizar una variable Public o llamar a una función Public definidas <strong>en</strong> un formulariodesde otro módulo se debe preceder el nombre de la variable o procedimi<strong>en</strong>to con el nombre delformulario al que pert<strong>en</strong>ece, <strong>como</strong> por ejemplo:Modulo1.Variable1Call Modulo1.Procedimi<strong>en</strong>to1(Parametro1, …)Retorno = Modulo1.Funcion1(Parametro1, …)Sin embargo <strong>si</strong> el módulo al que pert<strong>en</strong>ec<strong>en</strong> la variable o el procedimi<strong>en</strong>to Public es unmódulo estándar (*.bas) no es necesario poner el nombre del módulo más que <strong>si</strong> hay coincid<strong>en</strong>ciade nombres con los de otro módulo también estándar. Una variable Private, por el contrario, no esacce<strong>si</strong>ble desde ningún otro módulo distinto de aquél <strong>en</strong> el que se haya declarado.Se llama variable local a una variable definida d<strong>en</strong>tro de un procedimi<strong>en</strong>to o función. Lasvariables locales no son acce<strong>si</strong>bles más que <strong>en</strong> el procedimi<strong>en</strong>to o función <strong>en</strong> que están definidas.Una variable local es reinicializada (a cero, por defecto) cada vez que se <strong>en</strong>tra <strong>en</strong> elprocedimi<strong>en</strong>to. Es decir, una variable local no conserva su valor <strong>en</strong>tre una llamada al procedimi<strong>en</strong>toy la <strong>si</strong>gui<strong>en</strong>te. Para hacer que el valor de la variable se conserve hay que declarar la variable <strong>como</strong>static (<strong>como</strong> por ejemplo: Static n As Integer). <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> inicializa una variable estáticasolam<strong>en</strong>te la primera vez que se llama al procedimi<strong>en</strong>to. Para declarar una variable estática, seutiliza la palabra Static <strong>en</strong> lugar de Dim. Un poco más adelante se verá que Dim es una palabrautilizada para crear variables. Si un procedimi<strong>en</strong>to se declara Static todss sus variables localesti<strong>en</strong><strong>en</strong> carácter Static.3.3.1.2 Variables y funciones de ámbito globalSe puede acceder a una variable o función global desde cualquier parte de la aplicación. Para hacerque una variable sea global, hay que declararla <strong>en</strong> la parte g<strong>en</strong>eral de un módulo *.bas o de unformulario de la aplicación. Para declarar una variable global se utiliza la palabra Public. Porejemplo:Public var1_global As Double, var2_global As StringDe esta forma se podrá acceder a las variables var1_global, var2_global desde todos losformularios. La Tabla 3.1 muestra la acce<strong>si</strong>bilidad de las variable <strong>en</strong> función de dónde y cómo sehayan declarado 1 .La difer<strong>en</strong>cia <strong>en</strong>tre las variables y/o procedimi<strong>en</strong>tos Public de los formularios y de losmódulos estándar está <strong>en</strong> que las de los procedimi<strong>en</strong>tos deb<strong>en</strong> ser cualificadas (precedidas) por elnombre del formulario cuando se llaman desde otro módulo distinto, mi<strong>en</strong>tras que las de un móduloestándar (*.bas) sólo nece<strong>si</strong>tan ser cualificadas <strong>si</strong> hay coli<strong>si</strong>ón o coincid<strong>en</strong>cia de nombres.1Las palabras Global y Dim proced<strong>en</strong> de ver<strong>si</strong>ones antiguas de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> y debe preferirse la utilización de laspalabras clave Public y Private, que expresan mejor su <strong>si</strong>gnificado.


Capítulo 3: L<strong>en</strong>guaje BASIC página 27Tipo de variable Lugar de declaración Acce<strong>si</strong>bilidadGlobal o Public Declaraciones de *.bas Desde todos los formulariosDim o Private Declaraciones de *.bas Desde todas las funciones de esemóduloPublic Declaraciones de *.frm Desde cualquier procedimi<strong>en</strong>todel propio formulario y desdeotros precedida del nombre delmodulo <strong>en</strong> el que se ha declaradoDim o Private Declaraciones de *.frm Desde cualquier procedimi<strong>en</strong>todel propio formularioDimCualquier procedimi<strong>en</strong>to deun móduloDesde el propio procedimi<strong>en</strong>toTabla 3.1. Acce<strong>si</strong>bilidad de las variables.3.4 VARIABLES3.4.1 Id<strong>en</strong>tificadoresLa memoria de un computador consta de un conjunto <strong>en</strong>orme de bits (1 y 0), <strong>en</strong> la que se almac<strong>en</strong>andatos y programas. Las nece<strong>si</strong>dades de memoria de cada tipo de dato no son homogéneas (porejemplo, un carácter alfanumérico ocupa un byte (8 bits), mi<strong>en</strong>tras que un número real con 16 cifrasocupa 8 bytes), y tampoco lo son las de los programas. Además, el uso de la memoria cambia a lolargo del tiempo d<strong>en</strong>tro incluso de una misma se<strong>si</strong>ón de trabajo, ya que el <strong>si</strong>stema reserva o liberamemoria a medida que la va nece<strong>si</strong>tando.Cada po<strong>si</strong>ción de memoria <strong>en</strong> la que un dato está almac<strong>en</strong>ado (ocupando un conjunto de bits)puede id<strong>en</strong>tificarse mediante un número o una dirección, y éste es el modo más bá<strong>si</strong>co de referirse auna determinada información. No es, <strong>si</strong>n embargo, un <strong>si</strong>stema cómodo o práctico, por la nularelación nemotécnica que una dirección de memoria suele t<strong>en</strong>er con el dato cont<strong>en</strong>ido, y porque –<strong>como</strong> se ha dicho antes– la dirección fí<strong>si</strong>ca de un dato cambia de ejecución a ejecución, o incluso <strong>en</strong>el transcurso de una misma ejecución del programa. Lo mismo ocurre con partes concretas de unprograma determinado.Dadas las citadas dificultades para referirse a un dato por medio de su dirección <strong>en</strong> memoria,se ha hecho habitual el uso de id<strong>en</strong>tificadores. Un id<strong>en</strong>tificador es un nombre <strong>si</strong>mbólico que serefiere a un dato o programa determinado. Es muy fácil elegir id<strong>en</strong>tificadores cuyo nombre guardeestrecha relación con el s<strong>en</strong>tido fí<strong>si</strong>co, matemático o real del dato que repres<strong>en</strong>tan. Así por ejemplo,es lógico utilizar un id<strong>en</strong>tificador llamado salario_bruto o salarioBruto para repres<strong>en</strong>tar el costeanual de un empleado. El usuario no ti<strong>en</strong>e nunca que preocuparse de direcciones fí<strong>si</strong>cas dememoria: el <strong>si</strong>stema se preocupa por él por medio de una tabla, <strong>en</strong> la que se relaciona cadaid<strong>en</strong>tificador con el tipo de dato que repres<strong>en</strong>ta y la po<strong>si</strong>ción de memoria <strong>en</strong> la que está almac<strong>en</strong>ado.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>, <strong>como</strong> todos los demás l<strong>en</strong>guajes de programación, ti<strong>en</strong>e sus propias reglaspara elegir los id<strong>en</strong>tificadores. Los usuarios pued<strong>en</strong> elegir con gran libertad los nombres de susvariables y funciones, t<strong>en</strong>i<strong>en</strong>do <strong>si</strong>empre cuidado de respetar las reglas del l<strong>en</strong>guaje y de no utilizarun conjunto de palabras reservadas (keywords), que son utilizadas por el propio l<strong>en</strong>guaje. En elApartado 3.4.3, <strong>en</strong> la página 28, se explicarán las reglas para elegir nombres y cuáles son laspalabras reservadas del l<strong>en</strong>guaje <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 283.4.2 Variables y constantesUna variable es un nombre que de<strong>si</strong>gna a una zona de memoria (se trata por tanto de unid<strong>en</strong>tificador), que conti<strong>en</strong>e un valor de un tipo de información.Tal y <strong>como</strong> su nombre indica, las variablespued<strong>en</strong> cambiar su valor a lo largo de la ejecución deun programa. Completando a las variables existe loque se d<strong>en</strong>omina constantes las cuales sonid<strong>en</strong>tificadores pero con la particularidad de que elvalor que se <strong>en</strong>cu<strong>en</strong>tra <strong>en</strong> ese lugar de la memoriasólo puede ser a<strong>si</strong>gnado una única vez. Eltratami<strong>en</strong>to y tipos de datos es igual al de lasvariables.Para declarar un dato <strong>como</strong> constanteúnicam<strong>en</strong>te es necesario utilizar la palabra Const <strong>en</strong>la declaración de la variable. Si durante la ejecuciónFigura 3.1. Constantes de color predefinidas.se int<strong>en</strong>ta variar su valor se producirá un error.Ejemplos:Const MyVar = 459’ Las constantes son privadas por defecto.Public Const MyString = "HELP" ' Declaración de una constante pública.Private Const MyInt As Integer = 5 ' Declaración de un <strong>en</strong>tero constante.Const Str = "Hi", PI As Double = 3.14 ' Múltiples constantes <strong>en</strong> una línea.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ti<strong>en</strong>e sus propias constantes, muy útiles por cierto. Algunas ya se han visto alhablar de los colores. En g<strong>en</strong>eral estas constantes empiezan por ciertos caracteres <strong>como</strong> vb (u otros<strong>si</strong>milares que indican a que grupo pert<strong>en</strong>ec<strong>en</strong>) y van seguidas de una o más palabras que indican su<strong>si</strong>gnificado. Para ver las constantes disponibles se puede utilizar el comando View/Object Browser,tal <strong>como</strong> se muestra <strong>en</strong> la Figura 3.1.3.4.3 Nombres de variablesEl nombre de una variable (o de una constante) ti<strong>en</strong>e que com<strong>en</strong>zar <strong>si</strong>empre por una letra y puedet<strong>en</strong>er una longitud hasta 255 caracteres. No se admit<strong>en</strong> espacios o caracteres <strong>en</strong> blanco, ni puntos (.),ni otros caracteres especiales.Los caracteres pued<strong>en</strong> ser letras, dígitos, el carácter de subrayado (_) y los caracteres dedeclaración del tipo de la variable (%, &, #, !, @, y $ ). El nombre de una variable no puede ser unapalabra reservada del l<strong>en</strong>guaje (For, If, Loop, Next, Val, Hide, Caption, And, ...). Para sabercuáles son las palabras reservadas <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> puede utilizarse el Help de dicho programa,buscando la refer<strong>en</strong>cia Reserved Words. De ordinario las palabras reservadas del l<strong>en</strong>guaje aparec<strong>en</strong>de color azul <strong>en</strong> el editor de código, lo que hace más fácil saber <strong>si</strong> una palabra es reservada o no.A difer<strong>en</strong>cia de C, Matlab, Maple y otros l<strong>en</strong>guajes de programación, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> nodistingue <strong>en</strong>tre minúsculas y mayúsculas. Por tanto, las variables LongitudTotal y longitudtotalson con<strong>si</strong>deradas <strong>como</strong> idénticas (la misma variable). En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es habitual utilizar lasletras mayúsculas para separar las distintas palabras que están unidas <strong>en</strong> el nombre de una variable,<strong>como</strong> se ha hecho anteriorm<strong>en</strong>te <strong>en</strong> la variable LongitudTotal. La declaración de una variable o laprimera vez que se utiliza determnan cómo se escribe <strong>en</strong> el resto del programa.También es habitual <strong>en</strong>tre los programadores, aunque no obligado, el utilizar nombres contodo mayúsculas para los nombres de las constantes <strong>si</strong>mbólicas, <strong>como</strong> por ejemplo PI.


Capítulo 3: L<strong>en</strong>guaje BASIC página 293.4.4 Tipos de datosAl igual que C y otros l<strong>en</strong>guajes de programación, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> dispone de distintos tipos de datos,aplicables tanto para constantes <strong>como</strong> para variables. La Tabla 3.2 muestra los tipos de datosdisponibles <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>.Tipo Descripción Carácter dedeclaraciónRangoBoolean Binario True o FalseByte Entero corto 0 a 255Integer Entero (2 bytes) % -32768 a 32767Long Entero largo (4 bytes) & -2147483648 a 2147483647Single Real <strong>si</strong>mple preci<strong>si</strong>ón (4 bytes ) ! -3.40E+38 a 3.40E+38Double Real doble preci<strong>si</strong>ón ( 8 bytes) # -1.79D+308 a 1.79D+308Curr<strong>en</strong>cy Número con punto decimal fijo (8 bytes) @ -9.22E+14 a 9.22E+14String Cad<strong>en</strong>a de caracteres (4 bytes + 1byte/car hasta 64 K)$ 0 a 65500 caracteres.Date Fecha (8 bytes) 1 de <strong>en</strong>ero de 100 a 31 de diciembre de9999. Indica también la hora, desde 0:00:00a 23:59:59.Variant Fecha/hora;ninguno F/h: <strong>como</strong> DateUser-definednúmeros <strong>en</strong>teros, reales, o caracteres(16 bytes + 1 byte/car. <strong>en</strong> cad<strong>en</strong>as decaracteres)Cualquier tipo de dato o estructura dedatos. Se crean utilizando la s<strong>en</strong>t<strong>en</strong>ciaType (Ver Apartado 3.10)ningunoTabla 3.2. Tipos de datos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.números: mismo rango que el tipo de valoralmac<strong>en</strong>adoEn el l<strong>en</strong>guaje <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> exist<strong>en</strong> dos formas de agrupar varios valores bajo un mismonombre. La primera de ellas son los arrays (vectores y matrices), que agrupan datos de tipohomogéneo. La segunda son las estructuras, que agrupan información heterogénea o de distintotipo. En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> las estructuras son verdaderos tipos de datos definibles por el usuario.Para declarar las variables se utiliza la s<strong>en</strong>t<strong>en</strong>cia <strong>si</strong>gui<strong>en</strong>te:Dim NombreVariable As TipoVariablecuyo empleo se muestra <strong>en</strong> los ejemplos <strong>si</strong>gui<strong>en</strong>tes:Dim Radio As Double, Superficie as SingleDim Nombre As StringDim Etiqueta As String * 10Dim Francos As Curr<strong>en</strong>cyDim Longitud As Long, X As Curr<strong>en</strong>cyEs importante evitar declaraciones del tipo:Dim i, j As Integerpues contra lo que podría parecer a <strong>si</strong>mple vista no se crean dos variables Integer, <strong>si</strong>no una Integer(j) y otra Variant (i).En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> no es estrictam<strong>en</strong>te necesario declarar todas las variables que se van autilizar (a no ser que se elija la opción Option Explicit que hace obligatorio el declararlas), y hayotra forma de declarar las variables anteriores, utilizando los caracteres especiales vistos


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 30anteriorm<strong>en</strong>te. Así por ejemplo, el tipo de las variables del ejemplo anterior se puede declarar alutilizarlas <strong>en</strong> las distintas expre<strong>si</strong>ones, poniéndoles a continuación el carácter que ya se indicó <strong>en</strong> laTabla 3.2, <strong>en</strong> la forma:Radio#Nombre$Francos@Longitud&doble preci<strong>si</strong>óncad<strong>en</strong>a de caracteresunidades monetarias<strong>en</strong>tero largoEsta forma de indicar el tipo de dato no es la más conv<strong>en</strong>i<strong>en</strong>te. Se manti<strong>en</strong>e <strong>en</strong> las suce<strong>si</strong>vasver<strong>si</strong>ones de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> por la compatibilidad con códigos anteriores. Es preferible utilizar lanotación donde se escribe directam<strong>en</strong>te el tipo de dato.3.4.5 Elección del tipo de una variableSi <strong>en</strong> el código del programa se utiliza una variable que no ha <strong>si</strong>do declarada, se con<strong>si</strong>dera que estavariable es de tipo Variant. Las variables de este tipo se adaptan al tipo de información o dato quese les a<strong>si</strong>gna <strong>en</strong> cada mom<strong>en</strong>to. Por ejemplo, una variable tipo Variant puede cont<strong>en</strong>er al principiodel programa un string de caracteres, después una variable de doble preci<strong>si</strong>ón, y finalm<strong>en</strong>te unnúmero <strong>en</strong>tero. Son pues variables muy flexibles, pero su uso debe restringirse porque ocupan másmemoria (almac<strong>en</strong>an el tipo de dato que conti<strong>en</strong><strong>en</strong>, además del propio valor de dicho dato) yrequier<strong>en</strong> más tiempo de CPU que los restantes tipos de variables.En g<strong>en</strong>eral es el tipo de dato (los valores que puede t<strong>en</strong>er <strong>en</strong> la realidad) lo que determina quétipo de variable se debe utilizar. A continuación se muestran algunos ejemplos:• Integer para numerar las filas y columnas de una matriz no muy grande• Long para numerar los habitantes de una ciudad o los números de teléfonos• Boolean para una variable con sólo dos po<strong>si</strong>bles valores (sí o no)• Single para variables fí<strong>si</strong>cas con decimales que no exijan preci<strong>si</strong>ón• Double para variables fí<strong>si</strong>cas con decimales que exijan preci<strong>si</strong>ón• Curr<strong>en</strong>cy para cantidades grandes de dineroEs muy importante t<strong>en</strong>er <strong>en</strong> cu<strong>en</strong>ta que se debe utilizar el tipo de dato más s<strong>en</strong>cillo querepres<strong>en</strong>te correctam<strong>en</strong>te el dato real ya que <strong>en</strong> otro caso se ocupará más memoria y la ejecuciónde los programas o funciones será más l<strong>en</strong>ta.3.4.6 Declaración explícita de variablesUna variable que se utiliza <strong>si</strong>n haber <strong>si</strong>do declarada toma por defecto el tipo Variant. Puede ocurrirque durante la programación, se cometa un error y se escriba mal el nombre de una variable. Porejemplo, se puede t<strong>en</strong>er una variable " declarada <strong>como</strong> <strong>en</strong>tera, y al programar referirse a ella porerror <strong>como</strong> "; <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> supondría que ésta es una nueva variable de tipo Variant.Para evitar este tipo de errores, se puede indicar a <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> que g<strong>en</strong>ere un m<strong>en</strong>saje deerror <strong>si</strong>empre que <strong>en</strong>cu<strong>en</strong>tre una variable no declarada previam<strong>en</strong>te. Para ello lo más práctico esestablecer una opción por defecto, utilizando el comando Environm<strong>en</strong>t del m<strong>en</strong>ú Tools/Options; <strong>en</strong>el cuadro que se abre se debe poner Yes <strong>en</strong> la opción Require Variable Declaration. También sepuede hacer esto escribi<strong>en</strong>do la s<strong>en</strong>t<strong>en</strong>cia <strong>si</strong>gui<strong>en</strong>te <strong>en</strong> la sección de declaraciones de cadaformulario y de cada módulo:Option Explicit


Capítulo 3: L<strong>en</strong>guaje BASIC página 313.5 OPERADORESLa Tabla 3.3 pres<strong>en</strong>ta el conjunto de operadores que soporta <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Tipo Operación Operador <strong>en</strong> Vba<strong>si</strong>cAritmético Expon<strong>en</strong>ciación ^Cambio de <strong>si</strong>gno (operador unario) -Multiplicación, divi<strong>si</strong>ón *, /Divi<strong>si</strong>ón <strong>en</strong>tera \Resto de una divi<strong>si</strong>ón <strong>en</strong>teraModSuma y resta +, -Concat<strong>en</strong>ación Concat<strong>en</strong>ar o <strong>en</strong>lazar & +Relacional Igual a =Distinto M<strong>en</strong>or que / m<strong>en</strong>or o igual que < >=Otros Comparar dos expre<strong>si</strong>ones de caracteres LikeComparar dos refer<strong>en</strong>cias a objetosIsLógico Negación NotAndOr inclu<strong>si</strong>voOr exclu<strong>si</strong>voEquival<strong>en</strong>cia (opuesto a Xor)Implicación (False <strong>si</strong> el primer operando es Truey el segundo operando es False)Tabla 3.3. Operadores de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Cuando <strong>en</strong> una expre<strong>si</strong>ón aritmética intervi<strong>en</strong><strong>en</strong> operandos de difer<strong>en</strong>tes tipos, el resultado seexpresa, g<strong>en</strong>eralm<strong>en</strong>te, <strong>en</strong> la misma preci<strong>si</strong>ón que la del operando que la ti<strong>en</strong>e más alta. El ord<strong>en</strong>, dem<strong>en</strong>or a mayor, según la preci<strong>si</strong>ón es Integer, Long, Single, Double y Curr<strong>en</strong>cy.Los operadores relacionales, también conocidos <strong>como</strong> operadores de comparación, comparandos expre<strong>si</strong>ones dando un resultado True (verdadero), False (falso) o Null (no válido).El operador & realiza la concat<strong>en</strong>ación de dos operandos. Para el caso particular de queambos operandos sean cad<strong>en</strong>as de caracteres, puede utilizarse también el operador +. No obstante,para evitar ambigüedades (sobre todo con variables de tipo Variant) es mejor utilizar &.El operador Like <strong>si</strong>rve para comparar dos cad<strong>en</strong>as de caracteres. La <strong>si</strong>ntaxis para este operadores la <strong>si</strong>gui<strong>en</strong>te:Respuesta = Cad<strong>en</strong>a1 Like Cad<strong>en</strong>a2donde la variable Respuesta será True <strong>si</strong> la Cad<strong>en</strong>a1 coincide con la Cad<strong>en</strong>a2, False <strong>si</strong> nocoincid<strong>en</strong> y Null <strong>si</strong> Cad<strong>en</strong>a1 y/o Cad<strong>en</strong>a2 son Null.Para obt<strong>en</strong>er más información se puede consultar el Help de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>.AndOrXorEqvImp3.6 SENTENCIAS DE CONTROLLas s<strong>en</strong>t<strong>en</strong>cias de control, d<strong>en</strong>ominadas también estructuras de control, permit<strong>en</strong> tomar deci<strong>si</strong>onesy realizar un proceso repetidas veces. Son los d<strong>en</strong>ominados bifurcaciones y bucles. Este tipo de


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 32estructuras son comunes <strong>en</strong> cuanto a concepto <strong>en</strong> la mayoría de los l<strong>en</strong>guajes de programación,aunque su <strong>si</strong>ntaxis puede variar de un l<strong>en</strong>guaje de programación a otro. Se trata de unas estructurasmuy importantes ya que son las <strong>en</strong>cargadas de controlar el flujo de un programa según losrequerimi<strong>en</strong>tos del mismo. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de las <strong>si</strong>gui<strong>en</strong>tes estructuras de control:If ... Th<strong>en</strong> ... ElseSelect CaseFor ... NextDo ... LoopWhile … W<strong>en</strong>dFor Each … Next3.6.1 S<strong>en</strong>t<strong>en</strong>cia IF ... THEN ... ELSE ...Esta estructura permite ejecutar condicionalm<strong>en</strong>te una o más s<strong>en</strong>t<strong>en</strong>cias y puede escribirse de dosformas. La primera ocupa sólo una línea y ti<strong>en</strong>e la forma <strong>si</strong>gui<strong>en</strong>te:If condicion Th<strong>en</strong> s<strong>en</strong>t<strong>en</strong>cia1 [Else s<strong>en</strong>t<strong>en</strong>cia2]La segunda es más g<strong>en</strong>eral y se muestra a continuación:If condicion Th<strong>en</strong>s<strong>en</strong>t<strong>en</strong>cia(s)[Elses<strong>en</strong>t<strong>en</strong>cia(s)]End IfSi condicion es True (verdadera), se ejecutan las s<strong>en</strong>t<strong>en</strong>cias que están a continuación deTh<strong>en</strong>, y <strong>si</strong> condicion es False (falsa), se ejecutan las s<strong>en</strong>t<strong>en</strong>cias que están a continuación de Else, <strong>si</strong>esta cláusula ha <strong>si</strong>do especificada (pues es opcional). Para indicar que se quiere ejecutar uno devarios bloques de s<strong>en</strong>t<strong>en</strong>cias dep<strong>en</strong>di<strong>en</strong>tes cada uno de ellos de una condición, la estructuraadecuada es la <strong>si</strong>gui<strong>en</strong>te:If condicion1 Th<strong>en</strong>s<strong>en</strong>t<strong>en</strong>cias1ElseIf condicion2 Th<strong>en</strong>s<strong>en</strong>t<strong>en</strong>cias2Elses<strong>en</strong>t<strong>en</strong>cia-nEnd IfSi se cumple la condicion1 se ejecutan las s<strong>en</strong>t<strong>en</strong>cias1, y <strong>si</strong> no se cumple, se examinansecu<strong>en</strong>cialm<strong>en</strong>te las condiciones <strong>si</strong>gui<strong>en</strong>tes hasta Else, ejecutándose las s<strong>en</strong>t<strong>en</strong>cias correspondi<strong>en</strong>tesal primer ElseIf cuya condición se cumpla. Si todas las condiciones son falsas, se ejecutan lass<strong>en</strong>t<strong>en</strong>cias-n correspondi<strong>en</strong>tes a Else, que es la opción por defecto. La Figura 3.2 pres<strong>en</strong>taesquemáticam<strong>en</strong>te ambas formas de repres<strong>en</strong>tar estas s<strong>en</strong>t<strong>en</strong>cias:


Capítulo 3: L<strong>en</strong>guaje BASIC página 33condición 1TruecondiciónFalseFalseBloque 1Truecondición 2TrueBloque 1 des<strong>en</strong>t<strong>en</strong>ciasBloque 2 des<strong>en</strong>t<strong>en</strong>ciasFalseBloque 3Bloque 2Por ejemplo,Figura 3.2. Bifurcaciones If e If...Else.Numero = 53 ’ Se inicializa la variable.If Numero < 10 Th<strong>en</strong>Digitos = 1ElseIf Numero < 100 Th<strong>en</strong>' En este caso la condición se cumple (True) luego se ejecuta lo <strong>si</strong>gui<strong>en</strong>te.Digitos = 2Else 'En el caso <strong>en</strong> que no se cumplan los dos anteriores se a<strong>si</strong>gna 3Digitos = 3End If3.6.2 S<strong>en</strong>t<strong>en</strong>cia SELECT CASEEsta s<strong>en</strong>t<strong>en</strong>cia permite ejecutar una de <strong>en</strong>tre varias acciones <strong>en</strong> función del valor de una expre<strong>si</strong>ón.Es una alternativa a If ... Th<strong>en</strong> ... ElseIf cuando se compara la misma expre<strong>si</strong>ón con difer<strong>en</strong>tesvalores. Su forma g<strong>en</strong>eral es la <strong>si</strong>gui<strong>en</strong>te:Select Case expre<strong>si</strong>onCase etiq1[s<strong>en</strong>t<strong>en</strong>cias1]Case etiq2[s<strong>en</strong>t<strong>en</strong>cias2]Case Elses<strong>en</strong>t<strong>en</strong>ciasnEnd Selectdonde expre<strong>si</strong>on es una expre<strong>si</strong>ón numérica o alfanumérica, y etiq1, etiq2, ... pued<strong>en</strong> adoptar lasformas <strong>si</strong>gui<strong>en</strong>tes:1. expre<strong>si</strong>on2. expre<strong>si</strong>on To expre<strong>si</strong>on3. Is operador-de-relación expre<strong>si</strong>on4. combinación de las anteriores separadas por comasPor ejemplo,Numero = 8’ Se inicializan las variable.Select Case Numero ’ Se va a evaluar la variable Numero.Case 1 To 5 ' Numero está <strong>en</strong>tre 1 y 5.Resultado = "Se <strong>en</strong>cu<strong>en</strong>tra <strong>en</strong>tre 1 y 5"' Lo <strong>si</strong>gui<strong>en</strong>te se ejecuta <strong>si</strong> es True la expre<strong>si</strong>ón.Case 6, 7, 8' Numero es uno de los tres valores.Resultado = "Se <strong>en</strong>cu<strong>en</strong>tra <strong>en</strong>tre 6 y 8"


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 34Case Is = 9 , Is = 10 ' Numero es 9 ó 10.Resultado = "El valor es 9 o 10"Case Else' Resto de valores.Resultado = "El número no se <strong>en</strong>cu<strong>en</strong>tra <strong>en</strong>tre 1 y 10"End SelectCuando se utiliza la forma expre<strong>si</strong>on To expre<strong>si</strong>on, el valor más pequeño debe aparecer <strong>en</strong>primer lugar.Cuando se ejecuta una s<strong>en</strong>t<strong>en</strong>cia Select Case, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> evalúa la expre<strong>si</strong>on y el controldel programa se transfiere a la s<strong>en</strong>t<strong>en</strong>cia cuya etiqueta t<strong>en</strong>ga el mismo valor que la expre<strong>si</strong>ónevaluada, ejecutando a continuación el correspondi<strong>en</strong>te bloque de s<strong>en</strong>t<strong>en</strong>cias. Si no existe un valorigual a la expre<strong>si</strong>on <strong>en</strong>tonces se ejecutan las s<strong>en</strong>t<strong>en</strong>cias a continuación de Case Else.3.6.3 S<strong>en</strong>t<strong>en</strong>cia FOR ... NEXTLa s<strong>en</strong>t<strong>en</strong>cia For da lugar a un lazo o bucle, y permite ejecutar un conjunto de s<strong>en</strong>t<strong>en</strong>cias ciertonúmero de veces. Su forma g<strong>en</strong>eral es:For variable = expre<strong>si</strong>on1 To expre<strong>si</strong>on2 [Step expre<strong>si</strong>on3][s<strong>en</strong>t<strong>en</strong>cias]Exit For[s<strong>en</strong>t<strong>en</strong>cias]Next [variable]Cuando se ejecuta una s<strong>en</strong>t<strong>en</strong>cia For, primero se a<strong>si</strong>gna el valor de la expre<strong>si</strong>on1 a la variabley se comprueba <strong>si</strong> su valor es mayor o m<strong>en</strong>or que la expre<strong>si</strong>on2. En caso de ser m<strong>en</strong>or se ejecutanlas s<strong>en</strong>t<strong>en</strong>cias, y <strong>en</strong> caso de ser mayor el control del programa salta a las líneas a continuación deNext. Todo esto sucede <strong>en</strong> caso de ser la expre<strong>si</strong>on3 po<strong>si</strong>tiva. En caso contrario se ejecutarán lass<strong>en</strong>t<strong>en</strong>cias cuando la variable sea mayor que expre<strong>si</strong>on2. Una vez ejecutadas las s<strong>en</strong>t<strong>en</strong>cias, lavariable se increm<strong>en</strong>ta <strong>en</strong> el valor de la expre<strong>si</strong>on3, o <strong>en</strong> 1 <strong>si</strong> Step no se especifica, volviéndose aefectuar la comparación <strong>en</strong>tre la variable y la expre<strong>si</strong>on2, y así suce<strong>si</strong>vam<strong>en</strong>te.La s<strong>en</strong>t<strong>en</strong>cia Exit For es opcional y permite salir de un bucle For ... Next antes de que éstefinalice. Por ejemplo,MyString="Informática "For Words = 3 To 1 Step -1 ' 3 veces decrem<strong>en</strong>tando de 1 <strong>en</strong> 1.For Chars = Words To Words+4 '5 veces.MyString = MyString & Chars ' Se añade el número Chars al string.Next Chars' Se increm<strong>en</strong>ta el contadorMyString = MyString & " " ' Se añade un espacio.Next Words'El valor de MyString es: Informática 34567 23456 123453.6.4 S<strong>en</strong>t<strong>en</strong>cia DO ... LOOPUn Loop (bucle) repite la ejecución de un conjunto de s<strong>en</strong>t<strong>en</strong>cias mi<strong>en</strong>tras una condición dada seacierta, o hasta que una condición dada sea cierta. La condición puede ser verificada antes o despuésde ejecutarse el conjunto de s<strong>en</strong>t<strong>en</strong>cias. Sus po<strong>si</strong>bles formas son las <strong>si</strong>gui<strong>en</strong>tes:’ Formato 1:Do [{While/Until} condicion][s<strong>en</strong>t<strong>en</strong>cias][Exit Do][s<strong>en</strong>t<strong>en</strong>cias]Loop


Capítulo 3: L<strong>en</strong>guaje BASIC página 35’ Formato 2:Do[s<strong>en</strong>t<strong>en</strong>cias][Exit Do][s<strong>en</strong>t<strong>en</strong>cias]Loop [{While/Until}condicion]La s<strong>en</strong>t<strong>en</strong>cia opcional Exit Do permite salir de una bucle Do ... Loop antes de que finaliceéste. Por ejemplo,Check = True’ Se inicializan las variables.Counts = 0Do' Empieza <strong>si</strong>n comprobar ninguna condición.Do While Counts < 20 ' Bucle que acaba <strong>si</strong> Counts>=20 o con Exit Do.Counts = Counts + 1 ' Se increm<strong>en</strong>ta Counts.If Counts = 10 Th<strong>en</strong> ' Si Counts es 10.Check = False ' Se a<strong>si</strong>gna a Check el valor False.Exit Do' Se acaba el segundo Do.End IfLoopLoop Until Check = False ' Salir del "loop" <strong>si</strong> Check es False.En el ejemplo mostrado, se sale de los bucles <strong>si</strong>empre con Counts = 10. Es necesario fijarseque <strong>si</strong> se inicializa Counts con un número mayor o igual a 10 se <strong>en</strong>traría <strong>en</strong> un bucle infinito (elprimer bucle acabaría con Counts = 20 pero el segundo no finalizaría nunca, bloqueándose elprograma y a veces el ord<strong>en</strong>ador).3.6.5 S<strong>en</strong>t<strong>en</strong>cia WHILE … WENDEsta s<strong>en</strong>t<strong>en</strong>cia es otra forma de g<strong>en</strong>erar bucles que se recorr<strong>en</strong> mi<strong>en</strong>tras se cumpla la condicióninicial. Su estructura es la <strong>si</strong>gui<strong>en</strong>te:While condicion[s<strong>en</strong>t<strong>en</strong>cias]W<strong>en</strong>dPor ejemplo,Counts = 0’ Se inicializa la variable.While Counts < 20’ Se comprueba el valor de Counts.Counts = Counts + 1 ’ Se increm<strong>en</strong>ta el valor de Counts.W<strong>en</strong>d ’ Se acaba el bucle cuando Counts > 19.En cualquier caso se recuerda que la mejor forma de mirar y apr<strong>en</strong>der el funcionami<strong>en</strong>to detodas estas s<strong>en</strong>t<strong>en</strong>cias es mediante el uso del Help de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>. Ofrece una explicación de cadacomando con ejemplos de utilización.3.6.6 S<strong>en</strong>t<strong>en</strong>cia FOR EACH ... NEXTEsta construcción es <strong>si</strong>milar al bucle For, con la difer<strong>en</strong>cia de que la variable que controla larepetición del bucle no toma valores <strong>en</strong>tre un mínimo y un máximo, <strong>si</strong>no a partir de los elem<strong>en</strong>tosde un array (o de una colección de objetos). La forma g<strong>en</strong>eral es la <strong>si</strong>gui<strong>en</strong>te:For Each variable In grupo[s<strong>en</strong>t<strong>en</strong>cias]Next variableCon arrays variable ti<strong>en</strong>e que ser de tipo Variant. Con colecciones variable puede ser Varianto una variable de tipo Object. Esta construcción es muy útil cuando no se sabe el número deelem<strong>en</strong>tos que ti<strong>en</strong>e el array o la colección de objetos.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 363.7 ALGORITMOS3.7.1 IntroducciónUn algoritmo es <strong>en</strong> un s<strong>en</strong>tido amplio una “secu<strong>en</strong>cia de pasos o etapas que conduc<strong>en</strong> a larealización de una tarea”. Los primeros algoritmos nacieron para resolver problemas matemáticos.Antes de escribir un programa de ord<strong>en</strong>ador, hay que t<strong>en</strong>er muy claro el algoritmo, es decir, cómo seva a resolver el problema con<strong>si</strong>derado. Es importante desarrollar bu<strong>en</strong>os algoritmos (correctos yefici<strong>en</strong>tes). Una vez que el algoritmo está desarrollado, el problema se puede resolver incluso <strong>si</strong>n<strong>en</strong>t<strong>en</strong>derlo.Ejemplo: Algoritmo de Euclides para calcular el m.c.d. de dos números <strong>en</strong>teros A y B1. A<strong>si</strong>gnar a M el valor de A, y a N el valor de B.2. Dividir M por N, y llamar R al resto.3. Si R distinto de 0, a<strong>si</strong>gnar a M el valor de N, a<strong>si</strong>gnar a N el valor de R,volver a com<strong>en</strong>zarla etapa 2.4. Si R = 0, N es el m.c.d. de los números originalesEs muy fácil pasar a <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> este algoritmo:Dim a, b As Integera = 45: b = 63’ Estos son los valores M y NIf a < b Th<strong>en</strong>’ Se permutan a y btemp = a : a = b : b = tempEnd Ifm = a : n = b : resto = m Mod n ’ Mod devuelve el valor del restoWhile resto 0 ’Mi<strong>en</strong>tras el resto sea distinto de 0m = n: n = resto:resto = m Mod nW<strong>en</strong>d' La solución es la variable n. En este caso el resultado es 9Si son necesarios, deb<strong>en</strong> existir criterios de terminación claros (por ejemplo, para calculars<strong>en</strong>o(x) por desarrollo <strong>en</strong> serie se deberá indicar el número de términos de la serie). No puede haberetapas impo<strong>si</strong>bles (por ejemplo: "imprimir el conjunto de todos los números <strong>en</strong>teros").3.7.2 Repres<strong>en</strong>tación de algoritmosExist<strong>en</strong> diversas formas de repres<strong>en</strong>tar algoritmos. A continuación se pres<strong>en</strong>tan algunas de ellas:• Detallada: Se trata de escribir el algoritmo <strong>en</strong> un determinado l<strong>en</strong>guaje de programación(l<strong>en</strong>guaje de máquina, <strong>en</strong>samblador, fortran, ba<strong>si</strong>c, pascal, C, Matlab, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>, ...).• Simbólica: Las etapas son descritas con l<strong>en</strong>guaje próximo al natural, con el grado de detalleadecuado a la etapa de desarrollo del programa.• Gráfica: por medio de diagramas de flujo.La <strong>si</strong>ntaxis (el modo de escribir) debe repres<strong>en</strong>tar correctam<strong>en</strong>te la semántica (el cont<strong>en</strong>ido).La <strong>si</strong>ntaxis debe ser clara, s<strong>en</strong>cilla y acce<strong>si</strong>ble.En cualquier caso e indep<strong>en</strong>di<strong>en</strong>tem<strong>en</strong>te del tipo de repres<strong>en</strong>tación utilizada lo importante est<strong>en</strong>er muy claro el algoritmo a realizar y ponerlo por escrito <strong>en</strong> forma de esquema antes de ponerse aprogramarlo. Merece la p<strong>en</strong>a pasar unos minutos realizando un esquema sobre papel antes deponerse a teclear el código sobre un teclado de ord<strong>en</strong>ador.


Capítulo 3: L<strong>en</strong>guaje BASIC página 373.8 FUNCIONES Y PROCEDIMIENTOS3.8.1 Conceptos g<strong>en</strong>erales sobre funcionesLas aplicaciones informáticas que habitualm<strong>en</strong>te se utilizan, incluso a nivel de informática personal,suel<strong>en</strong> cont<strong>en</strong>er dec<strong>en</strong>as y aún ci<strong>en</strong>tos de miles de líneas de código fu<strong>en</strong>te. A medida que losprogramas se van desarrollando y aum<strong>en</strong>tan de tamaño, se convertirían rápidam<strong>en</strong>te <strong>en</strong> <strong>si</strong>stemaspoco manejables <strong>si</strong> no fuera por la modularización, que es el proceso con<strong>si</strong>st<strong>en</strong>te <strong>en</strong> dividir unprograma muy grande <strong>en</strong> una serie de módulos mucho más pequeños y manejables. A estos módulosse les suele d<strong>en</strong>ominar de distintas formas (subprogramas, subrutinas, procedimi<strong>en</strong>tos, funciones,etc.) según los distintos l<strong>en</strong>guajes. Sea cual sea la nom<strong>en</strong>clatura, la idea es <strong>si</strong>n embargo <strong>si</strong>empre lamisma: dividir un programa grande <strong>en</strong> un conjunto de subprogramas o funciones más pequeñas queson llamadas por el programa principal; éstas a su vez llaman a otras funciones más específicas y asísuce<strong>si</strong>vam<strong>en</strong>te.La divi<strong>si</strong>ón de un programa <strong>en</strong> unidades más pequeñas o funciones pres<strong>en</strong>ta –<strong>en</strong>tre otras– lasv<strong>en</strong>tajas <strong>si</strong>gui<strong>en</strong>tes:1. Modularización. Cada función ti<strong>en</strong>e una mi<strong>si</strong>ón muy concreta, de modo que nunca ti<strong>en</strong>e unnúmero de líneas exce<strong>si</strong>vo y <strong>si</strong>empre se manti<strong>en</strong>e d<strong>en</strong>tro de un tamaño manejable. Además,una misma función (por ejemplo, un producto de matrices, una resolución de un <strong>si</strong>stema deecuaciones lineales, ...) puede ser llamada muchas veces <strong>en</strong> un mismo programa, e inclusopuede ser reutilizada por otros programas. Cada función puede ser desarrollada y comprobadapor separado.2. Ahorro de memoria y tiempo de desarrollo. En la medida <strong>en</strong> que una misma función esutilizada muchas veces, el número total de líneas de código del programa disminuye, ytambién lo hace la probabilidad de introducir errores <strong>en</strong> el programa.3. Indep<strong>en</strong>d<strong>en</strong>cia de datos y ocultami<strong>en</strong>to de información. Una de las fu<strong>en</strong>tes más comunes deerrores <strong>en</strong> los programas de computador son los efectos colaterales o perturbaciones que sepued<strong>en</strong> producir <strong>en</strong>tre distintas partes del programa. Es muy frecu<strong>en</strong>te que al hacer unamodificación para añadir una funcionalidad o corregir un error, se introduzcan nuevos errores<strong>en</strong> partes del programa que antes funcionaban correctam<strong>en</strong>te. Una función es capaz demant<strong>en</strong>er una gran indep<strong>en</strong>d<strong>en</strong>cia con el resto del programa, mant<strong>en</strong>i<strong>en</strong>do sus propios datos ydefini<strong>en</strong>do muy claram<strong>en</strong>te la interfaz o comunicación con la función que la ha llamado y conlas funciones a las que llama, y no t<strong>en</strong>i<strong>en</strong>do ninguna po<strong>si</strong>bilidad de acceso a la informaciónque no le compete.3.8.2 Funciones y procedimi<strong>en</strong>tos Sub <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se distingue <strong>en</strong>tre funciones y procedimi<strong>en</strong>tos Sub. En oca<strong>si</strong>ones se utiliza lapalabra g<strong>en</strong>érica procedimi<strong>en</strong>to para ambos. La fundam<strong>en</strong>tal difer<strong>en</strong>cia <strong>en</strong>tre un procedimi<strong>en</strong>to Suby una función es que ésta última puede ser utilizada <strong>en</strong> una expre<strong>si</strong>ón porque ti<strong>en</strong>e un valor deretorno. El valor de retorno ocupa el lugar de la llamada a la función donde esta aparece. Porejemplo, <strong>si</strong> <strong>en</strong> una expre<strong>si</strong>ón aparece <strong>si</strong>n(x) se calcula el s<strong>en</strong>o de la variable x y el resultado es elvalor de retorno que sustituye a <strong>si</strong>n(x) <strong>en</strong> la expre<strong>si</strong>ón <strong>en</strong> la que aparecía. Por tanto, las funcionesdevuelv<strong>en</strong> valores, a difer<strong>en</strong>cia de los procedimi<strong>en</strong>tos que no devuelv<strong>en</strong> ningún valor, y por tanto nopued<strong>en</strong> ser utilizadas <strong>en</strong> expre<strong>si</strong>ones. Un procedimi<strong>en</strong>to Sub es un segm<strong>en</strong>to de códigoindep<strong>en</strong>di<strong>en</strong>te del resto, que una vez llamado por el programa, ejecuta un número determinado de


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 38instrucciones, <strong>si</strong>n nece<strong>si</strong>dad de devolver ningún valor al mismo (puede dar resultados modificandolos argum<strong>en</strong>tos), mi<strong>en</strong>tras que una función <strong>si</strong>empre t<strong>en</strong>drá un valor de retorno.Los nombres de los procedimi<strong>en</strong>tos ti<strong>en</strong><strong>en</strong> reglas de vi<strong>si</strong>bilidad parecidas a las de lasvariables. Para llamar desde un formulario a un procedimi<strong>en</strong>to Public definido <strong>en</strong> otro formulario esnecesario preceder su nombre por el del formulario <strong>en</strong> que está definido. Sin embargo, <strong>si</strong> se deseallamar a un procedimi<strong>en</strong>to definido <strong>en</strong> un módulo estándar (*.bas) no es necesario precederlo delnombre del módulo más que <strong>si</strong> hay coincid<strong>en</strong>cia de nombre con otro procedimi<strong>en</strong>to de otro móduloestándar.3.8.3 Funciones (function)La <strong>si</strong>ntaxis correspondi<strong>en</strong>te a una función es la <strong>si</strong>gui<strong>en</strong>te:[Static] [Private] Function nombre ([parámetros]) [As tipo][s<strong>en</strong>t<strong>en</strong>cias][nombre = expre<strong>si</strong>on][Exit Function][s<strong>en</strong>t<strong>en</strong>cias][nombre = expre<strong>si</strong>on]End Functiondonde nombre es el nombre de la función. Será de un tipo u otro dep<strong>en</strong>di<strong>en</strong>do del dato quedevuelva. Para especificar el tipo se utiliza la cláusula As Tipo (Integer, Long, Single, Double,Curr<strong>en</strong>cy, String o Variant). parámetros son los argum<strong>en</strong>tos que son pasados cuando se llama a lafunción. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> a<strong>si</strong>gna el valor de cada argum<strong>en</strong>to <strong>en</strong> la llamada al parámetro que ocupa sumisma po<strong>si</strong>ción. Si no se indica un tipo determinado los argum<strong>en</strong>tos son Variant por defecto. Comose verá <strong>en</strong> un apartado posterior, los argum<strong>en</strong>tos pued<strong>en</strong> ser pasados por refer<strong>en</strong>cia o por valor.El nombre de la función, que es el valor de retorno, actúa <strong>como</strong> una variable d<strong>en</strong>tro delcuerpo de la función. El valor de la variable expre<strong>si</strong>on es almac<strong>en</strong>ado <strong>en</strong> el propio nombre de lafunción. Si no se efectúa esta a<strong>si</strong>gnación, el resultado devuelto será 0 <strong>si</strong> la función es numérica, nulo("") <strong>si</strong> la función es de caracteres, o Empty <strong>si</strong> la función es Variant.Exit Function permite salir de una función antes de que ésta finalice y devolver así el controldel programa a la s<strong>en</strong>t<strong>en</strong>cia inmediatam<strong>en</strong>te a continuación de la que efectuó la llamada a lafunción.La s<strong>en</strong>t<strong>en</strong>cia End Function marca el final del código de la función y, al igual que la ExitFunction, devuelve el control del programa a la s<strong>en</strong>t<strong>en</strong>cia <strong>si</strong>gui<strong>en</strong>te a la que efectuó la llamada,pero lógicam<strong>en</strong>te una vez finalizada la función.La llamada a una función se hace de diversas formas. Por ejemplo, una de las más usuales esla <strong>si</strong>gui<strong>en</strong>te:variable = nombre([argum<strong>en</strong>tos])donde argum<strong>en</strong>tos son un lista de constantes, variables o expre<strong>si</strong>ones separadas por comas que sonpasadas a la función. En principio, el número de argum<strong>en</strong>tos debe ser igual al número de parámetrosde la función. Los tipos de los argum<strong>en</strong>tos deb<strong>en</strong> coincidir con los tipos de sus correspondi<strong>en</strong>tesparámetros, de lo contrario puede haber fallos importantes <strong>en</strong> la ejecución del programa. Esta reglano rige <strong>si</strong> los argum<strong>en</strong>tos se pasan por valor (concepto que se verá más adelante).En cada llamada a una función hay que incluir los parénte<strong>si</strong>s, aunque ésta no t<strong>en</strong>gaargum<strong>en</strong>tos.


Capítulo 3: L<strong>en</strong>guaje BASIC página 39El <strong>si</strong>gui<strong>en</strong>te ejemplo corresponde a una función que devuelve <strong>como</strong> resultado la raíz cuadradade un número N:Function Raiz (N As Double) As DoubleIf N < 0 Th<strong>en</strong>Exit FunctionElseRaiz = Sqr(N)End FunctionLa llamada a esta función se hace de la forma <strong>si</strong>gui<strong>en</strong>te:Cuadrada = Raiz(Num)A difer<strong>en</strong>cia de C y C++ <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> no es necesario devolver explícitam<strong>en</strong>te el valorde retorno, pues el nombre de la función ya conti<strong>en</strong>e el valor que se desea devolver. Tampoco esnecesario declarar las funciones antes de llamarlas.3.8.4 Procedimi<strong>en</strong>tos SubLa <strong>si</strong>ntaxis que define un procedimi<strong>en</strong>to Sub es la <strong>si</strong>gui<strong>en</strong>te:[Static] [Private] Sub nombre [(parámetros)][s<strong>en</strong>t<strong>en</strong>cias][Exit Sub][s<strong>en</strong>t<strong>en</strong>cias]End SubLa explicación es análoga a la dada para funciones.La llamada a un procedimi<strong>en</strong>to Sub puede ser de alguna de las dos formas <strong>si</strong>gui<strong>en</strong>tes:Call nombre[(argum<strong>en</strong>tos)]o bi<strong>en</strong>, <strong>si</strong>n pasar los argum<strong>en</strong>tos <strong>en</strong>tre parénte<strong>si</strong>s, <strong>si</strong>no poniéndolos a continuación del nombre<strong>si</strong>mplem<strong>en</strong>te separados por comas:nombre [argum<strong>en</strong>tos]A difer<strong>en</strong>cia de una función, un procedimi<strong>en</strong>to Sub no puede ser utilizado <strong>en</strong> una expre<strong>si</strong>ónpues no devuelve ningún valor. Por supuesto una función puede ser llamada al modo de unprocedimi<strong>en</strong>to Sub, pero <strong>en</strong> esta caso no se hace nada con el valor devuelto por la función.El <strong>si</strong>gui<strong>en</strong>te ejemplo corresponde a un procedimi<strong>en</strong>to Sub que devuelve una variable F que esla raíz cuadrada de un número N.Sub Raiz (N As Double, F As Double)If N < 0 Th<strong>en</strong>Exit Sub 'Se mandaría un m<strong>en</strong>saje de errorElseF = Sqr(N)End IfEnd SubLa llamada a este procedimi<strong>en</strong>to Sub puede ser de cualquiera de las dos formas <strong>si</strong>gui<strong>en</strong>tes:Raiz N, FCall Raiz(N, F)En el ejemplo anterior, el resultado obt<strong>en</strong>ido al extraer la raíz cuadrada al número N sedevuelve <strong>en</strong> la variable F pasada <strong>como</strong> argum<strong>en</strong>to, debido a que <strong>como</strong> se ha m<strong>en</strong>cionadoanteriorm<strong>en</strong>te, un procedimi<strong>en</strong>to Sub no puede ser utilizado <strong>en</strong> una expre<strong>si</strong>ón.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 403.8.5 Argum<strong>en</strong>tos por refer<strong>en</strong>cia y por valorEn las funciones (Function) y <strong>en</strong> los procedimi<strong>en</strong>tos Sub de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>, por defecto losargum<strong>en</strong>tos se pasan por refer<strong>en</strong>cia 2 ; de este modo, cualquier cambio de valor que sufra unparámetro d<strong>en</strong>tro de la función o del procedimi<strong>en</strong>to Sub también se produce <strong>en</strong> el argum<strong>en</strong>tocorrespondi<strong>en</strong>te de la llamada a la función o al procedimi<strong>en</strong>to Sub.Cuando se llama a una función o a un procedimi<strong>en</strong>to Sub, se podrá especificar que el valor deuna argum<strong>en</strong>to no sea cambiado por la función o por el procedimi<strong>en</strong>to, poni<strong>en</strong>do dicho argum<strong>en</strong>to<strong>en</strong>tre parénte<strong>si</strong>s <strong>en</strong> la llamada. Un argum<strong>en</strong>to <strong>en</strong>tre parénte<strong>si</strong>s <strong>en</strong> la llamada es un argum<strong>en</strong>topasado por valor. Por ejemplo,Raiz ((Num))Raiz (Num), F' En el caso de la función' En el caso del procedimi<strong>en</strong>toEl argum<strong>en</strong>to Num es pasado por valor. Significa que lo que se pasa es una copia de Num. Siel procedimi<strong>en</strong>to cambia ese valor, el cambio afecta sólo a la copia y no a la propia variable Num.Otra forma de especificar que un argum<strong>en</strong>to será <strong>si</strong>empre pasado por valor es anteponi<strong>en</strong>do lapalabra ByVal a la declaración del parámetro <strong>en</strong> la cabecera del procedimi<strong>en</strong>to (Sub o Function).Por ejemplo,Function Raiz (ByVal N As Double)Sub Raiz (ByVal N As Double, F As Double)Pasar argum<strong>en</strong>tos por valor evita modificaciones accid<strong>en</strong>tales, pero ti<strong>en</strong>e un coste <strong>en</strong> tiempo ymemoria que puede ser <strong>si</strong>gnificativo cuando se pasan grandes volúm<strong>en</strong>es de información, <strong>como</strong>sucede con vectores, matrices y estructuras.3.8.6 Procedimi<strong>en</strong>tos recur<strong>si</strong>vosSe dice que una función (Function) es recur<strong>si</strong>va o que un procedimi<strong>en</strong>to Sub es recur<strong>si</strong>vo <strong>si</strong> sellaman a sí mismos.A continuación se pres<strong>en</strong>ta una ejemplo de una función que calcula el factorial de un númeroprogramada de forma recur<strong>si</strong>va.Function Factorial (N As Integer) As LongIf N = 0 Th<strong>en</strong>Factorial = 1 'Condición de finalElseFactorial = N * Factorial (N - 1)End IfEnd FunctionEn este ejemplo, <strong>si</strong> la variable N que se le pasa a la función vale 0, <strong>si</strong>gnificará que se hallegado al final del proceso, y por tanto se le a<strong>si</strong>gna el valor 1 al valor del factorial (recordar que 0!= 1). Si es distinto de 0, la función se llama a ella misma, pero variando el argum<strong>en</strong>to a (N-1), hastallegar al punto <strong>en</strong> el que N-1=0, finalizándose el proceso.2Pasar un argum<strong>en</strong>to por refer<strong>en</strong>cia implica que <strong>en</strong> realidad se pasa a la función la variable original, de modo que lafunción puede modificar su valor. Pasar por valor implica crear una nueva variable d<strong>en</strong>tro de la función y pasarleuna copia del valor de la variable externa. Si se modifica el valor de la variable copia, la variable original quedainalterada. Cuando <strong>en</strong> la llamada a una función se pon<strong>en</strong> <strong>como</strong> argum<strong>en</strong>tos constantes numéricas o expre<strong>si</strong>ones losvalores se pasan por valor.


Capítulo 3: L<strong>en</strong>guaje BASIC página 413.8.7 Procedimi<strong>en</strong>tos con argum<strong>en</strong>tos opcionalesPuede haber procedimi<strong>en</strong>tos <strong>en</strong> los que algunos de los argum<strong>en</strong>tos incluidos <strong>en</strong> su definición seanopcionales, de forma que el programador pueda o no incluirlos <strong>en</strong> la llamada de dichosprocedimi<strong>en</strong>tos. La forma de incluir un argum<strong>en</strong>to opcional es incluir la palabra Optional antes dedicho argum<strong>en</strong>to <strong>en</strong> la definición del procedimi<strong>en</strong>to. Si un argum<strong>en</strong>to es opcional, todos losargum<strong>en</strong>tos que vi<strong>en</strong><strong>en</strong> a continuación deb<strong>en</strong> también ser opcionales.Cuando un argum<strong>en</strong>to es opcional y <strong>en</strong> la llamada es omitido, el valor que se le pasa es unVariant con valor Empty. A los argum<strong>en</strong>tos opcionales se les puede dar <strong>en</strong> la definición delprocedimi<strong>en</strong>to un valor por defecto para el caso <strong>en</strong> que sean omitidos <strong>en</strong> la llamada, <strong>como</strong> porejemplo:Private Sub miProc(x as Double, Optional n=3 As Integer)s<strong>en</strong>t<strong>en</strong>ciasEnd Sub3.8.8 Número indeterminado de argum<strong>en</strong>tosEste caso es <strong>si</strong>milar pero difer<strong>en</strong>te del anterior. En este caso no es que haya argum<strong>en</strong>tos opcionalesque puedan omitirse <strong>en</strong> la llamada, <strong>si</strong>no que realm<strong>en</strong>te no se sabe con cuántos argum<strong>en</strong>tos va allamarse la función; unas veces se llamará con 2, otras con 3 y otras con 8. En este caso losargum<strong>en</strong>tos se pasan al procedimi<strong>en</strong>to por medio de un array, especificándolo con la palabraParamArray <strong>en</strong> la definición del procedimi<strong>en</strong>to, <strong>como</strong> por ejemplo:Public Function maximo(ParamArray numeros())For Each x in numeross<strong>en</strong>t<strong>en</strong>ciasmaximo = xNext xEnd Function3.8.9 Utilización de argum<strong>en</strong>tos con nombre<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ofrece tambieén la po<strong>si</strong>bilidad de llamar a las funciones y procedimi<strong>en</strong>tos Sub deuna forma más libre y m<strong>en</strong>os formal, pasando los argum<strong>en</strong>tos <strong>en</strong> la llamada al procedimi<strong>en</strong>to con unord<strong>en</strong> arbitrario. Esto se con<strong>si</strong>gue incluy<strong>en</strong>do el nombre de los argum<strong>en</strong>tos <strong>en</strong> la llamada ya<strong>si</strong>gnándoles un valor por medio de una construcción del tipo miArgum<strong>en</strong>to:=unValor. Unosargum<strong>en</strong>tos se separan de otros por medio de comas (,). Con<strong>si</strong>dérese el <strong>si</strong>gui<strong>en</strong>te ejemplo:Public Sub EnviarCarta(direccion As String, destinatario As String)s<strong>en</strong>t<strong>en</strong>ciasEnd Subque se puede llamar <strong>en</strong> la forma:EnviarCarta destinatario:="Mike Tyson", direccion:="Las Vegas"No todas las funciones que se pued<strong>en</strong> llamar <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> admit<strong>en</strong> argum<strong>en</strong>tos connombre. Con AutoQuickInfo puede obt<strong>en</strong>erse más información al respecto.3.9 ARRAYSUn array permite referirse a una serie de elem<strong>en</strong>tos del mismo tipo con un mismo nombre, y hacerefer<strong>en</strong>cia un único elem<strong>en</strong>to de la serie utilizando uno o más índices, <strong>como</strong> un vector o una matriz<strong>en</strong> Álgebra.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 42<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite definir arrays de variables de una o más dim<strong>en</strong><strong>si</strong>ones (hasta 60) y decualquier tipo de datos (tipos fundam<strong>en</strong>tales y definidos por el usuario). Pero además <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>introduce una nueva clase de arrays, los arrays de controles (esto es, arrays de botones, de etiquetas,de paneles, etc.) que permit<strong>en</strong> una programación más breve y clara. En este apartado sólo se trataránlos arrays de variables.Todos los elem<strong>en</strong>tos de un array deb<strong>en</strong> ser del mismo tipo y están almac<strong>en</strong>ados de formacontigua <strong>en</strong> la memoria. Por supuesto, <strong>si</strong> el array es de tipo Variant cada elem<strong>en</strong>to puede cont<strong>en</strong>erun dato de tipo difer<strong>en</strong>te, e incluso puede cont<strong>en</strong>er otro array.Entre los arrays de variables cabe distinguir dos tipos fundam<strong>en</strong>tales, dep<strong>en</strong>di<strong>en</strong>do de qu<strong>en</strong>úmero de elem<strong>en</strong>tos sea constante o pueda variar durante la ejecución del programa.1. Arrays estáticos, cuya dim<strong>en</strong><strong>si</strong>ón es <strong>si</strong>empre la misma.2. Arrays dinámicos, cuya dim<strong>en</strong><strong>si</strong>ón se puede modificar durante la ejecución delprograma.3.9.1 Arrays estáticosLa declaración de un array estático dep<strong>en</strong>derá de su ámbito.• La declaración de un array público se hace <strong>en</strong> la sección de declaraciones de un móduloutilizando la s<strong>en</strong>t<strong>en</strong>cia Public.• La declaración de un array a nivel del módulo o del formulario se hace <strong>en</strong> la sección dedeclaraciones del módulo o del formulario utilizando la s<strong>en</strong>t<strong>en</strong>cia Dim o Private.• Para declarar un array local a un procedimi<strong>en</strong>to, se utiliza la s<strong>en</strong>t<strong>en</strong>cia Dim, Private o Staticd<strong>en</strong>tro del propio procedimi<strong>en</strong>to.A continuación se pres<strong>en</strong>tan algunos ejemplos:Dim vector(19) As DoubleEste ejemplo declara un array de una dim<strong>en</strong><strong>si</strong>ón, llamado vector, con veinte elem<strong>en</strong>tos,vector(0), vector(1), ... , vector(19), cada uno de los cuales permite almac<strong>en</strong>ar un Double. Salvo quese indique otra cosa, los índices se empiezan a contar <strong>en</strong> cero.Dim matriz(3, 1 To 6) As IntegerEste ejemplo declara un array de dos dim<strong>en</strong><strong>si</strong>ones, llamado matriz, con 4x6 elem<strong>en</strong>tos,matriz(0,1), ... matriz(3,6), de tipo <strong>en</strong>tero.Public cad<strong>en</strong>a(1 To 12) As StringEl ejemplo anterior declara un array de una dim<strong>en</strong><strong>si</strong>ón, cad<strong>en</strong>a, con doce elem<strong>en</strong>tos,caract(1), ... , caract(12), cada uno de los cuáles permite almac<strong>en</strong>ar una cad<strong>en</strong>a de caracteres.La declaración de los arrays estáticos es bastante cómoda. Se declaran una vez. Sin embargoti<strong>en</strong><strong>en</strong> el inconv<strong>en</strong>i<strong>en</strong>te que <strong>en</strong> la mayoría de los casos están sobredim<strong>en</strong><strong>si</strong>onados y utilizan másmemoria de la que realm<strong>en</strong>te nece<strong>si</strong>tan. Esto implica que se está malgastando memoria. Parasolucionar este problema se utilizan los arrays dinámicos.3.9.2 Arrays dinámicosEl espacio necesario para un array estático se a<strong>si</strong>gna al iniciarse el programa y permanece fijodurante su ejecución. El espacio para un array dinámico se a<strong>si</strong>gna durante la ejecución del


Capítulo 3: L<strong>en</strong>guaje BASIC página 43programa. Un array dinámico, puede ser redim<strong>en</strong><strong>si</strong>onado <strong>en</strong> cualquier mom<strong>en</strong>to de la ejecución. Laforma mejor de redim<strong>en</strong><strong>si</strong>onar los arrays es mediante variables que conti<strong>en</strong><strong>en</strong> los valores adecuados.Para crear un array dinámico primero hay que declararlo <strong>como</strong> <strong>si</strong> fuera una array estático, pero<strong>si</strong>n darle dim<strong>en</strong><strong>si</strong>ón. Es decir, se deja la lista -<strong>en</strong>tre parénte<strong>si</strong>s- vacía <strong>si</strong>n ponerle ningún número.Esto se hace con la s<strong>en</strong>t<strong>en</strong>cia Public <strong>si</strong> se quiere que sea global, con Dim o Private <strong>si</strong> se quiere anivel de módulo o con Static, Dim o Private <strong>si</strong> se quiere que sea local.Para a<strong>si</strong>gnar el número actual de elem<strong>en</strong>tos del array se utiliza la s<strong>en</strong>t<strong>en</strong>cia ReDim. Las<strong>en</strong>t<strong>en</strong>cia ReDim puede aparecer solam<strong>en</strong>te <strong>en</strong> un procedimi<strong>en</strong>to y permite cambiar el número deelem<strong>en</strong>tos del array y sus límites inferior y superior, pero no el número de dim<strong>en</strong><strong>si</strong>ones. Esto quieredecir que, por ejemplo, no se puede trasformar un vector <strong>en</strong> una matriz.A continuación se pres<strong>en</strong>ta un ejemplo de cómo se declaran arrays dinámicos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>.Si se declara el array Matriz a nivel del formulario,Dim Matriz( ) As Integery más tarde, un procedimi<strong>en</strong>to Calculo puede a<strong>si</strong>gnar espacio para el array, <strong>como</strong> se indica acontinuación:Sub Calculo( )...ReDim Matriz(F, C)...End SubCada vez que se ejecuta la s<strong>en</strong>t<strong>en</strong>cia ReDim, todos los valores almac<strong>en</strong>ados <strong>en</strong> el array sepierd<strong>en</strong> (<strong>si</strong> son Variant se pon<strong>en</strong> a Empty; <strong>si</strong> son numéricos a cero y <strong>si</strong> son cad<strong>en</strong>as de caracteres ala cad<strong>en</strong>a vacía). Cuando interese cambiar el tamaño del array conservando los valores del array,hay que ejecutar ReDim con la palabra clave Preserve. Por ejemplo, supóngase un array A de dosdim<strong>en</strong><strong>si</strong>ones. La s<strong>en</strong>t<strong>en</strong>cia,ReDim Preserve A(D1, UBound(A, 2) + 2)increm<strong>en</strong>ta el tamaño del array <strong>en</strong> dos columnas más. Cuando se utiliza la palabra Preserve nopuede cambiarse el índice inferior del array (sí el superior). La función UBound utilizada <strong>en</strong> esteejemplo es una función que devuelve el valor más alto de la segunda dim<strong>en</strong><strong>si</strong>ón de la matriz (ver elHelp para más información).3.10 ESTRUCTURAS: SENTENCIA TYPEUna estructura (según la nom<strong>en</strong>clatura típica del l<strong>en</strong>guaje C) es un nuevo tipo de datos, un tipodefinido por el usuario, que puede ser manipulado de la misma forma que los tipos predefinidos(Int, Double, String, ...). Una estructura puede definirse <strong>como</strong> una colección o agrupación de datosde difer<strong>en</strong>tes tipos evid<strong>en</strong>tem<strong>en</strong>te relacionados <strong>en</strong>tre sí.Para crear una estructura con <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> hay que utilizar la s<strong>en</strong>t<strong>en</strong>cia Type ... End Type.Esta s<strong>en</strong>t<strong>en</strong>cia solam<strong>en</strong>te puede aparecer <strong>en</strong> la sección G<strong>en</strong>eral o de declaraciones de un módulo.Pued<strong>en</strong> crearse <strong>como</strong> Public o <strong>como</strong> Private <strong>en</strong> un módulo estándar o de clase y sólo <strong>como</strong> Private<strong>en</strong> un formulario. Dim equivale a Public. Véase el <strong>si</strong>gui<strong>en</strong>te ejemplo,Public Type AlumnoNombre As StringDireccion As String *40Telefono As LongDNI As LongEnd Type


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 44Este ejemplo declara un tipo de datos d<strong>en</strong>ominado Alumno que consta de cuatro miembros ocampos, d<strong>en</strong>ominados Nombre, Direccion, Telefono y DNI.Una vez definido un nuevo tipo de datos, <strong>en</strong> un módulo estándar o de clase se pued<strong>en</strong> declararvariables Public o Private de ese tipo (<strong>en</strong> un formulario sólo Private), <strong>como</strong> por ejemplo:Public Mikel as AlumnoPara referirse a un determinado miembro de una estructura se utiliza la notaciónvariable.miembro. Por ejemplo,Mikel.DNI = 34103315A su vez, un miembro de una estructura puede ser otra estructura, es decir un tipo definido porel usuario. Por ejemplo,Type FechaDia As IntegerMes As IntegerAnio As IntegerEnd TypeType AlumnoAlta As FechaNombre As StringDireccion As String * 40Telefono AS LongDNI As LongEnd TypeD<strong>en</strong>tro de una estructura puede haber arrays tanto estáticos <strong>como</strong> dinámicos.En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se pued<strong>en</strong> definir arrays de estructuras. La declaración de un array deestructuras se hará con la palabra Public, Private o Static, dep<strong>en</strong>di<strong>en</strong>do de su ámbito. La forma dehacerlo es la <strong>si</strong>gui<strong>en</strong>te:Public grupoA (1 To 100) As AlumnoPrivate grupoB (1 To 100) As AlumnoStatic grupoC (1 To 100) As AlumnoEn <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>, a la hora de declarar arrays de estructuras, sucede lo mismo que aldeclarar arrays de cualquier tipo de variables. Con GrupoA(1 To 100), se crea un vector deestructuras de 100 elem<strong>en</strong>tos de tipo Alumno (grupoA(1), grupoA(2), ..., grupoA(100)). CongrupoB(100), se crearía un vector de estructuras de 101 elem<strong>en</strong>tos (grupoB(0), grupoB(1), ...grupoB(100)).Es po<strong>si</strong>ble a<strong>si</strong>gnar una estructura a otra del mismo tipo. En este caso se realiza una copiamiembro a miembro. Véase el <strong>si</strong>gui<strong>en</strong>te ejemplo:GrupoA(1) = delegadoLas estructuras pued<strong>en</strong> ser también argum<strong>en</strong>tos <strong>en</strong> las llamadas a funciones y procedimi<strong>en</strong>tosSub. Siempre son pasados por refer<strong>en</strong>cia, lo cual implica que pued<strong>en</strong> ser modificados d<strong>en</strong>tro delprocedimi<strong>en</strong>to y esas modificaciones perm<strong>en</strong>ec<strong>en</strong> <strong>en</strong> el <strong>en</strong>torno de llamada al procedimi<strong>en</strong>to. En elcaso de las funciones, las estructuras pued<strong>en</strong> ser también valores de retorno.


Capítulo 3: L<strong>en</strong>guaje BASIC página 453.11 FUNCIONES PARA MANEJO DE CADENAS DE CARACTERESExist<strong>en</strong> varias funciones útiles para el manejo de cad<strong>en</strong>as de caracteres (Strings). Estas funcionesse utilizan para la evaluación, manipulación o conver<strong>si</strong>ón de cad<strong>en</strong>as de caracteres. Algunas de ellasse muestran <strong>en</strong> la Tabla 3.4.UtilidadNúmero de caracteres de una cad<strong>en</strong>aConver<strong>si</strong>ón a minúsculas o a mayúsculasConver<strong>si</strong>ón de cad<strong>en</strong>as a números y d<strong>en</strong>úmeros a cad<strong>en</strong>asExtracción de un nº de caracteres <strong>en</strong> unrango, de la parte derecha o izquierda deuna cad<strong>en</strong>aFunción <strong>en</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>L<strong>en</strong>(string | varname)LCase(x), UCase(x)Str(n), CStr(n),Val(string)Mid(string, ini[, n]),Right(string, l<strong>en</strong>gth),Left(string, l<strong>en</strong>gth)Com<strong>en</strong>tariosel parámetro n de Mid es opcionale indica el número de caracteres aextraer a partir de "ini"Extracción de sub-cad<strong>en</strong>as Split(string, [[delim], n]) devuelve un array con las n (-1 paratodas) subcad<strong>en</strong>as separadas pordelim (por defecto, el espacio)Unión de sub-cad<strong>en</strong>asJoin(string, [delim])Comparación de cad<strong>en</strong>as de caracteres strComp(str1, str2) devuelve -1, 0, 1 según str1 seam<strong>en</strong>or, igual o mayor que str2Hallar <strong>si</strong> una cad<strong>en</strong>a es parte de otra(está cont<strong>en</strong>ida <strong>como</strong> sub-cad<strong>en</strong>a)Hallar una cad<strong>en</strong>a <strong>en</strong> otra a partir delfinal (reverse order)Buscar y reemplazar una subcad<strong>en</strong>a porotra <strong>en</strong> una cad<strong>en</strong>aInStr([n], str1, str2)InstrRev(str1, str2, [n])Replace(string, substring,replacewith)devuelve la po<strong>si</strong>ción de str2 <strong>en</strong> str1buscando a partir del carácter ndevuelve la po<strong>si</strong>ción de str2 <strong>en</strong> str1buscando a partir del carácter nreemplaza substring porreplacewithTabla 3.4. Funciones de manejo de cad<strong>en</strong>as de caracteres <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Es necesario t<strong>en</strong>er pres<strong>en</strong>te que cuando se quier<strong>en</strong> comparar dos cad<strong>en</strong>as de caracteres, dichacomparación se realiza por defecto <strong>en</strong> función del código ASCII asociado a cada letra (ver Anexo8.1). Esto <strong>si</strong>gnifica que por ejemplo caña es posterior a casa debido a que la letra ñ ti<strong>en</strong>e un códigoASCII asociado superior a la letra s (ñ es el 164; s es el 115). Esto mismo ocurre con las vocalesac<strong>en</strong>tuadas. Si se desea conseguir una comparación alfabética lógica es necesario incluir alcomi<strong>en</strong>zo del fichero de código la s<strong>en</strong>t<strong>en</strong>cia Option Compare Text (fr<strong>en</strong>te a Option CompareBinary establecida por defecto). La función strComp() admite un tercer argum<strong>en</strong>to que permiteespecificar el tipo de comparación (constantes vbBinaryCompare o vbTextCompare).Ejemplos:MyDouble = 437.324’ MyDouble es un Double.MyString = CStr(MyDouble) ’ MyString conti<strong>en</strong>e "437.324".MyValue = Val("2457") ’ Devuelve 2457.MyValue = Val(" 2 45 7") ’ Devuelve 2457.MyValue = Val("24 and 57") ’ Devuelve 24.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 46AnyString = "Hello World"MyStr = Right(AnyString, 6)MyStr = Left(AnyString, 7)MyStr = Right(AnyString, 20)’ Se define el string.’ Devuelve " World".’ Devuelve "Hello W".’ Devuelve "Hello World".i = StrComp("casa", "caña") ' Devuelve –1 por defecto y 1 con OptionCompare TextMyString = "Mid Function Demo" ' Se crea un nuevo string.LastWord = Mid(MyString, 14, 4) ' Devuelve "Demo".MidWords = Mid(MyString, 5) ' Devuelve "Function Demo".El operador Like permite comparar dos cad<strong>en</strong>as de caracteres. Si son iguales devuelve Truey <strong>si</strong> no lo son, False. Téngase <strong>en</strong> cu<strong>en</strong>ta que Like es un operador, no una función.Existe además el operador de concat<strong>en</strong>ación & que puede ser utilizado con cad<strong>en</strong>as decaracteres. Se utiliza para poner una cad<strong>en</strong>a a continuación de otra. Por ejemplo:str1 = "My first string" ’Se inicializan los stringsstr2 = "My second string"TextoFinal = str1 & str2 ’TextoFinal vale "My first stringMy second string"El operador "+" opera de forma análoga, pero su uso se desaconseja pues <strong>en</strong> ciertasoca<strong>si</strong>ones convierte las cad<strong>en</strong>as <strong>en</strong> números y realiza la suma.Para obt<strong>en</strong>er más información sobre cada una de las funciones buscar Strings <strong>en</strong> el Help de<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.3.12 FUNCIONES MATEMÁTICASAl igual que las funciones vistas para el manejo de cad<strong>en</strong>as de caracteres, existe una serie defunciones matemáticas las cuales permit<strong>en</strong> realizar cálculos d<strong>en</strong>tro de un programa de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>.Dichas funciones se muestran <strong>en</strong> la Tabla 3.5:FunciónmatemáticaFunción <strong>en</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>FunciónmatemáticaValor absoluto Abs(x) Nº aleatorio RndFunción <strong>en</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>Arco tang<strong>en</strong>te Atn(x) S<strong>en</strong>o y cos<strong>en</strong>o Sin(x), Cos(x)Expon<strong>en</strong>cial Exp(x) Tang<strong>en</strong>te Tan(x)Parte <strong>en</strong>tera Int(x), Fix(x) Raíz cuadrada Sqr(x)Logaritmo Log(x) Signo (1, 0, -1) Sgn(x)RedondeoEjemplos:Round(x, ndec)Tabla 3.5. Funciones matemáticas <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.MyNumber = Abs(50.3) ’ Devuelve 50.3.MyNumber = Abs(-50.3) ’ Devuelve 50.3.MyAngle = 1.3' El ángulo debe estar <strong>en</strong> radianes.MySecant = 1 / Cos(MyAngle) ' Calcula la secante.MySqr = Sqr(4) ' Devuelve 2.MySqr = Sqr(23) ' Devuelve 4.79583152331272.MyVar1 = 12: MyVar2 = -2.4: MyVar3 = 0 'Declaración de las variablesMySign = Sgn(MyVar1) ' Devuelve 1.MySign = Sgn(MyVar2) ' Devuelve -1.MySign = Sgn(MyVar3) ' Devuelve 0.


Capítulo 3: L<strong>en</strong>guaje BASIC página 47Las funciones trigonométricas de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> utilizan radianes para medir los ángulos.Con el fin de completar estas funciones, se ofrece a continuación una relación de funcionesque son derivadas de las anteriores. El alumno podría programar dichas funciones <strong>en</strong> un fichero*.bas y así poderlas utilizar posteriorm<strong>en</strong>te <strong>en</strong> cualquier programa. Dichas funciones se muestran <strong>en</strong>la Tabla 3.6:SecanteFunción matemáticaCosecanteCotang<strong>en</strong>teSec(X) = 1 / Cos(X)Cosec(X) = 1 / Sin(X)Cotan(X) = 1 / Tan(X)Expre<strong>si</strong>ón equival<strong>en</strong>teArcos<strong>en</strong>o Arc<strong>si</strong>n(X) = Atn(X / Sqr(-X * X + 1))Arcocos<strong>en</strong>oArcosecanteArcocosecanteArcocotang<strong>en</strong>teArccos(X) = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)Arcsec(X) = Atn(X / Sqr(X * X – 1)) + Sgn((X) -1) * (2 * Atn(1))Arccosec(X) = Atn(X / Sqr(X * X - 1)) + (Sgn(X) - 1) * (2 * Atn(1))Arccotan(X) = Atn(X) + 2 * Atn(1)S<strong>en</strong>o Hiperbólico HSin(X) = (Exp(X) - Exp(-X)) / 2Cos<strong>en</strong>o Hiperbólico Hcos(X) = (Exp(X) + Exp(-X)) / 2Tang<strong>en</strong>te HiperbólicaSecante HiperbólicaCosecante HiperbólicaCotang<strong>en</strong>te HiperbólicaHtan(X) = (Exp(X) - Exp(-X)) / (Exp(X) + Exp(-X))HSec(X) = 2 / (Exp(X) + Exp(-X))Hcosec(X) = 2 / (Exp(X) - Exp(-X))Hcotan(X) = (Exp(X) + Exp(-X)) / (Exp(X) - Exp(-X))Arcos<strong>en</strong>o Hiperbólico Harc<strong>si</strong>n(X) = Log(X + Sqr(X * X + 1))Arcocos<strong>en</strong>o Hiperbólico Harccos(X) = Log(X + Sqr(X * X - 1))Arcotang<strong>en</strong>te Hiperbólica Harctan(X) = Log((1 + X) / (1 - X)) / 2Arcosecante Hiperbólica Harcsec(X) = Log((Sqr(-X * X + 1) + 1) / X)Arcocosecante Hiperbólica Harccosec(X) = Log((Sgn(X) * Sqr(X * X + 1) +1) / X)Arcocotang<strong>en</strong>te Hiperbólica Harccotan(X) = Log((X + 1) / (X – 1)) / 2Logaritmo <strong>en</strong> base NLogN(X) = Log(X) / Log(N)Tabla 3.6. Funciones auxiliares matemáticas (no las ti<strong>en</strong>e <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>).


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 484. EVENTOS, PROPIEDADES Y CONTROLESEn este capítulo se pret<strong>en</strong>de recoger de una manera más <strong>si</strong>stemática y g<strong>en</strong>eral los ev<strong>en</strong>tos ycontroles más habituales de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>. Hay que señalar que <strong>en</strong> ningún mom<strong>en</strong>to se pret<strong>en</strong>deabandonar el carácter introductorio de este manual, y que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ti<strong>en</strong>e muchas máspo<strong>si</strong>bilidades de las que aquí se muestran. Por ejemplo, muchos de los controles y ev<strong>en</strong>tos de <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> están relacionados con el acceso a bases de datos. Estos aspectos no se citarán <strong>en</strong> estosapuntes. Para una información más detallada se puede acudir a un bu<strong>en</strong> libro de refer<strong>en</strong>cia o al Helpdel programa.La programación <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> (al m<strong>en</strong>os para ejemplos s<strong>en</strong>cillos) suele proceder del<strong>si</strong>gui<strong>en</strong>te modo:1. Se defin<strong>en</strong> interactivam<strong>en</strong>te sobre elformulario los controles que van aconstituir la aplicación.2. Se define para cada control el códigocon el que se va a responder a cadauno de los ev<strong>en</strong>tos. Para ello bastaclicar dos veces sobre el control y seabre una v<strong>en</strong>tana de código <strong>como</strong> lamostrada <strong>en</strong> la Figura 4.1. En ella<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ha preparado ya elinicio y el final de la función con laFigura 4.1. Código que gestionará el ev<strong>en</strong>to Click sobreel control de nombre cmbSalir.que se va a responder al ev<strong>en</strong>to. El nombre del ev<strong>en</strong>to forma parte del nombre de lafunción, junto al nombre del control. En el ejemplo del la Figura 4.1 está preparada lafunción para escribir el código que se ejecutará al producirse el ev<strong>en</strong>to Click sobre elcontrol cmbSalir.En el resto de este capítulo se verán con un cierto detalle los ev<strong>en</strong>tos, controles y propiedadesmás habituales <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.4.1 EVENTOSA continuación se pres<strong>en</strong>tan brevem<strong>en</strong>te los ev<strong>en</strong>tos más normales que reconoce <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.Es importante t<strong>en</strong>er una vi<strong>si</strong>ón g<strong>en</strong>eral de los ev<strong>en</strong>tos que exist<strong>en</strong> <strong>en</strong> Windows 95/98/NT porquecada control de los que se verán más adelante ti<strong>en</strong>e su propio conjunto de ev<strong>en</strong>tos que reconoce, yotros que no reconoce. Cualquier usuario de las aplicaciones escritas para Windows 95/98/NT haceuso continuo e intuitivo de los ev<strong>en</strong>tos, pero es po<strong>si</strong>ble que nunca se haya det<strong>en</strong>ido a p<strong>en</strong>sar <strong>en</strong> ello.Para saber qué ev<strong>en</strong>tos puede recibir un control determinado basta seleccionarlo y pulsar. De esta forma se abre una v<strong>en</strong>tana del Help que explica el control y permite acceder a losev<strong>en</strong>tos que soporta.4.1.1 Ev<strong>en</strong>tos g<strong>en</strong>erales4.1.1.1 Carga y descarga de formulariosCuando se arranca una aplicación, o más <strong>en</strong> concreto cuando se visualiza por primera vez unformulario se produc<strong>en</strong> varios ev<strong>en</strong>tos consecutivos: Initialize, Load, Activate y Paint. Cada uno de


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 49estos ev<strong>en</strong>tos se puede aprovechar para realizar ciertas operaciones por medio de la funcióncorrespondi<strong>en</strong>te.Al ocultar, cerrar o eliminar un formulario se produc<strong>en</strong> otra serie de ev<strong>en</strong>tos: Deactivate,QueryUnload, Unload y Terminate que se verán <strong>en</strong> un próximo ejemplo.Para inicializar las variables definidas a nivel de módulo se suele utilizar el ev<strong>en</strong>to Initialize,que ti<strong>en</strong>e lugar antes que el Load. El ev<strong>en</strong>to Load se activa al cargar un formulario. Con elformulario principal esto sucede al arrancar la ejecución de un programa; con el resto de losformularios al mandarlos cargar desde cualquier procedimi<strong>en</strong>to o al hacer refer<strong>en</strong>cia a algunapropiedad o control de un formulario que no esté cargado. Al descargar un formulario se produce elev<strong>en</strong>to Unload. Si se deti<strong>en</strong>e el programa desde el botón Stop de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> (o del m<strong>en</strong>úcorrespondi<strong>en</strong>te) o con un End, no se pasa por el ev<strong>en</strong>to Unload. Para pasar por el ev<strong>en</strong>to Unloades necesario cerrar la v<strong>en</strong>tana con el botón de cerrar o llamarlo explícitam<strong>en</strong>te. El ev<strong>en</strong>toQueryUnload se produce antes del ev<strong>en</strong>to Unload y permite por ejemplo <strong>en</strong>viar un m<strong>en</strong>saje deconfirmación.El ev<strong>en</strong>to Load de un formulario se suele utilizar para ejecutar una función que dé valor a suspropiedades y a las de los controles que dep<strong>en</strong>d<strong>en</strong> de dicho formulario. No se puede utilizar paradibujar o imprimir sobre el formulario, pues <strong>en</strong> el mom<strong>en</strong>to <strong>en</strong> que se produce este ev<strong>en</strong>to elformulario todavía no está disponible para dichas operaciones. Por ejemplo, <strong>si</strong> <strong>en</strong> el formulario debeaparecer la salida del método Print o de los métodos gráficos Pset, Line y Circle (que se estudian <strong>en</strong>el Capítulo 6 de este manual) puede utilizarse el ev<strong>en</strong>to Paint u otro posterior (por ejemplo, elev<strong>en</strong>to GotFocus del primer control) pero no puede utilizarse el ev<strong>en</strong>to Load.Se puede ocultar un formulario <strong>si</strong>n descargarlo con el método Hide o haci<strong>en</strong>do la propiedadVi<strong>si</strong>ble = False. Esto hace que el formulario desaparezca de la v<strong>en</strong>tana, aunque sus variables ypropiedades <strong>si</strong>gan estando acce<strong>si</strong>bles y conservando sus valores. Para hacer vi<strong>si</strong>ble un formulariooculto pero ya cargado se utiliza el método Show, que equivale a hacer la propiedad Vi<strong>si</strong>ble = True,y que g<strong>en</strong>era los ev<strong>en</strong>tos Activate y Paint. Si el formulario no había <strong>si</strong>do cargado previam<strong>en</strong>te, elmétodo Show g<strong>en</strong>era los cuatro ev<strong>en</strong>tos m<strong>en</strong>cionados.Cuando un formulario pasa a ser la v<strong>en</strong>tana activa se produce el ev<strong>en</strong>to Activate y al dejar deserlo el ev<strong>en</strong>to Deactivate. En el caso de que el formulario que va a ser activo no <strong>estuviera</strong> cargadoya, primero sucederían los ev<strong>en</strong>tos Initialize, Load y luego los ev<strong>en</strong>tos Activate y Paint.Todo esto se puede ver y <strong>en</strong>t<strong>en</strong>der con un <strong>si</strong>mple ejemplo, mostrado <strong>en</strong> la Figura 4.2. Se hande crear dos formularios (frmPrincipal y frmSecundario). El primero de ellos cont<strong>en</strong>drá dosbotones (cmdVerSec y cmdSalir) y el segundo tres (cmdHide, cmdUnload y cmdTerminate). Elformulario principal será el primero que aparece, y sólo se verá el segundo <strong>si</strong> se clica <strong>en</strong> el botónCargar Formulario. Cuando así se haga, a medida que los ev<strong>en</strong>tos antes m<strong>en</strong>cionados se vayansucedi<strong>en</strong>do, irán apareci<strong>en</strong>do <strong>en</strong> pantalla unas cajas de m<strong>en</strong>sajes que t<strong>en</strong>drán <strong>como</strong> texto el nombredel ev<strong>en</strong>to que se acaba de producir. Según con cual de los tres botones se haga desaparecer elsegundo formulario, al volverlo a ver se producirán unos ev<strong>en</strong>tos u otros, según se puede ver por losm<strong>en</strong>sajes que van apareci<strong>en</strong>do con cada ev<strong>en</strong>to.' código del form. principalPrivate Sub cmdCargar_Click()frmSecundario.ShowEnd Sub' código del form. secundarioPrivate Sub cmdHide_Click()HideEnd Sub


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 50Private Sub cmdUnload_Click()Unload MeEnd SubPrivate Sub cmdTerminate_Click()HideSet Form2 = NothingEnd SubPrivate Sub Form_Activate()MsgBox ("Ev<strong>en</strong>to Activate")End SubPrivate Sub Form_Deactivate()MsgBox ("Ev<strong>en</strong>to Deactivate")End SubFigura 4.2. Resultado del ejemplo de carga de formularios.Private Sub Form_Initialize()MsgBox ("Ev<strong>en</strong>to Initialize")End SubPrivate Sub Form_Load()MsgBox ("Ev<strong>en</strong>to Load")End SubPrivate Sub Form_Paint()MsgBox ("Ev<strong>en</strong>to Paint")End SubPrivate Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)MsgBox ("Ev<strong>en</strong>to QueryUnload")End SubPrivate Sub Form_Terminate()MsgBox ("Ev<strong>en</strong>to Terminate")End SubPrivate Sub Form_Unload(Cancel As Integer)MsgBox ("Ev<strong>en</strong>to Unload")End SubEs muy interesante realizar este ejemplo y seguir la secu<strong>en</strong>cia de ev<strong>en</strong>tos que se produc<strong>en</strong> alhacer aparecer y desaparecer los formularios.4.1.1.2 PaintEl ev<strong>en</strong>to Paint sucede cuando hay que redibujar un formulario o PictureBox. Esto sucede cuandoesos objetos se hac<strong>en</strong> vi<strong>si</strong>bles por primera vez y también cuando vuelv<strong>en</strong> a ser vi<strong>si</strong>bles después dehaber estado tapados por otros, tras haber <strong>si</strong>do movidos o tras haber <strong>si</strong>do modificados de tamaño.4.1.1.3 El foco (focus)En todas las aplicaciones de Windows, <strong>en</strong> cualquiera de sus ver<strong>si</strong>ones, <strong>si</strong>empre hay un únicocontrol, formulario o v<strong>en</strong>tana que puede recibir <strong>en</strong>tradas desde teclado. En cada mom<strong>en</strong>to esecontrol, v<strong>en</strong>tana o formulario es el que dispone del “foco” (focus). El objeto que posee el foco estácaracterizado por estar resaltado con letra negrita, con un contorno más vivo o t<strong>en</strong>i<strong>en</strong>doparpadeando el cursor <strong>en</strong> él. Este foco puede ser trasladado de un objeto a otro por código o porinteracciones del usuario, <strong>como</strong> por ejemplo clicando con el ratón <strong>en</strong> distintos puntos de la pantallao pulsando la tecla Tab. Cada vez que un objeto pierde el foco se produce su ev<strong>en</strong>to LostFocus y,posteriorm<strong>en</strong>te, el ev<strong>en</strong>to GotFocus del objeto que ha recibido el foco.


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 51El método SetFocus permite dar el focus al objeto al que se aplica.Dos propiedades de muchos controles relacionadas con el foco son TabIndex y TabStop.TabStop determina <strong>si</strong> el foco se va o no a posar <strong>en</strong> el objeto al pulsar la tecla Tab (<strong>si</strong> TabStop está aFalse no se puede obt<strong>en</strong>er el foco mediante el tabulador) y TabIndex determina el ord<strong>en</strong> <strong>en</strong> el queesto va a suceder. Así al cargar un formulario, el foco estará <strong>en</strong> aquel objeto cuyo TabIndex sea 0.Al pulsar la tecla Tab el foco irá al objeto que t<strong>en</strong>ga TabIndex = 1 y así suce<strong>si</strong>vam<strong>en</strong>te. Pararetroceder <strong>en</strong> esta lista se pulsa Mayúsculas+Tab. La propiedad TabIndex se puede determinar <strong>en</strong>tiempo de diseño por medio de la caja de propiedades de un control, del modo habitual.Cuando a un control se le a<strong>si</strong>gna un determinado valor de TabIndex, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> ajustaautomáticam<strong>en</strong>te los valores de los demás controles (<strong>si</strong> ti<strong>en</strong>e que desplazarlos hacia arriba o haciaabajo, lo hace de modo que <strong>si</strong>empre t<strong>en</strong>gan números consecutivos). Para que un formulario recibael foco es necesario que no haya <strong>en</strong> él ningún control que sea capaz de recibirlo.Un grupo de botones de opción ti<strong>en</strong>e un único TabIndex, es decir, se comporta <strong>como</strong> <strong>si</strong> fueraun único control. Para elegir una u otra de las opciones se utilizan las flechas del teclado (↑ y ↓).4.1.1.4 KeyPress, KeyUp y KeyDownEl ev<strong>en</strong>to KeyPress sucede cuando el usuario pulsa y suelta determinada tecla. En el procedimi<strong>en</strong>toasociado con este ev<strong>en</strong>to el único argum<strong>en</strong>to KeyAscii es necesario para conocer cuál es el códigoASCII de la tecla pulsada. El ev<strong>en</strong>to KeyDown se produce cuando el usuario pulsa determinadatecla y el ev<strong>en</strong>to KeyUp al soltar una tecla.Los ev<strong>en</strong>tos KeyUp y KeyDown ti<strong>en</strong><strong>en</strong> un segundo argum<strong>en</strong>to llamado Shift que permit<strong>en</strong>determinar <strong>si</strong> esa tecla se ha pulsado estando pulsadas a la vez cualquier combinación de las teclasShift, Alt y Ctrl. En un apartado próximo se explica cómo se id<strong>en</strong>tifican las teclas pulsadas a partirdel argum<strong>en</strong>to Shift.4.1.2 Ev<strong>en</strong>tos relacionados con el ratón4.1.2.1 Click y DblClickEl ev<strong>en</strong>to Click se activa cuando el usuario pulsa y suelta rápidam<strong>en</strong>te uno de los botones del ratón.También puede activarse desde código (<strong>si</strong>n tocar el ratón) variando la propiedad Value de alguno delos controles. En el caso de un formulario este ev<strong>en</strong>to se activa cuando el usuario clica sobre unazona del formulario <strong>en</strong> la que no haya ningún control o sobre un control que <strong>en</strong> ese mom<strong>en</strong>to estéinhabilitado (propiedad Enabled = False). En el caso de un control, el ev<strong>en</strong>to se activa cuando elusuario realiza una de las <strong>si</strong>gui<strong>en</strong>tes operaciones:• Clicar sobre un control con el botón derecho o izquierdo del ratón. En el caso de un botónde comando, de un botón de selección o de un botón de opción, el ev<strong>en</strong>to sucede solam<strong>en</strong>teal clicar con el botón izquierdo.• Seleccionar un registro de alguno de los varios tipos listas desplegables que dispone <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong>.• Pulsar la barra espaciadora cuando el foco está <strong>en</strong> un botón de comando, <strong>en</strong> un botón deselección o <strong>en</strong> un botón de opción.• Pulsar la tecla Return cuando <strong>en</strong> un formulario hay un botón que ti<strong>en</strong>e su propiedadDefault = True.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 52• Pulsar la tecla Esc cuando <strong>en</strong> un formulario hay un botón que ti<strong>en</strong>e su propiedad Cancel =True.• Pulsar una combinación de teclas aceleradoras (Alt + otra tecla, <strong>como</strong> por ejemplo cuandode despliega el m<strong>en</strong>ú File de Word con Alt+F) definidas para activar un determinadocontrol de un formulario.También se puede activar el ev<strong>en</strong>to Click desde código realizando una de las <strong>si</strong>gui<strong>en</strong>tesoperaciones:• Hacer que la propiedad Value de un botón de comando valga True.• Hacer que la propiedad Value de un botón de opción valga True• Modificar la propiedad Value de un botón de selección.El ev<strong>en</strong>to DblClick sucede al clicar dos veces seguidas sobre un control o formulario con elbotón izquierdo del ratón.4.1.2.2 MouseDown, MouseUp y MouseMoveEl ev<strong>en</strong>to MouseDown sucede cuando el usuario pulsa cualquiera de los botones del ratón, mi<strong>en</strong>trasque el ev<strong>en</strong>to MouseUp sucede al soltar un botón que había <strong>si</strong>do pulsado. El ev<strong>en</strong>to MouseMovesucede al mover el ratón sobre un control o formulario.Los ev<strong>en</strong>tos MouseUp y MouseDown ti<strong>en</strong><strong>en</strong> algunos argum<strong>en</strong>tos que merec<strong>en</strong> sercom<strong>en</strong>tados. El argum<strong>en</strong>to Button indica cuál de los botones del ratón ha <strong>si</strong>do pulsado o soltado, yel argum<strong>en</strong>to Shift indica <strong>si</strong> además alguna de las teclas alt, shift o ctrl está también pulsada. Lalista con todos los po<strong>si</strong>bles valores de estos argum<strong>en</strong>tos se muestra <strong>en</strong> la Tabla 4.1:Cte <strong>si</strong>mbólica Valor Acción Cte <strong>si</strong>mbólica Valor AcciónvbLeftButton 1 Botón izdo pulsado o soltado vbShiftMask 1 Tecla SHIFT pulsadavbRightButton 2 Botón dcho pulsado o soltado vbCtrlMask 2 Tecla CTRL pulsadavbMiddleButton 4 Botón c<strong>en</strong>tral pulsado o soltado vbAltMask 4 Tecla ALT pulsadaTabla 4.1. Valores de los argum<strong>en</strong>tos de los ev<strong>en</strong>tos MouseUp y MouseDown.Con estos valores se aplica la aritmética booleana, lo cual quiere decir que <strong>si</strong> se pulsan<strong>si</strong>multáneam<strong>en</strong>te los botones izquierdo y derecho del ratón el argum<strong>en</strong>to Button valdrá 3 (1+2) y <strong>si</strong>se pulsan las tres teclas shift, ctrl y alt <strong>si</strong>multáneam<strong>en</strong>te el argum<strong>en</strong>to Shift valdrá 7 (1+2+4). Conesta forma de combinar los valores se resuelv<strong>en</strong> todas las indeterminaciones po<strong>si</strong>bles.4.1.2.3 DragOver y DragDropEl ev<strong>en</strong>to DragOver sucede mi<strong>en</strong>tras se está arrastrando un objeto sobre un control. Suele utilizarsepara variar la forma del cursor que se mueve con el ratón dep<strong>en</strong>di<strong>en</strong>do de <strong>si</strong> el objeto sobre el que se<strong>en</strong>cu<strong>en</strong>tra el cursor <strong>en</strong> ese mom<strong>en</strong>to es válido para soltar o no. El ev<strong>en</strong>to DragDrop sucede alconcluir una operación de arrastrar y soltar. El ev<strong>en</strong>to DragOver requiere de los argum<strong>en</strong>tos que semuestran a continuación:Private Sub Text1_DragOver(Source As Control, _X As Single, Y As Single, State As Integer)...End Sub


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 53Los argum<strong>en</strong>tos de este ev<strong>en</strong>to son Source que conti<strong>en</strong>e el objeto que está <strong>si</strong><strong>en</strong>do arrastrado,X e Y que indican la po<strong>si</strong>ción del objeto arrastrado d<strong>en</strong>tro del <strong>si</strong>stema de coord<strong>en</strong>adas del objetosobre el que se está arrastrando y State (que es propio del DragOver, pero no aparece <strong>en</strong> elDragDrop) que vale 0, 1 ó 2 según se esté <strong>en</strong>trando, sali<strong>en</strong>do o permaneci<strong>en</strong>do d<strong>en</strong>tro del mismoobjeto, respectivam<strong>en</strong>te. Es importante señalar que el ev<strong>en</strong>to DragOver pert<strong>en</strong>ece al objeto sobre elque se arrastra, no al objeto que es arrastrado.En el Help se puede <strong>en</strong>contrar información sobre la propiedad DragMode, que puede tomardos valores (vbManual y vbAutomatic). Esta constante determina cómo comi<strong>en</strong>za una oparación dearrastre de un objeto. En modo manual se debe com<strong>en</strong>zar llamando al método Drag para el objeto aarrastrar. En modo automático basta clicar sobre el objeto a arrastrar, pero puede que <strong>en</strong> esta casodicho objeto no responda del modo habitual a otros ev<strong>en</strong>tos.4.2 ALGUNAS PROPIEDADES COMUNES A VARIOS CONTROLESHay algunas propiedades que son comunes a muchos controles. A continuación se hace una lista conlas utilizadas más habitualm<strong>en</strong>te:• Appearance: Establece <strong>si</strong> un objeto ti<strong>en</strong>e un aspecto plano (valor 0) o tridim<strong>en</strong><strong>si</strong>onal (valor1).• BackColor: Establece el color de fondo de un objeto.• Caption: Establece el texto que aparece d<strong>en</strong>tro o junto al objeto. Ti<strong>en</strong>e el papel de untítulo.• Enabled: Establece <strong>si</strong> un objeto es acce<strong>si</strong>ble y modificable o no.• Font: Establece las características del tipo de letra del objeto.• ForeColor: Establece el color del texto y/o gráficos de un objeto.• Height y Width: Establec<strong>en</strong> la altura y achura de un objeto.• Left y Top: Establec<strong>en</strong> la distancia horizontal y vertical <strong>en</strong>tre el orig<strong>en</strong> del control y elorig<strong>en</strong> del objeto que lo conti<strong>en</strong>e, que puede ser un formulario, un marco (frame), etc.• MousePointer: Establece la forma que adoptará el puntero del ratón al po<strong>si</strong>cionarse sobreel objeto. Esta forma puede elegirse d<strong>en</strong>tro de una lista <strong>en</strong> las que aparec<strong>en</strong> las habitualesdel puntero del ratón o creando iconos propios. Algunas constantes de <strong>si</strong>gnificadoinmediato que defin<strong>en</strong> la forma del cursor son las <strong>si</strong>gui<strong>en</strong>tes: vbDefault, vbArrow,vbCrosshair, vbIbeam, vbSizePointer, vbUpArrow, vbHourglass, etc. Para más informaciónpuede consultarse el Help de MousePointer.• Name: Nombre del objeto. Todos los objetos incluidos <strong>en</strong> un formulario deb<strong>en</strong> t<strong>en</strong>er unnombre con el que poder referirse a él a la hora de programar la forma <strong>en</strong> que debe actuar.Exist<strong>en</strong> unas reglas para definir los nombre de los controles, que ya se vieron <strong>en</strong> elCapítulo 1.• Vi<strong>si</strong>ble: Establece <strong>si</strong> el objeto es vi<strong>si</strong>ble o invi<strong>si</strong>ble.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 54Figura 4.3. Algunos de los controles más habituales de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>.4.3 CONTROLES MÁS USUALESEn la Figura 4.3 se muestran algunos de los controles más habituales <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>. Estoscontroles se explican a continuación con más detalle.4.3.1 Botón de comando (Command Button)La propiedades más importantes del botón de comando son su Caption,que es lo que aparece escrito <strong>en</strong> él, las refer<strong>en</strong>tes a su po<strong>si</strong>ción (Left yTop) y apari<strong>en</strong>cia externa (Height, Width y tipo de letra) y la propiedadEnabled, que determina <strong>si</strong> <strong>en</strong> un mom<strong>en</strong>to dado puede ser pulsado o no.No hay que confundir la propiedad Caption con la propiedad Name. Laprimera define a un texto que aparecerá escrito <strong>en</strong> el control, mi<strong>en</strong>tras quelas segunda define el nombre interno con el que se puede hacer refer<strong>en</strong>cia al citado objeto.Si <strong>en</strong> la propiedad Caption se pone el carácter (&) antes de una de sus letras, dicha letraaparece subrayyada <strong>en</strong> el botón (<strong>como</strong> la “x” <strong>en</strong> el botón Exit de la figura anexa). Esto quiere decirque, <strong>como</strong> es habitual <strong>en</strong> Windows, dicho botón puede activarse con el teclado por medio de lacombinación Alt+letra subrayada. Esta característica es común a muchos de los controles queti<strong>en</strong><strong>en</strong> propiedad Caption.El ev<strong>en</strong>to que <strong>si</strong>empre suel<strong>en</strong> t<strong>en</strong>er programado los botones de comandos es el ev<strong>en</strong>to Click.


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 554.3.2 Botones de opción (Option Button)Además de las m<strong>en</strong>cionadas para el caso anterior estos botones ti<strong>en</strong><strong>en</strong> lapropiedad Value, que <strong>en</strong> un determinado mom<strong>en</strong>to sólo puede ser True <strong>en</strong>uno de los botones del grupo ya que se trata de opciones que se excluy<strong>en</strong>mutuam<strong>en</strong>te.Para agrupar botones se coloca primero un marco o frame <strong>en</strong> elformulario y, estando seleccionado, se colocan después cuantos botones deopción se desee. En un mismo formulario se pued<strong>en</strong> colocar cuantos grupos de botones de opción sequiera, cada uno de ellos agrupado d<strong>en</strong>tro de su propio marco. Es muy importante colocar primeroel frame y después los botones de opción. Con esto se con<strong>si</strong>gue que los botones de opción esténagrupados, de modo que sólo uno de ellos pueda estar activado. Si no se coloca ningún frame todoslos botones de opción de un mismo formulario forman un único grupo. Si los botones ya exist<strong>en</strong> yse quier<strong>en</strong> introducir un un frame se seleccionan, se hace Cut y luego Paste d<strong>en</strong>tro del frameseleccionado.Sólo un grupo de botones de opción puede recibir el focus, no cada botón por separado.Cuando el grupo ti<strong>en</strong>e el focus, con las flechas del teclado (↑ y ↓) se puede activar una u otra opción<strong>si</strong>n nece<strong>si</strong>dad de usar el ratón. También se puede utilizar Alt+carácter introduci<strong>en</strong>do antes de dichocarácter un (&) <strong>en</strong> el Caption del botón de opción.4.3.3 Botones de selección (Check Box)La única difer<strong>en</strong>cia <strong>en</strong>tre estos botones y los anteriores es que <strong>en</strong> losbotones de selección puede haber más de uno con la propiedad Value aTrue. Estos botones no forman grupo aunque estén d<strong>en</strong>tro de un frame, yrecib<strong>en</strong> el focus individualm<strong>en</strong>te. Se puede también utilizar el carácter (&)<strong>en</strong> el Caption para activarlos con el teclado.El usuario debe decidir qué tipo de botones se ajustan mejor a susnece<strong>si</strong>dades: <strong>en</strong> el caso de la edad, está claro que no se puede ser de dosedades difer<strong>en</strong>tes; sí es po<strong>si</strong>ble <strong>si</strong>n embargo conocer varios l<strong>en</strong>guajes de programación.4.3.4 Barras de desplazami<strong>en</strong>to (Scroll Bars)En este tipo de control las propiedades más importantes son Max y Min, quedeterminan el rango <strong>en</strong> el que está incluido su valor, LargeChange y SmallChangeque determinan lo que se modifica su valor al clicar <strong>en</strong> la barra o <strong>en</strong> el botón con laflecha respectivam<strong>en</strong>te y Value que determina el valor actual de la barra dedesplazami<strong>en</strong>to. Las barras de desplazami<strong>en</strong>to no ti<strong>en</strong><strong>en</strong> propiedad Caption.El ev<strong>en</strong>to que se programa habitualm<strong>en</strong>te es Change, que se activa cuando labarra de desplazami<strong>en</strong>to modifica su valor. Todo lo com<strong>en</strong>tado <strong>en</strong> este apartado escomún para las barras de desplazami<strong>en</strong>to verticales y horizontales.Además de las Scroll Bars horizontal y vertical, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone también del controlSlider, utilizado <strong>en</strong> los paneles de control de Windows, que ti<strong>en</strong>e una función <strong>si</strong>milar.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 564.3.5 Etiquetas (Labels)En las etiquetas o labels la propiedad más importante es Caption, que conti<strong>en</strong>eel texto que aparece sobre este control. Esta propiedad puede ser modificadadesde programa, pero no interactivam<strong>en</strong>te clicando sobre ella (a difer<strong>en</strong>cia delas cajas de texto, que se verán a continuación). Puede controlarse su tamaño,po<strong>si</strong>ción, color de fondo y una especie de borde 3-D. Habitualm<strong>en</strong>te las labelsno suel<strong>en</strong> recibir ev<strong>en</strong>tos ni cont<strong>en</strong>er código.Las Labels ti<strong>en</strong><strong>en</strong> las propiedades AutoSize y WordWrap. La primera, cuando está a True,ajusta el tamaño del control al del texto <strong>en</strong> él cont<strong>en</strong>ido. La segunda hace que el texto se distribuya<strong>en</strong> varias líneas cuando no cabe <strong>en</strong> una sola.4.3.6 Cajas de texto (Text Box)La propiedad más importante de las cajas de texto es Text, que almac<strong>en</strong>a eltexto cont<strong>en</strong>ido <strong>en</strong> ellas. También se suel<strong>en</strong> controlar las que hac<strong>en</strong>refer<strong>en</strong>cia a su tamaño, po<strong>si</strong>ción y apari<strong>en</strong>cia. En algún mom<strong>en</strong>to se puededesear impedir el acceso a la caja de texto, por lo que se establecerá supropiedad Enabled <strong>como</strong> False. La propiedad Locked <strong>como</strong> True hace quela caja de texto sea de sólo lectura. La propiedad MultiLine, que sólo seaplica a las cajas de texto, determina <strong>si</strong> <strong>en</strong> una de ellas se pued<strong>en</strong> incluir más de una línea o <strong>si</strong> seignoran los saltos de línea. La justificación o c<strong>en</strong>trado del texto se controla con la propiedadAlignm<strong>en</strong>t. La propiedad ScrollBars permite controlar el que aparezca ninguna, una o las dos barrasde desplazami<strong>en</strong>to de la caja.En una caja de texto no se pued<strong>en</strong> introducir Intros con el teclado <strong>en</strong> modo de diseño. Enmodo de ejecución se deb<strong>en</strong> introducir <strong>como</strong> caracteres ASCII (el 13 seguido del 10, esto CarriageReturn y Line Feed). Afortunadam<strong>en</strong>te <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de la constante vbCrLf, que realizaesta mi<strong>si</strong>ón de modo automático.Otras propiedades importantes hac<strong>en</strong> refer<strong>en</strong>cia a la selección de texto d<strong>en</strong>tro de la caja, quesólo están disponibles <strong>en</strong> tiempo de ejecución. La propiedad SelStart <strong>si</strong>rve para po<strong>si</strong>cionar el cursoral comi<strong>en</strong>zo del texto que se desea seleccionar (el primer carácter es el cero); SelL<strong>en</strong>gth indica elnúmero de caracteres o longitud de la selección; SelText es una cad<strong>en</strong>a de caracteres que repres<strong>en</strong>tael texto seleccionado. Para hacer Paste con otro texto sustituy<strong>en</strong>do al seleccionado basta a<strong>si</strong>gnarle aesta propiedad ese otro texto (<strong>si</strong> no hay ningún texto seleccionado, el texto de SelText se inserta <strong>en</strong>la po<strong>si</strong>ción del cursor); para <strong>en</strong>tresacar el texto seleccionado basta utilizar esta propiedad <strong>en</strong> algunaexpre<strong>si</strong>ón.Los ev<strong>en</strong>tos que se programan son Change, cuando se quiere realizar alguna acción al modificarel cont<strong>en</strong>ido de la caja, Click y DblClick y <strong>en</strong> algunos casos especiales KeyPress para controlarlos caracteres que se introduc<strong>en</strong>. Por ejemplo, se puede chequear la introducción del código ASCII13 (Intro) para detectar que ya se finalizado con la introducción de datos. También se utiliza lapropiedad MaxL<strong>en</strong>gth para determinar el número máximo de caracteres que pued<strong>en</strong> introducirse <strong>en</strong>la caja de texto.En aquellos casos <strong>en</strong> los que se utilice una caja de texto <strong>como</strong> <strong>en</strong>trada de datos (es el controlque se utiliza la mayoría de las veces con esta finalidad), puede ser interesante utilizar el métodoSetFocus para <strong>en</strong>viar el foco a la caja cuando se con<strong>si</strong>dere oportuno.Otras propiedades de las cajas de texto hac<strong>en</strong> refer<strong>en</strong>cia a los tipos de letra y al estilo. Así lapropiedad FontName es una cad<strong>en</strong>a que conti<strong>en</strong>e el nombre del Font (Courier New, Times New


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 57Roman, etc.), FontSize es un tipo Short que conti<strong>en</strong>e el tamaño de la letra, y FontBold, FontItalic,FontUnderline y FontStrikethrough son propiedades tipo Boolean que indican <strong>si</strong> el texto va at<strong>en</strong>er esa característica o no.4.3.7 Listas (List Box)Una lista es un control <strong>en</strong> el que se pued<strong>en</strong> mostrar varios registroso líneas, t<strong>en</strong>i<strong>en</strong>do uno o varios de ellos seleccionado(s). Si <strong>en</strong> lalista hay más registros de los que se pued<strong>en</strong> mostrar al mismotiempo, se añade automáticam<strong>en</strong>te una scrollBar.Para añadir o eliminar registros de la lista <strong>en</strong> modo deejecución se utilizan los métodos AddItem y RemoveItem. Laslistas se suel<strong>en</strong> inicializar desde el ev<strong>en</strong>to Form_Load.La propiedad List es un array que permite definir el cont<strong>en</strong>idode la lista <strong>en</strong> modo de diseño a través de la v<strong>en</strong>tana de propiedades.List permite también acceder a los elem<strong>en</strong>tos de la lista <strong>en</strong> tiempo de ejecución, para utilizar y/ocambiar su valor. Para ello se pone <strong>en</strong> índice del elem<strong>en</strong>to <strong>en</strong>tre parénte<strong>si</strong>s (empezando a contar porcero) a continuación de List, <strong>como</strong> se muestra a continuación por ejemplo, para cambiar el tercerelem<strong>en</strong>to:lstName.List(2) = "Tercero"Para añadir un registro <strong>en</strong> tiempo de ejecución se utiliza AddItem:lstName.AddItem Registro_Añadido, po<strong>si</strong>ciondonde po<strong>si</strong>cion es un argum<strong>en</strong>to opcional que permite especificar la po<strong>si</strong>ción <strong>en</strong> que se debe añadir.Si se omite el registro se añade al final de la lista. Lo anterior es válido <strong>si</strong> la propiedad Sorted está aFalse; <strong>si</strong> está a True el nuevo registro se añade <strong>en</strong> la po<strong>si</strong>ción ord<strong>en</strong>ada que le corresponde. Paraeliminar un registro,lstName.RemoveItem Po<strong>si</strong>ción_del_registro_<strong>en</strong>_la_listaEn el caso de que se quiera vaciar completam<strong>en</strong>te el cont<strong>en</strong>ido de una lista se puede utilizar elmétodo Clear.Dos propiedades interesantes de las listas son ListCount y ListIndex. La primera conti<strong>en</strong>e elnúmero total de registros incluidos <strong>en</strong> la lista. La segunda permite acceder a una po<strong>si</strong>ción concretade la lista para añadir un registro nuevo <strong>en</strong> esa po<strong>si</strong>ción, borrar uno ya exist<strong>en</strong>te, seleccionarlo, etc.Hay que recordar una vez más que los elem<strong>en</strong>tos de la lista se empiezan a numerar por cero. Elvalor de propiedad ListIndex <strong>en</strong> cada mom<strong>en</strong>to coincide con el registro seleccionado y <strong>en</strong> el caso d<strong>en</strong>o haber ninguno seleccionado esta propiedad vale -1.Es interesante saber que al seleccionar uno de los registros de la lista se activa el ev<strong>en</strong>to Clickde dicha lista.Las listas permit<strong>en</strong> selecionar más de un elem<strong>en</strong>to poni<strong>en</strong>do la propiedad MultiSelect a valor1-Simple o 2-Ext<strong>en</strong>ded. En el primer caso los elem<strong>en</strong>tos se seleccionan o se elimina la selección<strong>si</strong>mplem<strong>en</strong>te clicando sobre ellos. En el segundo caso la forma de hacer selecciones múltiples es latípica de Windows, utilizando las teclas Ctrl y Shift. Con selección múltile la propiedad SelCountindica el número de elem<strong>en</strong>tos seleccionados, mi<strong>en</strong>tras que la propiedad Selected() es un array devalores boolean que indica <strong>si</strong> cada uno de los elem<strong>en</strong>tos de la lista está seleccionado o no.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 584.3.8 Cajas combinadas (ComboBox)Un ComboBox ti<strong>en</strong>e muchas cosas <strong>en</strong> común con una lista. Por ejemplo losmétodos AddItem, RemoveItem o Clear y las propiedades List, ListIndex oListCount.La difer<strong>en</strong>cia principal es que <strong>en</strong> un ComboBox ti<strong>en</strong>e una propiedad llamadaStyle, que puede adoptar tres valores (1,2 ó 3) que correspond<strong>en</strong> con tres distintasformas de pres<strong>en</strong>tar una lista:1. Style=0 ó Style=vbComboDropDown (Dropdown Combo), Éste es el valormás habitual y corresponde con el caso <strong>en</strong> el que sólo se muestra el registroseleccionado, que es editable por el usuario, permaneci<strong>en</strong>do el resto oculto hasta que elusuario despliega la lista completa clicando sobre el botón-flecha.2. Style=1 ó Style=vbComboSimple (Simple Combo). En este caso el registro seleccionadotambién es editable, y se muestra una lista no desplegable dotada <strong>si</strong> es necesario de unascrollbar.3. Style=2 ó Style=vbComboDropDownList (DropDown List). En este último caso el registroseleccionado no es editable y la lista es desplegable.En una caja combinada, al igual que <strong>en</strong> una caja de texto s<strong>en</strong>cilla, está permitido escribir conel teclado <strong>en</strong> tiempo de ejecución, <strong>si</strong> la propiedad Enabled vale True. En una lista esto no espo<strong>si</strong>ble.La propiedad Text corresponde con lo que aparece <strong>en</strong> la parte de caja de texto del controlComboBox, bi<strong>en</strong> sea porque el usuario lo ha introducido, bi<strong>en</strong> porque lo haya seleccionado.4.3.9 Controles relacionados con ficherosTrabajando <strong>en</strong> un <strong>en</strong>torno Windows 95/98/NT es habitual t<strong>en</strong>er que abrir y cerrarficheros parar leer datos, guardar un docum<strong>en</strong>to, etc. Hay tres controles bá<strong>si</strong>cos que resultan desuma utilidad <strong>en</strong> esta tarea. Son la lista de unidades lógicas o discos (Drive ListBox), la lista dedirectorios (Dir ListBox) y la lista de ficheros (File ListBox). Estos controles se tratan con másdetalle <strong>en</strong> el Capítulo 7.4.3.10 Control TimerSi se desea que una acción suceda con cierta periodicidad se puede utilizar un control Timer.Este control produce de modo automático un ev<strong>en</strong>to cada cierto número de milisegundos y esde fundam<strong>en</strong>tal importancia para crear animaciones o aplicaciones con movimi<strong>en</strong>to de objetos. Lapropiedad más importante de un objeto de este tipo es Interval, que determina, precisam<strong>en</strong>te, elintervalo <strong>en</strong> milisegundos <strong>en</strong>tre ev<strong>en</strong>tos consecutivos. La acción que se desea activar debeprogramarse <strong>en</strong> el ev<strong>en</strong>to Timer de ese mismo control.Si <strong>en</strong> algún mom<strong>en</strong>to se desea det<strong>en</strong>er mom<strong>en</strong>táneam<strong>en</strong>te la acción periódica es sufici<strong>en</strong>te conhacer False la propiedad Enabled del control Timer y para arrancarla de nuevo volver a hacer Trueesa propiedad. Haci<strong>en</strong>do 0 la propiedad Interval también se con<strong>si</strong>gue inhabilitar el Timer.4.4 CAJAS DE DIÁLOGO ESTÁNDAR (CONTROLES COMMON DIALOG)El control de cuadro de diálogo estándar de Windows 95/NT (Common Dialog) ofrece una formas<strong>en</strong>cilla y efici<strong>en</strong>te de realizar algunas de las tareas más comunes de un programa, tales <strong>como</strong> la


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 59selección de un fichero para lectura/escritura, la impre<strong>si</strong>ón de un fichero o la selección de un tipo deletra o un color.Lo primero que hay que hacer es ubicar el control <strong>en</strong> el formulario. El control se repres<strong>en</strong>tará<strong>como</strong> un icono de tamaño invariable. No es po<strong>si</strong>ble especificar la ubicación que t<strong>en</strong>drá la caja dediálogo cuando se abra <strong>en</strong> la pantalla, ya que se trata de una propiedad no acce<strong>si</strong>ble por el usuario.Un único cuadro de diálogo estándar puede bastar para realizar todas las funciones que sedese<strong>en</strong>, es decir, no es necesario insertar un cuadro de diálogo para imprimir un texto y otro paraguardarlo, <strong>si</strong>no que ambos pued<strong>en</strong> compartir el mismo cuadro de diálogo <strong>si</strong>mplem<strong>en</strong>te invocando auno u otro tipo <strong>en</strong> tiempo de ejecución (no es po<strong>si</strong>ble indicarlo <strong>en</strong> tiempo de diseño). Para ello sedispone de los métodos <strong>si</strong>gui<strong>en</strong>tes: ShowColor, ShowFont, ShowHelp, ShowOp<strong>en</strong>, ShowPrinter yShowSave. En oca<strong>si</strong>ones interesará introducir varios controles difer<strong>en</strong>tes por motivos de claridad opara que ciertas propiedades sean distintas.Figura 4.4. Controles Common Dialog.En la Figura 4.4 se pued<strong>en</strong> observar distintos tipos de control Common Dialog. Por ejemplo,<strong>si</strong> se desea visualizar un cuadro de diálogo para abrir un fichero, habrá que escribir:dlgAbrir.ShowOp<strong>en</strong>donde dlgAbrir es el nombre a<strong>si</strong>gnado al control Common Dialog.Las principales propiedades de este control <strong>en</strong> cada una de sus variantes se explican <strong>en</strong> losapartados <strong>si</strong>gui<strong>en</strong>tes. La propiedad Flag existe para todos los controles y determina algunas de suscaracterísticas más importantes.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 604.4.1 Op<strong>en</strong>/Save Dialog ControlLas propiedades más importantes de este control son:• DefaultExt: Es la ext<strong>en</strong><strong>si</strong>ón por defecto a utilizar para abrir/salvar archivos. Con Save, <strong>si</strong> elnombre del fichero se teclea <strong>si</strong>n ext<strong>en</strong><strong>si</strong>ón, se añade esta ext<strong>en</strong><strong>si</strong>ón por defecto.• DialogTitle: Devuelve o da valor al título de la caja de diálogo (cad<strong>en</strong>a de caracteres).• FileName: Nombre completo del archivo a abrir/salvar, incluy<strong>en</strong>do el path.• FileTitle: Nombre del archivo a abrir/salvar pero <strong>si</strong>n la ruta de acceso correspondi<strong>en</strong>te.• Filter: Conti<strong>en</strong>e los filtros de selección que aparecerán indicados <strong>en</strong> la parte inferior de lapantalla <strong>en</strong> la lista de tipos de archivo. Pued<strong>en</strong> indicarse múltiples tipos de archivo,separándolos mediante un barra vertical ( Alt Gr +< 1> ). Su <strong>si</strong>ntaxis es la <strong>si</strong>gui<strong>en</strong>te:Objeto.Filter = "(descripción a aparecer <strong>en</strong> la listbox)|filtro"Por ejemplo:"Texto (*.txt)|*.txt|Imág<strong>en</strong>es(*.bmp;*.ico)|*.bmp;*.ico"• FilterIndex: Indica el índice (con respecto a la lista de tipos) del filtro por defecto. Seempiezan a numerar por "1".• InitDir: Conti<strong>en</strong>e el nombre del directorio por defecto. Si no se especifica, se utiliza eldirectorio actual.• Flags: Esta propiedad puede tomar muchos valores con objeto de fijar los detallesconcretos de este control (por ejemplo, abrir un fichero <strong>en</strong> modo read only, avisar antes deescribir sobre un fichero ya exist<strong>en</strong>te, etc.). Estos valores están definidos por constantes de<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> cuyos nombres empiezan con las letras cdl. Para más información <strong>en</strong> elHelp de Common Dialog Control buscar Properties, Flags Properties (Op<strong>en</strong>, Save AsDialogs). Por ejemplo, el valor definido por la constante cdlOFNOverwritePrompt haceque antes de escribir <strong>en</strong> un fichero ya exist<strong>en</strong>te se pida confirmación al usuario. Paraestablecer varias opciones a la vez se le a<strong>si</strong>gna a Flags la suma de las constantescorrespondi<strong>en</strong>tes. Las distintas constantes disponibles se pued<strong>en</strong> <strong>en</strong>contrar <strong>en</strong> el Helpbuscando Constants/CommonDialog Control.4.4.2 Print Dialog ControlLas propiedades más importantes de este control son:• Copies: Determina el número de copias a realizar por la impresora.• FromPage: Selecciona el número de página a partir del cual comi<strong>en</strong>za el rango deimpre<strong>si</strong>ón.• ToPage: Selecciona el número de página hasta la cual llega el rango de impre<strong>si</strong>ón.• PrinterDefault: Cuando es True se imprime <strong>en</strong> el objeto <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> Printer. Además lasopciones actuales de impre<strong>si</strong>ón que se cambi<strong>en</strong> serán a<strong>si</strong>gnadas <strong>como</strong> las opciones deimpre<strong>si</strong>ón por defecto del <strong>si</strong>stema.• Flags: Ver con ayuda del Help los po<strong>si</strong>bles valores de esta propiedad.


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 614.4.3 Font Dialog ControlLas propiedades más importantes de este control son:• Color: Color de impre<strong>si</strong>ón. Para usar esta propiedad hace falta establecer la propiedadFlags al valor de la constante cdlCFEffects.• FontBold, FontItalic, FontStrikethru, FontUnderline: Devuelve o a<strong>si</strong>gna los valores delos estilos de la fu<strong>en</strong>te actual.• FontName: Devuelve o a<strong>si</strong>gna el nombre de la fu<strong>en</strong>te <strong>en</strong> uso.• FontSize: Devuelve o a<strong>si</strong>gna el tamaño de la fu<strong>en</strong>te <strong>en</strong> uso.• Min y Max: A<strong>si</strong>gna o lee los valores del tamaño de fu<strong>en</strong>te mínimo y máximorespectivam<strong>en</strong>te que aparecerán <strong>en</strong> la lista de selección de tamaños de la fu<strong>en</strong>te.• Flags: Indica <strong>si</strong> los tipos de letra que se van a mostrar son los de la pantalla(cdlCFScre<strong>en</strong>Fonts), los de la impresora (cdlCFPrinterFonts) o ambos (cdlCFBoth). Conla constante cdlCFEffects se puede indicar que se permite cambiar efectos <strong>como</strong> el color,subrayado y cruzado con una línea. Si Flags vale 0 da un error <strong>en</strong> tiempo de ejecucióninndicando que no hay fonts instaladas.4.4.4 Color Dialog ControlLas propiedades más importantes de este control son:• Color: Devuelve o a<strong>si</strong>gna el valor del color actual.• Flags: Ver con ayuda del Help los po<strong>si</strong>bles valores de esta propiedad. Por ejemplo, con elvalor cdlCCFullOp<strong>en</strong> muestra el cuadro de diálogo completo, mi<strong>en</strong>tras que el valorcdlCCPrev<strong>en</strong>tFullOp<strong>en</strong> muestra sólo los colores predefinidos, impidi<strong>en</strong>do definir otrosnuevos. Con el valor cdlCCRGBInit se establece el color inicial para el cuadro de diálogo.4.5 FORMULARIOS MÚLTIPLESUn programa puede cont<strong>en</strong>er más de un formulario. De hecho, habitualm<strong>en</strong>te los programasconti<strong>en</strong><strong>en</strong> múltiples formularios. Recuérdese que el formulario es la v<strong>en</strong>tana de máximo nivel <strong>en</strong> laque aparec<strong>en</strong> los distintos controles.Sin embargo, un programa <strong>si</strong>empre debe t<strong>en</strong>er un formulario principal, que es el que apareceal arrancar el programa. Se puede indicar cuál debe ser el formulario principal <strong>en</strong> el m<strong>en</strong>úProject/Project Properties, <strong>en</strong> la l<strong>en</strong>güeta G<strong>en</strong>eral, <strong>en</strong> la sección Startup Form. Por defecto, elprograma con<strong>si</strong>dera <strong>como</strong> formulario principal el primero que se haya creado. El resto deformularios que se incluyan <strong>en</strong> el programa serán cargados <strong>en</strong> su mom<strong>en</strong>to, a lo largo de laejecución del programa.Para añadir <strong>en</strong> tiempo de diseño nuevos formularios al programa, hay que acudir al m<strong>en</strong>úProject/Add Form. La forma de cargar y descargar estos formularios se ha explicado conanterioridad. Es importante <strong>si</strong>n embargo recordar que convi<strong>en</strong>e descargar aquellos sub-formulariosque ya no sean de utilidad, ya que así se ahorran recursos al <strong>si</strong>stema.Para activar <strong>en</strong> tiempo de ejecución un formulario distinto del inicial (o del que esté activo <strong>en</strong>ese mom<strong>en</strong>to), se utiliza el método Show (frmName.Show). El método Hide oculta el formulario,pero lo deja cargado; el método Activate lo vuelve a mostrar. El método Unload elimina loselem<strong>en</strong>tos gráficos del formulario, pero no las variables y el código. El método Unload Me descarga


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 62el propio formulario que lo llama. Para eliminar completam<strong>en</strong>te un formulario se puede utilizar elcomando:Set frmName = NOTHINGque llama al ev<strong>en</strong>to Terminate (hay que utilizar también los métodos Hide o Unload para quedesaparezca de la pantalla).Para referirse desde un formulario a los objetos y variables de otro formulario se utiliza eloperador punto (frmName.Object.Property).4.5.1 Apertura de controles <strong>en</strong> forma modalEn ciertas oca<strong>si</strong>ones se desea que el programa no realice ninguna acción hasta que el usuario cierreuna v<strong>en</strong>tana o formulario <strong>en</strong> la que se le pregunta algo o <strong>en</strong> la que ti<strong>en</strong>e que tomar alguna deci<strong>si</strong>ón.En esos casos, al utilizar el método Show, es necesario utilizar el argum<strong>en</strong>to Style con valor 1. Aesto se le llama mostrar una v<strong>en</strong>tana <strong>en</strong> forma modal. Esto quiere decir que no se permitirá alusuario hacer activa ninguna pantalla hasta que el usuario cierre esa v<strong>en</strong>tana modal. Esto se haceasí:o bi<strong>en</strong>,frmName.Show 1frmName.Show vbModal4.5.2 Formularios MDI (Multiple Docum<strong>en</strong>t Interface)En algunos casos puede serinteresante establecer una jerarquía<strong>en</strong>tre las v<strong>en</strong>tanas o formulariosque van apareci<strong>en</strong>do suce<strong>si</strong>vam<strong>en</strong>te<strong>en</strong> la pantalla del ord<strong>en</strong>ador,de tal manera que al cerrar una quese haya establecido <strong>como</strong> principal,se cierr<strong>en</strong> también todas lasque se han abierto desde ella yd<strong>en</strong>tro de ella. De esta forma unamisma aplicación puede t<strong>en</strong>ervarios docum<strong>en</strong>tos abiertos, uno <strong>en</strong>cada v<strong>en</strong>tana hija. Así trabajan porejemplo Word y Excel, que pued<strong>en</strong>Figura 4.5. Formularios MDI (Multiple Docum<strong>en</strong>t Interface).t<strong>en</strong>er varios docum<strong>en</strong>tos abiertosd<strong>en</strong>tro de la v<strong>en</strong>tana principal de la aplicación. En el mundo de las Windows de Microsoft a esto sellama MDI (Multiple Docum<strong>en</strong>t Interface). La Figura 4.5 muestra un ejemplo de formulario MDI.En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> estos formularios que ti<strong>en</strong><strong>en</strong> sub-formularios hijos se conoc<strong>en</strong> <strong>como</strong>MDIForms. Los formularios MDI se crean desde el m<strong>en</strong>ú de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> con el comandoProject/Add MDI Form. En una aplicación sólo puede haber un formulario MDI, pero éste puedet<strong>en</strong>er varios hijos. Si se quiere que un formulario sea Child, debe t<strong>en</strong>er su propiedad MDIChild<strong>como</strong> True.Si al iniciar una aplicación el formulario que se carga <strong>en</strong> primer lugar es un formulario Child,el formulario MDI se carga al mismo tiempo. Al cerrar un formulario MDIForm se cierran todossus formularios Child; por ejemplo, al cerrar Word también se cierran todos los docum<strong>en</strong>tos que


Capítulo 4: Ev<strong>en</strong>tos, Propiedades y Controles página 63<strong>estuviera</strong>n abiertos. Los formularios Child se minimizan y maximizan d<strong>en</strong>tro de los límites delformulario MDI. Cuando están maximizados, su Caption aparece junto al Caption del formularioMDI. Los formularios Child no ti<strong>en</strong><strong>en</strong> m<strong>en</strong>ús propios, <strong>si</strong>no que sus m<strong>en</strong>ús aparec<strong>en</strong> <strong>en</strong> la barra dem<strong>en</strong>ús del formulario MDI.En una aplicación con un formulario MDI y uno o más formularios Child, puede haber otrosformularios que no sean Child y que se abr<strong>en</strong> fuera de los límites del formulario MDI cuando sonrequeridos.4.6 ARRAYS DE CONTROLESUn array de controles esta formado por controles del mismo tipo que compart<strong>en</strong> el nombre y losprocedimi<strong>en</strong>tos o funciones para gestionar los ev<strong>en</strong>tos. Para id<strong>en</strong>tificar a cada uno de los controlespert<strong>en</strong>eci<strong>en</strong>tes al array se utiliza Index o índice, que es una propiedad más de cada control.Suponi<strong>en</strong>do que el <strong>si</strong>stema t<strong>en</strong>ga memoria sufici<strong>en</strong>te un array <strong>en</strong> Windows 95/98/NT podría llegar at<strong>en</strong>er hasta 32767 elem<strong>en</strong>tos.La utilidad principal de los arrays se pres<strong>en</strong>ta <strong>en</strong> aquellos casos <strong>en</strong> los que el programa deberesponder de forma semejante a un mismo ev<strong>en</strong>to sobre varios controles del mismo tipo. Losejemplos más claros son los botones de opción y los m<strong>en</strong>ús. En estos casos el programa responde demanera semejante indep<strong>en</strong>di<strong>en</strong>tem<strong>en</strong>te de cuál es la opción seleccionada. Los arrays de controlescompart<strong>en</strong> código, lo cual quiere decir que sólo hay que programar una función para responder a unev<strong>en</strong>to de un determinado tipo sobre cualquier control del array. Las funciones que gestionan losev<strong>en</strong>tos de un array ti<strong>en</strong><strong>en</strong> <strong>si</strong>empre u argum<strong>en</strong>to adicional del tipo Index As Integer que indica quécontrol del array ha recibido el ev<strong>en</strong>to.Una opción avanzada de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite crear objetos <strong>en</strong> tiempo de ejecución,<strong>si</strong>empre que sean elem<strong>en</strong>tos de un array ya exist<strong>en</strong>te, con la instrucción Load. De forma análoga sepued<strong>en</strong> destruir con Unload.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 645. MENÚSEntre las capacidades de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> no podíafaltar la de construir m<strong>en</strong>ús con gran facilidad. Sinembargo, hay algunas difer<strong>en</strong>cias respecto al modo elque se construy<strong>en</strong> los controles. Para crear m<strong>en</strong>ús<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> dispone de una herrami<strong>en</strong>ta especial que seactiva mediante el comando M<strong>en</strong>u Editor del m<strong>en</strong>úTools. El cuadro de diálogo que se abre se nuestra <strong>en</strong> laFigura 5.1. Más adelante se verá cómo se utiliza estaherrami<strong>en</strong>ta; antes, convi<strong>en</strong>e recordar brevem<strong>en</strong>te lascaracterísticas más importantes de los m<strong>en</strong>ús deWindows 95/98/NT.Los m<strong>en</strong>ús pres<strong>en</strong>tan sobre los demás controles lav<strong>en</strong>taja de que ocupan m<strong>en</strong>os espacio <strong>en</strong> pantalla, peroti<strong>en</strong><strong>en</strong> el inconv<strong>en</strong>i<strong>en</strong>te de que sus po<strong>si</strong>bilidades noestán a la vista más que cuando se despliegan.Figura 5.1. Editor de m<strong>en</strong>ús de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>.5.1 INTRODUCCIÓN A LAS POSIBILIDADES DE LOSMENÚSLa mayor parte de las aplicaciones de Windows 95utilizan m<strong>en</strong>ús. Aunque todo el mundo estáfamiliarizado con sus funciones más bá<strong>si</strong>cas, convi<strong>en</strong>ever algunas po<strong>si</strong>bilidades m<strong>en</strong>os usuales. Se utilizaránpara ello unas aplicaciones tan conocidas <strong>como</strong> Word yExcel.La Figura 5.2 recoge el aspecto del m<strong>en</strong>ú View deWord 97, <strong>en</strong> el que convi<strong>en</strong>e destacar las <strong>si</strong>gui<strong>en</strong>tescaracterísticas:1. Lo primero que llama la at<strong>en</strong>ción es que los m<strong>en</strong>úsaparec<strong>en</strong> divididos <strong>en</strong> grupos de opcionesseparados por líneas horizontales.Figura 5.2. El m<strong>en</strong>ú View de Word 97.2. Algunos items <strong>como</strong> Page Layout ti<strong>en</strong><strong>en</strong> un iconoresaltado a su izquierda. Esto quiere decir que eseítem es la opción elegida <strong>en</strong>tre los cuatro items desu grupo. En este s<strong>en</strong>tido los m<strong>en</strong>ús se parec<strong>en</strong> alos controles OptionButton. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> nopermite hacer esto directam<strong>en</strong>te, pero lo puede<strong>si</strong>mular.3. Otros items <strong>como</strong> Ruler ti<strong>en</strong><strong>en</strong> una marca deselección a su izquierda. En este caso el m<strong>en</strong>úFigura 5.3. El m<strong>en</strong>ú Format/Sheet de Excel 97.realiza la función de las cajas de selección (CheckBox).4. Todas las opciones del m<strong>en</strong>ú ti<strong>en</strong><strong>en</strong> una letra subrayada. La finalidad es poder desplegar yactivar los m<strong>en</strong>ús desde teclado, <strong>si</strong>n ayuda del ratón (con Alt y la letra subrayada).


Capítulo 5: M<strong>en</strong>ús página 655. También se observa que el ítem Comm<strong>en</strong>ts aparece <strong>en</strong> gris claro. Esto quiere decir que <strong>en</strong> estemom<strong>en</strong>to no está activo y por tanto no es seleccionable.6. Otros items <strong>como</strong> Toolbars están seguidos por un pequeño triángulo. Eso quiere decir queexiste un m<strong>en</strong>ú secundario con más opciones. Otros items <strong>como</strong> Zoom aparec<strong>en</strong> seguidos porpuntos susp<strong>en</strong><strong>si</strong>vos (...). Este es un conv<strong>en</strong>io utilizado para indicar que eligi<strong>en</strong>do esa opción seabrirá un cuadro de diálogo <strong>en</strong> el que habrá que tomar otras deci<strong>si</strong>ones.Por lo que respecta al m<strong>en</strong>ú de Excel 97 que aparece <strong>en</strong> la Figura 5.3 la característica má<strong>si</strong>mportante es que ti<strong>en</strong>e sub-m<strong>en</strong>ús (señalados mediante un pequeño triángulo a su derecha), que seabr<strong>en</strong> al colocar el cursor sobre el ítem correspondi<strong>en</strong>te. Estos m<strong>en</strong>ús se suel<strong>en</strong> llamar m<strong>en</strong>ús <strong>en</strong>cascada, y son muy frecu<strong>en</strong>tes <strong>en</strong> Windows 95/98/NT.Otra característica de los m<strong>en</strong>ús, que no aparece <strong>en</strong> la Figura 5.2 ni <strong>en</strong> la Figura 5.3, es lapo<strong>si</strong>bilidad de definir combinaciones de teclas que realizan la misma función que una opción delm<strong>en</strong>ú. Por ejemplo, <strong>en</strong> muchas aplicaciones Ctrl+C equivale a Edit/Copy y Ctrl+V a Edit/Paste.Estas combinaciones de teclas se llaman accesos rápidos (shortcut) y hay que distinguirlas deacceder a los m<strong>en</strong>ús mediante la tecla Alt y las letras subrayadas de los nombres.5.2 EL EDITOR DE MENÚS (MENU EDITOR)En la Figura 5.4 se vuelve a recoger -amayor tamaño y con algunoselem<strong>en</strong>tos ya definidos- el editor dem<strong>en</strong>ús mostrado <strong>en</strong> la Figura 5.1, quese abre con Tools/M<strong>en</strong>u Editor oclicando <strong>en</strong> el botón correspondi<strong>en</strong>tede la barra de herrami<strong>en</strong>tas.Se llama título a cada elem<strong>en</strong>toque aparece <strong>en</strong> la barra de m<strong>en</strong>ús ylínea o ítem a cada elem<strong>en</strong>to queaparece al desplegarse un título. Paraintroducir un nuevo título <strong>en</strong> la barrade m<strong>en</strong>ús hay que definir, <strong>en</strong> la caja detexto Caption de la Figura 5.4, elnombre con el que se quiere queaparezca. Si se desea acceder a dichotítulo mediante teclado (Alt+letra), laletra que se desea utilizar deberá irprecedida por el carácter (&). Además,y al igual que todos los controles de<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>, convi<strong>en</strong>e que elFigura 5.4. Definición de m<strong>en</strong>ús con M<strong>en</strong>u Editor.título t<strong>en</strong>ga un nombre (caja de textoName) para que se pueda acceder a él desde programa. Los nombres de los títulos de los m<strong>en</strong>ússuel<strong>en</strong> com<strong>en</strong>zar por las letras mnu, <strong>como</strong> por ejemplo mnuFile, mnuEdit o mnuHelp.En la Figura 5.4 la caja de texto Index hace refer<strong>en</strong>cia a la po<strong>si</strong>bilidad de crear arrays dem<strong>en</strong>ús. Se puede definir también un shortcut <strong>en</strong> la caja de texto correspondi<strong>en</strong>te. En esta figuraaparec<strong>en</strong> cuatro checkButtons (Enabled, Checked, Vi<strong>si</strong>ble y WindowList) con los que se pued<strong>en</strong>especificar algunas propiedades iniciales del m<strong>en</strong>ú, <strong>como</strong> por ejemplo que esté activado o que seavi<strong>si</strong>ble.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 66Se pued<strong>en</strong> introducir items subordinados a un título por mediode la flecha hacia la derecha. Para ello basta definirlos del modohabitual y luego clicar sobre dicha flecha. El resultado es queaparec<strong>en</strong> unos puntos a la izquierda del caption correspondi<strong>en</strong>te. Porejemplo, <strong>en</strong> el m<strong>en</strong>ú definido <strong>en</strong> la Figura 5.4, Exit es una líneasubordinada del m<strong>en</strong>ú File, mi<strong>en</strong>tras que Undo, Repeat, Cut, Copy yPaste son items subordinados del m<strong>en</strong>ú Edit. En este último caso seha introducido una línea de separación <strong>en</strong>tre Repeat y Cut; para ellobasta introducir un ítem más cuyo caption sea el carácter m<strong>en</strong>os (-).Figura 5.5. M<strong>en</strong>ú Edit s<strong>en</strong>cillo.La Figura 5.5 muestra el resultado de ejecutar la aplicacióncuyos m<strong>en</strong>ús están definidos <strong>en</strong> el M<strong>en</strong>u Editor de la Figura 5.4. Obsérvese la línea horizontal deseparación, los shortcuts y las letras subrayadas para poder abrir el m<strong>en</strong>ú desde teclado.Respecto a los nombres de los items, lo habitual es seguir la nom<strong>en</strong>clatura que ya se muestra<strong>en</strong> la Figura 5.4 para Undo: primero se pon<strong>en</strong> las tres letras mnu, y después los nombres del título ydel ítem com<strong>en</strong>zando por mayúscula: mnuEditUndo. Caso que haya m<strong>en</strong>ús <strong>en</strong> cascada, se pon<strong>en</strong>los distintos nombres <strong>si</strong>gui<strong>en</strong>do estas mismas normas. De esta forma <strong>si</strong>empre queda claro a partirdel nombre a qué elem<strong>en</strong>to del m<strong>en</strong>ú se está haci<strong>en</strong>do refer<strong>en</strong>cia.La Figura 5.4 es bastante auto-explicativa respecto a cómo se debe proceder para estructurarun m<strong>en</strong>ú, añadi<strong>en</strong>do, borrando o cambiando de po<strong>si</strong>ción los distintos elem<strong>en</strong>tos. De formaresumida, se pued<strong>en</strong> establecer las <strong>si</strong>gui<strong>en</strong>tes normas g<strong>en</strong>erales:1. Para insertar un título o ítem basta seleccionar la línea por <strong>en</strong>cima de la cual se quiere insertary clicar <strong>en</strong> el botón Insert. Para añadir un nuevo ítem al final de la lista se selecciona el últimoelem<strong>en</strong>to introducido y se clica <strong>en</strong> el botón Next. Para borrar un elem<strong>en</strong>to, se selecciona y seclica <strong>en</strong> el botón Delete.2. Se puede cambiar de po<strong>si</strong>ción un título o ítem seleccionándolo y clicando <strong>en</strong> los botones quemuestran las flechas hacia arriba y hacia abajo. Para convertir un título <strong>en</strong> ítem o para cambiarel nivel de un ítem se selecciona y se utilizan las flechas hacia la derecha y hacia la izquierda.Convi<strong>en</strong>e recordar que los nombres de los items (por ejemplo mnuEditCopy) deb<strong>en</strong> estar<strong>si</strong>empre de acuerdo con su po<strong>si</strong>ción, según las normas explicadas anteriorm<strong>en</strong>te.5.3 AÑADIR CÓDIGO A LOS MENÚSLos items de los m<strong>en</strong>ús admit<strong>en</strong> un único ev<strong>en</strong>to: el ev<strong>en</strong>to click, que con<strong>si</strong>ste <strong>en</strong> ser seleccionadospor medio del ratón o del teclado. Para añadir el código correspondi<strong>en</strong>te basta elegir <strong>en</strong> el m<strong>en</strong>ú,estando <strong>en</strong> modo diseño, el ítem correspondi<strong>en</strong>te para que se abra la v<strong>en</strong>tana de código <strong>en</strong> elprocedimi<strong>en</strong>to ligado a ese ev<strong>en</strong>to. También puede buscarse directam<strong>en</strong>te el objeto y el ev<strong>en</strong>tocorrespondi<strong>en</strong>te <strong>en</strong> las listas desplegables de la v<strong>en</strong>tana de código.En oca<strong>si</strong>ones habrá que cambiar las propiedades checked, active y vi<strong>si</strong>ble desde losprocedimi<strong>en</strong>tos. A estas propiedades se accede del modo habitual, con el nombre del ítem y eloperador punto (.)5.4 ARRAYS DE MENÚSDe la misma manera que pued<strong>en</strong> definirse arrays de controles, también pued<strong>en</strong> definirse arrays deitems (y de títulos) <strong>en</strong> un m<strong>en</strong>ú. La v<strong>en</strong>taja de definir arrays de items es que basta definir un únicoprocedimi<strong>en</strong>to que se haga cargo del ev<strong>en</strong>to click de todos los items del array. Este procedimi<strong>en</strong>to


Capítulo 5: M<strong>en</strong>ús página 67recibe <strong>como</strong> parámetro la variable <strong>en</strong>tera Index, que indica que ítem del array ha <strong>si</strong>do seleccionadopor el usuario. D<strong>en</strong>tro de este procedimi<strong>en</strong>to se podrá utilizar por ejemplo la s<strong>en</strong>t<strong>en</strong>cia Select Casepara tratar de forma adecuada cada uno de los casos.5.5 EJEMPLO: MENÚ PARA DETERMINAR LAS CARACTERÍSTICAS DE UN TEXTOLa Figura 5.6 muestra un formulario queconti<strong>en</strong>e una caja de texto con una frase(“<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> es el l<strong>en</strong>guaje de programaciónque hace más fácil el desarrollar aplicacionespara Windows 95”) a la que se puede darformato desde el m<strong>en</strong>ú Text. El m<strong>en</strong>ú Textti<strong>en</strong>e tres subm<strong>en</strong>ús: Font, Size y Style. Elm<strong>en</strong>ú File sólo ti<strong>en</strong>e la opción Exit, quetermina la ejecución.El sub-m<strong>en</strong>ú Font ti<strong>en</strong>e tres opciones:Arial, Courier New y Times New Roman. Elsub-m<strong>en</strong>ú Size ti<strong>en</strong>e 5 opciones: 10, 11, 12, 13,y 14. El sub-m<strong>en</strong>ú Style ti<strong>en</strong>e 2 opciones: Bold Figura 5.6. Caja de texto con formatos desde m<strong>en</strong>ú.e Italic. Los tipos de letra y los tamaños deb<strong>en</strong>actuar <strong>como</strong> los Option Buttons: sólo una opción puede estar seleccionada para el texto de la caja.Sin embargo, los estilos Bold e Italic actúan <strong>como</strong> Checked Boxes: el texto puede ser a la vez Bolde Italic, y puede no ser ninguna de las dos cosas.Para los tamaños de letra se debe utilizar un array de m<strong>en</strong>ús con cinco elem<strong>en</strong>tos (propiedadIndex de 0 a 4). Se deja al usuario que ponga los nombres que desee a los controles de la Figura 5.6,o que utilice los del código del programa que se muestra a continuación. Nótese que con los m<strong>en</strong>úsque se comportan <strong>como</strong> Option Buttons la propiedad Checked se pone a False <strong>en</strong> todas las opcionesantes de poner a True la que el usuario ha elegido. Con el m<strong>en</strong>ú que se comporta <strong>como</strong> CheckedBox <strong>si</strong>mplem<strong>en</strong>te se cambia la propiedad Checked de True a False o viceversa, cuando el usuario laelige. El código se muestra a continuación:Option ExplicitPrivate Sub Form_Load()txtBox.Text = "<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> es el l<strong>en</strong>guaje de programación " & _"que hace más fácil el desarrollar aplicaciones para Windows 95"txtBox.Font.Name = "Arial"mnuTextFontArial.Checked = TruetxtBox.Font.Size = 10mnuTextSizeA(0).Checked = TruetxtBox.Font.Bold = FalsetxtBox.Font.Italic = FalseEnd SubPrivate Sub mnuFileExit_Click()EndEnd SubPrivate Sub mnuTextFontArial_Click()mnuTextFontCou.Checked = FalsemnuTextFontTimes.Checked = FalsetxtBox.Font.Name = "Arial"mnuTextFontArial.Checked = TrueEnd Sub


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 68Private Sub mnuTextFontCou_Click()mnuTextFontArial.Checked = FalsemnuTextFontTimes.Checked = FalsetxtBox.Font.Name = "Courier New"mnuTextFontCou.Checked = TrueEnd SubPrivate Sub mnuTextFontTimes_Click()mnuTextFontArial.Checked = FalsemnuTextFontCou.Checked = FalsetxtBox.Font.Name = "Times New Roman"mnuTextFontTimes.Checked = TrueEnd SubPrivate Sub mnuTextSizeA_Click(Index As Integer)Dim i As IntegerFor i = 0 To 4mnuTextSizeA(i).Checked = FalseNext iSelect Case IndexCase 0txtBox.Font.Size = 10Case 1txtBox.Font.Size = 11Case 2txtBox.Font.Size = 12Case 3txtBox.Font.Size = 13Case 4txtBox.Font.Size = 14End SelectmnuTextSizeA(Index).Checked = TrueEnd SubPrivate Sub mnuTextStyleBold_Click()txtBox.Font.Bold = Not txtBox.Font.BoldmnuTextStyleBold.Checked = Not mnuTextStyleBold.CheckedEnd SubPrivate Sub mnuTextStyleItalic_Click()txtBox.Font.Italic = Not txtBox.Font.ItalicmnuTextStyleItalic.Checked = Not mnuTextStyleItalic.CheckedEnd Sub5.6 MENÚS CONTEXTUALES (POPUP MENU)Los m<strong>en</strong>ús contextuales aparec<strong>en</strong> cuando el usuario clica con el botón derecho sobre un elem<strong>en</strong>tode la aplicación. El programa debe reconocer el ev<strong>en</strong>to MouseUp o MouseDown, ver <strong>si</strong> el usuarioha clicado con el botón derecho (argum<strong>en</strong>to Button igual a 2) y llamar al método PopupM<strong>en</strong>u, queti<strong>en</strong>e la <strong>si</strong>gui<strong>en</strong>te forma g<strong>en</strong>eral:PopupM<strong>en</strong>u m<strong>en</strong>uName [,flags[,x[,y]]]donde m<strong>en</strong>uName ee el nombre de un m<strong>en</strong>ú (con al m<strong>en</strong>os un elem<strong>en</strong>to), x e y son las coord<strong>en</strong>adasbase para hacer aparecer el m<strong>en</strong>ú contextual, y flags son unas constantes que determinan más <strong>en</strong>concreto dónde y cómo se muestra el m<strong>en</strong>ú. Las constantes que determinan dónde aparece el m<strong>en</strong>úson: vbPopupM<strong>en</strong>uLeftAlign (default), vbPopupM<strong>en</strong>uC<strong>en</strong>terAlign y vbPopupM<strong>en</strong>uRightAlign. Porotra parte vbPopupM<strong>en</strong>uLeftButton (default) y vbPopupM<strong>en</strong>uRightButton determinan <strong>si</strong> el comandose activa con el botón izquierdo o con cualquiera de los dos botones. Las constantes se combina conel operador Or. El nombre del m<strong>en</strong>ú que aparece <strong>en</strong> el método PopupM<strong>en</strong>u debe haber <strong>si</strong>do creadocon el M<strong>en</strong>u Editor, aunque puede t<strong>en</strong>er la propiedad Vi<strong>si</strong>ble a False, <strong>si</strong> no se desea que se vea.


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 696. GRÁFICOS EN VISUAL BASIC <strong>6.0</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>, además de hacer fácil la construcción de interfaces gráficas de usuario, ti<strong>en</strong>etambién grandes po<strong>si</strong>bilidades gráficas <strong>en</strong> lo que se refiere a dibujo de líneas y formas geométricas,así <strong>como</strong> <strong>en</strong> lo refer<strong>en</strong>te a la introducción de gráficos y figuras realizados con otras aplicaciones. Eneste capítulo se pres<strong>en</strong>tarán brevem<strong>en</strong>te las po<strong>si</strong>bilidades gráficas más importantes de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong><strong>6.0</strong>.6.1 TRATAMIENTO DEL COLORAntes de ver cómo se dibuja <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se verá cómo se defin<strong>en</strong> los colores. Al igual que<strong>en</strong> tantas aplicaciones informáticas, los colores de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> se defin<strong>en</strong> por medio de lascompon<strong>en</strong>tes fundam<strong>en</strong>tales RGB (Red, Gre<strong>en</strong> and Blue). La int<strong>en</strong><strong>si</strong>dad de cada color fundam<strong>en</strong>talse define con un byte, es decir con un número <strong>en</strong>tero <strong>en</strong>tre 0 y 255. Se utilizan pues tres bytes paradefinir los tres colores. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> utiliza un <strong>en</strong>tero long (32 bits, 4 bytes) para guardar uncolor, lo cual quiere decir que existe un byte adicional donde se podrá guardar alguna otrainformación (ver Apartado 6.1.2).6.1.1 Repres<strong>en</strong>tación hexadecimal de los coloresPara los números <strong>en</strong>teros <strong>en</strong>tre 0 y 255 se utilizan dosdígitos hexadecimales. Con esta notación el cero es el“00” y el 255 el “FF”. El número que indica el color vaprecedido por el carácter “&” y la letra “H”. Así, elcolor verde se define <strong>en</strong> la forma: &H00FF00. Con estanotación es po<strong>si</strong>ble prescindir de los ceros <strong>si</strong>tuados a laizquierda. Por ejemplo, el color rojo se puede escribir<strong>como</strong> &H0000FF y <strong>como</strong> &HFF.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone también de nombrespara los colores fundam<strong>en</strong>tales y los que soncombinación de los colores fundam<strong>en</strong>tales, segúnpuede verse <strong>en</strong> la Tabla 6.1.Nombre Código HEX ColorvbBlack &H000000 NegrovbRed &H0000FF Rojo.vbGre<strong>en</strong> &H00FF00 Verde.vbYellow &H00FFFF Amarillo.vbBlue &HFF0000 Azul.vbMag<strong>en</strong>ta &HFF00FF Mag<strong>en</strong>ta.vbCyan &HFFFF00 Cyan.vbWhite &HFFFFFF Blanco.Tabla 6.1. Nombres de colores.6.1.2 Acceso a los colores del <strong>si</strong>stemaEl cuarto byte (<strong>en</strong> el <strong>en</strong>tero long que conti<strong>en</strong>e el color) puede utilizarse para hacer refer<strong>en</strong>cia a loscolores del <strong>si</strong>stema. Los colores del <strong>si</strong>stema son aquellos colores con los que Windows 95/98/NTrepres<strong>en</strong>ta las v<strong>en</strong>tanas y sus bordes, las barras de desplazami<strong>en</strong>to, etc. Dichos colores se elig<strong>en</strong> <strong>en</strong>el panel de control Display/Appearance, y <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite acceder a ellos a través de sunombre o de su valor hexadecimal, que empieza por “&H8” y utiliza el cuarto byte. La Tabla 6.2muestra algunos de estos valores. Para una descripción completa buscar Color Constants <strong>en</strong> el Helpde <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 70Nombre Valor DescripciónvbScrollBars &H80000000 Scroll bar color.vbDesktop &H80000001 Desktop color.vbActiveTitleBar &H80000002 Color of the title bar for the active window.vbInactiveTitleBar &H80000003 Color of the title bar for the inactive window.vbM<strong>en</strong>uBar &H80000004 M<strong>en</strong>u background color.vbWindowBackground &H80000005 Window background color.vbWindowFrame &H80000006 Window frame color.vbM<strong>en</strong>uText &H80000007 Color of text on m<strong>en</strong>us.vbWindowText &H80000008 Color of text in windows.vbTitleBarText &H80000009 Color of text in caption, <strong>si</strong>ze box, and scroll arrow.... ... ...Tabla 6.2. Colores del <strong>si</strong>stema.6.1.3 Función RGBEsta función devuelve un número que repres<strong>en</strong>ta un color a partir de tres argum<strong>en</strong>tos <strong>en</strong>teros <strong>en</strong>tre 0y 255, que son sus compon<strong>en</strong>tes RGB. Como ejemplo de uso:form1.BackColor = RGB(127, 127, 64)Si alguno de los argum<strong>en</strong>tos ti<strong>en</strong>e un valor mayor que 255, se toma <strong>como</strong> 255.6.1.4 Paleta de coloresElegir adecuadam<strong>en</strong>te un color a partir de sus compon<strong>en</strong>tesRGB no es una tarea fácil. Por eso <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>proporciona una paleta de 64 colores predefinidos, 16 de loscuales pued<strong>en</strong> ser definidos a medida por el usuario. LaFigura 6.1 muestra la paleta de colores, que aparece conView/Color Palette.La Figura 6.2 muestra el cuadro de diálogo que se abreal pulsar el botón Define Colors... <strong>en</strong> la parte inferior dcha.de la Figura 6.1. Para elegir un color se pued<strong>en</strong> introducirdirectam<strong>en</strong>te los valores RGB, pero también se puede clicar<strong>en</strong> el mapa de colores de la parte superior izda. y luegomover el cursor de la parte superior dcha. Finalm<strong>en</strong>te,clicando <strong>en</strong> el botón Add Color. El color seleccionado seañade <strong>en</strong> la parte inferior de la paleta de colores (Figura6.1).Por supuesto es necesario t<strong>en</strong>er <strong>en</strong> cu<strong>en</strong>ta el númerode colores soportado por la tarjeta gráfica del PC <strong>en</strong> el quese esté trabajando. Lo más frecu<strong>en</strong>te es que los PCs esténconfigurados para soportar 256 colores (8 bits por pixel),65.536 colores (16 bits por pixel) o 16.777.216 colores (24bits por pixel). Si la tarjeta gráfica soporta 65.536 colores seelige el color más cercano al que el usuario ha queridoFigura 6.1. Paleta de colores.Figura 6.2. Creación de colores a medida.


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 71repres<strong>en</strong>tar, con la función RGB por ejemplo. Si la tarjeta gráfica soporta sólo 256 colores se utilizael dithering, que con<strong>si</strong>ste <strong>en</strong> mezclar pixels de distintos colores con objeto de obt<strong>en</strong>er un efecto lomás parecido po<strong>si</strong>ble al color solicitado.Una vez añadidos los colores a la paleta, al clicar <strong>en</strong> el pequeñotriángulo que aparece <strong>en</strong> cualquier propiedad de color <strong>en</strong> la v<strong>en</strong>tanaProperties aparecerán una v<strong>en</strong>tana donde es po<strong>si</strong>ble elegir <strong>en</strong>tre loscolores de la paleta y los d<strong>en</strong>ominados colores del <strong>si</strong>stema (Figura6.3).El Ejemplo 1.5.4 (Colores RGB), mostrado <strong>en</strong> la página 11 deeste manual, es un bu<strong>en</strong> ejemplo de la utilización de los colores <strong>en</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.6.2 FORMATOS GRÁFICOSFigura 6.3. Colores de <strong>si</strong>stemaEn un formulario de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> -y <strong>en</strong> los controles Image y PictureBox- es po<strong>si</strong>ble insertargráficos, tanto de tipo bitmap (los producidos por aplicaciones <strong>como</strong> Paint, Paintbrush, Paint ShopPro, etc.), <strong>como</strong> de tipo vectorial (los producidos por las herrami<strong>en</strong>tas gráficas de Word yPowerPoint).<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> admite varios formatos de ficheros gráficos: los ficheros *.bmp y *.ico paralos gráficos de tipo bitmap, los ficheros *.wmf (Windows Meta File) y *.emf (Enhanced Meta File)para los gráficos de tipo vectorial y *.jpg (JPEG o Joint Photographic Experts Group) y *.gif(Graphic Interchange Format). Los ficheros *.ico son ficheros bitmap de pequeño tamaño (32 por32) destinados a cont<strong>en</strong>er iconos. Los ficheros JPEG y GIF son formatos gráficos comprimidos quesoportan respectivam<strong>en</strong>te color de 24 bit (~16 millones de colores) y 8 bit (256 colores). Ambosformatos son los utilizados <strong>en</strong> Internet para mostrar imág<strong>en</strong>es.Si se desea insertar ficheros gráficos que estén <strong>en</strong> otros formatos, habrá que convertirlospreviam<strong>en</strong>te a uno de estos formatos usando el programa adecuado.6.3 CONTROLES GRÁFICOS<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de varios controles con los que insertar gráficos <strong>en</strong> un formulario.Algunos ti<strong>en</strong><strong>en</strong> más po<strong>si</strong>bilidades que otros y es necesario conocerlos bi<strong>en</strong>. A continuación se veránlos controles Line, Shape, Image y PictureBox.6.3.1 Control LineEs el control gráfico más elem<strong>en</strong>tal, ya que carece de propiedades <strong>como</strong> Text, Caption y Value.Además no reconoce ningún ev<strong>en</strong>to, por lo que su mi<strong>si</strong>ón es ca<strong>si</strong> exclu<strong>si</strong>vam<strong>en</strong>te decorativa.El control Line permite dibujar líneas <strong>en</strong> un formulario o <strong>en</strong> un control PictureBox. Laspropiedades más importantes son las coord<strong>en</strong>adas de los puntos extremos (X1, Y1, X2 e Y2), laanchura <strong>en</strong> pixels (BorderWidth), el estilo de la línea (BorderStyle) -continua, a trazos, etc.- quesólo está activo cuando la anchura es 1 pixel, el color (BorderColor) y el nombre (Name). La líneapuede estar vi<strong>si</strong>ble o no (Vi<strong>si</strong>ble), y existe la propiedad Index, que permite crear arrays de líneas.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 726.3.2 Control ShapeEste control es <strong>en</strong> muchos aspectos <strong>si</strong>milar al control Line: tampoco ti<strong>en</strong>e las propiedades text,Caption y Value, ni reconoce ev<strong>en</strong>tos. Se difer<strong>en</strong>cia <strong>en</strong> que admite formas geométricas máscomplejas, que vi<strong>en</strong><strong>en</strong> definidas por la propiedad Shape, que admite los valores <strong>si</strong>gui<strong>en</strong>tes:cuadrado (Square), rectángulo (Rectangle), círculo (Circle), elipse (Oval), cuadrado redondeado(Rounded Square) y rectángulo redondeado (Rounded Rectangle).Además de las propiedades correspondi<strong>en</strong>tes al tamaño y po<strong>si</strong>ción, las propiedades má<strong>si</strong>nteresantes del control Shape son las <strong>si</strong>gui<strong>en</strong>tes: BackColor, BackStyle, BorderColor, BorderStyle,BorderWidth, FillColor, FillStyle, DrawMode. Un control Shape puede estar vi<strong>si</strong>ble o no (Vi<strong>si</strong>ble),y existe la propiedad Index, que permite crear arrays de Shapes.6.3.3 Ejemplo 6.1: Uso de los controles Line y ShapeLa Figura 6.4 muestra un formulario <strong>en</strong> el que se handibujado tres controles Line y dos controles Shape.Las tres líneas se han dibujado con la propiedadBorderWidth=1, pues <strong>si</strong> no la propiedadBorderStyle no surte efecto. La propiedadBorderStyle es 2-Dash para la segunda línea y 3-Dotpara la tercera.Después se han dibujado dos controles Shapellamados shpRect y shpRRec, cuyas propiedadesShape están respectivam<strong>en</strong>te a 0-Rectangle y a4-Rounded Rectangle. La propiedad BackColor estáFigura 6.4. Controles Line y Shape.<strong>en</strong> amarillo para shpRect y <strong>en</strong> blanco para shpRRect.En ambos casos BackStyle está <strong>en</strong> 1-Opaque, pues <strong>si</strong> no el color de fondo no surte efecto. Lapropiedad FillColor (que determina el color de las líneas de rayado) está <strong>en</strong> rojo para shpRect y <strong>en</strong>negro para shpRRect. Finalm<strong>en</strong>te, la propiedad FillStyle que determina el tipo de rayado está <strong>en</strong>5-Downward Diagonal para shpRect y <strong>en</strong> 6-Cross para shpRRect. Como la propiedad DrawModeestá <strong>en</strong> 13-Copy P<strong>en</strong> para ambos controles, shpRRect se superpone sobre shpRect porque ha <strong>si</strong>docreada sobre él con posterioridad.6.3.4 Control ImageEl control Image es un cont<strong>en</strong>edor de gráficos bitmap, iconos, metafile, <strong>en</strong>hanced metafile, GIF yJPEG. Este control admite ya una amplia colección de ev<strong>en</strong>tos, por lo que es ya un control con unpapel mucho más activo que los anteriores.Las propiedades más propias e importantes de este control son las propiedades Picture yStretch. La propiedad Picture <strong>si</strong>rve para relacionar este control con el fichero que conti<strong>en</strong>e elgráfico que se desea repres<strong>en</strong>tar, a través del cuadro de diálogo Load Picture que permite elegir elfichero a insertar. El fichero deberá ser de uno de los tipos admitidos. Según el fichero elegido, lapropiedad Picture t<strong>en</strong>drá uno de los tres valores <strong>si</strong>gui<strong>en</strong>tes: icon (ficheros cur, ico), bitmap (bmp,gif, jpg) o metafile (wmf, emf).La propiedad Stretch indica cómo se comporta el control Image al introducir <strong>en</strong> él elcont<strong>en</strong>ido del fichero gráfico. Por defecto, cuando se crea un control Image arrastrando <strong>en</strong> elformulario con el ratón esta propiedad ti<strong>en</strong>e el valor False. Estando la propiedad Stretch <strong>en</strong> False eltamaño del control se ajusta al tamaño del bitmap o del metafile que se introduce <strong>en</strong> dicho control.


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 73Por el contrario, <strong>si</strong> dicha propiedad está <strong>en</strong> True el gráfico que provi<strong>en</strong>e del fichero se adapta altamaño de control.Se puede tratar de modificar el tamaño del gráfico <strong>en</strong> modo de diseño (con el ratón ocambiando las propiedades de tamaño del control). Si el gráfico es un bitmap y la propiedad Stretchestá <strong>en</strong> False, el tamaño de la imag<strong>en</strong> no cambia aunque cambie el del control (quedando <strong>en</strong> laesquina superior izquierda <strong>si</strong> el control se hace más grande, o quedando parcialm<strong>en</strong>te oculta <strong>si</strong>alguna de las dim<strong>en</strong><strong>si</strong>ones del control se hace más pequeña que la del bitmap. Si la propiedadStretch está <strong>en</strong> True, el bitmap se adapta al tamaño del control y su tamaño se cambia con el deéste. Los gráficos metafile <strong>si</strong>empre se pued<strong>en</strong> cambiar de tamaño <strong>en</strong> modo de diseño, tanto <strong>si</strong>Stretch está <strong>en</strong> True <strong>como</strong> <strong>si</strong> está <strong>en</strong> False.Exist<strong>en</strong> otras formas de cargar un gráfico <strong>en</strong> un control Image, además de utilizar lapropiedad Picture <strong>en</strong> modo de diseño, <strong>como</strong> se ha visto anteriorm<strong>en</strong>te. Una segunda forma,utilizable también <strong>en</strong> modo de diseño, es hacer Copy y Paste a partir de un gráfico cont<strong>en</strong>ido <strong>en</strong> otraaplicación <strong>como</strong> Paint Shop Pro o Excel.En modo de ejecución se puede copiar el cont<strong>en</strong>ido de un control Image <strong>en</strong> otro control delmismo tipo por medio de una s<strong>en</strong>t<strong>en</strong>cia de a<strong>si</strong>gnación <strong>en</strong> la forma:imgCuadro.picture = imgCaja.picturey se puede también cargar una imag<strong>en</strong> de un fichero utilizando el procedimi<strong>en</strong>to LoadPicture, porejemplo <strong>en</strong> la forma <strong>si</strong>gui<strong>en</strong>te (habrá que estar seguro de que existe el fichero):imgCuadro.picture = LoadPicture("G:\graficos\pc.wmf")Aunque el control Image admite algunos ev<strong>en</strong>tos (Click, DblClick, DragDrop, DragOver,MouseUp, MouseDown, MouseMove), sus po<strong>si</strong>bilidades son también limitadas. Por la forma <strong>en</strong> quese dibuja, el control Image no puede estar sobre otro control, <strong>como</strong> por ejemplo un botón (ver loslayers, más adelante <strong>en</strong> este capítulo). Tampoco puede cont<strong>en</strong>er otros controles <strong>en</strong> su interior: sólopuede cont<strong>en</strong>er gráficos. Finalm<strong>en</strong>te, este control no puede obt<strong>en</strong>er el focus y por tanto no puederesponder a acciones desde el teclado. El control PictureBox, que se verá a continuación, resuelveestas limitaciones aunque pres<strong>en</strong>ta la desv<strong>en</strong>taja de ser más l<strong>en</strong>to <strong>en</strong> dibujar que el control Image.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 746.3.5 Control PictureBoxEste es el control gráfico ( ) máspot<strong>en</strong>te y g<strong>en</strong>eral de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong><strong>6.0</strong>. Se trata de una especie deformulario reducido, pues puedecont<strong>en</strong>er imág<strong>en</strong>es y otros tipos decontroles tales <strong>como</strong> botones,shapes, labels, cajas de texto, etc.Con respecto a los bitmaps, elFigura 6.5. Comparación <strong>en</strong>tre Image y PictureBox con bitmaps.control PictureBox se comporta demodo difer<strong>en</strong>te que el controlImage. El control PictureBox noti<strong>en</strong>e propiedad Stretch, con lo cualal cargar un icono o un bitmap<strong>si</strong>empre aparec<strong>en</strong> con su tamañonatural (tal y <strong>como</strong> se puedeobservar <strong>en</strong> la Figura 6.5). Sinembargo el control PictureBox ti<strong>en</strong>eFigura 6.6. Comparación <strong>en</strong>tre Image y PictureBox con metafiles.la propiedad AutoSize, que pordefecto está <strong>en</strong> False. Cuando se carga un bitmap con AutoSize <strong>en</strong> False el gráfico aparece <strong>en</strong> laesquina superior izquierda del control; <strong>si</strong>n embargo, <strong>si</strong> AutoSize está <strong>en</strong> True el control PictureBoxadapta su tamaño al del bitmap que es cargado. La Figura 6.5 muestra los resultados de introducirun icono <strong>en</strong> un control Image (Stretch: False y True) y <strong>en</strong> un control PictureBox (AutoSize: Falsey True).Los gráficos metafile se comportan de un modo difer<strong>en</strong>te, según puede verse <strong>en</strong> la Figura 6.6.En el control Image se cargan con su verdadero tamaño <strong>si</strong> la propiedad Stretch es False, mi<strong>en</strong>trasque se adaptan al tamaño del control <strong>si</strong> dicha propiedad es True. Con el control PictureBox seadaptan al tamaño del control <strong>si</strong> AutoSize es False, mi<strong>en</strong>tras que se cargan con su propio tamaño <strong>si</strong>es AutoSize es True.En el control PictureBox (al igual que <strong>en</strong> los formularios) son importantes las cuatropropiedades relacionadas con el color: BackColor, ForeColor, FillColor y FillStyle. La propiedadBackColor controla el color de fondo del control. La propiedad ForeColor controla el color deltexto que se escribe <strong>en</strong> el control (con el método Print, por ejemplo, <strong>como</strong> luego se verá). Laspropiedades FillColor y FillStyle no afectan directam<strong>en</strong>te al control <strong>si</strong>no a los elem<strong>en</strong>tos gráficosque se dibuj<strong>en</strong> sobre él con métodos tales <strong>como</strong> Line y Circle, que se verán a continuación.FillStyle determina el tipo de rell<strong>en</strong>o o pattern (líneas horizontales, verticales, inclinadas, cruzadas,...), mi<strong>en</strong>tras que FillColor determina el color de estas líneas del rell<strong>en</strong>o.6.4 MÉTODOS GRÁFICOSSólo los formularios y los controles PictureBox pued<strong>en</strong> albergar otros tipos de controles. Ademáses po<strong>si</strong>ble escribir texto y dibujar directam<strong>en</strong>te sobre ellos por medio de ciertos métodos 3 de <strong>Visual</strong><strong>Ba<strong>si</strong>c</strong>. Por defecto estos métodos actúan sobre el formulario activo. Si se desea que actú<strong>en</strong> sobre uncontrol PictureBox hay que precederlos por el nombre del control y el operador punto.3Los métodos son procedimi<strong>en</strong>tos que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> ofrece ya programados. El usuario sólo ti<strong>en</strong>e que llamarlospasándoles los argum<strong>en</strong>tos apropiados.


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 756.4.1 Método PrintEn tiempo de ejecución se puede escribir texto <strong>en</strong> un formulario o <strong>en</strong> un control PictureBox pormedio del método Print. La forma g<strong>en</strong>eral de este método es la <strong>si</strong>gui<strong>en</strong>te:objeto.Print {spc(n)|tab(n)} expre<strong>si</strong>on poschardonde spc(n) es opcional y <strong>si</strong>rve para insertar n caracteres <strong>en</strong> la salida; tab(n) es también opcional y<strong>si</strong>rve para po<strong>si</strong>cionar la salida <strong>en</strong> una po<strong>si</strong>ción absoluta determinada por n con un tabulador. Si tabse utiliza <strong>si</strong>n argum<strong>en</strong>tos lleva al comi<strong>en</strong>zo de la <strong>si</strong>gui<strong>en</strong>te región de salida 4 ; expre<strong>si</strong>on repres<strong>en</strong>tacualquier expre<strong>si</strong>ón cuyo resultado sea un número o una cad<strong>en</strong>a de caracteres. poschar indica dóndese imprimirá el <strong>si</strong>gui<strong>en</strong>te carácter. Si es un punto y coma (;) la impre<strong>si</strong>ón se hace a continuación delúltimo carácter impreso; <strong>si</strong> es un tab(n) o un tab ti<strong>en</strong>e el efecto antes descrito; <strong>si</strong> se omite, laimpre<strong>si</strong>ón comi<strong>en</strong>za <strong>en</strong> una nueva línea.El color, la fu<strong>en</strong>te y el tamaño del texto se toman de las correspondi<strong>en</strong>tes propiedades delformulario o control PictureBox.6.4.2 Dibujo de puntos: método PSetEl método PSet <strong>si</strong>rve para dibujar puntos <strong>en</strong> un formulario o <strong>en</strong> un control PictureBox. Su formag<strong>en</strong>eral es la <strong>si</strong>gui<strong>en</strong>te:donde:objectStep(x, y)object.PSet Step (x, y), colores opcional y repres<strong>en</strong>ta el objeto (form o PictureBox) <strong>en</strong> el que se va a dibujar elpunto. Si se omite, el punto se dibuja <strong>en</strong> el formulario activo (el que ti<strong>en</strong>e el focus).es opcional. Si se introduce las coord<strong>en</strong>adas que le <strong>si</strong>gu<strong>en</strong> son relativas respecto a laspropiedades Curr<strong>en</strong>tX y Curr<strong>en</strong>tY de la PictureBox. Al dibujar un punto, estaspropiedades se actualizan a las coord<strong>en</strong>adas de dicho punto.son las coord<strong>en</strong>adas absolutas o relativas del punto a dibujar (expre<strong>si</strong>ones, variables oconstantes <strong>si</strong>ngle). Tanto las coord<strong>en</strong>adas <strong>como</strong> la coma, <strong>como</strong> los parénte<strong>si</strong>s sonobligatorios. Las unidades dep<strong>en</strong>d<strong>en</strong> de la propiedad ScaleMode del objeto <strong>en</strong> que sedibuja.Color es opcional y es un nombre de color (vbRed, vbBlue, etc.) o un long cont<strong>en</strong>i<strong>en</strong>do elcódigo de color hexadecimal (puede ser el valor de retorno de la función RGB). Si seomite, se utiliza la propiedad ForeColor del objeto <strong>en</strong> el que se dibuja.El tamaño del punto vi<strong>en</strong>e determinado por la propiedad DrawWidth del objeto <strong>en</strong> que sedibuja. Si el tamaño es mayor que uno, el punto se dibuja c<strong>en</strong>trado <strong>en</strong> las coord<strong>en</strong>adas suministradasa PSet. Si se desea eliminar un punto previam<strong>en</strong>te dibujado es necesario volver a pintar ese puntocon el color de fondo del objeto (BackColor).6.4.3 Dibujo de líneas y rectángulos: método LineEl método Line dibuja líneas y -<strong>en</strong> ciertas condiciones- cajas rectangulares de lados horizontales yverticales. Su forma g<strong>en</strong>eral es la <strong>si</strong>gui<strong>en</strong>te:object.Line Step (x1, y1) - Step (x2, y2), color, BF4En <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> se comi<strong>en</strong>za una región de salida cada 14 caracteres, <strong>si</strong> se utiliza un tipo de letra de anchuraconstante. Con otros tipos de letra esta medida es sólo aproximada.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 76donde object, step y color ti<strong>en</strong><strong>en</strong> el mismo <strong>si</strong>gnificado que <strong>en</strong> PSet, y(x1, y1) son opcionales y son las coord<strong>en</strong>adas del punto inicial de la línea. Si se omit<strong>en</strong> la líneacomi<strong>en</strong>za <strong>en</strong> las coord<strong>en</strong>adas definidas por Curr<strong>en</strong>tX y Curr<strong>en</strong>tY.(x2, y2) son obligados y conti<strong>en</strong><strong>en</strong> las coord<strong>en</strong>adas del punto final de la línea.B es un carácter opcional. Si se incluye se dibuja un rectángulo (Box) con los puntos dados<strong>como</strong> extremos de una de sus diagonales.F es también un carácter opcional, que sólo se puede incluir <strong>si</strong> se ha incluido B. Si seincluye, la caja rectangular se rell<strong>en</strong>a (Fill) con el mismo color del contorno. Si se omitela caja se rell<strong>en</strong>a con las propiedades FillColor y FillStyle del objeto <strong>en</strong> el que sedibuja.Después de ejecutarse estemétodo las propiedades Curr<strong>en</strong>tX yCurr<strong>en</strong>tY ti<strong>en</strong><strong>en</strong> el valor del puntofinal de la línea. Es necesariointroducir el carácter (-), aunque seomita el primero de los puntos quedefin<strong>en</strong> la línea.Las propiedades DrawWidth yDrawStyle determinan cómo sedibujan las líneas rectas o curvas <strong>en</strong><strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>. Más <strong>en</strong> concreto, lapropiedad DrawWidth determina elValor Nombre Estilo de línea0 vbSolid continua (valor por defecto)1 vbDash trazos (continua <strong>si</strong> w>1)2 vbDot puntos (continua <strong>si</strong> w>1)3 vbDashDot raya-pto (continua <strong>si</strong> w>1)4 vbDashDotDot raya-pto-pto (continua <strong>si</strong> w>1)5 vbInvi<strong>si</strong>ble transpar<strong>en</strong>te (continua <strong>si</strong> w>1)6 vbIn<strong>si</strong>deSolid continua internaTabla 6.3. Valores de DrawStyle.grosor <strong>en</strong> pixels, mi<strong>en</strong>tras que DrawStyle determina el tipo de línea. La Tabla 6.3 con<strong>si</strong>dera lospo<strong>si</strong>bles valores de la propiedad DrawStyle.Los tipos de raya discontinua no permit<strong>en</strong> que el grosor sea mayor que 1 pixel. Si el grosor essuperior, la línea se dibuja de modo continuo.Ejemplo:Line (0 ,0 )-(100 , 0) ' Línea del punto (0,0) al (100,0)Line -(100 , 100) ' Línea del punto (100,0) al (100,100)Line -Step (20 , 80) ' Línea del punto (100,100) al (120,180)Line (100,100)-(200 , 200), vbRed, BF ' Rectángulo rojo del punto' (100,100) al (200,200)6.4.4 Dibujo de circunfer<strong>en</strong>cias, arcos y elipses: método CircleEl método Circle permite dibujar circunfer<strong>en</strong>cias, elipses y arcos. Su forma g<strong>en</strong>eral es la <strong>si</strong>gui<strong>en</strong>te:object.Circle Step (x, y), radius, color, start, <strong>en</strong>d, aspectdonde object, step y color ti<strong>en</strong><strong>en</strong> el mismo <strong>si</strong>gnificado que <strong>en</strong> PSet y Line, y:(x, y) son obligatorias, y conti<strong>en</strong><strong>en</strong> las coord<strong>en</strong>adas del c<strong>en</strong>tro de la circunfer<strong>en</strong>cia.Radius es obligatoria y define el radio de la circunfer<strong>en</strong>cia.Start, <strong>en</strong>d son opcionales, y permit<strong>en</strong> definir arcos por medio del ángulo inicial (start) y final(<strong>en</strong>d). Los ángulos se mid<strong>en</strong> <strong>si</strong>empre <strong>en</strong> radianes y <strong>en</strong> s<strong>en</strong>tido contrario a las agujasdel reloj. Sus valores deb<strong>en</strong> estar <strong>en</strong>tre -2π y 2π. En principio se dibuja solam<strong>en</strong>te elarco, pero <strong>si</strong> uno o ambos valores son negativos se tratan <strong>como</strong> po<strong>si</strong>tivos, pero se


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 77dibuja una línea que une el c<strong>en</strong>tro de la circunfer<strong>en</strong>cia con el orig<strong>en</strong> o el extremo delarco.Aspect es también opcional y se utiliza para dibujar elipses. Es la relación <strong>en</strong>tre el diámetrovertical y el horizontal. El valor por defecto es 1.0, lo que corresponde a unacircunfer<strong>en</strong>cia. Cuando aspect es distinto de 1.0, el parámetro radius define el mayorde los dos diámetros.Sólo las figuras cerradas (no los arcos <strong>si</strong>n líneas que unan los extremos con el c<strong>en</strong>tro) pued<strong>en</strong>ser rell<strong>en</strong>adas con el color determinado por las propiedades FillColor y FillStyle del objeto <strong>en</strong> quese dibuja). El grosor y estilo de las líneas se determina con las propiedades DrawWidth yDrawStyle. Después de ejecutarse este método, las propiedades Curr<strong>en</strong>tX y Curr<strong>en</strong>tY ti<strong>en</strong><strong>en</strong> elvalor del c<strong>en</strong>tro de la circunfer<strong>en</strong>cia. Si se omite algún argum<strong>en</strong>to (excepto los que van al final),deb<strong>en</strong> respetarse las comas de separación <strong>en</strong>tre argum<strong>en</strong>tos.6.4.5 Otros métodos gráficosExist<strong>en</strong> algunos otros métodos gráficos de interés. Por ejemplo, el método Cls cuya forma g<strong>en</strong>eralesobject.Clsborra del formulario o control PictureBox todos los resultados de los métodos gráficos y del métodoPrint, al mismo tiempo que pone las propiedades Curr<strong>en</strong>tX y Curr<strong>en</strong>tY a cero. No afecta a losgráficos introducidos <strong>en</strong> modo de diseño (por ejemplo con la propiedad Picture). Tampoco seborran con este método el texto y gráficos que se hayan creado con la propiedad AutoRedraw <strong>en</strong>True, <strong>si</strong> dicha propiedad se pone a False antes de llamar al método Cls. De esta forma se pued<strong>en</strong>realizar borrados selectivos.El método Point devuelve, <strong>como</strong> <strong>en</strong>tero long, el color (RGB) del punto especificado <strong>en</strong> unformulario o control PictureBox. Su forma g<strong>en</strong>eral es:object.Point(x, y)Si se desea, el <strong>en</strong>tero long devuelto por Point puede convertirse a la notación hexadecimal quese usa para los colores utilizando la función Hex.6.5 SISTEMAS DE COORDENADASUn punto de particular importancia con<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es el que hacerefer<strong>en</strong>cia a la po<strong>si</strong>ción y tamaño de losformularios y de los demás controles,así <strong>como</strong> a las unidades <strong>en</strong> que seexpresan y determinan.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite elegir<strong>en</strong>tre distintas unidades, e inclusoutilizar distintas unidades para distintoselem<strong>en</strong>tos de la aplicación. Lasunidades se especifican con lapropiedad ScaleMode, que es propia delos formularios y controles PictureBox.Valor Nombre Unidades0 vbUser definidas por el usuario1 vbTwips twips (1440 por pulgada)2 vbPoints puntos (72 por pulgada)3 vbPixels pixels4 vbCharacters caracteres (120x240 twips)5 vbInches pulgadas6 vbMillimeters milímetros7 vbC<strong>en</strong>timeters c<strong>en</strong>tímetrosTabla 6.4. Valores de ScaleMode.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 78La Tabla 6.4 especifica los po<strong>si</strong>bles valores de esta propiedad. La unidad por defecto es el twip, quees la vigé<strong>si</strong>ma parte del punto o pixel.En un formulario las propiedades relacionadas con la escala y las dim<strong>en</strong><strong>si</strong>ones, agrupadas decuatro <strong>en</strong> cuatro, son las <strong>si</strong>gui<strong>en</strong>tes: (top, left, height y width) y (scaleTop, scaleLeft, scaleHeight yscaleWidth). Su <strong>si</strong>gnificado de explica a continuación con ayuda de la Figura 6.7.En esta figura se muestra la pantalla y un formulario. La po<strong>si</strong>ción y dim<strong>en</strong><strong>si</strong>ones delformulario vi<strong>en</strong><strong>en</strong> dadas por las propiedades (top, left, height y width). Para un formulario, estaspropiedades se defin<strong>en</strong> <strong>si</strong>empre <strong>en</strong> twips. Obsérvese que se mid<strong>en</strong> a partir de la esquina superiorizquierda.Sin embargo, el formulario puede t<strong>en</strong>er su propio <strong>si</strong>stema de coord<strong>en</strong>adas interno, definidopor las propiedades (scaleTop, scaleLeft, scaleHeight y scaleWidth), para lo cual su propiedadScaleMode debe estar puesta a cero. Las propiedades scaleLeft y scaleTop determinan lascoord<strong>en</strong>adas de la esquina superior izquierda <strong>en</strong> el propio <strong>si</strong>stema de coord<strong>en</strong>adas, mi<strong>en</strong>tras quescaleWidth y scaleHeight determinan su anchura y altura <strong>en</strong> dichas coord<strong>en</strong>adas. En realidad estaspropiedades determinan indirectam<strong>en</strong>te la po<strong>si</strong>ción del orig<strong>en</strong> de coord<strong>en</strong>adas y la escala yori<strong>en</strong>tación de los ejes. Si scaleHeight es po<strong>si</strong>tiva el eje de ord<strong>en</strong>adas va hacia abajo, mi<strong>en</strong>tras que<strong>si</strong> es negativa estará ori<strong>en</strong>tado hacia arriba. El eje horizontal va hacia la derecha <strong>si</strong> scaleWidth espo<strong>si</strong>tiva, y hacia la izquierda <strong>si</strong> es negativa.El método Scale permite establecer las cuatro propiedades (scaleTop, scaleLeft, scaleHeighty scaleWidth) conjuntam<strong>en</strong>te, <strong>como</strong> se verá <strong>en</strong> el <strong>si</strong>gui<strong>en</strong>te apartado. Sólo los formularios y loscontroles PictureBox pued<strong>en</strong> t<strong>en</strong>er las propiedades scaleTop, scaleLeft, scaleHeight y scaleWidth.Si las propiedades (top, left,height y width) no se aplican a unformulario <strong>si</strong>no a un control, ya nopantallaleftes obligatorio medirlas <strong>en</strong> twips,form<strong>si</strong>no que se mid<strong>en</strong> <strong>en</strong> las unidades(scaleLeft, scaleTop)determinadas por la propiedadscaleHeightscaleMode del formulario o pictureBoxque las conti<strong>en</strong>e. Cuandoestas propiedades se utilizan <strong>si</strong>nscaleWidthanteponerles el nombre de unobjeto se aplican al formulariowidthactivo. Para que se apliqu<strong>en</strong> a unobjeto cualquiera basta anteponerlesel nombre del objeto separadoFigura 6.7. Po<strong>si</strong>ción y tamaño de una caja PictureBox.por el operador punto (.).6.5.1 Método ScaleEl método Scale permite definir las cuatro propiedades (scaleTop, scaleLeft, scaleHeight yscaleWidth) de un formulario o PictureBox <strong>si</strong>multáneam<strong>en</strong>te. Su forma g<strong>en</strong>eral es:object.Scale (x1, y1) - (x2, y2)heighttop


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 79donde object es el nombre del control PictureBox (<strong>si</strong> se omite, el método se aplica al formularioactivo). Las coord<strong>en</strong>adas (x1, y1) son las coord<strong>en</strong>adas del vértice superior izquierdo del formularioo PictureBox, mi<strong>en</strong>tras que (x2, y2) correspond<strong>en</strong> al vértice inferior derecho. Por ejemplo, el<strong>si</strong>gui<strong>en</strong>te método:pctCaja.Scale (-100, 100) - (100, -100)establece unos ejes <strong>en</strong> el c<strong>en</strong>tro de la PictureBox, con loss<strong>en</strong>tidos ordinarios, que varían <strong>en</strong>tre -100 y 100, tal <strong>como</strong> puedeverse <strong>en</strong> la Figura 6.8. Este método equivale establecer lascuatro propiedades <strong>si</strong>gui<strong>en</strong>tes:pctCaja.scaleTop = 100pctCaja.scaleLeft = -100pctCaja.scaleHeight = -100pctCaja.scaleWidth = 100(-100,100)(0,0) •(100,-100)Figura 6.8. Método Scale.6.6 EVENTOS Y PROPIEDADES RELACIONADAS CON GRÁFICOS6.6.1 El ev<strong>en</strong>to PaintEl ev<strong>en</strong>to Paint se ejecuta cuando un objeto -de tipo form o PictureBox- se hace vi<strong>si</strong>ble. Sufinalidad es que el resultado de los métodos gráficos y del método Print aparezcan <strong>en</strong> el objetocorrespondi<strong>en</strong>te. Hay que t<strong>en</strong>er <strong>en</strong> cu<strong>en</strong>ta que <strong>si</strong> se introduc<strong>en</strong> métodos gráficos <strong>en</strong> el procedimi<strong>en</strong>toForm_load su resultado no aparece al hacerse vi<strong>si</strong>ble el formulario (es <strong>como</strong> <strong>si</strong> se dibujara sobre elformulario antes de que éste existiera). Para que el resultados de Print y de los métodos gráficosaparezcan al hacerse vi<strong>si</strong>ble el formulario, deb<strong>en</strong> introducirse <strong>en</strong> el procedimi<strong>en</strong>to Paint_form.También los controles pictureBox ti<strong>en</strong><strong>en</strong> ev<strong>en</strong>to Paint, que se ejecuta al hacerse vi<strong>si</strong>bles.El ev<strong>en</strong>to Paint ti<strong>en</strong>e mucha importancia <strong>en</strong> relación con el refresco de los gráficos y con lavelocidad de ejecución de los mismos. En los apartados <strong>si</strong>gui<strong>en</strong>tes se completará la explicación deeste tema.6.6.2 La propiedad DrawModeEsta es una propiedad bastante importante y difícil de manejar, sobre todo <strong>si</strong> se quier<strong>en</strong> realizarcierto tipo de acciones con los métodos gráficos. La opción por defecto es la nº 13: Copy P<strong>en</strong>.La propiedad DrawMode controla cómo se dibujan los controles Line y Shape, así <strong>como</strong> losresultados de los métodos gráficos PSet, Line y Circle. La opción por defecto hace que cadaelem<strong>en</strong>to gráfico se dibuje con el color correspondi<strong>en</strong>te (por defecto el foreColor) sobre lo dibujadoanteriorm<strong>en</strong>te. En oca<strong>si</strong>ones esto no es lo más adecuado pues, por ejemplo, <strong>si</strong> se superpon<strong>en</strong> dosfiguras del mismo color o <strong>si</strong> se dibuja con el backColor, los gráficos resultan indistinguibles.Para <strong>en</strong>t<strong>en</strong>der cómo funciona DrawMode es necesario t<strong>en</strong>er claros los conceptos de colorcomplem<strong>en</strong>tario y combinación de dos colores. El color complem<strong>en</strong>tario de un color es el colorque sumado con él da el blanco (&HFFFFFF&). Por ejemplo, el color complem<strong>en</strong>tario del rojo(&H0000FF&) es el cyan (&HFFFF00&).El color complem<strong>en</strong>tario se puede obt<strong>en</strong>er mediante la <strong>si</strong>mple resta del color blanco m<strong>en</strong>os elcolor original. Por su parte la combinación de dos colores es el color que resulta de aplicar eloperador lógico Or: el color resultante ti<strong>en</strong>e sus bits a 1 <strong>si</strong> alguno o los dos de los colores originalesti<strong>en</strong>e a 1 el bit correspondi<strong>en</strong>te. La explicación de los distintos valores de la propiedad DrawModeque se obti<strong>en</strong>e del Help es la <strong>si</strong>gui<strong>en</strong>te:


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 80Constant Setting DescriptionVbBlackness 1 Blackness.VbNotMergeP<strong>en</strong> 2 Not Merge P<strong>en</strong>— Inverse of setting 15 (Merge P<strong>en</strong>).VbMaskNotP<strong>en</strong> 3Mask Not P<strong>en</strong> — Combination of the colors common to thebackground color and the inverse of the p<strong>en</strong>.VbNotCopyP<strong>en</strong> 4 Not Copy P<strong>en</strong> — Inverse of setting 13 (Copy P<strong>en</strong>).VbMaskP<strong>en</strong>Not 5Mask P<strong>en</strong> Not — Combination of the colors common to both thep<strong>en</strong> and the inverse of the display.VbInvert 6 Invert — Inverse of the display color.VbXorP<strong>en</strong> 7Xor P<strong>en</strong> — Combination of the colors in the p<strong>en</strong> and in the displaycolor, but not in both.VbNotMaskP<strong>en</strong> 8 Not Mask P<strong>en</strong> — Inverse of setting 9 (Mask P<strong>en</strong>).VbMaskP<strong>en</strong> 9Mask P<strong>en</strong> — Combination of the colors common to both the p<strong>en</strong>and the display.VbNotXorP<strong>en</strong> 10 Not Xor P<strong>en</strong> — Inverse of setting 7 (Xor P<strong>en</strong>).VbNop 11Nop — No operation — output remains unchanged. In effect, thissetting turns drawing off.VbMergeNotP<strong>en</strong> 12Merge Not P<strong>en</strong> — Combination of the display color and the inverseof the p<strong>en</strong> color.VbCopyP<strong>en</strong> 13 Copy P<strong>en</strong> (Default) — Color specified by the ForeColor property.VbMergeP<strong>en</strong>Not 14Merge P<strong>en</strong> Not — Combination of the p<strong>en</strong> color and the inverse ofthe display color.VbMergeP<strong>en</strong> 15 Merge P<strong>en</strong> — Combination of the p<strong>en</strong> color and the display color.VbWhit<strong>en</strong>ess 16 Whit<strong>en</strong>ess.El explicar más a fondo las distintas aplicaciones de esta propiedad esta fuera del alcance deeste manual introductorio.6.6.3 Planos de dibujo (Layers)<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> con<strong>si</strong>dera tres planos superpuestos (layers): el plano frontal, el plano intermedioy el plano de fondo. Es importante saber <strong>en</strong> qué plano se introduce cada elem<strong>en</strong>to gráfico para<strong>en</strong>t<strong>en</strong>der cuándo unos elem<strong>en</strong>tos se superpondrán a otros <strong>en</strong> la pantalla. En principio, los tres planosse utilizan del <strong>si</strong>gui<strong>en</strong>te modo:1. En el plano frontal (Front) se dibujan todos los controles, excepto los controles gráficos y laslabels.2. En el plano intermedio se repres<strong>en</strong>tan los controles gráficos y labels.3. En el plano de fondo se repres<strong>en</strong>ta el color de fondo y el resultado de los métodos gráficos.Estas reglas ti<strong>en</strong><strong>en</strong> excepciones que dep<strong>en</strong>d<strong>en</strong> de la propiedad AutoRedraw, de la propiedadClipControl y de <strong>si</strong> los métodos gráficos se utilizan o no asociados al ev<strong>en</strong>to Paint.6.6.4 La propiedad AutoRedrawEsta propiedad ti<strong>en</strong>e una gran importancia. En principio, todas las aplicaciones de Windowspermit<strong>en</strong> superponer v<strong>en</strong>tanas y/u otros elem<strong>en</strong>tos gráficos, recuperando completam<strong>en</strong>te elcont<strong>en</strong>ido de cualquier v<strong>en</strong>tana cuando ésta se selecciona de nuevo y vi<strong>en</strong>e a primer plano (es lav<strong>en</strong>tana activa). A esto se llama redibujar (redraw) la v<strong>en</strong>tana. Cualquier aplicación que sedesarrolle <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> debe ser capaz de redibujarse correctam<strong>en</strong>te, pero para ello elprogramador debe conocer algo de la propiedad AutoRedraw.


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 81Por defecto, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> redibuja <strong>si</strong>empre los controles que aparec<strong>en</strong> <strong>en</strong> un formulario.Esto no sucede <strong>si</strong>n embargo con el resultado de los métodos gráficos y de Print. Para que la salidade estos métodos se redibuje es necesario adoptar uno de los dos métodos <strong>si</strong>gui<strong>en</strong>tes:1. Si <strong>en</strong> el form o pictureBox la propiedad AutoRedraw está <strong>en</strong> False:• Si los métodos gráficos y Print están <strong>en</strong> el procedimi<strong>en</strong>to correspondi<strong>en</strong>te al ev<strong>en</strong>to Paintse redibujan <strong>en</strong> el plano de fondo (los métodos vuelv<strong>en</strong> a ejecutarse, por lo que el procesopuede ser l<strong>en</strong>to <strong>en</strong> ciertos casos).• Si los métodos gráficos y Print están fuera del ev<strong>en</strong>to Paint no se redibujan.2. Si <strong>en</strong> el form o pictureBox la propiedad AutoRedraw está <strong>en</strong> True:• Si los métodos gráficos y Print están <strong>en</strong> el ev<strong>en</strong>to Paint se ignoran.• Si los métodos gráficos y Print están fuera del ev<strong>en</strong>to Paint se redibujan guardando <strong>en</strong>memoria una copia de la zona de pantalla a refrescar. Este es la forma más rápida deconseguir que los gráficos y el texto se redibuj<strong>en</strong>. Ti<strong>en</strong>e el inconv<strong>en</strong>i<strong>en</strong>te de nece<strong>si</strong>tar másmemoria.La propiedad AutoRedraw de los forms y de las pictureBox es indep<strong>en</strong>di<strong>en</strong>te, por lo que lasdos formas anteriores de conseguir que los gráficos se redibuj<strong>en</strong> se pued<strong>en</strong> utilizar conjuntam<strong>en</strong>te,por ejemplo una <strong>en</strong> el formulario y otra <strong>en</strong> las pictureBox.6.6.5 La propiedad ClipControlPor defecto esta propiedad de las forms y pixtureBox está <strong>en</strong> True. En este caso los controles están<strong>si</strong>empre por <strong>en</strong>cima de la salida de los métodos gráficos, por lo que nunca por ejemplo una línea sedibujará sobre un botón o una barra de desplazami<strong>en</strong>to (los controles están <strong>si</strong>empre <strong>en</strong> el planofrontal o <strong>en</strong> el plano intermedio, según se ha explicado antes).Cuando la propiedad ClipControl se pone a False se produce una doble circunstancia:• Los métodos gráficos <strong>si</strong>tuados <strong>en</strong> un ev<strong>en</strong>to Paint <strong>si</strong>empre se dibujan <strong>en</strong> el plano de fondoy por tanto respetan los controles.• Los métodos gráficos <strong>si</strong>tuados fuera de un ev<strong>en</strong>to Paint se dibujan sobre cualquierelem<strong>en</strong>to que esté <strong>en</strong> la pantalla, incluidos los controles.6.7 EJEMPLOSA continuación se muestra dos ejemplos que hac<strong>en</strong>uso de algunos de los controles y métodos gráficosexplicados previam<strong>en</strong>te.6.7.1 Ejemplo 6.1: Gráficos y barras dedesplazami<strong>en</strong>toEste primer programa, cuyo formulario se muestra<strong>en</strong> la Figura 6.9, es un ejemplo s<strong>en</strong>cillo que permiteutilizar algunas de las herrami<strong>en</strong>tas gráficas de<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>. Para ello se han utilizado dos barrasde desplazami<strong>en</strong>to que, junto a otras dos cajas deFigura 6.9. Movimi<strong>en</strong>to de un punto con PSet.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 82texto, modificarán y visualizarán las coord<strong>en</strong>adas del punto a dibujar.La Tabla 6.5 muestra los objetos y las propiedades a con<strong>si</strong>derar <strong>en</strong> este ejemplo.Control Propiedad Valor Control Propiedad ValorHscrollbar Name HScroll1 TextBox Name txtCaja2LargeChange 5 Text 0Max 100 TextBox Name txtCaja3Min 0 Text 0SmallChange 1 PictureBox Name PctBoxVScrollbar Name VScroll1 BackColor &H00FFFFFF&LargeChange 5 CommandButton Name Command1Max 100 Caption SalirMin 0SmallChange 1Tabla 6.5. Controles y propiedades del Ejemplo 6.2.Se pres<strong>en</strong>ta a continuación el código del programa:Private Sub cmdSalir_Click()EndEnd SubPrivate Sub Form_Load()pctBox.Scale (0, 0)-(100, 100)End SubPrivate Sub hsbX_Change()txtCaja3.Text = Format(hsbX.Value)pctBox.PSet (hsbX.Value, vsbY.Value), vbRedEnd SubPrivate Sub txtCaja2_KeyPress(KeyAscii As Integer)Dim valor As Integervalor = Val(txtCaja2.Text)If KeyAscii = 13 Th<strong>en</strong>If valor = vsbY.Min Th<strong>en</strong>vsbY.Value = valorElseIf valor > vsbY.Max Th<strong>en</strong>vsbY.Value = vsbY.MaxElsevsbY.Value = vsbY.MinEnd IfEnd IfEnd SubPrivate Sub txtCaja3_KeyPress(KeyAscii As Integer)Dim valor As Integervalor = Val(txtCaja3.Text)If KeyAscii = 13 Th<strong>en</strong>If valor = hsbX.Min Th<strong>en</strong>hsbX.Value = valorElseIf valor > hsbX.Max Th<strong>en</strong>hsbX.Value = hsbX.MaxElsehsbX.Value = hsbX.MinEnd IfEnd IfEnd Sub


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 83Private Sub vsbY_Change()txtCaja2.Text = Format(vsbY.Value)pctBox.PSet (hsbX.Value, vsbY.Value), vbRedEnd Sub6.7.2 Ejemplo 6.2: Repres<strong>en</strong>tación gráfica de la solución de la ecuación de segundo gradoEn este segundo ejemplo, cuyo formulario semuestra <strong>en</strong> la Figura 6.10, se repres<strong>en</strong>ta el lugar deraíces de la ecuación de segundo grado <strong>en</strong> función delos coefici<strong>en</strong>tes, o más <strong>en</strong> concreto <strong>en</strong> función de loscoci<strong>en</strong>tes B/A y C/A. El valor de estas relaciones secambia interactivam<strong>en</strong>te por medio de dos barras dedesplazami<strong>en</strong>to.El programa permite además la po<strong>si</strong>bilidad demant<strong>en</strong>er dibujadas las soluciones anteriores de laecuación, o borrarlas y dibujar sólo las últimas raícescalculadas borrando las anteriores. Para finalizar elFigura 6.10. Raíces de una ecuación de 2º grado.programa basta pre<strong>si</strong>onar el botón Salir.La Tabla 6.6 muestra los nombres y los valores de las principales propiedades de los objetosque aparec<strong>en</strong> <strong>en</strong> la Figura 6.10.Control Propiedad Valor Control Propiedad ValorFrame Name fraDib Label NameCaptionLabel2C/ACaption Dibujo Label NameCaptionLabel3BFrame Name fraEjes Label NameCaptionLabel4CCaption Divi<strong>si</strong>ones Ejes Label NameCaptionLabel5X1/XRHScrollBar Name hsbBA Label NameCaptionLabel6X2/XILargeChange 10 CommandButton Name CmdSalirMax 1000 Caption SalirMin -1000 Label Name lblBA, lblCA,lblX1, lblB2SmallChange 1 BackColor &H00C0FFFF&HScrollBar Name hsbCA Option Name optD1LargeChange 10 Caption BorrarMax 100 Option Name optD2Min -100 Caption Mant<strong>en</strong>erSmallChange 1 Option Name OptNoPictureBox Name pctBox Caption NoBackColor &H00FFFFFF& Option Name OptSiLabelNameCaptionLabel1B/ACaption SiTabla 6.6. Controles y propiedades del Ejemplo 6.3.Todas las labels que aparec<strong>en</strong> ti<strong>en</strong><strong>en</strong> la propiedad BorderStyle igual a 1- Fixed Single.El código del programa es el <strong>si</strong>gui<strong>en</strong>te:


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 84Option ExplicitDim a, b, c As DoubleDim x1, x2, dis, xr, xi As DoublePrivate Sub divi<strong>si</strong>ones(nx As Integer, ny As Integer)Dim i As IntegerDim x, xinc, y, yinc As SinglepctBox.DrawWidth = 1xinc = 20 / (nx - 1)x = -10For i = 1 To nxpctBox.Line (x, 0)-(x, -1)x = x + xincNext iyinc = 10 / (ny - 1)y = -5For i = 1 To nypctBox.Line (-1, y)-(0, y)y = y + yincNext ipctBox.DrawWidth = 2End SubPrivate Sub cmdSalir_Click()EndEnd SubPrivate Sub Form_Load()pctBox.Scale (-10, 5)-(10, -5)End SubPrivate Sub hsbBA_Change()a = 1b = hsbBA.Value / 10#c = hsbCA.Value / 10#lblBA.Caption = blblCA.Caption = cdis = b ^ 2 - 4 * a * cIf optD2.Value = True Th<strong>en</strong> ’mant<strong>en</strong>erpctBox.AutoRedraw = TrueElse’borrarpctBox.AutoRedraw = FalsepctBox.ClsEnd IfIf dis > 0 Th<strong>en</strong>x1 = (-b + Sqr(dis)) / (2 * a)x2 = (-b - Sqr(dis)) / (2 * a)lblX1.Caption = Format(x1, "###0.000")lblX2.Caption = Format(x2, "###0.000")pctBox.PSet (x1, 0), vbRedpctBox.PSet (x2, 0), vbRedElseIf dis = 0 Th<strong>en</strong>x1 = -b / (2 * a)x2 = x1lblX1.Caption = Format(x1, "###0.000")lblX2.Caption = ""pctBox.PSet (x1, 0), vbGre<strong>en</strong>Elsexr = -b / (2 * a)xi = Sqr(-dis) / (2 * a)lblX1.Caption = Format(xr, "###0.000")lblX2.Caption = Format(xi, "###0.000")pctBox.PSet (xr, xi), vbBluepctBox.PSet (xr, -xi), vbBlueEnd If


Capítulo 6: Gráficos <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> página 85If optSi = True Th<strong>en</strong>Call divi<strong>si</strong>ones(10, 5)End IfEnd SubPrivate Sub hsbCA_Change()a = 1b = hsbBA.Value / 10#c = hsbCA.Value / 10#lblBA.Caption = blblCA.Caption = cdis = b ^ 2 - 4 * a * cIf optD2.Value = True Th<strong>en</strong> ’mant<strong>en</strong>erpctBox.AutoRedraw = TrueElse’borrarpctBox.AutoRedraw = FalsepctBox.ClsEnd IfIf dis > 0 Th<strong>en</strong>x1 = (-b + Sqr(dis)) / (2 * a)x2 = (-b - Sqr(dis)) / (2 * a)lblX1.Caption = Format(x1, "###0.000")lblX2.Caption = Format(x2, "###0.000")pctBox.PSet (x1, 0), vbRedpctBox.PSet (x2, 0), vbRedElseIf dis = 0 Th<strong>en</strong>x1 = -b / (2 * a)x2 = x1lblX1.Caption = Format(x1, "###0.000")lblX2.Caption = ""pctBox.PSet (x1, 0), vbGre<strong>en</strong>Elsexr = -b / (2 * a)xi = Sqr(-dis) / (2 * a)lblX1.Caption = Format(xr, "###0.000")lblX2.Caption = Format(xi, "###0.000")pctBox.PSet (xr, xi), vbBluepctBox.PSet (xr, -xi), vbBlueEnd IfIf optSi = True Th<strong>en</strong>Call divi<strong>si</strong>ones(10, 5)End IfEnd SubPrivate Sub optD1_Click()pctBox.AutoRedraw = TruepctBox.ClspctBox.DrawWidth = 1pctBox.Line (-90, 0)-(90, 0), vbBlackpctBox.Line (0, -45)-(0, 45), vbBlackpctBox.DrawWidth = 2End SubPrivate Sub pctBox_Paint()pctBox.AutoRedraw = TruepctBox.Line (-90, 0)-(90, 0), vbBlackpctBox.Line (0, -45)-(0, 45), vbBlackpctBox.DrawWidth = 2End Sub


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 866.8 BARRAS DE HERRAMIENTAS (TOOLBARS)JGJCon <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> es fácil crear barras de herrami<strong>en</strong>tas constituidas por botones clicables,al estilo de las aplicaciones de Windows. De ordinario las barras de herrami<strong>en</strong>tas dan acceso a lasfunciones o comandos más comunes de los m<strong>en</strong>ús de la aplicación.Se puede crear una barra de herrami<strong>en</strong>tas por medio de un PictureBox colocado <strong>en</strong> unformulario. En este PictureBox se pued<strong>en</strong> colocar controles CommandButton o Image <strong>en</strong> los quese programa el ev<strong>en</strong>to click. La propiedad Picture del control Image puede cont<strong>en</strong>er la dirección dealguno de los iconos estándar que vi<strong>en</strong><strong>en</strong> con <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> (ext<strong>en</strong><strong>si</strong>ón *.ico) o la de un iconoconstruido por el programador.En el caso de los formularios MDI se puede colocar una barra de herrami<strong>en</strong>tas <strong>en</strong> elMDIform, que automáticam<strong>en</strong>te adquiere la anchura del formulario.


Capítulo 7: Archivos y Entrada/Salida de Datos página 877. ARCHIVOS Y ENTRADA/SALIDA DE DATOSEn este capítulo se van a describir varias formas de introducir información <strong>en</strong> el programa, así <strong>como</strong>de obt<strong>en</strong>er resultados <strong>en</strong> forma impresa o mediante escritura <strong>en</strong> un fichero. Se va a pres<strong>en</strong>tar unanueva forma interactiva de comunicarse con el usuario, <strong>como</strong> son las cajas de diálogo MsgBox eInputBox. Particular interés ti<strong>en</strong>e la lectura y escritura de datos <strong>en</strong> el disco, lo cual es necesariotanto cuando el volum<strong>en</strong> de información es muy importante (la memoria RAM está <strong>si</strong>empre máslimitada que el espacio <strong>en</strong> disco), <strong>como</strong> cuando se desea que los datos no desaparezcan al terminarla ejecución del programa. Los ficheros <strong>en</strong> disco resuelv<strong>en</strong> ambos problemas.También se verá <strong>en</strong> este capítulo cómo obt<strong>en</strong>er resultados alfanuméricos y gráficos por laimpresora.7.1 CAJAS DE DIÁLOGO INPUTBOX Y MSGBOXEstas cajas de diálogo son <strong>si</strong>milares a las que se utilizan <strong>en</strong> muchas aplicaciones de Windows. Lacaja de m<strong>en</strong>sajes o MsgBox abre una v<strong>en</strong>tana a través de la cual se <strong>en</strong>vía un m<strong>en</strong>saje al usuario y sele pide una respuesta, por ejemplo <strong>en</strong> forma de clicar un botón O.K./Cancel, o Yes/No. Este tipo dem<strong>en</strong>sajes son muy utilizados para confirmar acciones y para deci<strong>si</strong>ones s<strong>en</strong>cillas. La caja de diálogoInputBox pide al usuario que teclee una frase, por ejemplo su nombre, un título, etc.La forma g<strong>en</strong>eral de la función MsgBox es la <strong>si</strong>gui<strong>en</strong>te:respuesta = MsgBox("texto para el usuario", tiposBotones, "titulo")donde respuesta es la variable donde se almac<strong>en</strong>a el valor de retorno, que es un número indicativodel botón clicado por el usuario, de acuerdo con los valores de la Tabla 7.1. La constante <strong>si</strong>mbólicaque repres<strong>en</strong>ta el valor de retorno indica claram<strong>en</strong>te el botón clicado. Los otros dos argum<strong>en</strong>tos sonopcionales. El parámetro tiposBotones es un <strong>en</strong>tero que indica la combinación de botones deseadapor el usuario; sus po<strong>si</strong>bles valores se muestran <strong>en</strong> la Tabla 7.2. También <strong>en</strong> este caso la constante<strong>si</strong>mbólica correspondi<strong>en</strong>te es sufici<strong>en</strong>tem<strong>en</strong>te explícita. Si este argum<strong>en</strong>to se omite se muestra sóloel botón O.K. El parámetro titulo conti<strong>en</strong>e un texto que aparece <strong>como</strong> título de la v<strong>en</strong>tana; <strong>si</strong> seomite, se muestra <strong>en</strong> su lugar el nombre de la aplicación.Valor de retorno Constante <strong>si</strong>mbólica1 vbOK2 vbCancel3 vbAbort4 vbRetry5 vbIgnore6 vbYes7 vbNoTabla 7.1. Botón clicado por el usuario.Valor tiposBotones Constante <strong>si</strong>mbólica0 vbOKOnly1 vbOKCancel2 vbAbortRetryIgnore3 vbYesNoCancel4 vbYesNo5 vbRetryCancelTabla 7.2. Botones mostrados <strong>en</strong> MsgBox.Se puede modificar el valor de tiposBotones de modo que el botón que se activa por defectocuando se pulsa la tecla Intro (el botón que ti<strong>en</strong>e el focus) sea cualquiera de los botones de la caja.Para ello basta sumar a tiposBotones otra constante que puede tomar uno de los tres valores<strong>si</strong>gui<strong>en</strong>tes: 0 (vbDefaulButton1, que repres<strong>en</strong>ta el primer botón), 256 (vbDefaulButton2, querepres<strong>en</strong>ta el segundo botón) y 512 (vbDefaulButton3, que repres<strong>en</strong>ta el tercer botón).


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 88Figura 7.1. Ejemplo de caja MsgBox.Figura 7.2. Ejemplo de caja de InputBox.Finalm<strong>en</strong>te, se puede incluir <strong>en</strong> el m<strong>en</strong>saje un icono ad-hoc por el mismo procedimi<strong>en</strong>to desumarle al argum<strong>en</strong>to tiposBotones una nueva constante numérica con los <strong>si</strong>gui<strong>en</strong>tes valores y<strong>si</strong>gnificados definidos por la constante <strong>si</strong>mbólica apropiada: 16 (vbCritical), 32 (vbQuestion), 48(vbExclamation) y 64 (vbInformation). Es obvio que, por los propios valores con<strong>si</strong>derados, al sumarestas constantes o las anteriores al argum<strong>en</strong>to tiposBotones, la información original descrita <strong>en</strong> laTabla 7.2 no se pierde. La Figura 7.1 muestra un ejemplo de caja MsgBox resultado de ejecutar elcomando <strong>si</strong>gui<strong>en</strong>te:lblBox.Caption = MsgBox("Pulse un botón: ", 2 + 256 + 48, _"Caja de m<strong>en</strong>sajes")donde el “2” indica que deb<strong>en</strong> aparecer los botones Abort, Retry y Cancel, el “256” indica que elbotón por defecto es el segundo (Retry) y el “48” indica que debe aparecer el icono de exclamación.Por otra parte, la forma g<strong>en</strong>eral de la función InputBox es la <strong>si</strong>gui<strong>en</strong>te:texto = InputBox("texto para el usuario", "titulo", "default", left, top)donde texto es la variable donde se almac<strong>en</strong>a el valor de retorno, que es el texto tecleado por elusuario. Los parámetros "texto para el usuario" y titulo ti<strong>en</strong><strong>en</strong> el mismo <strong>si</strong>gnificado que <strong>en</strong>MsgBox. El parámetro default es un texto por defecto que aparece <strong>en</strong> la caja de texto y que elusuario puede aceptar, modificar o sustituir; el cont<strong>en</strong>ido de esta caja es lo que <strong>en</strong> definitiva estafunción devuelve <strong>como</strong> valor de retorno. Finalm<strong>en</strong>te, left y top son las coord<strong>en</strong>adas de la esquinasuperior izquierda de la InputBox; <strong>si</strong> se omit<strong>en</strong>, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dibuja esta caja c<strong>en</strong>trada <strong>en</strong>horizontal y algo por <strong>en</strong>cima de la mitad de la pantalla <strong>en</strong> vertical. La Figura 7.2 muestra un ejemplode caja InputBox resultado de ejecutar el comando <strong>si</strong>gui<strong>en</strong>te:lblBox.Caption = InputBox("Escriba su nombre: ", _"Caja de <strong>en</strong>trada", "Miguel Indurain")donde el nombre que aparece por defecto es el del mejor ciclista de los últimos tiempos. Est<strong>en</strong>ombre aparece seleccionado y puede ser sustituido por otro que teclee el usuario.7.2 MÉTODO PRINTEste método permite escribir texto <strong>en</strong> formularios, cajas pictureBox y <strong>en</strong> un objeto llamado Printerque se verá un poco más adelante, <strong>en</strong> el Apartado 7.3.7.2.1 Características g<strong>en</strong>eralesLa forma g<strong>en</strong>eral del método Print se explica mejor con algunos ejemplos <strong>como</strong> los <strong>si</strong>gui<strong>en</strong>tes:pctBox.Print "La distancia es: "; Dist; " km."pctBox.Print 123; 456; "San"; "Sebastián"


Capítulo 7: Archivos y Entrada/Salida de Datos página 89pctBox.Print 123, 456, "San", "Sebastián"pctBox.Print -123; -456cuyo resultado se puede ver <strong>en</strong> la Figura 7.3 (puedevariar dep<strong>en</strong>di<strong>en</strong>do del tipo y tamaño de las letras):De estos ejemplos se pued<strong>en</strong> ya sacar algunasconclu<strong>si</strong>ones:1. El método Print recibe <strong>como</strong> datos una lista devariables y/o cad<strong>en</strong>as de caracteres. Las cad<strong>en</strong>asson impresas y las variables se sustituy<strong>en</strong> por suvalor.2. Hay dos tipos bá<strong>si</strong>cos de separadores para los Figura 7.3: Ejemplo del método Print.elem<strong>en</strong>tos de la lista. El carácter punto y coma (;)hace que se escriba inmediatam<strong>en</strong>te a continuación de lo anterior. La coma (,) hace que sevaya al comi<strong>en</strong>zo de la <strong>si</strong>gui<strong>en</strong>te área de salida. Con letra de paso constante <strong>como</strong> la Courierlas áreas de salida empiezan cada 14 caracteres, es decir <strong>en</strong> las columnas 1, 15, 29, etc. Conletras de paso variable esto se hace sólo de modo aproximado.3. Las constantes numéricas po<strong>si</strong>tivas van precedidas por un espacio <strong>en</strong> blanco y separadas <strong>en</strong>tresí por otro espacio <strong>en</strong> blanco. Si son negativas el segundo espacio es ocupado por el <strong>si</strong>gnom<strong>en</strong>os (-).4. El tipo y tamaño de letra que se utiliza dep<strong>en</strong>de de la propiedad Font del formulario, objetoPictureBox u objeto Printer <strong>en</strong> que se esté escribi<strong>en</strong>do.Exist<strong>en</strong> otros separadores tales <strong>como</strong> Tab(n) y Spc(n). El primero de ellos lleva el punto deinserción de texto a la columna n, mi<strong>en</strong>tras que el segundo deja n espacios <strong>en</strong> blanco antes de seguirescribi<strong>en</strong>do. Tab <strong>si</strong>n argum<strong>en</strong>to equivale a la coma (,). Estos espaciadores se utilizan <strong>en</strong>combinación con el punto y coma (;), para separarlos de los demás argum<strong>en</strong>tos.Por defecto, la salida de cada método Print se escribe <strong>en</strong> una nueva línea, pero <strong>si</strong> se coloca unpunto y coma al final de un método Print, el resultado del <strong>si</strong>gui<strong>en</strong>te Print se escribe <strong>en</strong> la mismalínea.Puede controlarse el lugar del formulario o control donde se imprime la salida del métodoPrint. Esta salida se imprime <strong>en</strong> el lugar indicado por las propiedades Curr<strong>en</strong>tX y Curr<strong>en</strong>tY delformulario o control donde se imprime. Cambiando estas propiedades se modifica el lugar deimpre<strong>si</strong>ón, que por defecto es la esquina superior izquierda. Exist<strong>en</strong> unas funciones llamadasTextWidth(string) y TextHeight(string) que devuelv<strong>en</strong> la anchura y la altura de una cad<strong>en</strong>a decaracteres pasada <strong>como</strong> argum<strong>en</strong>to. Estas funciones pued<strong>en</strong> ayudar a calcular los valores másadecuados para las propiedades Curr<strong>en</strong>tX y Curr<strong>en</strong>tY.La función str(valor_numérico) convierte un número <strong>en</strong> cad<strong>en</strong>a de caracteres para facilitar suimpre<strong>si</strong>ón. En realidad, es lo que <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> ha hecho de modo implícito <strong>en</strong> los ejemplosanteriores. En ver<strong>si</strong>ones anteriores del programa era necesario que el usuario realizase la conver<strong>si</strong>ónde modo explícito.7.2.2 Función FormatLa función Format realiza las conver<strong>si</strong>ones necesarias para que ciertos datos numéricos o de otrotipo puedan ser impresos con Print. Como se ha visto, <strong>en</strong> el caso de las variables numéricas esto noes imprescindible, pero la función Format permite controlar el número de espacios, el número dedecimales, etc. En el caso de su aplicación a objetos tipo fecha (date) y hora (time) la aplicación de


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 90Format es imprescindible, pues Print no los escribe directam<strong>en</strong>te. La forma g<strong>en</strong>eral de esta funciónes la <strong>si</strong>gui<strong>en</strong>te:Format(expre<strong>si</strong>on, formato)donde expre<strong>si</strong>on es una variable o expre<strong>si</strong>ón y formato -que es opcional- describe el formatodeseado para el resultado. El valor de retorno es una cad<strong>en</strong>a de caracteres directam<strong>en</strong>te utilizable <strong>en</strong>Print. Para fechas exist<strong>en</strong> formatos predefinidos tales <strong>como</strong> “G<strong>en</strong>eral Date”, “Long Date”,“Medium Date” y “Short Date”; para la hora los formatos predefinidos son “Long Time”,“Medium Time” y “Short Time”. Además existe la po<strong>si</strong>bilidad de que el usuario defina sus propiosformatos (ver User-Defined Date/Time Formats (Format Function), <strong>en</strong> el Help del programa). Elusuario también puede definir sus propios formatos numéricos y de cad<strong>en</strong>as de caracteres.A difer<strong>en</strong>cia de la función Str, la función Format no deja espacio <strong>en</strong> blanco para el <strong>si</strong>gno delos números po<strong>si</strong>tivos.7.3 UTILIZACIÓN DE IMPRESORAS<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> permite obt<strong>en</strong>er por la impresora gráficos y texto <strong>si</strong>milares a los que se pued<strong>en</strong>obt<strong>en</strong>er por la pantalla, aunque con algunas difer<strong>en</strong>cias de cierta importancia. Exist<strong>en</strong> dos formas deimprimir: la primera mediante el método PrintForm, y la segunda utilizando el objeto Printer, quees un objeto <strong>si</strong>milar al objeto PictureBox. Ambos métodos ti<strong>en</strong><strong>en</strong> puntos fuertes y débiles que secom<strong>en</strong>tarán a continuación.7.3.1 Método PrintFormEl método PrintForm permite imprimir un formulario con sus controles y con los resultados de losmétodos gráficos (PSet, Line y Circle) y del método Print. Para ello la propiedad AutoRedraw delformulario ti<strong>en</strong>e que estar puesta a True, y los métodos citados ti<strong>en</strong><strong>en</strong> que estar llamados desde unev<strong>en</strong>to distinto del Paint. Lo único que no se dibuja del formulario es la barra de título.Este <strong>si</strong>stema de impre<strong>si</strong>ón es muy s<strong>en</strong>cillo de utilizar, pero ti<strong>en</strong>e el inconv<strong>en</strong>i<strong>en</strong>te de que elresultado se imprime con la misma resolución de la pantalla (<strong>en</strong>tre 50 y 100 puntos por pulgada), noaprovechando por tanto la mayor resolución que suel<strong>en</strong> t<strong>en</strong>er las impresoras (300, 600 ó más puntospor pulgada).7.3.2 Objeto PrinterEste segundo <strong>si</strong>stema ti<strong>en</strong>e la v<strong>en</strong>taja de que permite aprovechar pl<strong>en</strong>am<strong>en</strong>te la resolución de laimpresora, pero no permite dibujar controles <strong>si</strong>no sólo los métodos gráficos habituales (PSet, Liney Circle), el método Print y un método no visto hasta ahora que es PaintPicture.Para <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> la impresora es un objeto gráfico más, <strong>si</strong>milar a los formularios y a lascajas gráficas PictureBox. Como tal objeto gráfico ti<strong>en</strong>e sus propiedades g<strong>en</strong>erales (DrawStyle,BackColor, ForeColor, etc.), además de otras propiedades específicas de la impresora, <strong>como</strong>DeviceName, DriverName, Ori<strong>en</strong>tation, Copies, etc. Para más información puede utilizarse el Help,buscando Printer object. En principio se utiliza la impresora por defecto del PC, pero <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong>manti<strong>en</strong>e una Printers Collection, que es algo así <strong>como</strong> un array de impresoras disponibles. A partirde esta Printers Collection se puede cambiar a la impresora que se desee.El objeto Printer ti<strong>en</strong>e un método llamado EndDoc para <strong>en</strong>viar realm<strong>en</strong>te a la impresora elresultado de los métodos gráficos. El método PaintPicture permite incorporar el cont<strong>en</strong>ido deficheros gráficos a un formulario, PictureBox o Printer. Su forma g<strong>en</strong>eral es:


Capítulo 7: Archivos y Entrada/Salida de Datos página 91object.PaintPicture pictProp X, Y, Width, Heightdonde pictProp indica el gráfico (coincide con la propiedad Picture de PictureBox), X e Y indicanlas coord<strong>en</strong>adas de inserción y los dos últimos parámetros las dim<strong>en</strong><strong>si</strong>ones (opcionales).7.4 CONTROLES FILELIST, DIRLIST Y DRIVELISTUno de los problemas que hay queresolver para leer o escribir <strong>en</strong> ficherosde disco es ser capaces de localizarinteractivam<strong>en</strong>te los correspondi<strong>en</strong>tesficheros, de modo análogo a <strong>como</strong> serealiza con los comandos File/Op<strong>en</strong> oFile/Save As de Word, Excel o decualquier otra aplicación. Este tipo deoperaciones se pued<strong>en</strong> hacer muchomás fácilm<strong>en</strong>te con los CommonDialog Controls vistos <strong>en</strong> el Apartado4.4, <strong>en</strong> la página 58, aconsejando porlo tanto su uso. A pesar de ello, aquí seFigura 7.4. Cajas DriveListBox, DirListBox y FileListBox.van a explicar los controles específicosde que dispone <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>.<strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de tres controles que facilitan el recorrer el árbol de ficheros y dedirectorios, localizando o creando interactivam<strong>en</strong>te un fichero determinado. Estos controles son elFileListBox (para ficheros), el DirListBox (para directorios) y el DriveListBox (para unidades dedisco). La Figura 7.4 muestra estos tres controles, junto con unas etiquetas que los id<strong>en</strong>tifican. Losdos primeros son listas, mi<strong>en</strong>tras que el tercero es una caja de tipo ComboBox.En principio estos controles, cuando se colocan <strong>en</strong> un formulario tal <strong>como</strong> se muestra <strong>en</strong> laFigura 7.4, están desconectados. Quiere esto decir que al cambiar la unidad de disco (drive) no semuestran <strong>en</strong> la caja dirListBox los directorios correspondi<strong>en</strong>tes a la nueva unidad de disco. Por otraparte, al cambiar de directorio t<strong>en</strong>drán que cambiar de modo acorde los ficheros <strong>en</strong> la cajafileListBox. La dificultad de conectar estas cajas no es grande, pero sí hay que saber cómo se hacepues dep<strong>en</strong>de de propiedades de estas cajas que no aparec<strong>en</strong> <strong>en</strong> la v<strong>en</strong>tana de propiedades (v<strong>en</strong>tanaProperties) <strong>en</strong> modo de diseño, y que sólo están acce<strong>si</strong>bles <strong>en</strong> modo de ejecución. De <strong>en</strong>tre estaspropiedades las más importantes son las <strong>si</strong>gui<strong>en</strong>tes:1. La DriveListBox ti<strong>en</strong>e una propiedad llamada Drive que recoge la unidad seleccionada por elusuario (puede ser una unidad fí<strong>si</strong>ca <strong>como</strong> el disco c:\ o una unidad lógica a<strong>si</strong>gnada por elusuario a otro disco o directorio <strong>en</strong> un servidor o <strong>en</strong> otro ord<strong>en</strong>ador de la red).2. La propiedad path de la caja DirListBox determina el drive seleccionado y por tanto quédirectorios se muestran <strong>en</strong> dicha caja.3. Finalm<strong>en</strong>te, una propiedad también llamada path de la caja FileListBox determina eldirectorio que conti<strong>en</strong>e los ficheros mostrados.Para <strong>en</strong>lazar correctam<strong>en</strong>te las cajas de discos, directorios y ficheros se puede utilizar elev<strong>en</strong>to Change, de tal forma que cada vez que el usuario cambia la unidad de disco se cambia elpath del directorio y cada vez que se cambia el directorio se cambia el path de los ficheros. Estopuede hacerse con el código <strong>si</strong>gui<strong>en</strong>te:


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 92Private Sub dirPrueba_Change()filPrueba.Path = dirPrueba.PathEnd SubPrivate Sub drvPrueba_Change()dirPrueba.Path = drvPrueba.DriveEnd SubLa caja FileListBox ti<strong>en</strong>e una propiedad llamada FileName que conti<strong>en</strong>e el nombre delfichero seleccionado por el usuario. Para t<strong>en</strong>er el path completo del fichero basta anteponerle lapropiedad Path de la fileListBox, que incluye el directorio y el drive, y la barra invertida (\). Si elusuario introduce FileName incluy<strong>en</strong>do el path, <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> actualiza también de modoautomático la propiedad Path de FileListBox. El usuario se debe preocupar de utilizar el ev<strong>en</strong>toChange para actualizar el Path de la caja DirListBox y la propiedad Drive de DriveListBox.Otra propiedad importante es la propiedad Pattern, que indica los tipos de ficheros que semostrarán <strong>en</strong> la caja. El valor por defecto es “*.*”, lo cual hace que se muestr<strong>en</strong> todos los ficheros.Si su valor fuese “*.doc” sólo se mostrarían los ficheros con esta ext<strong>en</strong><strong>si</strong>ón. La propiedad Patternadmite varias opciones separadas por untos y coma (“*.doc; *.dot”).7.5 TIPOS DE FICHEROSTanto <strong>en</strong> Windows <strong>como</strong> <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> exist<strong>en</strong>, principalm<strong>en</strong>te, dos tipos de archivos:1. Ficheros ASCII o ficheros de texto. Conti<strong>en</strong><strong>en</strong> caracteres codificados según el código ASCIIy se pued<strong>en</strong> leer con cualquier editor de texto <strong>como</strong> Notepad. Suel<strong>en</strong> t<strong>en</strong>er ext<strong>en</strong><strong>si</strong>ón *.txt o*.bat, pero también otras <strong>como</strong> *.m para los programas de Matlab, *.c para los ficheros fu<strong>en</strong>tede C, *.cpp para los ficheros fu<strong>en</strong>te de C++ y *.java para los de Java.2. Ficheros binarios: Son ficheros imag<strong>en</strong> de los datos o programas tal <strong>como</strong> están <strong>en</strong> lamemoria del ord<strong>en</strong>ador. No son legibles directam<strong>en</strong>te por el usuario. Ti<strong>en</strong><strong>en</strong> la v<strong>en</strong>taja de queocupan m<strong>en</strong>os espacio <strong>en</strong> disco y que no se pierde tiempo y preci<strong>si</strong>ón cambiándolos a formatoASCII al escribirlos y al leerlos <strong>en</strong> el disco.Con <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se pued<strong>en</strong> leer tanto ficheros ASCII <strong>como</strong> ficheros binarios. Además elacceso a un fichero puede ser de tres formas principales.1. Acceso secu<strong>en</strong>cial. Se le<strong>en</strong> y escrib<strong>en</strong> los datos <strong>como</strong> <strong>si</strong> se tratara de un libro: <strong>si</strong>empre acontinuación del anterior y <strong>si</strong>n po<strong>si</strong>bilidad de volver atrás o saltar datos. Si se quiere acceder aun dato que está hacia la mitad de un fichero, habrá que pasar primero por todos los datosanteriores. Los ficheros de texto ti<strong>en</strong><strong>en</strong> acceso secu<strong>en</strong>cial.2. Acceso aleatorio (random): Permit<strong>en</strong> acceder directam<strong>en</strong>te a un dato <strong>si</strong>n t<strong>en</strong>er que pasar portodos los demás, y pued<strong>en</strong> acceder a la información <strong>en</strong> cualquier ord<strong>en</strong>. Ti<strong>en</strong><strong>en</strong> la limitaciónde que los datos están almac<strong>en</strong>ados <strong>en</strong> unas unidades o bloques que se llaman registros, y quetodos los registros que se almac<strong>en</strong>an <strong>en</strong> un fichero deb<strong>en</strong> ser del mismo tamaño. Los ficherosde acceso aleatorio son ficheros binarios.3. Acceso binario. Son <strong>como</strong> los de acceso aleatorio, pero el acceso no se hace por registros <strong>si</strong>nopor bytes.Antes de poder leer o escribir <strong>en</strong> un fichero hay que abrirlo por medio de la s<strong>en</strong>t<strong>en</strong>cia Op<strong>en</strong>.En esta s<strong>en</strong>t<strong>en</strong>cia hay que especificar qué tipo de acceso se desea t<strong>en</strong>er, distingui<strong>en</strong>do también <strong>si</strong> espara lectura (input), escritura (output) o escritura añadida (app<strong>en</strong>d).


Capítulo 7: Archivos y Entrada/Salida de Datos página 937.6 LECTURA Y ESCRITURA EN FICHEROS SECUENCIALES7.6.1 Apertura y cierre de ficherosPara poder leer o escribir <strong>en</strong> un fichero antes debe ser abierto con la s<strong>en</strong>t<strong>en</strong>cia Op<strong>en</strong>, cuya formag<strong>en</strong>eral es la <strong>si</strong>gui<strong>en</strong>te:Op<strong>en</strong> fil<strong>en</strong>ame For modo As # fileNodonde:fil<strong>en</strong>amemodoes el nombre del fichero a abrir. Será una variable string o un nombre <strong>en</strong>tre doblescomillas (“ ”).Para acceso secu<strong>en</strong>cial exist<strong>en</strong> tres po<strong>si</strong>bilidades: Input para leer, Output paraescribir al comi<strong>en</strong>zo de un fichero y App<strong>en</strong>d para escribir al final de un fichero yaexist<strong>en</strong>te. Si se int<strong>en</strong>ta abrir <strong>en</strong> modo Input un fichero que no existe, se produce unerror. Si se abre para escritura <strong>en</strong> modo Output un fichero que no existe se crea, y <strong>si</strong>ya existía se borra su cont<strong>en</strong>ido y se comi<strong>en</strong>za a escribir desde el principio. El modoApp<strong>en</strong>d es <strong>si</strong>milar al modo Output, pero respeta <strong>si</strong>empre el cont<strong>en</strong>ido previo delfichero escribi<strong>en</strong>do a continuación de lo último que haya <strong>si</strong>do escrito anteriorm<strong>en</strong>te.fileNo es un número <strong>en</strong>tero (o una variable con un valor <strong>en</strong>tero) que se a<strong>si</strong>gna a cada ficheroque se abre. En todas las operaciones suce<strong>si</strong>vas de lectura y/o escritura se harárefer<strong>en</strong>cia a este fichero por medio de este número. No puede haber dos ficherosabiertos con el mismo número. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> dispone de una función llamadaFreeFile que devuelve un número no ocupado por ningún fichero.A continuación puede verse un ejemplo de fichero abierto para lectura:Op<strong>en</strong> "C:\usuarios\PRUEBA1.txt" For Input as #1Después de terminar de leer o escribir <strong>en</strong> un fichero hay que cerrarlo. Para ello, se utilizara elcomando Close, que ti<strong>en</strong>e la <strong>si</strong>gui<strong>en</strong>te forma:Close # fileNodonde el fileNo es el número que se la había a<strong>si</strong>gnado al abrirlo con la instrucción Op<strong>en</strong>.7.6.2 Lectura y escritura de datos7.6.2.1 S<strong>en</strong>t<strong>en</strong>cia InputExist<strong>en</strong> varias formas de leer <strong>en</strong> un fichero de acceso secu<strong>en</strong>cial. Por ejemplo, para leer el valor deuna o más variables se utiliza la s<strong>en</strong>t<strong>en</strong>cia Input:Input # fileNo, varName1, varName2, varName3, ...donde el fileNo es el número a<strong>si</strong>gnado al archivo al abrirlo y varName1, varName2, ... son losnombres de las variables donde se guardarán los valores leídos <strong>en</strong> el fichero. Debe haber unacorrespond<strong>en</strong>cia <strong>en</strong>tre el ord<strong>en</strong> y los tipos de las variables <strong>en</strong> la lista, con los datos almac<strong>en</strong>ados <strong>en</strong>el fichero. No se pued<strong>en</strong> leer directam<strong>en</strong>te vectores, matrices o estructuras. Si los datos del discohan de ser escritos por el propio programa, convi<strong>en</strong>e utilizar la s<strong>en</strong>t<strong>en</strong>cia write (mejor que Print)para garantizar que los valores están conv<strong>en</strong>i<strong>en</strong>tem<strong>en</strong>te separados. La s<strong>en</strong>t<strong>en</strong>cia Write se veráposteriorm<strong>en</strong>te.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 947.6.2.2 Función Line Input y función InputLa función Line Input # lee una línea completa del archivo y devuelve su cont<strong>en</strong>ido <strong>como</strong> valor deretorno. Su forma g<strong>en</strong>eral es:varString = Line Input #fileNoConvi<strong>en</strong>e recordar que <strong>en</strong> los ficheros de texto se suele utilizar el carácter return (o Intro)para delimitar las distintas líneas. Este es el carácter ASCII nº 13, que por no ser un carácterimprimible se repres<strong>en</strong>ta <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> chr(13). En muchas oca<strong>si</strong>ones (<strong>como</strong> her<strong>en</strong>ciadel MS-DOS) se utiliza <strong>como</strong> delimitador de líneas una combinación de los caracteres return ylinefeed, repres<strong>en</strong>tada <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> chr(13)+chr(10). En la cad<strong>en</strong>a de caracteres quedevuelve Line no se incluye el carácter de terminación de la línea.Para leer todas las líneas de un fichero se utiliza un bucle for o while. <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong>dispone de la función EOF (End of File) que devuelve True cuando se ha llegado al final delfichero. Véase el <strong>si</strong>gui<strong>en</strong>te ejemplo:Do While Not EOF(fileNo)miLinea = Line Input #fileNo...LoopTambién se puede utilizar la función Input, que ti<strong>en</strong>e la <strong>si</strong>gui<strong>en</strong>te forma g<strong>en</strong>eral:varString = Input(nchars, #fileNo)donde nchars es el número de caracteres que se quier<strong>en</strong> leer y varString es la variable donde sealmac<strong>en</strong>an los caracteres leídos por la función. Esta función lee y devuelve todos los caracteres que<strong>en</strong>cu<strong>en</strong>tra, incluidos los intro y linefeed. Para ayudar a utilizar esta función existe la función LOF(fileNo), que devuelve el nº total de caracteres del fichero. Por ejemplo, para leer todo el cont<strong>en</strong>idode un fichero y escribirlo <strong>en</strong> una caja de texto se puede utilizar:txtCaja.text = Input(LOF(fileNo), #fileNo)7.6.2.3 Función Print #Para escribir el valor de unas ciertas variables <strong>en</strong> un fichero previam<strong>en</strong>te abierto <strong>en</strong> modo Output oApp<strong>en</strong>d se utiliza la instrucción Print #, que ti<strong>en</strong>e la <strong>si</strong>gui<strong>en</strong>te forma:Print #fileNo, var1, var2, var2, ...donde var1, var2,... pued<strong>en</strong> ser variables, expre<strong>si</strong>ones que dan un resultado numérico oalfanumérico, o cad<strong>en</strong>as de caracteres <strong>en</strong>tre dobles comillas, tales <strong>como</strong> “El valor de x es...”.Con<strong>si</strong>dérese el <strong>si</strong>gui<strong>en</strong>te ejemplo:Print #1, "El valor de la variable I es: ", Idonde I es una variable con un cierto valor que se escribe a continuación de la cad<strong>en</strong>a. Las reglaspara determinar el formato de la función Print # son las mismas que las del método Print vistopreviam<strong>en</strong>te.


Capítulo 7: Archivos y Entrada/Salida de Datos página 957.6.2.4 Función Write #A difer<strong>en</strong>cia de Print #, la función Write # introduce comas <strong>en</strong>tre las variables y/o cad<strong>en</strong>as decaracteres de la lista, además <strong>en</strong>cierra <strong>en</strong>tre dobles comillas las cad<strong>en</strong>as de caracteres antes deescribirlas <strong>en</strong> el fichero. La función Write # introduce un carácter newline, esto es, un return o unreturn+linefeed después del último carácter de las lista de variables. Los ficheros escritos conWrite # son <strong>si</strong>empre legibles con Input #, cosa que no se puede decir de Print #. Véase el <strong>si</strong>gui<strong>en</strong>teejemplo:’ Se abre el fichero para escrituraOp<strong>en</strong> "C:\Temp\TestFile.txt" For Output As #1Write #1, "Hello World", 234’ Datos separados por comasMyBool = False: MyDate = #2/12/1969# ’ Valores de tipo boolean y DateWrite #1, MyBool; " is a Boolean value"Write #1, MyDate; " is a date"Close #1’ Se cierra el ficheroEl fichero TestFile.txt guardado <strong>en</strong> C:\Temp cont<strong>en</strong>drá:"Hello World",234#FALSE#," is a Boolean value"#1969-02-12#," is a date"7.7 FICHEROS DE ACCESO ALEATORIOLos ficheros de acceso aleatorio se caracterizan porque <strong>en</strong> ellos se puede leer <strong>en</strong> cualquier ord<strong>en</strong>.Los ficheros de acceso aleatorio son ficheros binarios. Cuando se abre un fichero se debe escribirFor Random, al especificar el modo de apertura (<strong>si</strong> el fichero se abre For Binary el acceso es<strong>si</strong>milar, pero no por registros <strong>si</strong>no por bytes; este modo es mucho m<strong>en</strong>os utilizado).7.7.1 Abrir y cerrar archivos de acceso aleatorioEstos archivos se abr<strong>en</strong> también con la s<strong>en</strong>t<strong>en</strong>cia Op<strong>en</strong>, pero con modo Random. Al final se añadela s<strong>en</strong>t<strong>en</strong>cia L<strong>en</strong>=longitudRegistro, <strong>en</strong> bytes. Véase el <strong>si</strong>gui<strong>en</strong>te ejemplo:fileNo = FreeFile<strong>si</strong>ze = L<strong>en</strong>(unObjeto)Op<strong>en</strong> fil<strong>en</strong>ame For Random as #fileNo L<strong>en</strong> = <strong>si</strong>zedonde fil<strong>en</strong>ame es una variable que almac<strong>en</strong>a el nombre del archivo. Se recuerda que la funciónFreeFile devuelve un número <strong>en</strong>tero válido (esto es que no está <strong>si</strong><strong>en</strong>do utilizado) para poder abrirun fichero. El último parámetro informa de la longitud de los registros (todos deb<strong>en</strong> t<strong>en</strong>er la mismalongitud). <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> dispone de la función L<strong>en</strong>(objetoName), que permite calcular ladim<strong>en</strong><strong>si</strong>ón <strong>en</strong> bytes de cualquier objeto pert<strong>en</strong>eci<strong>en</strong>te a una clase o estructura.De ordinario los ficheros de acceso directo se utilizan para leer o escribir de una vez todo unbloque de datos. Este bloque suele ser un objeto de una estructura, con varias variables miembro.Los ficheros abiertos para acceso directo se cierran con Close, igual que los secu<strong>en</strong>ciales.7.7.2 Leer y escribir <strong>en</strong> una archivo de acceso aleatorio. Funciones Get y PutSe utilizan las funciones Get y Put. Su <strong>si</strong>ntaxis es la <strong>si</strong>gui<strong>en</strong>te:Get #fileNo, registroNo, variableObjetoPut #fileNo, registroNo, variableObjetoLa instrucción Get lee un registro del fichero y almac<strong>en</strong>a los datos leídos <strong>en</strong> una variable, quepuede ser un objeto de una determinada clase o estructura. La instrucción Put escribe el cont<strong>en</strong>ido


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 96de la variable <strong>en</strong> la po<strong>si</strong>ción determinada del fichero. Si se omite el número de registro se lee(escribe) a continuación del registro leído (escrito) anteriorm<strong>en</strong>te. Véase el <strong>si</strong>gui<strong>en</strong>te ejemplo:FileNo=FreeFile<strong>si</strong>ze=L<strong>en</strong>(unObjeto)Op<strong>en</strong> fil<strong>en</strong>ame for Random as #fileNo L<strong>en</strong>=<strong>si</strong>zeGet #fileNo, 3, <strong>si</strong>zeCon este ejemplo, se ha abierto el fichero fil<strong>en</strong>ame de la misma forma que se realizó <strong>en</strong> elejemplo anterior, pero ahora, además se ha leído un registro de longitud <strong>si</strong>ze, y más <strong>en</strong> concreto, eltercer registro. Si se qui<strong>si</strong>era modificar el valor de este registro, no habría más que a<strong>si</strong>gnarle el valorque se qui<strong>si</strong>era, para a continuación introducirlo <strong>en</strong> el fichero mediante la s<strong>en</strong>t<strong>en</strong>cia <strong>si</strong>gui<strong>en</strong>te:Put #fileNo, 3, <strong>si</strong>ze7.8 FICHEROS DE ACCESO BINARIOLa técnica a emplear es bá<strong>si</strong>cam<strong>en</strong>te la misma que con los ficheros de acceso aleatorio, con lasalvedad de que <strong>en</strong> lugar de manejar registros, <strong>en</strong> los ficheros de acceso binario se trabaja con bytes.Véase el <strong>si</strong>gui<strong>en</strong>te ejemplo:FileNo=FreeFileOp<strong>en</strong> fil<strong>en</strong>ame for Binary as #fileNoGet #1, 4, datodato = 7Put #1, 4, datoClose #1En el anterior ejemplo se puede observar <strong>como</strong> primero se introduce <strong>en</strong> la variable dato elvalor del cuarto byte del fichero fil<strong>en</strong>ame, para posteriorm<strong>en</strong>te a<strong>si</strong>gnarle el valor 7, e introducirlo d<strong>en</strong>uevo <strong>en</strong> el cuarto byte de fil<strong>en</strong>ame.


ANEXO A: Con<strong>si</strong>deraciones adicionales sobre datos y variables página 978. ANEXO A: CONSIDERACIONES ADICIONALES SOBRE DATOS Y VARIABLESEn este Anexo se incluy<strong>en</strong> algunas con<strong>si</strong>deraciones de interés para personas que no han programadoantes <strong>en</strong> otros l<strong>en</strong>guajes. A continuación se explican las po<strong>si</strong>bilidades y la forma de almac<strong>en</strong>ar losdistintos tipos de variables.8.1 CARACTERES Y CÓDIGO ASCIILas variables string (cad<strong>en</strong>as de caracteres) conti<strong>en</strong><strong>en</strong> un conjunto de caracteres que se almac<strong>en</strong>an<strong>en</strong> bytes de memoria. Cada carácter es almac<strong>en</strong>ado <strong>en</strong> un byte (8 bits). En un bit se pued<strong>en</strong>almac<strong>en</strong>ar dos valores (0 y 1); con dos bits se pued<strong>en</strong> almac<strong>en</strong>ar 2 2 = 4 valores (00, 01, 10, 11 <strong>en</strong>binario; 0, 1 2, 3 <strong>en</strong> decimal). Con 8 bits se podrán almac<strong>en</strong>ar 2 8 = 256 valores difer<strong>en</strong>tes(normalm<strong>en</strong>te <strong>en</strong>tre 0 y 255; con ciertos compiladores <strong>en</strong>tre -128 y 127).En realidad, cada letra se guarda <strong>en</strong> un solo byte <strong>como</strong> un número <strong>en</strong>tero, el correspondi<strong>en</strong>te aesa letra <strong>en</strong> el código ASCII (una correspond<strong>en</strong>cia <strong>en</strong>tre números <strong>en</strong>teros y caracteres, ampliam<strong>en</strong>teutilizada <strong>en</strong> informática), que se muestra <strong>en</strong> la Tabla 8.1 para los caracteres estándar (existe uncódigo ASCII ext<strong>en</strong>dido que utiliza los 256 valores y que conti<strong>en</strong>e caracteres especiales y caracteresespecíficos de los alfabetos de diversos países, <strong>como</strong> por ejemplo las vocales ac<strong>en</strong>tuadas y la letra ñpara el castellano).0 1 2 3 4 5 6 7 8 90 nul soh stx etx eot <strong>en</strong>q ack bel bs ht1 nl vt np cr so <strong>si</strong> dle dc1 dc2 dc32 dc4 nak syn etb can em sub esc fs gs3 rs us sp ! “ # $ % & ‘4 ( ) * + , - . / 0 15 2 3 4 5 6 7 8 9 : ;6 < = > ? @ A B C D E7 F G H I J K L M N O8 P Q R S T U V W X Y9 Z [ \ ] ^ _ ` a b c10 d e f g h i j k l m11 n o p q r s t u v w12 x y z { | } ~ delTabla 8.1. Código ASCII estándar.Esta tabla se utiliza de la <strong>si</strong>gui<strong>en</strong>te forma. La primera cifra (las dos primeras cifras, <strong>en</strong> el casode los números mayores o iguales que 100) del número ASCII correspondi<strong>en</strong>te a un carácterdeterminado figura <strong>en</strong> la primera columna de la Tabla 8.1, y la última cifra <strong>en</strong> la primera fila dedicha Tabla. Sabi<strong>en</strong>do la fila y la columna <strong>en</strong> la que está un determinado carácter puede componerseel número ASCII correspondi<strong>en</strong>te. Por ejemplo, la letra A está <strong>en</strong> la fila 6 y la columna 5. Sunúmero ASCII es por tanto el 65. El carácter % está <strong>en</strong> la fila 3 y la columna 7, por lo que surepres<strong>en</strong>tación ASCII será el 37. Obsérvese que el código ASCII asocia números consecutivos conlas letras mayúsculas y minúsculas ord<strong>en</strong>adas alfabéticam<strong>en</strong>te. Esto <strong>si</strong>mplifica notablem<strong>en</strong>te ciertasoperaciones de ord<strong>en</strong>ación alfabética de nombres. Nótese que todas las mayúsculas ti<strong>en</strong><strong>en</strong> códigoASCII anterior a cualquier minúscula.


ESIISS: <strong>Apr<strong>en</strong>da</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> <strong>como</strong> <strong>si</strong> <strong>estuviera</strong> <strong>en</strong> <strong>Primero</strong> página 98En la Tabla 8.1 aparec<strong>en</strong> muchos caracteres no imprimibles (todos aquellos que se expresancon 2 ó 3 letras). Por ejemplo, el ht es el tabulador horizontal, el nl es el carácter nueva línea, etc.En realidad la Ver<strong>si</strong>ón <strong>6.0</strong> de <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> no utiliza para repres<strong>en</strong>tar caracteres el códigoASCII <strong>si</strong>no el Unicode, que utiliza dos bytes por carácter, con lo cual ti<strong>en</strong>e capacidad pararepres<strong>en</strong>tar 65536 caracteres, pudiéndose adaptar a las l<strong>en</strong>guas ori<strong>en</strong>tales. Para los caracteres latinosel byte más <strong>si</strong>gnificativo coincide con el del código ASCII, mi<strong>en</strong>tras que el segundo byte está a cero.8.2 NÚMEROS ENTEROSLos números <strong>en</strong>teros <strong>en</strong> <strong>Visual</strong> <strong>Ba<strong>si</strong>c</strong> <strong>6.0</strong> se guardan <strong>en</strong> 1, 2 ó 4 bytes.• Con 8 bits (1 byte) se podrían guardar 2 8 números: desde 0 hasta 255.• Con 16 bits (2 bytes) se podrían guardar 2 16 números: desde 0 hasta 65.535. Si se reservaun bit para el <strong>si</strong>gno se t<strong>en</strong>drían 2 15 números: desde -32768 hasta 32767• Con 32 bits (4 bytes) se podrían guardar 2 32 números: desde 0 hasta 4.294.967.295. Si sereserva un bit para el <strong>si</strong>gno se t<strong>en</strong>drían 2 31 : desde -2.147.483.648 hasta 2.147.483.6478.3 NÚMEROS REALESEn muchas aplicaciones hac<strong>en</strong> falta variables reales, capaces de repres<strong>en</strong>tar magnitudes quecont<strong>en</strong>gan una parte <strong>en</strong>tera y una parte fraccionaria o decimal. Estas variables se llaman tambiénde punto flotante. De ordinario, <strong>en</strong> base 10 y con notación ci<strong>en</strong>tífica, estas variables se repres<strong>en</strong>tanpor medio de la mantisa, que es un número mayor o igual que 0.1 y m<strong>en</strong>or que 1.0, y un expon<strong>en</strong>teque repres<strong>en</strong>ta la pot<strong>en</strong>cia de 10 por la que hay que multiplicar la mantisa para obt<strong>en</strong>er el númerocon<strong>si</strong>derado. Por ejemplo, el número π se repres<strong>en</strong>ta <strong>como</strong> 0.3141592654⋅10 1 . Tanto la mantisa<strong>como</strong> el expon<strong>en</strong>te pued<strong>en</strong> ser po<strong>si</strong>tivos y negativos.8.3.1 Variables tipo SingleLos computadores trabajan <strong>en</strong> base 2. Por eso un número con decimales de tipo Single se almac<strong>en</strong>a<strong>en</strong> 4 bytes (32 bits), utilizando 24 bits para la mantisa (1 para el <strong>si</strong>gno y 23 para el valor) y 8 bitspara el expon<strong>en</strong>te (1 para el <strong>si</strong>gno y 7 para el valor). Es interesante ver qué clase de números depunto flotante pued<strong>en</strong> repres<strong>en</strong>tarse de esta forma. En este caso hay que distinguir el rango de lapreci<strong>si</strong>ón. La preci<strong>si</strong>ón hace refer<strong>en</strong>cia al número de cifras con las que se repres<strong>en</strong>ta la mantisa: con23 bits el número más grande que se puede repres<strong>en</strong>tar es,2 23 = 8.388.608lo cual quiere decir que se pued<strong>en</strong> repres<strong>en</strong>tar todos los números decimales de 6 cifras y la mayorparte –aunque no todos– de los de 7 cifras (por ejemplo, el número 9.213.456 no se puederepres<strong>en</strong>tar con 23 bits). Por eso se dice que las variables tipo Single ti<strong>en</strong><strong>en</strong> <strong>en</strong>tre 6 y 7 cifrasdecimales equival<strong>en</strong>tes de preci<strong>si</strong>ón.Respecto al expon<strong>en</strong>te de dos por el que hay que multiplicar la mantisa <strong>en</strong> base 2, con 7 bits elnúmero más grande que se puede repres<strong>en</strong>tar es 127. El rango v<strong>en</strong>drá definido por la pot<strong>en</strong>cia,2 127 = 1.7014 · 10 38lo cual indica el ord<strong>en</strong> de magnitud del número más grande repres<strong>en</strong>table de esta forma.En el caso de los números Single (4 bytes) el rango es: desde -3.402823E38 a -1.401298E-45para los valores negativos y desde 1.401298E-45 a 3.402823E38 para los valores po<strong>si</strong>tivos.


ANEXO A: Con<strong>si</strong>deraciones adicionales sobre datos y variables página 998.3.2 Variables tipo DoubleAsí pues, las variables tipo Single ti<strong>en</strong><strong>en</strong> un rango y –sobre todo– una preci<strong>si</strong>ón muy limitada,insufici<strong>en</strong>te para la mayor parte de los cálculos técnicos y ci<strong>en</strong>tíficos. Este problema se solucionacon el tipo Double, que utiliza 8 bytes (64 bits) para almac<strong>en</strong>ar una variable. Se utilizan 53 bits parala mantisa (1 para el <strong>si</strong>gno y 52 para el valor) y 11 para el expon<strong>en</strong>te (1 para el <strong>si</strong>gno y 10 para elvalor). La preci<strong>si</strong>ón es <strong>en</strong> este caso,2 52 = 4.503.599.627.370.496lo cual repres<strong>en</strong>ta <strong>en</strong>tre 15 y 16 cifras decimales equival<strong>en</strong>tes. Con respecto al rango, con unexpon<strong>en</strong>te de 10 bits el número más grande que se puede repres<strong>en</strong>tar será del ord<strong>en</strong> de 2 elevado a 2elevado a 10 (que es 1024):2 1024 = 1.7977 · 10 308Si se con<strong>si</strong>dera el caso de los números declarados <strong>como</strong> Double (8 bytes) el rango va desde-1.79769313486232E308 a -4.94065645841247E-324 para los valores negativos y desde4.94065645841247E-324 a 1.79769313486232E308 para los valores po<strong>si</strong>tivos.8.4 SISTEMA BINARIO, OCTAL, DECIMAL Y HEXADECIMALA contnuación se pres<strong>en</strong>tan los primeros números naturales expresados <strong>en</strong> distintos <strong>si</strong>stemas d<strong>en</strong>umeración (bases 10, 2, 8 y 16). Para expresar los números <strong>en</strong> base 16 se utilizan las seis primerasletras del abecedario (A, B, C, D, E y F) para repres<strong>en</strong>tar los números decimales 10, 11, 12, 13, 14 y15. La calculadora que se incluye <strong>como</strong> accesorio <strong>en</strong> Windows 95 ofrece po<strong>si</strong>bilidades de expresarun número <strong>en</strong> distintos <strong>si</strong>stemas de numeración.Decimal Binario Octal Hexadecimal0 0 0 01 1 1 12 10 2 23 11 3 34 100 4 45 101 5 56 110 6 67 111 7 78 1000 10 89 1001 11 910 1010 12 A11 1011 13 B12 1100 14 C13 1101 15 D14 1110 16 E15 1111 17 F16 10000 20 1017 10001 21 11Tabla 3.4 Expre<strong>si</strong>ón de un número <strong>en</strong> los distintos <strong>si</strong>stemas.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!