Professional Documents
Culture Documents
Este libro, Visual Basic - Guía del Estudiante se ofrece a todos los
estudiantes de habla hispana como texto de libre difusión para fines
educativos. Prohibida la copia total o parcial con fines comerciales.
Madrid, Julio de 1998
Pagina: 1
INTRODUCCION Antecedentes históricos.
___________________________________
El lenguaje de programación BASIC (Beginner's All purpose Symbolic Instruction Code ) nació
en el año 1964 como una herramienta destinado a principiantes, buscando una forma sencilla
de realizar programas, empleando un lenguaje casi igual al usado en la vida ordinaria ( en
inglés), y con instrucciones muy sencillas y escasas. Teniendo en cuenta el año de su
nacimiento, este lenguaje cubría casi todas las necesidades para la ejecución de programas.
Téngase en cuenta que las máquinas existentes en aquella época estaban estrenando los
transistores como elementos de conmutación, los ciclos de trabajo llegaban a la impensable
cifra de 10.000 por segundo y la memoria no pasaba de unos pocos k´s en toroides de ferrita.
La evolución del BASIC por los años 70 fue escasa, dado el auge que tomaron en aquella
época lenguajes de alto nivel como el FORTRAN y el COBOL. En 1978 se definió una norma
para unificar los Basics existentes creándose la normativa BASIC STANDARD
Con la popularización del PC, salieron varias versiones del BASIC que funcionaban en este
tipo de ordenadores (Versiones BASICA, GW-BASIC), pero todas estas versiones del BASIC
no hicieron otra cosa que terminar de rematar este lenguaje. Los programadores profesionales
no llegaron a utilizarlo, habida cuenta de las desventajas de este lenguaje respecto a otras
herramientas (PASCAL, C, CLIPPER). El BASIC con estas versiones para PC llegó incluso a
perder crédito entre los profesionales de la informática.
Tal fue ese abandono por parte de los usuarios, que la aparición del Quick-BASIC de Microsoft,
una versión ya potente del BASIC, que corregía casi todos los defectos de las versiones pasó
prácticamente inadvertida, a no ser porque las últimas versiones del sistema operativo MS-
DOS incluían una versión de Quick-BASIC algo recortada (Q-Basic) como un producto mas
dentro de la amplia gama de ficheros ejecutables que acompañan al sistema operativo, y
aprovecha de él el editor de textos (Cada vez que se llama al EDIT estamos corriendo el editor
del Q-Basic).
Esta versión del popular BASIC ya es un lenguaje estructurado, lo que permite crear
programas modularmente, mediante subrutinas y módulos, capaz de crear programas ya
competitivos con otros lenguajes de alto nivel. Sin embargo llegaba tarde, pues los entornos
MS-DOS estaban ya superados por el entorno gráfico Windows.
Sin embargo algo había en el BASIC que tentaba a superarse: su gran sencillez de manejo. Si
a esto se le añade el entorno gráfico Windows, el aprovechamiento al máximo de las
posibilidades de Windows en cuanto a intercambio de información, de sus librerías, de sus
drivers y controladores, manejo de bases de datos, etc. el producto resultante puede ser algo
que satisfaga todas las necesidades de programación en el entorno Windows. La suma de
todas estas cosas es VISUAL - BASIC. Esta herramienta conserva del BASIC de los años 80
únicamente su nombre y su sencillez, y tras su lanzamiento al mercado, la aceptación a nivel
Pagina: 2
profesional hizo borrar por fin el "mal nombre" asociado a la palabra BASIC.
Es obligado decir sin embargo, que sigue siendo BASIC. No se pueden comparar sus
prestaciones con otros lenguajes cuando deseamos llegar al fondo de la máquina y controlar
uno a uno sus registros. No es ese el fin perseguido con VB y si es necesario llegar a esas
precisiones será necesario utilizar otro lenguaje que permita bajar el nivel de programación.
(Visual-C). o realizar librerías (DLLs) que lo hagan. En la mayor parte de las aplicaciones, las
herramientas aportadas por VB son mas que suficiente para lograr un programa fácil de
realizar y de altas prestaciones.
Es por tanto un termino medio entre la programación tradicional, formada por una sucesión
lineal de código estructurado, y la programación orientada a objetos. Combina ambas
tendencias. Ya que no podemos decir que VB pertenezca por completo a uno de esos dos tipos
de programación, debemos inventar una palabra que la defina : PROGRAMACION VISUAL.
- Generación del código asociado a los eventos que ocurran a estos objetos. A la
respuesta a estos eventos (click, doble click, una tecla pulsada, etc.) le llamamos
Procedimiento, y deberá generarse de acuerdo a las necesidades del programa.
Pagina: 3
previa de una variable. Una variable, como Vd. seguro que conoce, es un nombre que en el
programa le asignamos a un dato. Ese dato podrá cambiar. Piense por ejemplo, en un
programa consistente en la toma de datos de los alumnos de un centro escolar. Existirán
varias variables para poder introducir los datos de los alumnos. Estas variables pueden tener
nombre tales como:
Nombre
Apellido1
Apellido2
Dirección
Teléfono
DNI
La variable Nombre tomará valores distintos según vayamos introduciendo los datos de los
distintos alumnos. Es posible, que a lo largo de la ejecución del programa, esta variable
Nombre valga:
José
Pedro
María
Luis
Espero que su intuición o conocimiento anterior le lleve a conocer el concepto de variable. Mas
adelante lo verá mas claro.
Decíamos que Basic no exige la definición previa de las variables. Otras herramientas exigen
que se haga así. Por lo tanto es normal encontrar, en otros sistemas de programación, que un
programa comienza de la siguiente forma:
Mediante estas declaraciones, el programa sabe de que tipo de dato se trata y por tanto cómo
debe trabajar con él. En otros sistemas de programación distintos de Basic, es necesario
realizar esta declaración antes de introducir una variable.
Basic permite que no se declaren. Cuando a lo largo del programa le introducimos una variable
nueva, asume que es una variable y que el tipo es el adecuado para el valor que le estamos
introduciendo en ese momento.
DNI=50000000
Nombre ="Pedro"
Teléfono = "1234567"
entiende que DNI, Nombre y Teléfono son variables, que DNI es un número (No hemos metido
su valor entre comillas), y que Nombre y Teléfono son sucesiones de caracteres alfanuméricos
(su valor está entre comillas)
Esta particularidad de no necesitar declarar las variables hace que sea sencillo introducir una
variable nueva. Sin embargo entraña un gran peligro. Imagínese que en un paso posterior del
programa, le mandamos escribir esos tres datos anteriores con la instrucción PRINT
Pagina: 4
Print DNI
Print Nombre
Print Telwfono
Habrá observado en tercer lugar la palabra Telwfono, que por error ha introducido el
programador. Basic interpreta que Telwfono es una variable e irá a leer en memoria el valor
que tiene. No tendrá ningún valor. Por lo tanto no escribirá nada y encima no dará ningún
aviso de que se ha cometido un error. Nada es gratis en esta vida, y la facilidad para introducir
variables se paga con la posibilidad de un error.
Basic ha pensado en ese problema, y se puede solucionar con esta que será la primera
instrucción BASIC que vamos a estudiar:
OPTION EXPLICIT
Obliga a declarar previamente las variables que se vayan a usar. De no
haberla declarado antes de usarla, el programa dará una comunicación de
error.
TIPOS DE VARIABLES
Las variables pueden ser de los siguientes tipos: (El número indicado en segundo lugar indica
el número de Bytes que ocupa en memoria.)
(*) Una variable tipo String ocupa el mismo número de bytes que caracteres tenga la cadena.
(**) Una variable tipo Variant ocupa 16 bytes si se trata de un número y 22 bytes + longitud de
la cadena si se trata de un dato tipo cadena de caracteres.
Existen también variables definidas por el usuario (Ya verá la sentencia Type). En este tipo de
variables se pueden introducir muchos datos de distinto tipo. Los bytes necesarios para
almacenar esa variable dependerá de los datos que se hayan definido.
Dentro de las variables Objet (variables que se refieren a objetos) existe una gran variedad
que a estas alturas del curso no debemos complicarnos con ellas. Pero para adelantar algo,
veremos que una variable puede ser del tipo Form - Formulario - , tipo Picture, etc. etc.
Cada tipo de variable ocupa unos determinados bytes. Si no se define una variable, VB toma
como tipo por defecto para la variable el tipo Variant. Este tipo ocupa mas bytes que, por
ejemplo, un integer. Si el tipo de dato que vamos a introducir en una variable es un integer, y
no la hemos declarado como tal, VB asumirá para esa variable que es del tipo Variant, lo que
le llevará a gastar mas bytes de memoria (16) que los que necesitaría (2) si la hubiésemos
declarado previamente. Si esa variable va a estar en el rango de 0 a 255, y no declaramos
previamente que la variable va a se del tipo Byte, o la declaramos como integer, p. e.,
estamos desperdiciando memoria RAM y posiblemente, retardando la ejecución del programa.
Lo mismo podemos decir del resto de las variables, y lo importante que es definirlas y
Pagina: 5
definirlas bien.
NOTA. Observe en la lista anterior que un dato Booleano ocupa 2 Bytes, mientras que un dato
tipo Byte ocupa un byte. En muchas ocasiones declaramos variables tipo Boolean con la
intención de que ocupen menos espacio. Paradoja del VB. Si la declaramos como Byte
ocupamos menos espacio en memoria. Declarar una variable como Boolean tiene también sus
ventajas (escribirá menos código por lo general cuando necesite leer o escribir una variable
tipo Boolean), pero tenga presente esta observación respecto a los datos Boolean.
Puede declarar el tipo de la variable mediante un carácter después del nombre de la variable.
Esta técnica, obligatoria en Quick-Basic, está en desuso en VB. No es recomendable definir el
tipo de esta forma, pues existe un serio peligro de error. De cualquier forma, eso es potestativo
del programador y de sus costumbres.
En Visual Basic, cuando declaramos una variable como String (Cadena de caracteres), no es
necesario declarar su longitud. VB aceptará cualquier número de caracteres. Si desea evitar
que se puedan introducir más de un determinado número de caracteres, debe declarar su
número. Por ejemplo :
En este segundo caso, si se introduce como Var2 una cadena de caracteres con mas de 15
caracteres, Var2 tomará solamente los 15 primeros. Visual basic no presenta ningún aviso de
que esa variable ha omitido los caracteres que han sobrepasado la cifra de 15. Si desea que el
usuario conozca esa circunstancia, debe introducir el código oportuno para producir el aviso.
La declaración de variables tipo String con número de caracteres predefinido presenta también
inconvenientes a la hora de tratar esa cadena de caracteres con sentencias tales como Mid,
Left y Right, o a la hora de añadir una cadena a otra. La experiencia nos indica que NO
merece la pena declarar variables tipo String con el número de caracteres prefijado.
En una gran parte de los casos una variable que se compone de números debe declararse
como una variable de cadena de caracteres (String), y no como numérica. Cuando pensamos
por ejemplo en un número de DNI, compuesto por 7 u 8 cifras, un código postal, el número de
una calle, el piso de un edificio, parecen invitar a que la variable que los contenga sea una
variable de tipo numérico (Byte, Integer, Long, ...). Estas variables, aunque su contenido sean
números, siempre se deben declarar como String, ya que se tratan en realidad de cadenas de
caracteres, aunque estos sean números. Para aclarar mas estas ideas, piense en el número
del DNI con la letra del NIF incluido, o que el lugar del DNI se deba rellenar con el número del
permiso de residencia, (lleva letras). Piense en el código postal de una provincia que
comienza por 0 ( 08XXX = Barcelona ) . Si la variable que va a contener ese código postal se
declara como numérica, el cero de la izquierda lo desprecia, por lo que ese código postal
quedaría reducido al 8XXX, número de 4 cifras que el cartero nunca reconocería como un
código postal, que necesariamente ha de tener 5 cifras. Para terminar, piense la forma de
introducir en una variable numérica el número 32Bis de una calle o el piso S2 de un edificio. O
piense en una variable que va a contener un código de un producto. Ese código siempre va a
Pagina: 6
ser un número, por ejemplo de 9 cifras. ¿Ha pensado como trataría el ordenador una variable
numérica que contiene el código 000100123 ?. El resultado sería que convertiría ese código en
la cifra 100123, y Vd. deberá buscarse la vida para añadir los ceros iniciales a la hora de
sacarlo a una impresora, por ejemplo.
En todos los casos anteriores, el número no representa una cantidad numérica, sino un
nombre. Lo que ocurre es que ese nombre contiene solamente números.
¿Qué variables debemos declarar entonces como numéricas ? La respuesta es bien sencilla :
Aquellas que van a contener datos con lo que vamos a realizar operaciones
matemáticas.
Las variables booleanas (True/False) pueden en muchos casos sustituirse por una variable del
tipo Byte. Si ese datos True / False se va a introducir en una base de datos o en fichero en el
disco, puede ser mas prudente poner 0 en vez de False y 1 en vez de True.
Una variable byte ocupa muy poco, simplemente 1 byte como su nombre indica. Pero no
puede contener números mayores de 255 ni números negativos.
Cada vez que declare una variable numérica piense en los valores que puede tener, sobre
todo cuando esa variable va a ser el resultado de una operación matemática. Recuerde el
escaso margen de una variable tipo Integer ( de -32768 a 32767)
Denominamos ámbito de una variable a las partes del programa donde esa variable está
declarada. Para entenderlo mejor, veamos someramente la forma de un programa
desarrollado en VB.
Un programa VB tiene uno o varios formularios. Cada formulario tiene varios controles. Tanto
el formulario como cada uno de sus controles tienen una parte del programa, justamente la
parte relacionada con cada uno de los eventos que pueden suceder bien al formulario o a los
controles. A estas partes las habíamos llamado Procedimientos. Podemos tener
procedimientos que no estén relacionados con ningún evento ocurrido al formulario o a sus
controles. (Los Procedimientos que iremos insertando a lo largo de la aplicación)
Aparte de formularios y controles, un programa puede tener Módulos, y en cada uno de los
módulos podemos insertar cuantos Procedimientos y Funciones queramos. La estructura de
un programa VB puede ser de la siguiente forma:
Pagina: 7
Si se declara una variable dentro de un procedimiento o Función, esa variable "NO SALE" del
Procedimiento o Función donde se declaró. El procedimiento puede estar en un Formulario
(Cualquier procedimiento de un control o un procedimiento creado por nosotros) o en un
Módulo (En este caso, el procedimiento solo puede ser creado por nosotros)
En un Formulario, una variable puede declararse de dos formas : Privada o Pública. Para
declarar una variable a nivel de formulario debe hacerse en la sección de declaraciones, que
está la ventana de código Objeto = General, Proc. = Declaraciones. Si se declara Privada,
esa variable se puede mover por todo el formulario, (es decir, por todos los procedimientos de
todos los controles del formulario y por los Procedimientos que pudiésemos insertar en ese
formulario), pero no sale de dicho formulario. Si se declara como Pública, esa variable puede
moverse por todo el formulario, de la misma forma que lo haría declarada como Privada, y
además puede ser usada desde otro Formulario o Módulo, citándola con el nombre del
Formulario, seguido del nombre de la variable (Formulario.Variable)
En un Módulo una variable puede declararse como Privada, con lo que no saldrá de ese
Módulo, o Pública, pudiendo en este caso usarse en todo el programa. Cuando se declara una
variable como pública en un Módulo, basta referirse a ella por su nombre, sin citar el nombre
del Módulo donde se declaró.
En VB es posible declarar varias veces las variables, es decir, pueden declararse a nivel de
formulario, en su apartado de declaraciones, y esa variable conservará su valor en todas las
partes de ese formulario. Sin embargo, si se declara una variable con el mismo nombre a un
nivel inferior, por ejemplo al principio de un procedimiento, esa variable será una variable
distinta a la anterior, aunque tenga el mismo nombre, a al declararla en un Procedimiento,
solamente será válida en ese Procedimiento. Una vez que hayamos salido de ese
procedimiento, la variable con ese nombre volverá a ser la declarada en el Formulario. En
realidad, lo que tenemos son dos variables distintas, pero con el mismo nombre, una declarada
para todo el formulario excepto para el procedimiento donde se volvió a declarar, y otra para
ese procedimiento concreto.
NOTA.- No es recomendable declarar una variable a dos niveles. Es mucho mejor utilizar otro
nombre para esa variable dentro del procedimiento donde se le declararía por segunda vez. A
esta nota cabe exceptuar cuando declaramos variables para una operación tipo contador
For I = 1 To N
Esa variable I es práctico declararla con el mismo nombre en cada Procedimiento donde se
use.
Pagina: 8
Private nombrevariable As Tipovariable
NombreFormulario.Nombrevariable
Mediante la sentencia Global la variable puede usarse en todo el espacio del programa.
Sentencia STATIC
El nombre de una variable puede ser tan largo como queramos. hasta un máximo de 40
caracteres. En la versión VB para España se pueden usar incluso la Ñ y vocales acentuadas.
Es indiferente usar mayúscula ó minúsculas. No se sorprenda, si por ejemplo, la ha declarado
con mayúsculas y luego la cita con minúsculas al escribir el código, que automáticamente se
cambie a mayúsculas. El nombre de una variable siempre debe comenzar por una letra.
No hay problema por utilizar variables largas. Al compilar el programa no se lleva el nombre,
es decir, no le va a ocupar mas espacio. Utilice siempre nombres que le definan la variable
Pagina: 9
con algún sentido. Es muy útil a la hora de acordarse como se llaman, y sobre todo, a la hora
de rehacer un programa que realizó hace seis meses.
Pese a que Visual Basic no obliga a declarar variables, es muy útil hacerlo. De esta forma se
tiene control sobre el programa. La experiencia se lo irá demostrando.
En un Módulo
Creo que esta costumbre viene del lenguaje C. Pero no vale en VB. Se trata de declarar varias
variables juntas en una misma línea :
Esta declaración está MAL hecha. Visual Basic interpretará que Variable1, Variable2 y
Variable3 son del tipo Variant, y solamente Variable4 la supone como tipo String. La forma
correcta de hacerlo, si queremos declarar esas variables un una sola línea, es la siguiente :
Pagina: 10
Lenguaje Basic del Visual Basic.
No ha sido un juego de palabras. VB emplea unas instrucciones casi iguales a las que emplea
Quick Basic. Sin embargo ha añadido otras nuevas instrucciones, inherentes con la
programación visual. Vamos a estudiar aquí las instrucciones y definiciones mas sencillas,
comunes a QB y VB.
Sentencias condicionales.
Si no se cumple
Fin de la sentencia.
Así de fácil es programar en Basic. Lo que ocurre es que esta herramienta habla inglés, y lo
descrito anteriormente toma la forma:
If condición Then
Instrucciones
Else
Otras instrucciones
End If
En este ejemplo, la condición era que, o se cumple una condición y ejecuta unas determinadas
instrucciones, o no se cumple, y ejecuta otras condiciones distintas. Puede ocurrir que, caso de
no cumplirse la condicione primera, se abra un abanico de dos o tres posibilidades. La
sentencia condicional tendría entonces la forma:
If condición 1 Then
Instrucciones
ElseIf Condición 2
Otras instrucciones
ElseIf Condición 3
Otro juego de instrucciones
Else
Instrucciones que debe realizar caso de no cumplir las condiciones 1, 2 y 3.
End If
Como decíamos anteriormente, este es el tipo de sentencia condicional mas usada. Existe
otra:
Select Case
Su nombre casi nos define lo que es: Selecciona, dependiendo del caso, un determinado juego
de instrucciones:
Select Case variable ' variable es una variable que puede tomar los valores (p.e.)
de 1 a 4
Pagina: 11
Case 1
Instrucciones a ejecutar en caso de que variable =1
Case 2
Instrucciones a ejecutar en caso de que variable =2
Case 3
Instrucciones a ejecutar en caso de que variable =3
Case 4
Instrucciones a ejecutar en caso de que variable =4
End Select
Este procedimiento resulta mucho mas sencillo y rápido que las sentencias If Then Else
vistas anteriormente, cuando el margen de elección es mayor que 2.
Switch toma una serie de parámetros, todos por parejas. El primer término de cada pareja es
la expresión a evaluar. El segundo es el valor que tiene que devolver. En realidad Switch es
una función (las funciones las veremos muy pronto)
Esta instrucción obtiene un valor para A que dependerá del valor que tome B entre los valores
posibles (1, 2 ó 3)
La sentencia Choose es casi igual, cambia solamente la forma. La misma intrucción anterior
puede realizarse con Choose de la siguiente forma:
A = Choose ( B, 5, 7, 11 )
Con estas sentencias condicionales es posible realizar bifurcaciones del programa, cambiar las
propiedades de un objeto, obtener resultados de operaciones, ....
Sentencias de bucle.
Es muy común utilizar bucles a lo largo de un programa. Un bucle es una sucesión repetitiva
de instrucciones, que se estarán realizando mientras se cumpla una condición o mientras no se
cumpla otra condición. Es tan sencillo como esto:
Mientras condición
Instrucciones
Existen dos formas de bucle: Una, que realiza un número determinado de recorridos por el
bucle. Es el denominado bucle por contador. Otra, realiza el bucle hasta que se cumpla (o deje
de cumplirse) una condición. Es el llamado bucle por condición.
Realiza el bucle tantas veces como le indiquemos. Por ejemplo, en este bucle nos va a
presentar las 26 letras mayúsculas del alfabeto inglés
Pagina: 12
For N=65 To 90
Label1.caption = Chr ( N )
Next N
Este "programa" nos presentará en una caja (Label) los caracteres cuyo número ASCII vaya
desde el 65 (A) al 90 (Z) Comenzará presentando el correspondiente al número 65, e irá
presentando sucesivamente el 66, el 67, etc., hasta llegar al 90, donde se parará.
X=0
Do While X < 1000
X=X+1
Loop
El programa toma una variable ( X ) que previamente tuvimos la curiosidad de ponerla a cero,
e incrementa su valor una unidad. Analiza si el valor de X es menor que 1000, y si es cierto,
vuelve a realizar el bucle. Así hasta que X ya no sea menor que 1000. Al dejar de cumplirse
que X sea menor que 1000, sale del bucle. Acabamos de realizar un temporizador, y también
de exponer las sentencias condicionales y los bucles, inicio de cualquier curso de Basic. Como
final de lección, se propone un problema. Con el primer bucle, donde visualizábamos los
caracteres A a la Z, posiblemente no nos diese tiempo de ver cada una de las letras que iban
apareciendo en la pantalla, en la etiqueta Label1, dado que cambiaría con mucha velocidad, y
solamente veríamos la Z, que es donde se detuvo el programa. Podemos poner un
temporizador cada vez que presente una letra, y así nos dará tiempo a verla. Con los dos
bucles vistos anteriormente ya podemos hacerlo.
X=0
Do Until X > 1000
X=X+1
Loop
Observe que la diferencia entre una y otra es la condición, While para indicar Mientras se
cumpla que ... y Until para indicar Mientras no se cumpla que ....
For N=65 To 90
Label1.caption = Chr ( N )
Label1.RefreshN ' Refresca la etiqueta
X=0
Do While X < 1000
X=X+1
Loop
Next N
Este es nuestro primer programa en BASIC. En VISUAL BASIC es idéntico, pero nos falta la
interface gráfica. Para realizarla basta con abrir el VB y sobre el formulario que aparece al
abrirlo, introducir una etiqueta, (Label) que llevará el nombre por defecto de Label1. Solo nos
queda pensar donde introducimos el código anterior. Podemos introducir un botón de comando
Pagina: 13
(Command Button) que saldrá con el nombre por defecto de Command1. Haga doble click
sobre el botón. Aparecerá el procedimiento Click. Este procedimiento es el que se realiza
cuando hacemos click sobre ese botón. Escriba en ese procedimiento este código.
Hemos puesto nuestra primera piedra en Visual Basic. Este ejemplo es muy sencillo. Visual
Basic es tan sencillo como este ejemplo.
Pagina: 14
BASIC DE VISUAL BASIC (2)
___________________________
Funciones de cadenas
Se denomina CADENA a una sucesión de caracteres. Una cadena puede tener uno o varios
caracteres alfanuméricos. Una cadena es también una sucesión de números.
Ejemplo de cadenas:
Hagamos una distinción entre una cadena que contenga números y un número. Un número
tiene un valor, pero también tiene una presentación escrita. El valor es algo que estará en el
ordenador como una sucesión de bits. Dependiendo de como lo hayamos declarado, tendrá
mas o menos bits. Pero esa información no es un número legible por el usuario. Lo que sí es
legible por el usuario es la representación en numeración decimal (u octal, o hexadecimal, o
incluso en binario) de ese número. Esa representación del número en un determinado sistema
de numeración es una cadena.
Así, el número nueve, que en la memoria del ordenador será una sucesión de bits, el
ordenador puede presentárnoslo como:
9 En numeración decimal
9 En numeración hexadecimal
11 En numeración octal
1001 En numeración binaria
Esas formas de presentarnos el número son CADENAS de caracteres. El valor del número
dentro del ordenador es un NUMERO.
Cuando introducimos un valor numérico por teclado o pantalla, el ordenador para hacer
operaciones con él, debe transformarlo a un número.
Estas consideraciones nos llevan a las dos primeras funciones con cadenas:
Ejemplos
Pagina: 15
Este ejemplo pondría en la etiqueta Label1 los caracteres correspondientes al valor
que tuviese la variable Variablenumerica .
Nota para recordar: Siempre habrá que convertir un número a una cadena cuando
queramos presentarlo en la pantalla. Siempre habrá que convertir a número la cadena
de caracteres numéricos que hayamos introducido por teclado o por pantalla, cuando
queramos operar con ese número. Un Label, cuando tiene que presentar un único
número, no le pedirá que se lo convierta a cadena, pues VB hace automáticamente esa
conversión. Sin embargo, cuando tiene que presentar un número, y además un texto en
el mismo Label, VB no realizará automáticamente ese cambio, por lo que le dará un
error. Le recomiendo que convierta los números a variables de cadena siempre que los
quiera presentar en un Label o TextBox.
Existe una función mas amplia que Str. Se trata de Cstr. Esta función no solamente
transforma un número a una cadena, como hace Str, sino que convierte cualquier tipo de
variable a una variable tipo String (cadena).
Esta función transforma, por ejemplo, una variable tipo Booleana en una variable de cadena,
devolviendo la cadena “Verdadero” si el valor de la variable booleana es True, y “Falso” si es
False.
Si se aplica Cstr a una variable tipo Fecha/Hora devuelve la fecha / Hora en formato corto.
Left (cadena, n)
Extrae los n primeros caracteres de una cadena, comenzando por la izquierda.
Pagina: 16
LCase (cadena) Devuelve otra cadena igual, pero con todos los
caracteres en minúsculas. (LCase = Lower Case)
UCase (cadena) Devuelve otra cadena igual, pero con todos los
caracteres en mayúsculas. (UCase = Upper Case)
LTrim Elimina los posibles espacios que tenga una cadena por su
izquierda.
Rtrim Elimina los posibles espacios que tenga una cadena por su
derecha.
Trim Elimina los espacios que tenga una cadena, tanto por su
izquierda como por su derecha. (No elimina los espacios
centrales de la cadena)
Estas tres funciones se emplean para quitar los posibles espacios que pueden resultar
de una entrada de datos. Tienen especial importancia cuando se toman los datos de un archivo
o base de datos, donde fueron introducidos por otro programa.
No se pone ningún ejemplo de estas funciones, pues sería difícil verlo impreso.
Pagina: 17
ProperCase.
Mid puede usarse también para cambiar el contenido de una cadena. Observe la sutileza entre
Mid como Función de cadena y Mid como Instrucción.
Resultado Mid (cadena, 7,2)=”Sobre” ---- > Resultado = Curso sobre Visual
Basic
Visual Basic puede operar con números tal como lo haría cualquier persona. Conoce las 4
reglas, y puede utilizar paréntesis de la misma forma que los escribimos sobre el papel.
+ Suma
- Resta
* Multiplicación
/ División
\ División sin decimales
Mod Resto de una división
^ Eleva a un exponente
Ejemplos
Existen otras operaciones que se pueden realizar con números: comparaciones. Los
operadores que realizan comparaciones se denominan Operadores relacionales. El
resultado de las operaciones realizadas con estos operadores solamente admiten dos
resultados: True (Cierto) o False (Falso) Estos operadores son:
Pagina: 18
= Igual que
<> No igual que
< Mayor que
<= Mayor o igual que
> Menor que
=> Igual o menor que
Estos operadores se suelen utilizar en estructuras de programa donde se tome una decisión.
Operadores Lógicos
Estos operadores sólo tienen sentido cuando hablemos de variables Booleanas, es decir,
aquellas que solamente pueden tomar los valores cero y uno.
Trigonométricas
Pagina: 19
Tan Tangente Devuelve la tangente de un ángulo
NOTA MUY IMPORTANTE.- Los números aleatorios generados de esta forma son siempre iguales,
eso sí, dependiendo del número que se le introduzca como parámetro. Esta generación de
números no produce números aleatorios pues como se dijo, dependen del numero que se meta
como parámetro, y si este se repite, se repite la sucesión de números que nos crea el generador
aleatorio.
Randomize Timer
La función Randomize devuelve una variable Rnd con un número comprendido entre 0 y 1
(Nunca será 0 ni 1) Leyendo el valor de la variable sucesivas veces, se puede obtener una
sucesión de números aleatorios. No es necesario ejecutar la instrucción Randomize Timer
cada vez que se quiera obtener un dato de la variable Rnd.
Supongamos que tenemos un formulario con una etiqueta de nombre Label1, un botón de
comando de nombre Command1. Cuando hagamos click sobre el botón de comando deberá
generar un número comprendido entre el 1 y el 49. En el procedimiento click de Command1
pondremos el siguiente código:
Randomize Timer
A = Rnd
A = Rnd * 100
A = CInt(A)
Do While A > 49
A = A - 49
Loop
Do While A < 1
A = A + 49
Loop
Label1.caption = A
End Sub
Realice este pequeño programa, con la instrucción Randomize Timer y sin ella.
Pagina: 20
Funciones con fechas.
Las fechas son cadenas especiales. Visual Basic sabe obtener y tratar la información relativa a
la fecha y la hora. Dispone para ello de una declaración de variable: Date. Una variable
declarada como date puede contener una fecha, una fecha y una hora o una hora solamente.
Date Devuelve la fecha de hoy. Esta fecha la toma del reloj del ordenador.
Mediante estas instrucciones podemos obtener el dato necesario de una fecha u hora. Por
ejemplo, para obtener el día de hoy solamente:
Pagina: 21
Función FORMAT
Esta función permite presentar cadenas de numéricas o fechas de una determinada forma.
Permite establecer el Formato de esa cadena.
Si recurre a la ayuda de VB acerca de esta función se va a enterar muy poco de lo que puede
dar de sí. La sintaxis que presenta es :
Lo mejor que puede hacer con esta definición de la sintaxis de Format es olvidarla. No le
aclara mucho lo que se puede hacer con Format. La función Format se usa para poner una
fecha en un determinado formato. Con la expresión :
la variable FechadeHoy tendrá el valor 1998-05-21, que se refiere al día 21 de mayo de 1998,
según el formato recomendado por la norma ISO-8601 para la presentación de fechas. Si
hubiésemos puesto la expresión FechadeHoy = Format (Now, “dd/mm/yy”) , la variable
FechadeHoy contendría el valor 21/05/98 referido al día citado.
Las posibilidades de Format llegan también al campo de las cadenas numéricas. Por ejemplo
la cifra 123456 se transformará en las siguientes expresiones, según como empleemos la
función Format
Donde
expresión es una cadena o fecha válida
formato es uno de los formatos predefinidos (Standard, Currency, etc. Vea mas abajo)
firstdayofweek. Especifica el primer día de la semana. Puede tomar uno de estos valores o
constantes :
firstweekofyear Especifica cual es la primera semana del año. Puede tomar uno de los
siguientes valores o constantes :
Pagina: 22
vbFirstFourDays 2 La primera semana es la que contiene al menos, 4 días de ese
año (Rec. ISO - 8601)
vbFirstFullWeek 3 La primera semana es la que tiene todos sus días en ese año
No se complique la vida con el tema del primer día de la semana ni la primera semana del
año. No lo usará con frecuencia. Centrémonos mas en el parámetro Formato. Puede tomar
muchos valores. Veamos los principales. Primero para números
Observe que usamos la expresión Variable =Format (1234567,”Formato”) para todos los
ejemplos de números.
(Cada carácter # indica que ahí va un número. El separador debe ser una coma, no un punto,
aunque esto depende del idioma que esté usando)
Puede poner una de estas expresiones, eso si, siempre entre comillas dobles :
Format dispone de mas opciones. Sería muy largo explicarlas aquí. Para mas información, en
la WEB de Microsoft puede encontrar mas formatos posibles.
Pagina: 23
MATRICES
Cuando utilizamos varias variables que tienen un significado similar para nosotros, pero que
son distintas (Por ejemplo, el nombre de los alumnos de una clase) podemos utilizar una
matriz. Esta matriz está formada por tantos elementos como alumnos tenga la clase. El
nombre asociado a cada uno de los elementos de la matriz puede ser:
Las matrices normalmente comienzan a numerar por el número 0. Este comienzo puede no
ser el mas apropiado para la variable que estamos planteando, pues ningún alumno tiene el
número de orden 0. Para hacer que una matriz comience a numerar por el 1 se debe definir
mediante la instrucción:
Option Base 1
que debe colocarse al comienzo del módulo o formulario donde declaremos la matriz.
Para declarar la matriz se hace como con todas las variables, especificando entre paréntesis el
número de elementos que componen la matriz:
Hemos declarado que la variable alumno es una cadena, y que hay 25 elementos en esa
matriz.
Donde le decimos que la variable Alumno tiene 25 elementos, que el primero tiene el índice 1
y el último tiene el índice 25.
Pero imaginemos que queremos meter en la misma matriz el nombre, primer apellido y
segundo apellido del alumno. Necesitaremos declarar una matriz de 25 por 3. Como todos los
elementos serán cadenas de caracteres, podemos declararla de la siguiente forma:
De esta forma, el primer apellido del alumno que ocupa el puesto número 15 de la clase, será
el elemento:
Alumno (15, 2)
Dim Variable ( 1 To N, 1 To M, 1 To P, 1 To Q, 1 To R)
Una variable ya declarada como una matriz puede redimensionarse a lo largo del programa
mediante la instrucción ReDim
Pagina: 24
Mediante la declaración 1 To 25 le estamos diciendo que el primer elemento de la matriz es el
1, independientemente de lo que hayamos puesto en OPTION BASE. Si se redimensiona
simplemente con el número de elementos :
ReDim (25)
le estamos diciendo que tiene 25 elementos, pero que el primero sea el 0 ó el 1 depende de
haber puesto OPTION BASE 0 u OPTION BASE 1.
Una matriz puede redimensionarse cuantas veces se quiera a lo largo de la aplicación, pero
esa redimensión no puede afectar al número de dimensiones de la matriz. Si redimensionamos
la matriz perderá la información existente. Para evitar perder la información presente en la
matriz, debe utilizar la sentencia ReDim Preserve.
Dim MiMatriz()
Observe que no solamente la hemos cambiado dos veces de dimensiones (la primera a 2 y la
segunda a 3), sino que también hemos cambiado el número de elementos en cada dimensión.
Si hubiésemos utilizado ReDim Preserve solamente podríamos haber usado la primera de las
dos líneas anteriores :
pero ya no podríamos volver a cambiar el número de dimensiones con la segunda línea. Nos
daría un error.
Con ReDim podemos cambiar el número de elementos de cada dimensión cuantas veces
queramos. Por ejemplo, podemos redimensionar MiMatriz de las siguiente forma :
ReDim MiMatriz (1 To 5, 1 To 9)
ReDim MiMatriz (1 To 15, 1 To 20)
ReDim MiMatriz (1 To 25, 1 To 30)
...........................
Si hubiésemos empleado ReDim Preserve, podríamos cambiar los elementos de todas las
dimensiones de la matriz una vez :
ReDim Preserve (1 To 5, 1 To 9)
Pagina: 25
ReDim Preserve (1 To 5, 1 To 30)
Esto no causa ningún error en una matriz de una dimensión, ya que si la matriz tiene sólo una
dimensión, puede cambiar el tamaño de esa dimensión porque es la única y la última.
Para conocer el índice máximo y mínimo de una matriz se usan las funciones UBound y
LBound.
UBound devuelve el mayor subíndice disponible para la dimensión indicada de una matriz.
LBound devuelve el mayor subíndice disponible para la dimensión indicada de una matriz.
En otro momento queremos tener el control de los índices de esa matriz, y queremos averiguar
el índice menor y mayor de cada una de sus dimensiones :
(IID1= Indice Inferior Dimensión 1, ISD 1 = Indice Superior Dimensión 1, etc. )
Pagina: 26
VISUAL BASIC
Entre en el programa VB. Le aparecerá en pantalla algo similar a esto : (Para VB Vers. 4)
Este es el comienzo del programa . Observe que en esta pantalla existen varias cosas. En la
parte superior , la barra de título del programa Visual Basic, con el texto :
Por debajo de esta barra de Título del VB, encontramos la barra de menú de VB, con las
leyendas :
Por debajo de esta barra de menú tenemos la barra de herramientas, donde podrá ver varios
iconos, que cada uno representa un determinada operación que Vd. puede realizar. Estas
operaciones está todas en la línea de menú, y puede acceder a ellas abriendo los menús
desplegables que existen en cada una de las palabrea Archivo Edición Ver ...... de esta línea
de menú. El hecho de colocar las operaciones mas usuales en un icono en la barra de
herramientas se hace para mayor comodidad del usuario.
A la izquierda de la pantalla tiene una caja rectangular con tres columnas de iconos. Esa caja
es la Caja de Herramientas (No la confunda con la barra de herramientas de la parte
superior)
Pagina: 27
Esta caja de herramientas es, salvando las distancias, lo mismo que una caja de herramientas
real que pueda tener un mecánico para realizar su trabajo. En ella están los iconos que
representan a los controles con los que Vd. va a desarrollar su aplicación VB. No están todos
los que pueden estar, al igual que en una caja de herramientas de un mecánico no están todas
las herramientas que puede usar. Están solamente las mas usuales. Si necesita alguna mas,
puede cogerla de otra parte (barra de Menú, Herramientas, Controles personalizados) y
agregarlos a esa caja de herramientas, al igual que lo haría un mecánico con una herramienta
especial, que la metería en su caja sólo cuando va a realizar un trabajo determinado para el
que la necesite.
Posiblemente esta caja de herramientas no le aparezca tal y como la ve en estos apuntes. Eso
depende si Ud. tiene la versión personal o la profesional, o si usa la versión de 16 ó 32 bits.
Esa caja de herramientas puede personalizarla a su gusto. Para ello, deberá cargar un
proyecto ya existente en los discos de distribución de Visual Basic, llamado AUTO32LD.VBP
(versión 32 bits) ó AUTO16LD.VBP (Versión 16 bits) que se encontrará en el directorio donde
haya cargado el programa Visual Basic. Este proyecto no tiene otra función que determinar las
herramientas con las que quiere abrir el VB. Para introducir herramientas nuevas en la caja de
herramientas, basta con desplegar el menú Herramientas de la barra de menú, e ir a
Controles personalizados. Haciendo click en esta línea de controles personalizados,
podemos seleccionar nuevos controles para añadir a la caja de herramientas, marcando la
casilla que está a la izquierda del nombre del control que quiere introducir. Una vez
seleccionados todos los nuevos controles, haga click en ACEPTAR, y podrá observar que esos
nuevos controles ya se le han añadido a la caja de herramientas. Para que esos nuevos
controles le aparezcan de entrada cuando inicia una sesión de VB, debe salir de Visual basic
guardando los cambios. Vuelva a entrar y observará que ya le aparecen esos nuevos controles
en la caja. No es prudente meter muchos controles en la caja. Ponga solamente los que
necesite normalmente en sus aplicaciones. Ocupará menos memoria y tardará menos tiempo
en cargar el programa VB. Además, cuando realice una aplicación y la distribuya una vez
compilada, Visual Basic entregará en los disquetes de distribución las DLL’s u OCX’s
correspondientes a todos los controles personalizados que Vd. tenga en la caja de
herramientas, los necesite el programa o no los necesite. Esto le va a suponer que está
cargando subprogramas inútiles en el ordenador destino de su aplicación. A la hora de
compilar el programa (Crear archivo .EXE) quite todos los controles personalizados que no
necesite su aplicación. (Sólo los controles personalizados. Los controles comunes -
CommandButton, Label, TextBox, etc.-, no se pueden eliminar de la caja de herramientas)
Para quitar controles de su caja de herramientas, debe proceder de forma análoga, cargando
el programa AUTOxxLD.VBP, abriendo menú de herramientas, Controles personalizados,
quitando la marca al cuadro situado en la parte izquierda del control a eliminar, y guardando el
proyecto al salir.
Observa dos ventanas, una denominada Ventana de Propiedades, donde puede ver las
propiedades del formulario, Form1, y otra, denominada Ventana de Proyecto. Existe otra
ventana, que no está en la figura anterior, la Ventana de Depuración. Por cada formulario y
cada control que introduzca en el proyecto, le aparecerá otra ventana, denominada ventana
de código.
No se extrañe de que esta presentación gráfica del Visual Basic coincida con otros sistemas de
desarrollo (Delphi, p.e.). La lógica de desarrollo de una aplicación en Windows ha llevado a
varios fabricantes de software a utilizar un entorno gráfico similar (diríamos idéntico). A Visual
basic le queda el orgullo de ser el primero en utilizarlo.
Con lo descrito anteriormente ya tenemos, al menos, fijado el argot con el que expresarnos
Pagina: 28
para comenzar a estudiar el VISUAL BASIC. Veamos con un poco mas detalle la Ventana de
Código.
Esta figura le muestra un Formulario con su ventana de código. Cada objeto gráfico de VB
tiene su propia ventana de código. Así, si en este formulario hubiésemos introducido un Label
y dos CommandButton, todos ellos tendrían su propia ventana de código. La ventana de
código la podemos ver haciendo doble click sobre cualquier objeto de nuestro proyecto. En
este caso hemos hecho doble click sobre el único objeto que teníamos : el formulario.
Observe las dos cajas de la parte superior, uno con la inscripción Objeto : que en el momento
que le sacamos la foto tenía Form, y el otro con la inscripción Proc : (procedimiento), que en
el momento de la foto tenía Load. A estas cajas les denominamos Lista de Objetos y Lista
de Procedimientos respectivamente.
Haciendo click sobre la flecha de cada lista, se despliega un menú, en la lista de objetos se
desplegará una lista con los nombres de cada objeto existente en ese momento dentro del
formulario. Haciendo click sobre uno de los nombres, nos presentará la ventana de código de
ese objeto. Todos los objetos gráficos (controles) existentes dentro de un formulario y el propio
formulario aparecerán en la misma lista de objetos.
Haciendo click sobre la flecha de la lista de procedimientos, se despliega la lista con todos los
procedimientos posibles para ese objeto. Siempre saldrá uno. Si tenemos escrito código en
uno de los procedimientos, saldrá por defecto ese procedimiento para el cual hemos escrito el
código. Si no hay código en ninguno de los procedimientos, saldrá el que tenga por defecto
cada objeto.
Solamente nos queda por decir, para cerrar este capítulo, que es un procedimiento.
Para ello vamos a explicar lo que es un evento. Un Evento es algo que le puede ocurrir a un
objeto. En una internase gráfica, lo que le puede ocurrir a un objeto es que se le haga click,
doble click, que se pase el cursor del ratón por encima, etc. Este es el Evento. El
Procedimiento es la respuesta por parte de ese objeto, al evento que le está sucediendo.
Esa respuesta, esa forma de Proceder del objeto al evento que le está sucediendo, debemos
programarla según nuestras necesidades, es decir, debemos escribir el código que necesite
Pagina: 29
nuestra aplicación como respuesta al evento que acaba de ocurrir. Posiblemente, no queramos
ninguna respuesta a muchos de los eventos que pueden acaecer a un objeto. Cada objeto
tiene muchos eventos y solamente queremos aprovechar los que nos interesan. Para que un
evento no produzca ningún efecto, basta con dejar sin código el procedimiento
correspondiente a ese evento. En los eventos que queramos que realice alguna operación, le
escribiremos en su procedimiento el código necesario para que esa operación se realice. Sin
darnos cuenta, hemos comenzado a escribir el código de la aplicación.
Observará que el primer elemento del menú desplegable de la lista de objetos se denomina
General. Este no es en realidad ningún objeto, sino un apartado existente en cada formulario,
que, al desplegar su lista de procedimientos tiene la sección de declaraciones, donde
debemos declarar las variables que queremos que afecten a todo el formulario y sus controles,
y tendrá además, los nombres de todos los procedimientos que introduzcamos (véase un
poco mas adelante). En este menú desplegable de la lista de procedimientos del General verá
con frecuencia cosas que Vd. no puso allí. Cosas tales como Command1_click, y en la
ventana un determinado código. Esto ocurre cuando se borra algún control que tenía escrito
código en alguno de sus procedimientos. Visual Basic sabe lo mucho que cuesta escribir el
código asociado a un control. Si borramos un control de nuestro formulario accidentalmente,
después de haber introducido todo el código asociado a él, Visual Basic nos sorprende con que
ese código no lo tira inmediatamente, sino que lo reserva como un procedimiento en ese
apartado General del formulario. Si en realidad queríamos borrar el control y todo su código,
debemos quitarlo de ese apartado General de nuestro formulario, pues en realidad, si no lo
queremos, no hará otra cosa que estorbar. Para quitarlo basta con borrar todo el código que
aparece en la ventana de código cuando hacemos click sobre el nombre del control eliminado.
Deberemos borrar todo el código, incluida la cabecera donde figura el nombre del control
eliminado, y la parte final, que siempre termina con EndSub.
El primer estorbo lo observará si crea otro control con el mismo nombre, cosa fácil ya que VB
da un nombre por defecto a cada control (Command1, Command2....). El código asociado al
control eliminado pasará automáticamente al nuevo control con el mismo nombre.
Una aplicación puede tener todo su código escrito en los sucesivos procedimientos del
formulario y de los controles que tenga ese formulario.
Puede ocurrir que un determinado evento no esté entre los posibles eventos de los controles
de nuestra aplicación. Piense por ejemplo, el evento de que la variable A sea igual a la
variable B. No existe en ninguno de los controles ese procedimiento. No se preocupe, puede
crear un procedimiento que se ejecute cuando su programa lo decida. Podemos añadir cuantos
procedimientos queramos. Estos procedimientos se añaden al formulario, y deberán definirse
por un nombre que Vd. debe elegir. Para que se ejecuten las instrucciones (código) incluido en
ese procedimiento, basta simplemente con nombrarlo por ese nombre.
Para insertar un procedimiento debe ir a la barra de menú, hacer click sobre Insertar, y en el
menú que le desplegará, volver a hacer click sobre Procedimiento. VB le presentará un cuadro
donde le pedirá el nombre, si quiere que sea un procedimiento, una función o una propiedad. A
lo largo del curso irá viendo que es cada cosa.
Escribiendo el código en los sucesivos procedimientos, bien en los propios de cada objeto,
bien en los procedimientos que vayamos creando, es posible completar la aplicación. Pero en
una aplicación larga esta forma de escribir el código no sería la mas adecuada. Es mas,
posiblemente sería demasiado engorroso escribirla de esta forma, y muy probablemente
deberíamos escribir el mismo código para varios procedimientos, lo que alargaría inútilmente
el programa y el tiempo de desarrollo.
Para disponer de un sitio donde escribir parte (o la mayor parte) de su programa, puede
introducir uno o varios módulos. Expliquemos lo que es un módulo.
Un Módulo es una parte del programa donde solamente puede escribir código. Es igual que un
formulario, sin interface gráfica. Un profesor de Visual Basic lo expresaba diciendo que un
Módulo es un Formulario sin cara. En un módulo pueden existir procedimientos al igual que en
Pagina: 30
los formularios, pero como un módulo no tiene interface gráfica, esos procedimientos debe
introducirlos el programador tal y como explicamos un poco mas atrás. El módulo tiene su
propia ventana de código, al igual que un formulario, con un objeto único, el apartado General.
Aquí también tenemos la sección de declaraciones, al igual que los formularios. En esta
sección de declaraciones se comporta de manera similar a la de los formularios, pero permite
algo que no nos permite la sección de declaraciones de un formulario : Declarar variables que
se pueden utilizar en todo el programa. Esto ya lo ha visto mas atrás, con las sentencia de
declaración Global y Public.
Los módulos se emplean para la declaración de variables globales, y para escribir el código de
la aplicación que sea común a varios formularios. Esto nos evita tener que repetir código
inútilmente. Ese código común se escribirá en un procedimiento que previamente habremos
insertado en este módulo, y lo citaremos por su nombre desde cualquier parte del programa.
Procedimiento1
Si la línea de código donde nos vamos a referir a él está fuera de MóduloA, deberemos
referirnos a ese procedimiento con :
MóduloA.Procedimiento1
Formulariox.Procedimientoy
donde damos por hecho que Formulariox es el nombre del formulario que lo contiene, y
Procedimientoy es el nombre del procedimiento.
Fíjese en el punto usado como separador entre el nombre del formulario y el nombre del
procedimiento. VB usa como separador un punto. Usa el separador para separar el nombre de
un control y una de sus propiedades (Label1.Caption), para separar el nombre del formulario
del nombre de uno de sus controles (Formulario1.label1.caption) Se irá familiarizando con la
terminología VB según vayamos avanzando en el curso.
Funciones
Main
Merece la pena pararse un poco para estudiar el Procedimiento Main. Para verlo con mas
detalle, comentaremos como comienza a trabajar una aplicación realizada en Visual Basic.
Imaginemos una aplicación que tiene 3 Formularios. En cada uno de ellos tiene código.
Logicamente la aplicación tendrá que presentar uno de ellos en primer lugar. Deberemos
decirle a Visual Basic cual es el formulario inicial, y será ese por el que empiece. En ese
Pagina: 31
formulario dispondremos el código necesario para que la aplicación se ejecute en el orden
deseado.
Verá que tiene 4 pestañas, y actualmente tiene abierta la pestaña correspondiente a Proyecto,
y tiene desplegada una lista donde nos pide el Formulario Inicial. En esa lista figura también la
expresión Sub Main. Si ponemos como formulario inicial uno de los formularios, la aplicación
comenzará por ese formulario. Si en uno de los Módulos existentes en el proyecto, ponemos
un procedimiento llamado Main, podemos comenzar la ejecución de la aplicación justamente
por ese procedimiento. En ese procedimiento pondremos el código necesario para que,
posteriormente, se muestre uno de los formularios. Esto es muy practico cuando queremos
hacer una función previa a mostrar cualquier formulario (abrir una base de datos, por ejemplo).
Para comenzar la aplicación por Main se elige esa opción en la lista Formulario Inicial.
¡ Recuerde que Main debe estar en un Módulo !
El cuadro de diálogo anterior sirve además para otras cosas. Entre ellas poner el nombre del
proyecto (nombre que no aparecerá por ninguna parte, solo en los datos internos de la
aplicación) y su descripción.
Guardar la aplicación antes de ejecutar. Esta prestación nos va a evitar muchos disgustos.
Es muy práctico guardar la aplicación antes de ejecutarla, pues de esta forma evitamos que, si
nuestra aplicación tiene un error tal que hagamos colgarse a Windows, siempre tendremos la
aplicación metida en el disco duro. Pero también es una pequeña pesadez tener que esperar a
que se guarde cada vez que la ejecutamos.
Pagina: 32
Podemos elegir también las ventanas que queremos que estén siempre visibles, y que
verifique automáticamente la sintaxis de una instrucción en el momento de escribirla.
Pagina: 33
Cambiar el color de la letra y del fondo del código, según el tipo que sea (código, comentario,
error devuelto, etc.). Los alumnos mas aventajados y con ganas de marear al profesor y, lo que
es peor, a sus compañeros, conocen la forma de poner como invisible una parte del texto del
código. Si observa comportamientos raros en el texto donde escribe el código, revise el
cuadro de Colores de Código.
Pagina: 34
FORMULARIO
El primer objeto Visual Basic con que nos encontramos es el FORMULARIO. De hecho, cada
vez que iniciamos Visual Basic (VB) nos presenta en pantalla un nuevo formulario, que tiene
por defecto el nombre de Form1
Pagina: 35
Ejemplo de un formulario para una aplicación industrial. Este formulario reproduce el panel de
control de un transmisor - receptor de radio. En este caso, parece que el nombre de ventana le
viene mejor que el de formulario. Observe que dentro del formulario existen gran cantidad de
objetos. Botones, que hacen la misma función que el botón real en el equipo de radio, y un par
de displays, que muestran un texto, en este caso las frecuencias de transmisión y recepción.
PROPIEDADES.
Name Nombre
Caption Título
Es el texto que aparecerá en la barra de Título cada vez que aparezca en pantalla este
formulario. No tiene otra función dentro del programa. El programa no accede a este
formulario por el título, sino por el nombre. Puede cambiarse en tiempo de ejecución.
Control Box Control “menos” del Formulario Valor por defecto : True
Propiedad booleana que admite los valores de true (verdadero) o False (Falso). Si esta
propiedad es True, aparecerá en la esquina superior izquierda el "menos" para
desplegar el menú de control de este formulario. Si esta propiedad se pone como
False, no existirá dicho "menos" y por tanto no se puede desplegar dicho menú.
Pagina: 36
MinButton
MaxButton Valor por defecto: True
Nota. En los formularios MDI child, es necesario poner a true las propiedades ControlBox,
MinButton y MaxButton para poder maximizar el formulario hijo. De no ponerlas a true, sí se
pretende maximizar el formulario hijo, (Propiedad WindowState=2) el formulario no aparece.
1 - Fixed Single
El formulario tendrá un borde fino, y no podrá cambiarse su tamaño
durante el tiempo de ejecución. Con este valor, el formulario puede
tener un menú de control, barra de título y botones de maximizar y
minimizar. Solo podrá cambiarse de tamaño utilizando estos botones.
2-Sizable
El formulario tendrá borde grueso, y se podrá cambiar su tamaño en
tiempo de ejecución mediante los botones de maximizar y minimizar, y
mediante el arrastre de uno de los bordes con el ratón.
3 - Fixed Dialog
El formulario tendrá borde grueso, y no se podrá redimensionar
durante la ejecución. No puede tener los botones de maximizar ni
minimizar.
4 - Fixed ToolWindow
En las versiones de 16 bits de Windows y Windows NT 3.51 y
anteriores se comporta como Fixed Single. No puede cambiar de
tamaño. En Windows 95 muestra el botón Cerrar, y el texto de la barra
de titulo aparece con un tamaño de fuente reducido. El formulario no
aparece en la barra de tareas de W95.
5 - Sizable ToolWindow
En las versiones de 16 bits se comporta como Sizable. En W95
muestra el botón Cerrar y el texto de la barra de titulo aparece con un
tamaño de fuente reducido. El formulario no aparece en la barra de
tareas de W95.
Admite los valores 0 (=Flat, plano) y 1 (=3D) Si tiene el valor 1 (3D), el formulario
aparecerá con cierto efecto tridimensional, y los controles que le introduzcamos a este
formulario aparecerán como esculpidos dentro de él. Con valor 0 (Flat) en esta
Pagina: 37
propiedad, el formulario aparecerá durante la ejecución como una superficie plana. El
color de fondo se ve afectado al cambiar esta propiedad. Si se cambia a 3D, el fondo
(Backcolor) toma el color definido en Windows en el Panel de Control. Si se cambia a
Flat, toma el color blanco
Establece el color del fondo del formulario. Puede cambiarse en tiempo de ejecución.
Propiedad Booleana. Establece si un evento Paint vuelve a dibujar el objeto entero (True) o si
solamente dibujan las partes que han sufrido cambios (False)
DrawMode
Propiedad booleana. Si está en True, el formulario está activado y se puede interactuar con él.
Si está en False, se desactiva el formulario, impidiendo de esta forma, que se pueda trabajar
con él.
Establece el color del primer plano del formulario. Es el color que tendrán las letras si
escribimos en él, o los dibujos, si lo que hacemos es dibujar. En tiempo de diseño, determina
el color de la rejilla,.
Pagina: 38
Establece el modo de rellenar controles Shape, o figuras (círculos o cuadrados) creados con
los métodos gráficos Circle y Line.
Valores: 0 - Continuo
1 - Transparente
2 - Línea Horizontal
3 - Línea Vertical
4 - Diagonal hacia arriba
5 - Diagonal hacia abajo
6 - Cruzado
7 - Diagonal cruzada
Pagina: 39
Esta propiedad define el icono que va a representar a este formulario cuando esté
minimizado. Si el formulario es el formulario padre o formulario de inicio de una
aplicación, este icono es el que toma el Asistente de Instalación para colocarlo como
icono de apertura del programa en el grupo de programas Windows correspondiente.
Como valor de esta propiedad se le puede asignar directamente el icono o el nombre
de un archivo (con su path correspondiente) que lo contiene, haciéndolo directamente
sobre la caja de propiedades.
Propiedad Booleana. Cuando un formulario tiene dentro de sí varios controles, uno de ellos es
el que está activo. En estas condiciones, si se pulsa una tecla, esa pulsación la recibe en
primer lugar el control que esté activo, y si éste no la procesa, pasa esa pulsación al
formulario. Para hacer que esa pulsación pase directamente al formulario, debe ponerse esta
propiedad en True.
Permite que una aplicación destino inicie una conversación DDE con el formulario
(origen de datos). Puede tomar los siguiente valores:
LinkTopic
Establece un icono personalizado para el puntero del ratón cuando esté encima de
este Formulario. Este icono puede ser un bit-map de los existentes en el directorio
Icons de Visual Basic o cualquiera que tengamos. Si se pone 99 como valor de la
propiedad MousePointer (siguiente), cada vez que el puntero del ratón pase por este
Formulario, cambiará su forma y adoptará la del icono elegido.
Determina la forma del puntero del ratón cuando se coloca encima del formulario.
Puede elegirse uno de los punteros preestablecidos (15 en total) o el personalizado
Pagina: 40
visto en la propiedad anterior. Para elegir ese icono personalizado, debemos poner en
esta propiedad el valor 99.
Mediante esta propiedad podemos poner un gráfico como fondo del formulario. El
gráfico puede ser un bit-map o un fichero .ICO
Estas unidades de medida afectarán a los controles que metamos en este Formulario.
Se medirán en su ancho y alto con la unidad de medida definida para el ancho y alto
del Formulario. Lógicamente también afectará a las propiedades Left y Top de los
controles, pero estas propiedades se verán afectadas además por las propiedades
ScaleLeft y ScaleTop del Formulario que se verán a continuación.
ScaleLeft, ScaleTop
Como aclaración de las relaciones entre distintas unidades de medida, puede ver en la
siguiente table la correspondencia entre cada una de ellas y la unidad imaginaria Twip.
Pagina: 41
1 Point=20 Twips ; 1Pixel=15 Twips : 1 Charecter=240 Twips ; 1 Inch (pulgada) =1440 Twips
1mm=56,52 Twips 1 cm=566 Twips
Esta propiedad establece la posición del borde superior del formulario. Normalmente
no se introduce como valor numérico sino que lo toma automáticamente de la posición
que tenga el Formulario durante el tiempo de diseño Este valor puede cambiarse
durante la ejecución para, conjuntamente con Left, variar la posición del Formulario.
Los valores de Top y Left definen la esquina superior izquierda del Formulario.
WindowState
PROCEDIMIENTOS
Pagina: 42
Un Formulario sirve, fundamentalmente, de contenedor de controles. Es la ventana de
Windows de nuestra aplicación. Una aplicación puede tener varios Formularios y dentro de
cada uno de ellos, los controles necesarios para cada paso o estado de la aplicación.
CONTROLES
Una vez introducido un Formulario, se pueden colocar los objetos (controles) que forman parte
de la aplicación. Estos controles se irán viendo en próximos capítulos.
Las Propiedades definen las características del Control. Los Procedimientos definen la
forma de actuar (la forma de proceder) de un control frente a un evento.
Tanto las propiedades como los procedimientos deben ser definidos por el programador. Las
propiedades dejan un pequeño margen de actuación, los procedimientos son en su totalidad,
definidos por el programador. Estos procedimientos forman parte del programa. Podría incluso
hacerse una aplicación que no tuviese mas código que el introducido en los procedimientos.
Pagina: 43
COMMAND BUTTON BOTON DE COMANDO
El Command Button es un objeto que sirve para introducir datos a través de la pantalla. El
Botón de Comando tiene la siguiente forma:
El botón de comando puede usarse para la entrada de datos con el ratón, o para validar
cualquier operación. El tamaño puede cambiarse a voluntad, pero la forma siempre es
rectangular. En la figura anterior vemos dos botones de comando, uno de ellos (el Command2)
marcado con unos puntos en su contorno. Estos puntos nos permiten variar su tamaño en
tiempo de diseño. También puede cambiarse su tamaño y posición en tiempo de ejecución.
PROPIEDADES
Name Nombre
Es el nombre que define a este objeto durante la ejecución del
programa. No se puede cambiar en tiempo de ejecución. El nombre
por defecto es Command1, Command2, etc. Estos nombres por
defecto deberían cambiarse por otros que nos indiquen algo respecto a
este control, aunque en este caso no es tan imprescindible como para
los formularios.
Caption Título
Es el texto que aparece en el botón. Puede cambiarse en tiempo de
ejecución. No tiene otra función dentro del programa.
Appearance Apariencia
Determina la forma del botón. Admite los valores de Flat (Plano)
y 3D. No se aprecia en gran medida la diferencia.
Cancel
Establece un valor que indica si un botón de comando es el botón
Cancelar de un formulario. Es una propiedad booleana, y admite los
valores True o False. Puede utilizar la propiedad Cancel para dar al
usuario la opción de cancelar los cambios que no se han hecho
efectivos y devolver el formulario a su estado anterior. En un
formulario sólo puede haber un botón de comando con la propiedad
Cancel = True.
Default
Establece un valor que determina el control CommandButton que es el
botón de comando predeterminado de un formulario. Sólo un botón de
comando de un formulario puede ser el botón de comando
predeterminado. Cuando Default se define a True para un botón de
comando, se define automáticamente a False para el resto de los
botones de comando del formulario. Cuando la propiedad Default del
Pagina: 44
botón de comando está establecida a True y su formulario primario
está activo, el usuario puede elegir el botón de comando (invocando
su evento Click) presionando ENTRAR. Cualquier otro control que
tuviera el enfoque no recibe evento de teclado (KeyDown, KeyPress o
KeyUp) de la tecla ENTRAR a menos que el usuario haya movido el
enfoque a otro botón de comando del mismo formulario. En este caso,
al presionar ENTRAR se elige el botón de comando que tiene el
enfoque en lugar del botón de comando predeterminado.
DragIcon
Establece el icono que se presenta como puntero en una operación de
arrastrar y colocar.
DragMode
Establece un valor que determina si se usa el modo de arrastre
manual o automático en una operación de arrastrar y colocar. Los
valores posibles de número son:
0 Manual (Predeterminado)
1 Automático
Enabled Habilitado
Propiedad Booleana que habilita o deshabilita el botón. Cuando está
deshabilitado (Enabled = False), el botón no tiene efecto, y su
apariencia varía, presentando un tono pálido tanto en su cuerpo como
en su título. Puede variarse en tiempo de ejecución.
Font Fuente
Es el tipo de letra para el título. Puede cambiarse en tiempo de
ejecución.
Height Altura
Establece la altura del botón. Normalmente esta propiedad no se
introduce numéricamente, sino que la toma automáticamente de las
dimensiones que se le den al botón en tiempo de diseño. Puede
cambiarse, cambiando el valor a esta propiedad, en tiempo de
ejecución.
HelpContextID
Establece un número de contexto asociado para este control. Este
número se aplica para determinar la ayuda interactiva.
Index Indice
En el caso de que se tengan varios botones que realicen una función
similar (Las teclas numéricas de una calculadora, p.e.) puede hacerse
un array con estos botones de comando. Todos tendrán el mismo
nombre, y se diferencian por un índice. Esta propiedad Index toma el
número de ese índice.
Left
Posición de su parte izquierda. Indica la posición del botón,
concretamente de la parte izquierda del mismo. Normalmente esta
propiedad no se introduce numéricamente, sino que la toma
automáticamente de la posición que se le de al botón en tiempo de
Pagina: 45
diseño. Puede cambiarse, cambiando el valor a esta propiedad, en
tiempo de ejecución.
Tag
Esta propiedad no la usa directamente Visual-Basic. Sirve para asociar
a este control alguna información adicional para fines externos a la
programación. Similar a la del formulario.
Top
Indica la coordenada de la parte superior del control. Puede variarse
durante el tiempo de ejecución. Esta propiedad, juntamente con Left
definen la esquina superior izquierda del botón de comando.
Normalmente esta propiedad no se introduce numéricamente, sino que
la toma automáticamente de la posición que se le den al botón en
tiempo de diseño. Puede cambiarse, cambiando el valor a esta
propiedad, en tiempo de ejecución.
Visible Visible
Propiedad Booleana. Si es true, el botón se ve, si es False el botón no
se ve. Puede cambiarse en tiempo de ejecución. De hecho, es un
recurso muy usado para dejar visibles en un formulario, solamente los
Pagina: 46
objetos (controles) necesarios.
Width Ancho
Define el ancho del botón. Con Height determina la dimensión del
botón.
LABEL ETIQUETA
____________________
Una etiqueta es un control que nos permite presentar un texto. La etiqueta debe usarse en
aquellos casos en los que exista una información estática o dinámica que no deba ser
cambiada por el operador.
Puede adoptar estas formas: con borde tridimensional, borde plano o sin borde, y el texto
justificado a la izquierda, a la derecha o centrado.
Se ha incluido la trama para poder observar los límites de la etiqueta sin borde.
PROPIEDADES
Alignment Justificación
Establece si el texto se justifica a la izquierda, a la derecha, o se
centra sobre la etiqueta.
Pagina: 47
Autosize Tamaño
Propiedad booleana. Si se pone a True, el tamaño de la etiqueta se
ajusta al texto que contiene.
Caption Título
Es el texto de la etiqueta. Puede cambiarse en tiempo de ejecución, lo
que permite usar la etiqueta como dispositivo de presentación de
textos. No se puede cambiar por el procedimiento de arrastrar con el
ratón, por lo que es el control adecuado cuando se quiere presentar un
texto que no se pueda cambiar por el operador.
DataField DataSource
Establecen la base de datos y el campo donde está el texto Datos que
se llevará a la propiedad Caption. Estas propiedades permiten
presentar los datos de una Base de Datos mediante un procedimiento
muy sencillo, con la ayuda de un control Data (Se verá mas adelante)
DragIcon
Establece el icono que se presenta como puntero en una operación de
arrastrar y colocar.
DragMode
Establece un valor que determina si se usa el modo de arrastre
manual o automático en una operación de arrastrar y colocar. Los
valores posibles de número son:
0 Manual (Predeterminado)
1 Automático
Enabled Habilitado
Propiedad Booleana que habilita o deshabilita la etiqueta Cuando está
deshabilitado (Enabled = False), no tienen efecto los eventos que se
produzcan sobre ella, y su apariencia varía, presentando un tono
pálido tanto en su cuerpo como en su título. Puede variarse en tiempo
de ejecución.
Font Fuente
Es el tipo de letra para el título. Puede cambiarse en tiempo de
ejecución.
ForeColor
Pagina: 48
Es el color de la letra de la etiqueta. Puede cambiarse en tiempo de
ejecución.
Height Altura
Establece la altura de la etiqueta. Normalmente esta propiedad no se
introduce numéricamente, sino que la toma automáticamente de las
dimensiones que se le den a la etiqueta en tiempo de diseño.
Index Indice
En el caso de que se tengan varios etiquetas que realicen una función
similar puede hacerse un array con etiquetas. Todas tendrán el mismo
nombre, y se diferencian por un índice. Esta propiedad Index toma el
número de ese índice.
Name Nombre
Es el nombre de la etiqueta con el que se le conocerá a lo largo del
programa
TabIndex Nº de orden
Al igual que para los botones de comando, la etiqueta tiene propiedad
TabIndex. Sin embargo, una etiqueta NUNCA tomará el foco. Vea la
propiedad UseMneumonic mas adelante.
Tag
Esta propiedad no la usa directamente Visual-Basic. Sirve para asociar
a este control alguna información adicional para fines externos a la
programación.
Top
Indica la coordenada de la parte superior del control. Puede variarse
durante el tiempo de ejecución. Esta propiedad, juntamente con Left
definen la esquina superior izquierda del botón de comando.
Normalmente esta propiedad no se introduce numéricamente, sino que
la toma automáticamente de la posición que se le den a la etiqueta en
tiempo de diseño. Puede cambiarse, cambiando el valor a esta
propiedad, en tiempo de ejecución.
UseMneumonic
Devuelve o establece un valor que indica si al incluir el signo (&) en el
texto de la propiedad Caption del control Label se define una tecla de
acceso. Es una propiedad Booleana.
Pagina: 49
Los valores que puede tomar son True o False.
Visible Visible
Propiedad Booleana. Si es true, la etiqueta se ve, si es False no se ve.
Puede cambiarse en tiempo de ejecución.
Width Ancho
Define el ancho de la etiqueta. Con Height determina la dimensión de
la misma.
WordWrap
Devuelve o establece un valor que indica si un control Label con el
valor True en su propiedad AutoSize se expande vertical u
horizontalmente para adaptarse al texto especificado en su propiedad
Caption. Es una propiedad Booleana.
Pagina: 50
Las cajas de texto son los controles en los que Visual Basic presenta o introduce textos. Es por
tanto un control bidireccional. Normalmente se usan para introdución de textos, o para la
presentación de aquellos que el operador pueda cambiar. Para cambiar o escribir un texto en
una caja de texto, basta con conseguir que esa caja de texto tenga el foco y teclear el texto en
el teclado. Esto se puede lograr, bien haciendo click con el ratón en esa caja de texto, bien con
la tecla TAB, bien por programa.
La caja de texto no se debe usar nunca para presentar textos que el operador de la aplicación
no deba cambiar. Úsese para ello la etiqueta, control no bidireccional, que además tiene la
ventaja de ocupar menos memoria de programa.
Las cajas de texto pueden tener una o varias líneas, según esté la propiedad Multiline. La
capacidad máxima de una caja de textos es de 64 Kbytes.
PROPIEDADES
Alignment Justificación
Establece si el texto se justifica a la izquierda, a la derecha, o se
centra sobre la etiqueta. Esta propiedad solamente tiene efecto
cuando la propiedad Multiline está a True, ignorándose en caso
contrario. Es decir, permite colocar el texto justificado a la derecha
cuando ese texto puede ser de varias líneas. Para una única línea, se
justifica siempre a la izquierda.
Esta propiedad no puede cambiarse en tiempo de ejecución, pero sí
puede leerse en que condición está.
Appearance Apariencia
Plana o tridimensional.
DataField
DataSource Fuente de Datos
Pagina: 51
Establecen la base de datos y el campo donde está el texto que se
llevará a la propiedad Text. Estas propiedades permiten presentar de
una forma muy sencilla datos de una Base de Datos. Se verán cuando
se estudie el control Data y el motor de bases de datos
DragIcon
Establece el icono que se presenta como puntero en una operación de
arrastrar y colocar.
DragMode
Establece un valor que determina si se usa el modo de arrastre
manual o automático en una operación de arrastrar y colocar. Los
valores posibles de número son:
0 Manual (Predeterminado)
1 Automático
Enabled Habilitado
Propiedad Booleana que habilita o deshabilita la etiqueta Cuando está
deshabilitado (Enabled = False), no tienen efecto los eventos que se
produzcan sobre el TextBox. No se puede escribir el él ni pasarle el
foco, pero sí se le puede cambiar el texto mediante el programa.
Puede ser una buena alternativa para impedir que el usuario pueda
cambiar un determinado texto. Esta propiedad puede variarse en
tiempo de ejecución.
Font Fuente
Es el tipo de letra que se utilizará en el TextBox. Puede cambiarse en
tiempo de ejecución.
Height Altura
Establece la altura de la caja de texto. Normalmente esta propiedad
no se introduce numéricamente, sino que la toma automáticamente de
las dimensiones que se le den a la caja en tiempo de diseño.
HelpContextID
Establece un número de contexto asociado para este control. Este
número se aplica para determinar la ayuda interactiva.
Index Indice
En el caso de que se tengan varias cajas de texto que realicen una
función similar puede hacerse un array con ellas. Todas tendrán el
mismo nombre, y se diferencian por un índice. Esta propiedad Index
toma el número de ese índice.
Pagina: 52
LinkItem LinkMode LinkTimeout LinkTopic
Estas propiedades establecen la forma en que debe llevarse a cabo
una conexión DDE con otra aplicación. Se verán con mas detalle al
estudiar los enlaces DDE
Locked
Establece si el texto se puede editar, es decir, cambiar. Cuando se
pone esta propiedad a True, el texto existente en la caja puede
resaltarse con el ratón, e incluso copiarlo al portapapeles, pero no
puede variarse tecleando un nuevo texto. Se puede cambiar por
programa, cambiando la propiedad Text.
Si está en False, puede cambiarse el texto mediante teclado.
MaxLenght
Indica, si se establece, la longitud máxima del texto.
Name Nombre
Es el nombre de la caja de texto con el que se le conocerá a lo largo
del programa
PasswordChar
En ocasiones, es conveniente que no se pueda leer lo que se escribe
en la caja de texto, caso por ejemplo de la entrada de un password o
palabra de paso. Esta propiedad nos permite indicar un carácter que
sustituye a cualquier carácter que tenga la caja de texto. (Típicos el *
o ?). El texto que tenga en la propiedad Text no cambia por el hecho
de presentar en pantalla un carácter distinto. Esta propiedad puede
cambiarse en tiempo de ejecución. Para quitar el PasswordChar basta
con forzarlo al carácter nulo : Text1.PasswordChar = “”
ScrollBars
Cuando la propiedad Multiline de la caja de texto está a True, se
pueden colocar barras de desplazamiento del texto hacia arriba y
abajo, o hacia los lados. Esto nos permite tener una caja de texto de
tamaño reducido y poder leer en ella un texto mayor que la propia
caja. Esta propiedad puede tomar los siguiente valores :
0 - No salen barras
1 - Barras de desplazamiento horizontal
2 - Barras de desplazamiento vertical
3 - Ambas barras.
Pagina: 53
tabulador marca el orden en el que le llegará el foco al pulsar la tecla
TAB
Tag
Esta propiedad no la usa directamente Visual Basic. Sirve para asociar
a este control alguna información adicional para fines externos a la
programación.
Top
Indica la coordenada de la parte superior del control. Puede variarse
durante el tiempo de ejecución. Esta propiedad, juntamente con Left
definen la esquina superior izquierda de la caja de texto. Normalmente
esta propiedad no se introduce numéricamente, sino que la toma
automáticamente de la posición que se le de en tiempo de diseño.
Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de
ejecución.
Visible Visible
Propiedad Booleana. Si es true, la caja de texto se ve, si es False no
se ve. Puede cambiarse en tiempo de ejecución.
Width Ancho
Define el ancho de la caja de texto. Con Height determina la
dimensión de la misma.
FRAME RECUADRO
Pagina: 54
Un control Frame proporciona un agrupamiento identificable para controles. También puede
utilizar un Frame para subdividir un formulario funcionalmente por ejemplo, para separar
grupos de controles OptionButton.
Para agrupar controles, en primer lugar trace el control Frame y, a continuación, meta los
controles dentro de Frame. De este modo podrá mover al mismo tiempo el Frame y los
controles que contiene. Si traza un control fuera del Frame y, a continuación, intenta moverlo
dentro de éste, el control se colocará sobre el Frame, pero no pertenecerá a el. Es decir, si es
un OptionButton este se comportará como si estuviese fuera del Frame, aunque físicamente
esté dentro de el.
Cuando un control Frame tiene dentro otros controles, y hacemos invisible al Frame, mediante
su propiedad Visible = False, los controles interiores al Frame quedan también invisibles.
PROPIEDADES
Las señaladas con (*) no presentan novedades respecto a las ya
comentadas para los controles precedentes.
Appearance (*)
Backcolor (*)
ClipControls
Si esta propiedad está a True, los métodos gráficos en eventos Paint
vuelven a dibujar el objeto entero. Antes del evento Paint se crea una
zona de recorte alrededor de los controles no gráficos del formulario.
Si esta propiedad está a False dibujarán solamente las áreas
últimamente expuestas. En tiempo de ejecución, esta propiedad es de
sólo lectura.
DragIcon (*)
DragMode (*)
Enabled
Cuando esta propiedad está a False, tanto los procedimientos
asociados al propio control Frame como todos los controles dentro del
Frame estarán inhabilitados. Si esta propiedad está a True, todos ellos
están habilitados.
Font
En esta propiedad, el tipo de letra afecta solamente al título del
Frame, no a los controles internos a el.
ForeColor
Color de las letras del título del Frame.
Height (*)
HelpContextID (*)
Pagina: 55
Index (*)
Left (*)
MouseIcon (*)
MousePointer (*)
Name (*)
TabIndex (*)
Tag (*)
Top (*)
Visible
Cuando un Frame está con la propiedad Visible = False, tanto el
propio Frame como todos los controles interiores a el serán invisibles.
WhatsThisHelpID (*)
Width (*)
MouseMove MouseUp
Un control OptionButton muestra una opción que se puede activar o desactivar, pero con
dependencia del estado de otros controles OptionButton que existan en el formulario.
Pagina: 56
En el ejemplo de la figura, existen tres grupos de OptionButton, uno en un PictureBox, que
actúa, al tiempo que como cuadro de imagen, como contenedor de controles OptionButton.
Otro grupo está en el interior de un control Frame, y el otro grupo está en el formulario. Los
tres grupos son independientes entre sí, pero interiormente al grupo solamente puede
seleccionarse uno de los OptionButton que lo componen.
En el formulario también existen tres CheckBox, que como puede verse, se pueden
seleccionar los que se desee, sin ningún tipo de exclusión entre ellos.
PROPIEDADES
0 - Left Justify
1 - Right Justify
Cuando se elige el valor 0, justificado a la izquierda, el título del control aparece a la derecha
del botón, pegado a la figura del botón. Cuando se elige el valor 1, justificado a la derecha, el
título (Caption) aparece a la izquierda del botón, comenzando en la parte izquierda del cuerpo
total del control, es decir, no tiene porqué aparecer con su parte derecha pegado al botón, caso
que el cuerpo total del control se haya hecho mas largo que la palabra del título.
Appearance (*)
Backcolor (*)
Caption (*).
Pagina: 57
DragIcon (*)
DragMode (*)
Enabled (*)
Font (*)
ForeColor (*)
HelpContextID (*)
Index (*)
Left (*)
MouseIcon (*)
MousePointer (*)
Name (*)
TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Check1.value = 1
El poner como Value el valor True nos dará en este control un error.
Para la lectura del Value, existe una diferencia entre el valor devuelto
por el CheckBox y el devuelto por el OptionButton.
Pagina: 58
variable = Option1.Value donde variable tomará el valor True (no 1)
Visible (*)
WhatsThisHelpID (*)
Width (*)
PROCEDIMIENTOS
Un control ListBox muestra una lista de elementos en la que el usuario puede seleccionar uno
o más. Si el número de elementos supera el número que puede mostrarse, se agregará
automáticamente una barra de desplazamiento al control ListBox.
La lista tiene varios elementos. Cada línea de esta lísta es un elemento de la lista. Como el
Pagina: 59
número de elementos de la lista tiene mas elementos de los que le podían caber, generó
automáticamente la barra de desplazamiento vertical.
El ComboBox está normalmente sin desplegar. Se despliega cuando se hace click con el
ratón en la flecha que tiene en su parte derecha (véase fig. Anterior). Al desplegarse, muestra
la lista con todos sus elementos. Haciendo click con el ratón en cualquiera de sus elementos,
el elemento elegido pasa a la parte TextBox del Combo y la lista vuelve a replegar.
El ListBox (y por tanto el ComboBox) tiene unas propiedades y métodos particulares que
solamente se pueden aplicar durante el tiempo de ejecución :
Para seleccionar un elemento de la lista, basta con hacer click con el ratón sobre él. Ese
elemento se resaltará con fondo en azul. Una vez seleccionado un elemento, la propiedad
ListIndex tomará el valor del número de orden que ocupa ese elemento en la lista,
comenzando por el 0 para el elemento que ocupa el primer lugar. Si no se selecciona ningún
elemento, el valor de la propiedad ListIndex será -1. El primer elemento de la lista es
ListIndex 0, y el valor de la propiedad ListCount siempre es uno más que el valor mayor de
ListIndex.
En el ComboBox la propiedad Text contiene el texto que contenga la parte TextBox del
Combo, bien haya sido introducida desde teclado o mediante la recuperación de un elemento
la parte ListBox del mismo.
Ejemplos
Variable = List1.Listcount
Variable contendrá un número con el número total de elementos de la lista
List1.
Variable = List1.ListIndex
Variable contendrá un número con el número de orden del elemento de la lista
seleccionado en ese momento.
Variable = “VISUALBASIC”
List1.AddItem Variable
Añade un elemento a List1. En este caso, el elemento añadido es la palabra
VISUALBASIC.
Variable = List1.Text
Variable contendrá el elemento que estaba seleccionado en List1. (Variable
será una cadena de caracteres)
Pagina: 60
Variable = List1.List (n)
Variable contendrá el elemento que ocupa el número de orden n dentro de la
lista.
List1.RemoveItem (n)
Elimina el elemento n de List1.
List1.RemoveItem (List1.ListIndex)
Elimina el elemento que estaba seleccionado en ese momento.
List1.listIndex = n
Selecciona el elemento n de List1 (Se resalta en azul el elemento n)
Las señaladas con (*) son comunes a ambos controles y no presentan novedades respecto a
las ya comentadas para los controles precedentes.
Appearance (*)
Backcolor (*)
Columns Propiedad de ListBox solamente.
Nombrelista.Columns = número
.
Esta propiedad no puede definirse a 0 o cambiada desde 0 en tiempo de ejecuciones decir, no
se puede convertir en tiempo de ejecución un ListBox de múltiples columnas en un ListBox de
columna única o un ListBox de columna única en un ListBox de múltiples columnas. Sin
embargo, sí es posible cambiar durante la ejecución el número de columnas de un ListBox de
múltiples columnas.
Pagina: 61
DataField DataSource .
Establecen la base de datos y el campo donde están los datos que se
llevarán al TextBox o ComboBox para presentar datos procedentes de
una Base de Datos.
DragIcon (*)
DragMode (*)
Enabled (*)
Font (*)
ForeColor (*)
Height (*)
HelpContextID (*)
Index (*)
IntegralHeight No aplicable a ListBox o ComboBox
ItemData Propiedad muy importante.
Sintaxis
objeto.ItemData(índice) [= número]
Comentarios
La propiedad ItemData es una matriz de valores enteros largos cuyo número de elementos es
el valor de la propiedad ListCount del control. Los números asociados con cada elemento se
pueden usar para cualquier fin. Por ejemplo, se puede usar en la confección de una lista de
teléfonos, el número de identificación de un empleado, etc. Cuando se rellena el ListBox,
también se rellena los elementos correspondientes de la matriz ItemData con los números
correspondientes.
La propiedad ItemData se usa a menudo como índice de una matriz de estructuras de datos
asociados con los elementos de un control ListBox.
Nota: Cuando se inserta un elemento en una lista con el método AddItem, el elemento también se
inserta automáticamente en la matriz ItemData. Sin embargo, el valor no se reinicializa a cero;
retiene el valor que estaba en esa posición antes agregar el elemento a la lista. Cuando se usa la
propiedad ItemData, asegúrese de establecer su valor al agregar nuevos elementos a la lista.
Left (*)
MouseIcon (*)
MousePointer (*)
Name (*)
Sorted
Pagina: 62
True o False.
Cuando esta propiedad tiene el valor True, Visual Basic se encarga de casi todo el
procesamiento de cadenas necesario para mantener el orden alfabético, incluyendo el
cambio de los números de índice cuando se agregan o eliminan elementos.
Nota El uso del método AddItem para agregar un elemento en una posición
específica de la lista puede romper el orden alfabético, y los elementos agregados con
posterioridad pueden no ordenarse correctamente.
TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Visible (*)
WhatsThisHelpID (*)
Width (*)
PROCEDIMIENTOS
Son dos controles similares, para introducir un dato cuasi-analógico en una aplicación. Se
toman directamente de la caja de herramientas, y tienen un aspecto parecido al de un control
de volumen de un equipo de música. El HScrollBar está en posición horizontal, y el VScrollBar
en posición vertical.
Pagina: 63
Mediante estos controles se pueden introducir datos variando la posición del cursor.
Las señaladas con (*) son comunes a ambos controles y no presentan novedades respecto a
las ya comentadas para los controles precedentes.
DragIcon (*)
DragMode (*)
Enabled (*)
Height (*)
HelpContextID (*)
Index (*)
LargeChange
Esta propiedad establece la variación de la propiedad Value cada vez que se
hace click en el interior de la barra de desplazamiento, en la parte por donde
pasa el cursor.
Left (*)
Max
Esta propiedad establece el valor máximo para la propiedad Value, es decir, el
valor de esta propiedad cuando el cursor está en su parte máxima. (Recuerde
que el cursor está en el máximo, cuando está mas a la derecha, caso del
HScrollBar, o cuando está en la parte mas baja, caso del HScrollBar.
Min
Esta propiedad establece el valor mínimo para la propiedad Value, es decir, el
valor de esta propiedad cuando el cursor está en su parte mínima. (Recuerde
que el cursor está en el mínimo, cuando está mas a la izquierda, caso del
HScrollBar, o cuando está en la parte mas alta, caso del HScrollBar.
MouseIcon (*)
MousePointer (*)
Name (*)
SmallChange
Esta propiedad establece la variación de la propiedad Value cada vez que se
hace click en las flechas superior o inferior de la barra de desplazamiento.
TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Pagina: 64
Value
Esta propiedad lee o establece el valor dado por la posición del cursor. Este
valor tiene un mínimo, establecido por Min y un máximo, establecido por Max.
Esta propiedad es la que se debe leer para conocer la posición del cursor.
Visible (*)
WhatsThisHelpID (*)
Width (*)
TIMER TEMPORIZADOR
Este objeto permite establecer temporizaciones. Presenta una novedad respecto a los
controles estudiados hasta ahora. El control Timer solamente se ve durante el tiempo de
diseño. En tiempo de ejecución, el control permanece invisible.
PROPIEDADES
Enabled (*)
Index (*)
Interval
El valor de esta propiedad nos dará el intervalo de tiempo (en milisegundos) en que se
producirá un evento Timer y consecuentemente, realizará el procedimiento asociado a este
evento. Si el valor de la propiedad Interval está a 0 (Predeterminado), no se produce el evento
Timer. (El control Timer está deshabilitado cuando se pone la propiedad Interval = 0)
Left (*)
Name (*)
Tag (*)
Top (*)
PROCEDIMIENTOS
Pagina: 65
Timer
SHAPE
Shape es un control gráfico que se muestra como un rectángulo, un cuadrado, una elipse, un
círculo, un rectángulo redondeado o un cuadrado redondeado.
Utilice controles Shape en tiempo de diseño en lugar o además de invocar los métodos Circle
y Line en tiempo de ejecución. Puede dibujar un control Shape en un contenedor, pero no
puede actuar como contenedor. (Esto quiere decir que un control Shape nunca le servirá, por
ejemplo, para albergar varios OptionButton y pretender que sean independientes de otros
controles OptionButton que se encuentren fuera del control Shape.
PROPIEDADES
Backcolor (*)
BackStyle
Esta propiedad establece si Shape permite ver a su través (Transparent) o n
lo permite (Opaque)
BorderColor
Establece el color del borde.
BorderStyle
Establece el tipo de borde. Puede ser : Transparent, (No se ve el borde), Solid,
(Borde de línea continua),Dash, (línea a rayas), Dot, (línea a puntos), Dash-
Dot, (línea de raya - punto), dash-Dot-Dot, (línea de raya - punto - punto),
InsideSolid, (raya continua)
BorderWidth
Establece el ancho de la línea.
DrawMode (*)
FillColor (*)
FillStyle (*)
Height (*)
Index (*)
Pagina: 66
Left (*)
Name (*)
Shape
Establece la forma del control. Puede ser : Rectangular, cuadrado, redondo,
ovalado, cuadrado con esquinas redondeadas y rectangular con esquinas
redondeadas.
Tag (*)
Top (*)
Visible (*)
Width (*)
PROCEDIMIENTOS No tiene.
.LINE
Line, al igual que Shape, es un control gráfico que solamente sirve para poner una línea en un
formulario. Del mismo modo, no tiene procedimientos, por lo que no sirve para aportar código
al programa. Solo sirve para aportar una característica gráfica, es un adorno.
PROPIEDADES
BorderColor
Establece el color de la línea.
BorderStyle
Establece el tipo de línea : Puede ser : Transparent, (No se ve la línea), Solid,
(Línea continua),Dash, (línea a rayas), Dot, (línea a puntos), Dash-Dot, (línea
de raya - punto), dash-Dot-Dot, (línea de raya - punto - punto), InsideSolid,
(raya continua)
BorderWidth
Establece el ancho de la línea.
DrawMode (*)
Index (*)
Left (*)
Name (*)
Tag (*)
Visible (*)
X1, X2 Establece las coordenadas x del inicio y final.
Y1, Y2 Establece las coordenadas y del inicio y final
PROCEDIMIENTOS No tiene.
CONTROL GAUGE
Pagina: 67
Este control presenta una información numérica de forma gráfica, bien como un display lineal
(típico por ejemplo en ecualizadores de audio ), o como una aguja. No está normalmente en la
caja de herramientas, por lo que hay que traerla desde los Controles Personalizados (Menú
desplegable de Herramientas). Se denomina MicroHelp Gauge Control. El archivo que lo
contiene se denomina GAUGE16.OCX, (Ver. 16 bits) GAUGE32.OCX (Ver. 32 bits)
Mediante este control, podemos presentar una magnitud numérica de una forma cuasi-
analógica. Podríamos decir que es un control similar al HScrollBar, que en vez de meter
información a la aplicación, la presenta.
Este control puede servir, por ejemplo, para presentar el tanto por ciento de ejecución de una
tarea, como elemento tranquilizante. Puede presentar el nivel de un depósito de agua, etc.
En la figura puede verse un Gauge de aguja, uno de barra horizontal y otro de barra vertical.
Para mejorar la presentación, el Gauge permite poner un gráfico como fondo, cambiar el color
de la barra, color de fondo, etc.
El control Gauge crea medidores definidos por el usuario, que puede elegir entre los estilos
lineales (relleno) o de aguja.
Nota para la distribución Cuando cree y distribuya aplicaciones con controles Gauge, tendrá
que instalar el archivo apropiado en el subdirectorio SYSTEM de Windows del cliente. El Kit
para instalación que incluye Visual Basic, le proporciona herramientas para escribir los
programas que instalan las aplicaciones correctamente.
PROPIEDADES
Pagina: 68
NeedleWidth Ancho de la aguja
Style Tipo de marcador. Puede tomar los siguientes valores :
0 = de barra, horizontal.
1 = de barra, vertical.
2 = de aguja, de 180 grados
3 = de aguja, de 360 grados.
Value
Valor numérico a presentar. Debe ser igual o menor que la propiedad Max, e
igual o mayor que la propiedad Min.
PROCEDIMIENTOS
Pagina: 69
Visual Basic - Guía del Estudiante Cap. 3
Controles (Continuación) El CommonDialog
El CommonDialog es un control del que se libran muy pocas aplicaciones. Dada la importancia
de este control, se le dedica un capitulo único en esta Guía del Estudiante.
Este control no se presenta en tiempo de diseño mas que con un simple icono :
Abrir Ficheros
Guardar Ficheros
Elegir colores
Seleccionar Impresora
Seleccionar Fuentes
Mostrar el fichero de Ayuda
En realidad el cuadro de diálogo permite conocer datos con los cuales, y mediante el código
adecuado, abriremos o guardaremos ficheros, elegiremos colores o seleccionaremos fuentes.
Es decir, el CommonDialog NO realiza mas funciones que mostrar ficheros existentes, fuentes
disponibles, colores, para que, mediante código, abramos esos ficheros o usemos una
determinada fuente.
Dependiendo de la aplicación para la que vaya a usarse se deberá activar de distintas formas.
Si el cuadro de diálogo se va a usar para seleccionar la impresora y para otras
aplicaciones, es recomendable usar uno exclusivamente para seleccionar la impresora.
Esta última recomendación se debe a que, para el control de la impresora, el CommonDialog
SI realiza las funciones de selección de impresora predeterminada. Esta diferencia operativa
hace que si usamos el mismo CommonDialog para seleccionar impresora y abrir ficheros, por
ejemplo, se “cuelgue” el CommonDialog.
Analizando las propiedades, vemos que tiene gran cantidad de ellas. Esto es porque agrupa
Pagina: 70
todas las propiedades correspondientes a la cinco funciones que puede desarrollar. Se detalla
a continuación la forma de usar el CommonDialog para cada aplicación.
Se entiende que el nombre - Name - que se ha puesto para el cuadro de diálogo en todos los
ejemplos es CD1)
FUENTES
Para mostrar el cuadro de diálogo correspondiente a Tipos de Letra ( Fonts ), debe ejecutarse
la instrucción:
CD1.ShowFont
En el ejemplo que acompaña a este capítulo, puede ver como se introducen las características
de una determinada fuente elegida en un cuadro de texto.
Pagina: 71
COLOR
CD1.ShowColor
(La parte derecha del cuadro puede no salir. Depende del valor de la propiedad Flags. Se saca
haciendo click en Definir colores personalizados, si está activado. También depende de la
propiedad Flags)
Variablecolor = CD1.Color
Para establecer un color por medio de código, se pondrá un valor de color a la propiedad
correspondiente de ese objeto. El valor del color puede establecerse de tres formas que se
comentan a continuación.
Visual Basic acepta para especificar un color, tres procedimientos: Mediante el número de
color, mediante la sentencia RGB ( rojo, verde, azul ) o mediante la función QBColor.
Por número
El número que representa el color en VB está formado por la suma de la componente roja, la
componente verde y la componente azul. Podríamos verlo muy bien en numeración
Hexadecimal:
Pagina: 72
Color = Hex XX YY ZZ
Donde ZZ es un número Hexadecimal que representa la cantidad del color rojo. El mínimo
estaría en 0 (H00) y el máximo en 255 (HFF)
YY representaría la cantidad de color verde y XX la de color azul, ambos con los mismos
límites explicados para el rojo.
Una mezcla de un poco de rojo (HB1), otro poco de verde (H56) y otro poco de azul (H1F)
daría el siguiente número:
Hex(1F56B1) = 2053809
Label1.Backcolor = 12345678
Se puede expresar el color, poniendo simplemente RGB (rojo, verde, azul), donde rojo es un
número entre 0 y 255 que indica la cantidad de color rojo que se aporta al color, verde un
número comprendido entre 0 y 255 indicando la cantidad de verde, y lo mismo para azul.
Esta es la forma mas sencilla de poner la propiedad color, y con la que mejor controlaremos el
mismo.
Esta función se ha puesto en Visual Basic para compatibilidad con los colores que se usan en
Quick-Basic y Qbasic. Mediante esta función se obtienen solamente 16 colores.
Sintaxis Objeto.QBColor(color)
0 Negro 8 Gris
1 Azul 9 Azul claro
2 Verde 10 Verde claro
3 Aguamarina 11 Aguamarina claro
4 Rojo 12 Rojo claro
5 Fucsia 13 Fucsia claro
6 Amarillo 14 Amarillo claro
7 Blanco 15 Blanco brillante
Pagina: 73
Para el mismo Label anterior, usaríamos la sentencia :
IMPRESORAS
CD2.ShowPrinter
(A este cuadro de dialogo le hemos llamado CD2 para evitar los problemas referidos en la
nota).
Nombredelaimpresora = Printer.DeviceName
Para que la impresora quede como impresora por defecto de Windows, debe tener a True la
propiedad PrinterDefault del cuadro de diálogo.
En este cuadro puede observarse, que además de los botones de ACEPTAR y CANCELAR,
existe otro, INSTALAR. Haciendo click en este, podemos cambiar la impresora por cualquier
otra que tenga instalada.
Posiblemente las opciones mas usadas del cuadro de diálogo. Para presentar el cuadro de
diálogo correspondiente a Abrir Archivo, debe ejecutar la instrucción:
Pagina: 74
CD1.ShowOpen
Si lo que necesita es abrir el cuadro de diálogo para guardar un fichero, debe ejecutar la
instrucción :
CD1.ShowSave
pero antes deberá introducir el filtro o filtros de archivos que necesite. Ojo, ¡ ANTES !
Un filtro sirve para que en el cuadro de diálogo se presenten solamente los ficheros de nuestro
interés. Se pueden seleccionar por el nombre, la extensión o las dos cosas. La sintaxis para
introducir un filtro es la siguiente:
donde "nombre" puede ser un nombre o usar caracteres comodín. Lo mismo para "extensión"
Por ejemplo, para buscar archivos ejecutables, con cualquier nombre y extensión .EXE
Puede buscar varios tipos de ficheros, separando los caracteres de busca por medio del
carácter punto y coma (;)
Puede también introducir dos filtros, separados por el separador | (En una línea solamente).
¡ No se pueden poner dos líneas con filtros, se quedaría solamente con la última !
En este caso, cuando se presente el cuadro de diálogo, solamente presentará uno de los
filtros, y deberá seleccionar manualmente el otro en un cuadro situado en la parte inferior
izquierda del cuadro de diálogo. Para predeterminar cuál de los dos filtros saldrá sin tener que
seleccionarlo, deberá ejecutar esta instrucción, ANTES de invocar el cuadro de diálogo
CD1.FilterIndex = 2
En este caso, aparecerá por defecto el filtro escrito en segundo lugar. El orden de los filtros
comienza por 1.
El cuadro de diálogo deberá presentar un directorio. Este directorio con el que, por defecto,
aparece el cuadro de diálogo, se puede introducir mediante la propiedad InitDir, que deberá
contener el nombre del directorio y su path. Si no se especifica, comenzará por el directorio
actual.
Nombrefichero= CD1.filename
El nombre del fichero, Nombrefichero en la sentencia anterior, viene con su path, es decir,
nombre y dirección completa, por lo que puede emplearse directamente la salida del
CommonDialog para abrir un fichero.
Pagina: 75
El cuadro de diálogo de abrir o cerrar tiene esta forma :
El cuadro de guardar es similar. Observe que en este caso hemos desplegado la segunda
opción de filtro de ficheros :
Como ve ambos cuadros son prácticamente iguales. Solamente se difieren en que uno pone
Abrir y el otro Guardar como en su barra de título. También en que el cuadro Guardar como
presenta los nombres de los ficheros con un tono apagado. Funcionalmente difieren. Por
ejemplo, si quiere guardar un fichero con un nombre ya existente, y dependiendo de la
propiedad Flags que verá mas adelante, le aparecerá la siguiente advertencia :
Pagina: 76
Si desea otra leyenda en la barra de título, puede cambiarla usando el asistente de
propiedades, que lo obtendrá colocando el cursor del ratón sobre el icono del CommonDialog
y pulsando el botón derecho. Haga click sobre Propiedades en el popmenú que se presenta.
Aparecerá esto :
PRESENTAR AYUDAS
Mediante el CommonDialog se puede presentar un fichero de ayuda. (Ficheros del tipo .HLP
de Windows)
Para mostrar el fichero de ayuda debe poner el nombre (y Path) del fichero de ayuda en la
propiedad HelpFile del CommonDialog
CD1.HelpFile = "C:\MiCarpeta\MiFicheroAyuda.HLP"
Puede mostrar el índice, o una página concreta de ese fichero. Para ello debe jugar con la
propiedad HelpCommand, que le va a indicar al CommonDialog qué ayuda debe mostrar.
Pagina: 77
CD1.HelpCommand =Valor
1 &H1 cdlContext
Muestra la Ayuda de un contexto determinado. Cuando se usa esta valor, también se
debe especificar un contexto con la propiedad HelpContext.
2 &H2 cdlQuit
Notifica a la aplicación Ayuda que el archivo de Ayuda especificado ya no se está
utilizando.
3 &H3 cdlContents
Muestra el tema de contenido de ayuda, definido con la opción Contents de la sección
[OPTION] del archivo .HPJ.
3 &H3 cdlIndex
Muestra el índice del archivo de Ayuda especificado. Las aplicaciones sólo deben
utilizar este valor para un archivo de Ayuda con índice único.
4 &H4 cdlHelpOnHelp
Muestra la Ayuda para utilizar la propia aplicación Ayuda.
5 &H5 cdlSetContents
Determina el tema de contenido a mostrar cuando el usuario presiona la tecla F1.
5 &H5 cdlSetIndex
Establece el contexto especificado en la propiedad HelpContext como índice actual
para el archivo especificado en la propiedad HelpFile. Este índice seguirá siendo el
actual hasta que el usuario acceda a un archivo de Ayuda distinto. Utilice este valor
sólo para los archivos de Ayuda con más de un índice.
8 &H8 cdlContextPopup
Muestra en una ventana emergente un tema de Ayuda determinado, identificado por
un número de contexto definido en la sección [MAP] del archivo .HPJ.
9 &H9 cdlForceFile
Asegura que WinHelp muestre el archivo de Ayuda correcto. Si se muestra el archivo
correcto, no sucede nada. Si se muestra un archivo incorrecto, WinHelp abrirá el
correcto.
257 &H101 cdlKey
Muestra la Ayuda sobre una palabra reservada determinada. Al usar esta opción,
deberá especificar también una palabra reservada con la propiedad HelpKey.
258 &H102 cdlCommand
Ejecuta una macro de Ayuda.
261 &H105 cdlPartialKey
Muestra el tema de la lista de palabras claves que coincide con la palabra pasada en
el parámetro dwData, si sólo se encuentra uno. Si se encuentra más de uno,
aparecerá el cuadro de diálogo Buscar mostrando los temas encontrados en el cuadro
de lista Ir a. Si no se encuentra ninguno, se mostrará el cuadro de diálogo Buscar.
Para que aparezca el cuadro de diálogo Buscar sin pasar una palabra reservada,
utilice un puntero largo a una cadena vacía.
CD1.HelpCommand = cdlHelpIndex
Para mostrar la página que se ha puesto en el fichero de ayuda como Contexto 2 (En Sección
[MAP] del fichero .HPJ (Vea Creación de Ficheros de Ayuda),
CD1.HelpCommand = cdlHelpContext
CD1.HelpContext = 2
CD1.HelpCommand = cdlHelpHelpOnHelp
Pagina: 78
Una vez establecidas estas propiedades, mostraremos la ayuda con el Método ShowHelp
CD1.ShowHelp
Repitiéndole que no se debe usar el CommonDialog para mostrar ayudas, pero para cumplir el
objetivo de plasmar en este texto la mayor información acerca de cada control, se enumeran a
continuación el resto de propiedades que afectan a la presentación de ayuda :
HelpFile
HelpContext
HelpKey
La Propiedad Action
Valor Descripción
0 Ninguna acción.
1 Muestra el cuadro de diálogo Abrir.
2 Muestra el cuadro de diálogo Guardar como.
3 Muestra el cuadro de diálogo Color.
4 Muestra el cuadro de diálogo Fuente.
5 Muestra el cuadro de diálogo Impresora.
6 Ejecuta WINHELP.EXE.
CancelError
Devuelve o establece un valor que indica si se genera un error cuando el usuario elige
el botón Cancelar.
Debe poner esta propiedad a true cuando quiera detectar que se ha pulsado el botón
CANCELAR. Luego, debe detectar con la rutina de detección de errores adecuada, si
el error producido ha sido el 32755. De ser así, es que han pulsado ese botón, y Vd.
procederá en consecuencia.
Pagina: 79
Color
Esta propiedad es de lectura / escritura
De escritura :Establece el color predeterminado con que aparecerá el CD para elegir
color. Puede introducirse como RGB o numéricamente, como se explicó mas atrás.
Para que aparezca este color predeterminado, debe poner la propiedad Flags a 1.
De lectura : Entrega el color elegido, bien en el cuadro de elección de color, bien en el
cuadro de elección de fuente.
Copies
Establece el valor predeterminado para número de copias que aparecerá en el CD
cuando se abra para elegir impresora.
DefaultExt
Devuelve o establece la extensión de archivo predeterminada para el cuadro de
diálogo.
DialogTitle
Devuelve o establece la cadena mostrada en la barra de título del cuadro de diálogo.
FileName
Devuelve o establece la ruta y el nombre de archivo de un archivo seleccionado. La
lectura de esta propiedad devuelve el nombre del archivo seleccionado actualmente
en la lista. Si no hay ningún archivo seleccionado, FileName devuelve una cadena
vacía.
Filter
(Explicada mas atrás)
Devuelve o establece los filtros que aparecen en el cuadro de lista Tipo de un cuadro
de diálogo.
Pagina: 80
Nota para los que no tiene teclado de 102 teclas. Para obtener el carácter ASCII 124, pulse la
tecla ALT y, sin dejar de pulsarla, teclee 124 en el teclado numérico.
FilterIndex
Devuelve o establece un filtro predeterminado para un cuadro de diálogo Abrir o
Guardar Como.
Esta propiedad indica el filtro predeterminado cuando se han especificado varios filtros
para un cuadro de diálogo Abrir o Guardar. El índice del primer filtro definido es 1.
Flags Propiedad que tiene distintos significados para cada tipo de cuadro de diálogo.
Tiene la misma sintaxis para todos los cuadros.
1 &H1& cdlRGBInit
Establece como valor de color inicial para el cuadro de diálogo el indicado en su
propiedad Color.
2 &H2& cdlFullOpen
Hace que el cuadro de diálogo se muestre completo al crearlo, incluyendo la sección
que permite al usuario crear colores personalizados. Sin esta opción, el usuario debe
elegir el botón de comando Definir colores personalizados para mostrar tal sección.
4 &H4& cdlPreventFullOpen
Desactiva el botón de comando Definir colores personalizados, evitando que el usuario
defina colores.
8 &H8& cdlShowHelp
Hace que el cuadro de diálogo muestre un botón Ayuda.
Se pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los
valores de cada una de las condiciones a poner.
1 &H1& cdlReadOnly
Hace que la casilla de verificación Sólo lectura aparezca marcada inicialmente al crear
el cuadro de diálogo. Este indicador también señala el estado de la casilla Sólo lectura
cuando el cuadro de diálogo está cerrado.
2 &H2& cdlOverwritePrompt
Hace que el cuadro de diálogo Guardar como genere un cuadro de mensaje si el
archivo seleccionado ya existe. El usuario deberá confirmar que desea sobrescribir el
archivo.
4 &H4& cdlHideReadOnly
Oculta la casilla de verificación Sólo lectura.
Pagina: 81
8 &H8& cdlNoChangeDir
Hace que el cuadro de diálogo restablezca como directorio actual el que lo era en el
momento de abrirse.
16 &H10& cdlShowHelp
Hace que el cuadro de diálogo muestre el botón Ayuda.
256 &H100& cdlNoValidate
Especifica que el cuadro de diálogo común permita caracteres no válidos en el nombre
de archivo devuelto. Funciona tanto con el cuadro de Abrir como con el de Cerrar.
Tenga cuidado a la hora de crear un archivo con nombre no válido !
512 &H200& cdlAllowMultiselect
Especifica que el cuadro de lista Nombre de archivo admita selecciones múltiples. El
usuario puede seleccionar más de un archivo en tiempo de ejecución presionando la
tecla MAYÚS y utilizando las teclas FLECHA ARRIBA y FLECHA ABAJO para
seleccionar los archivos deseados. Al hacerlo, la propiedad FileName devolverá una
cadena con los nombres de todos los archivos seleccionados. Los nombres están
delimitados en la cadena con espacios.
1024 &H400& cdlExtensionDifferent
Indica que la extensión del nombre de archivo devuelto es distinta de la especificada
en la propiedad DefaultExt. Este indicador no estará activado si la propiedad
DefaultExt es Null, si las extensiones coinciden, o si el archivo no tiene extensión. El
valor de este indicador puede comprobarse al cerrar el cuadro de diálogo.
2048 &H800& cdlPathMustExist
Especifica que el usuario sólo pueda introducir una ruta de acceso válida. Si se
establece este indicador y el usuario introduce una ruta no válida, aparecerá un
mensaje de advertencia.
4096 &H1000& cdlFileMustExist
Especifica, para el cuadro de Abrir, que el usuario sólo pueda escribir en el cuadro de
texto Nombre de archivo nombres de archivos existentes. Si este indicador está
activado y el usuario introduce un nombre de archivo no válido, aparecerá una
advertencia. Este indicador activa automáticamente cdlPathMustExist.
8192 &H2000& cdlCreatePrompt
Especifica, para el cuadro de diálogo de abrir, que si no existe el fichero consulte al
usuario antes de crear un archivo que no existe actualmente. Esta advertencia dice :
Este Archivo no existe ¿desea crearlo ? y aparecen los botones de ACEPTAR y
CANCELAR. Si el usuario pulsa aceptar el CommonDialog se cierra normalmente, si
se le pulsa CANCELAR desaparece esta advertencia y el CommonDialog espera a
que se le escriba o seleccione otro fichero. Este indicador establece automáticamente
los indicadores cdlPathMustExist y cdlFileMustExist.
16384 &H4000& cdlShareAware
Especifica que se ignoren los errores al compartir archivos.
Se pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los
valores de cada una de las condiciones a poner.
1 &H1& cdlScreenFonts
Hace que el cuadro de diálogo muestre solamente las fuentes de pantalla que admite
el sistema.
2 &H2& cdlPrinterFonts
Hace que el cuadro de diálogo muestre solamente las fuentes que admite la
Pagina: 82
impresora, especificadas por la propiedad hDC.
3 &H3& cdlBoth
Hace que el cuadro de diálogo muestre las fuentes de impresora y de pantalla
disponibles. La propiedad hDC identifica el contexto de dispositivo asociado a la
impresora
4 &H4& cdlShowHelp
Hace que el cuadro de diálogo muestre un botón Ayuda.
256 &H100& cdlEffects
Especifica que el cuadro de diálogo permita efectos de tachado, subrayado y color.
1024 &H400& cdlANSIOnly
Especifica que el cuadro de diálogo sólo permita seleccionar las fuentes que utilizan el
juego de caracteres de Windows. Si se establece este indicador, el usuario no podrá
seleccionar una fuente que sólo contenga símbolos.
2048 &H800& cdlNoVectorFonts
Especifica que el cuadro de diálogo no permita seleccionar fuentes vectoriales.
Se pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los
valores de cada una de las condiciones a poner.
0 &H0& cdlAllPages
Devuelve o establece el estado del botón de opción Todas las páginas.
Pagina: 83
1 &H1& cdlSelection
Devuelve o establece el estado del botón de opción Selección. Si no se
especifica cdlPageNums ni cdlSelection, el botón de opción Todas estará
seleccionado.
2 &H2& cdlPageNums
Devuelve o establece el estado del botón de opción Páginas.
4 &H4& cdlNoSelection
Desactiva el botón de opción Selección.
8 &H8& cdlNoPageNums
Desactiva el botón de opción Páginas y el control de edición asociado.
16 &H10& cdlCollate
Devuelve o establece el estado de la casilla de verificación Intercalar.
32 &H20& cdlPrintToFile
Devuelve o establece el estado de la casilla de verificación Imprimir a un
archivo.
64 &H40& cdlPrintSetup
Hace que el sistema muestre el cuadro de diálogo Configurar impresora en
lugar de Imprimir. Use este Flag cuando lo que desea es cambiar la impresora
predeterminada.
128 &H80& cdlNoWarning
Evita que aparezca una advertencia cuando no hay una impresora
predeterminada.
Las seis propiedades siguientes nos dan las características especiales de la fuente elegida
(negrita, cursiva, etc.). Una vez seleccionado el tipo de letra, el valor de estas propiedades
contiene la opción elegida para la letra (si FontBold=True es que hemos elegido negrita, etc.)
FontBold
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Negrita.
Pagina: 84
True Se ha elegido negrita False (Predeterminado) No se ha elegido negrita.
FontItalic
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Cursiva.
FontStrikethru
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Tachada.
FontUnderline
Propiedad Booleana que establece o devuelve que el tipo de letra usado es
Subrayado.
FontName
(Variable toma el valor del nombre de la fuente. Por ejemplo, Variable = “Arial”
Nota En tiempo de ejecución puede obtener información sobre las fuentes disponibles
a través de las propiedades FontCount y Fonts. Lo verá mas adelante
FontSize
Devuelve de la fuente elegida. Debe ser una variable tipo Integer o Long
donde Variable será una expresión numérica que especifica el tamaño de fuente a
utilizar, en puntos.
Pagina: 85
En general, deberá modificar FontName antes de establecer los atributos de tamaño y
estilo con las propiedades FontSize, FontBold, FontItalic, FontStrikethru y
FontUnderline. Sin embargo, cuando especifique un tamaño inferior a 8 puntos para
una fuente TrueType, primero deberá establecer el tamaño en puntos con la propiedad
FontSize, luego especificar la propiedad FontName y después establecer de nuevo el
tamaño con FontSize. El entorno operativo Microsoft Windows utiliza una fuente
distinta para las fuentes TrueType con un tamaño inferior a 8 puntos.
Index
InitDir
Devuelve o establece el directorio de archivos inicial.
Left y Top
Esto no ocurre para sistemas a 32 bytes, en los que el CD aparece siempre en la parte
superior izquierda de la pantalla, independientemente de donde esté el formulario que
lo contiene.
MaxFileSize
Devuelve o establece el tamaño máximo del nombre de archivo abierto con el control
CommonDialog.
Name
Pagina: 86
Nombre que define al CommonDialog
PrinterDefault
True Las opciones que elija el usuario en el apartado Configurar del cuadro de
diálogo Imprimir (selección de la impresora, orientación, etcétera) se utilizan para
modificar la configuración de impresora en el archivo WIN.INI del usuario. (En el
sistema operativo Windows NT, esta información se almacena en el Registro).
False Las opciones que elija el usuario no se utilizan para modificar la configuración
de impresora predeterminada del sistema.
Utilice esta propiedad, que por defecto está a True, para poner o no poner como
impresora predeterminada, la impresora seleccionada con el CommonDialog. Puede
por ejemplo, querer imprimir un texto en una impresora determinada, pero solo ese
texto, y no quiere cambiar la impresora predeterminada por el hecho de haber
seleccionado en este momento otra impresora. Ponga esta propiedad a False
(recuerde que por defecto está a True) para que la impresora seleccionada no se
quede como impresora por defecto.
Tag
Pagina: 87
CONTROLES PARA MOSTRAR IMAGENES
Una imagen representa una figura, bien natural (tipo fotografía) o sintética. Para presentar una
imagen es necesario hacerlo sobre un objeto que la admita. Los objetos que admiten una
imagen son:
Formularios
PictureBox
Image
Existen mas controles gráficos que se irán viendo a lo largo del curso. Estos tres son los mas
usados y con los que comenzaremos a trabajar.
Por ejemplo, si tenemos un formulario llamado Form1 y queremos rellenarlo con una imagen
contenida en el fichero de Windows metafile DOLLAR.WMF que se encuentra en el directorio
C:\VB\METAFILE\BUSINESS, deberemos ejecutar la instrucción:
Para "descargar" esa imagen de ese formulario, basta con ejecutar la misma instrucción sin
fichero alguno:
Form1.Picture = LoadPicture ( )
También pueden tomar la imagen desde otro control de imagen, mediante un procedimiento de
Intercambio Dinámico de Datos (DDE) (Solo el PictureBox)
Puede también meter una imagen en una variable, y luego poner en uno de los controles
citados anteriormente la imagen guardada en la variable. Este método es muy rápido, ya que
no necesita acceder al disco para buscar una imagen, pero emplea mucha memoria RAM, ya
que la variable )o variables conteniendo la(s) imágenes están en la RAM.
Para ello debemos declarar una o varias variables tipo Picture, y meter en ellas una imagen
mediante el método LoadPicture. Vea en el capitulo 7 (Métodos Gráficos - Método
LoadPicture) un ejemplo muy ilustrativo.
EL FORMULARIO
Ya hemos visto lo que es el Formulario. Simplemente podemos añadir a lo ya dicho, que un
formulario tiene la propiedad Picture, con lo que podemos poner como fondo un bit-map, un
fichero de icono ( .ICO) o un Metarchivo (.WMF). Un fondo gráfico sobre el Formulario puede
convertir una aplicación de buena a excelente. No intente nunca mejorar una aplicación
mediocre con un fondo artístico en un Formulario.
Pagina: 88
Este objeto permite presentar todo tipo de ficheros gráficos (.BMP, WMF, .ICO, .CUR)
Las dimensiones del PictureBox se establecen en el diseño o mediante programa, variando las
propiedades Height y Width. También puede cambiarse su posición mediante las propiedades
Top y Left. Dispone de una propiedad, Align que permite colocarlo adosado a uno de los lados
del formulario que lo contiene.
El Control PictureBox puede ser destino de los datos de un enlace DDE. (Los datos serán,
lógicamente, gráficos. Por ello, tiene las propiedades LinkMode, LinkItem, LinkTimeout y
LinkTopic.
También puede tomar el dato del gráfico de una Base de Datos. (A través de un control Data o
un objeto Recordset)
CONTROL IMAGE
Este control permite presentar todo tipo de ficheros gráficos (.BMP, WMF, .ICO, .CUR)
El control Image no puede ser destino de una comunicación DDE. Puede tomar la imagen de
una base de datos, bien a través de un control Data o a través de un objeto Recordset.
El control Image utiliza menos recursos del sistema y repinta con más rapidez que un control
PictureBox, pero sólo admite una parte de las propiedades, los eventos y los métodos de
PictureBox. Use la propiedad Stretch para determinar si el gráfico se escala para que se
ajuste al control o viceversa. Poniendo esta propiedad a True el gráfico se adaptará a las
dimensiones del control Image. Si se pone a False, el control Image tomará las medidas del
Pagina: 89
gráfico que contenga. Si el gráfico es un bit-map (Fichero .BMP), con la propiedad Stretch a
True podemos variar el tamaño del bit-map, variando las propiedades Width y Height del
control Image, propiedades que se pueden cambiar en tiempo de ejecución. Si esta propiedad
está a False, el tamaño del bit-map no cambiará, presentándose solamente una porción del bit-
map, caso que el control Image sea menor que el tamaño del bit-map, o sobrará espacio en el
control, en caso contrario. Aunque puede colocar un control Image en un contenedor, un
control Image no puede actuar como contenedor. Esto se entiende mejor con un ejemplo.
Prepare un formulario con un PictureBox y con un control Image. Introduzca dos
OptionButton en cada uno de ellos, y otro en otra parte del formulario, fuera de ambos.
Ejecute la aplicación. Los OptionButton colocados dentro del PictureBox se comportan entre
ellos independientes de los otros tres OptionButton presentes en el formulario, exactamente
igual que si se les hubiera introducido en un Frame. Los controles colocados dentro del control
Image cambian formando conjunto con el que se colocó en el formulario, fuera de los dos
controles. El PictureBox funciona como un contenedor de esos dos OptionButton que tiene
en su interior, mientras que el control Image, no. (Vea el ejemplo del capítulo 2, Oficina de
cambio de divisas)
Un Image es transparente, es decir, deja ver el fondo del formulario en las partes no ocupadas
por su gráfico. Por lo tanto, no tendrían sentido en este control propiedades como Backcolor,
FillColor, o FillStyle.
Sintaxis
NombrePictureBox.Align [= número]
número Un entero que especifica cómo se presenta el control. Puede tomar los
siguientes valores :
Pagina: 90
3-Left El control se coloca en la parte izquierda del formulario y su altura es
igual a la altura del formulario.
4-Right El control se coloca en la parte derecha del formulario y su altura es
igual a la altura del formulario.
Se puede usar propiedad Align para crear rápidamente una barra de herramientas
o una barra de estado en la parte superior o inferior de un formulario. Cuando un
usuario cambie el tamaño del formulario, un control con la propiedad Align
establecida a 1 ó 2 modificará su tamaño de forma automática para ajustarse a la
anchura del formulario.
Permite que el Formulario o PictureBox (El control Image no tiene esta propiedad),
mantenga siempre la imagen presente. Si Autoredraw está a False, el control no
presentará las imágenes que no se hayan dibujado realmente (caso por ejemplo de
un formulario minimizado) o que se hayan borrado por haber sido puestas tras otro
control.
Pagina: 91
Autosize (PictureBox solamente)
Devuelve o establece un valor que indica el nombre del campo de una Base de
datos de donde se tomará la imagen a presentar. (Vea controles enlazados a
datos)
Para poder presentar una imagen contenida en una base de datos, el control
PictureBox o Image deben estar enlazados a una base de datos mediante un
control
Data.
Establece un valor que especifica el control Data a través del cual el control
Picture ó Image se enlaza a una base de datos. No está disponible en tiempo de
ejecución.
Pagina: 92
Verá esto con mas detalles cuando estudie los Objetos enlazados a Datos.
DragIcon
DragMode (PictureBox e Image) Igual que otros controles
Pagina: 93
MouseIcon Establece un icono de mouse personalizado.
(Una vez que comenzamos a estudiar las propiedades gráficas, se comenta cómo se puede
cambiar el icono de la propiedad MouseIcon de todos los controles)
Sintaxis
objeto.MouseIcon = LoadPicture(ruta) ó
objeto.MouseIcon = imagen
donde :
objeto Nombre del objeto PictureBox o Image
ruta Expresión de cadena que especifica la ruta y el nombre del archivo que
contiene el icono personalizado. Así podemos cargar un icono de los existentes en
el disco. Ej. Image1.MouseIcon =
LoadPicture("C:\vb\icons\computer\disk05.ico")
Pagina: 94
Devuelve o establece un gráfico mostrado en un control.
Ya se ha estudiado mas atrás como cambiar la propiedad Picture.
ScaleHeight, ScaleWidth
ScaleLeft, ScaleTop
ScaleMode
Pagina: 95
Al establecer un valor en cualquier otra propiedad de escala, en ScaleMode se
establece automáticamente 0.
Al establecer en ScaleMode un número mayor que 0, ScaleHeight y ScaleWidth
cambian a la nueva unidad de medida, y en ScaleLeft y ScaleTop se establece 0.
Además, los valores de CurrentX y CurrentY cambian para reflejar las nuevas
coordenadas del punto actual.
Tag
Top
Visible
WhatsThisHelpID
Width Comunes a ambos. Igual que resto de controles.
IMAGE LIST
Este control nos permite almacenar varias imágenes. Es, tal como indica su nombre, como un
ListBox pero que en vez de contener textos, contiene imágenes.
La utilidad de este control es para almacenar en él distintas imágenes, y servirlas desde él a
otro control, un PictureBox o un control Image, sin necesidad de tener que acceder a leerlas
en el disco, que conllevaría una importante pérdida de tiempo si el cambio de imágenes debe
ser rápido.
Pagina: 96
Este control es necesario para almacenar las imágenes que se mostrarán en los iconos de la
barra de herramientas. Verá mas adelante como se realiza una barra de herramientas (La barra
de herramientas solo está disponible para la versión de 32 Bits)
Un ImageList permite tener varias imágenes dentro de él, pero este control no las presenta.
Solamente sirve de “almacén” para pasarlas rápidamente a otro control (PictureBox, p.e.) que
será el que las presenta en pantalla.
En la siguiente figura, pueden verse las propiedades de un ImageList con varias imágenes
cargadas.
Para introducir imágenes en el control ImageList deberemos acceder a sus propiedades, bien
mediante F4 y luego haciendo click sobre Personalizado, bien pulsando el botón derecho del
ratón sobre el icono del control. Aparecerá un cuadro donde podemos insertar imágenes
Pagina: 97
El tipo de imágenes pueden ser mapas de bits :BMP o iconos .ICO
El control ImageList tiene una colección llamada ListImages. Esta colección contiene todas
las imágenes introducidas en el ImageList y las propiedades de cada imagen. Como toda
colección, será un array donde podemos elegir uno de sus elementos designándolo por su
nombre seguido de su número (Index) encerrado entre paréntesis. Así la imagen número 3
será :
ImageList1.Listimages (3)
Observe que tras ListImages ( ) es necesario poner la propiedad Picture, ya que Picture es una
propiedad de la colección ListImages
Como cualquier colección, ListImages tiene la propiedad Count, que nos servirá para contar el
número de imágenes que guarda.
Una de las mayores aplicaciones del ImageList es proporcionar imágenes para otros controles.
Entre ellos el TOOLBAR
Este control permite realizar una barra de herramientas. La barra de herramientas es, como ya
conocerá, una barra donde existen varios iconos. Estos iconos realizan una determinada
función. Normalmente se ponen en la barra de herramientas los iconos que representan las
acciones mas frecuentes de una aplicación. Esto facilita la operación al no tener que desplegar
menús para buscar la operación a realizar.
Como el espacio que ocupan los iconos es grande, es también bastante normal que no estén
representados en la barra de herramientas todas las funciones posibles de la aplicación, sino
como decíamos, solamente las mas frecuentes. Pero ocurre que la función que para un
usuario es muy frecuente, para otro no lo es, por lo que también es habitual poder programar
los iconos que aparecen en la barra de herramientas.
Para introducir el Toolbar es necesario que esté presente en la caja de herramientas el control
personalizado Microsoft Windows Common Controls (COMCTL32.OCX).
El control Toolbar es un contenedor de un array de iconos. Estos iconos forman botones sobre
los que se puede insertar código en sus procedimientos. A cada botón se le denomina Button
y a la colección de botones se le denomina Buttons. Cada Button es un elemento de la
Pagina: 98
colección Buttons y por lo tanto podemos referirnos a cada uno de ellos por el índice que
tiene dentro de la colección.
Los iconos de cada uno de los botones del Toolbar debe introducirse previamente en un
control ImageList. Como se recordará, un control ImageList es un almacén de imágenes, que
podemos usar en cualquier parte de la aplicación. Una de esas partes es la confección de la
barra de herramientas. Por lo tanto, es necesario introducir un control ImageList en cualquier
aplicación que use un control Toolbar. Todas las imágenes del Toolbar deben estar en un
único ImageList. Y este ImageList debe estar en el mismo formulario que el Toolbar
La barra de herramientas puede realizarse en tiempo de diseño (este sería el caso para
cuando no existiese variación ni elección de botones a lo largo de la ejecución de la
aplicación)
o en tiempo de ejecución (caso que correspondería con una aplicación que tuviese una barra
de menú programable o que variase esta barra de menú dependiendo de cada operación que
se esté ejecutando en la aplicación).
Para realizar la barra de herramientas en tiempo de diseño, basta con visualizar el cuadro de
propiedades que aparece pulsando el botón derecho del ratón sobre el control Toolbar.
Aparecerá un cuadro de diálogo como este :
Puede ver que en el cuadro ImageList aparece el nombre de un ImageList. Al desplegar la lista
aparecerán todos los ImageList que existan en el formulario. El ImageList debe estar en el
mismo formulario que el Toolbar. Deberá elegirse el ImageList que contenga las imágenes de
los iconos que queremos introducir en el Toolbar.
Este cuadro nos permite también introducir la forma que adoptará el puntero del ratón cuando
entre en el Toolbar (MousePointer), si el Toolbar aparece por defecto habilitado o deshabilitado
(Enabled) y si muestra o no un rótulo programable al pasar el ratón por encima de cada botón
del Toolbar. (ShowTips). (El uso de estos pequeños rótulos pueden hacer una aplicación muy
bonita) La propiedad AllowCustomize permite, si es True, cambiar el orden de los botones e
introducir separadores (vea evento DobleClick).
En el cuadro botones podemos introducir los datos deseados para cada uno de los botones que
compondrán la colección Buttons.
Pagina: 99
Para insertar un nuevo botón hay que hacer click sobre Insertar botón e insertará un nuevo
botón inmediatamente después del que figura en la propiedad Index (en la figura del ejemplo,
lo insertaría en segundo lugar, no en el último lugar como podría creerse). También podemos
eliminar un botón haciendo click sobre Eliminar botón.
El Caption (opcional) es la palabra que figurará debajo del icono del botón.
La propiedad Key es un nombre que se puede añadir a cada botón. Esta propiedad sirve para
identificar el botón que se ha pulsado, pero no para nombrar al botón.
La propiedad Value es el valor por defecto, con el que aparecerá el botón al comienzo de la
aplicación. (Unpressed, no pulsado, Pressed, pulsado).
ToolTipText es el texto que aparecerá al lado del botón cada vez que se ponga el cursor del
ratón sobre el botón. Para que aparezca debe estar habilitada la propiedad ShowTips.
El control Toolbar también puede realizarse en tiempo de ejecución. Para introducir u botón en
el Toolbar hay que crear el botón y añadirlo a la colección Buttons de Toolbar. Podemos
hacerlo en una sola instrucción :
NombreBotón puede ser cualquier nombre (es el nombre del objeto botón)
Pagina: 100
NombreToolbar es el nombre del Toolbar
Indice es el número de orden de ese botón dentro del Toolbar
Key es el valor de la propiedad Key del botón. Este valor debe ser único para cada botón.
Style es un número del 0 al 4 con el tipo de botón. Vea lista mas arriba
Imagen es el número de la imagen para ese botón, dentro del ImageList que las contiene.
Los botones pueden habilitarse y deshabilitarse usando la propiedad Enabled (True / False).
Recuerde que los botones se identifican por su índice :
Toolbar1.Buttons(Indice).Enabled = False
Con la lectura de la propiedad Key, y la sentencia Case o If ... Then podemos iniciar la parte de
la aplicación asociada a cada botón.
ButtonClick
Este evento se produce cada vez que se hace click sobre un botón del Toolbar. Pasa como
parámetro el índice del botón pulsado. Podremos saber que botón se ha pulsado mediante
sentencias condicionales :
If Button.Index = 1 Then . . . .
If Button.Index = 2 Then . . . .
Click
Este evento se produce cuando se hace click sobre cualquier botón del Toolbar, pero no pasa
parámetros. (No distingue sobre que botón se ha hecho click) Podemos utilizarlo cuando se
quiera realizar una operación común para todos los botones (Que suene un Beep, por ejemplo)
DobleClick
Este evento solamente se produce cuando se hace doble click en la parte del Toolbar donde no
hay botones, y la propiedad AllowCustomize esté a True. Si se hace doble click sobre un
botón se produce solamente el evento click (dos veces). Haciendo doble click en una zona
libre de botones, con la propiedad AllowCustomize = True nos permite cambiar el orden de los
botones e introducir separadores.
Change
Se produce solamente cuando se ha realizado algún cambio del orden por el procedimiento
anterior.
DragDrop, DragOver
Igual que el resto de los controles Pasa como parámetro el índice del botón, la tecla de
mayúsculas, y las posiciones x e y del ratón.
Pagina: 101
Private Sub Toolbar_MouseDown(Button As Integer, Shift As Integer, x As Single, y As
Single)
Este control solamente funciona en la versión de VB de 32 Bits. Pero para 16 bits puede
hacerse una cosa parecida (y mas sencilla) utilizando un control Picture como contenedor de
tantos controles Image como necesitemos. Dado que el control Picture dispone de propiedad
Align y puede servir como contenedor de otros controles, puede realizarse una barra de
herramientas similar a esta, y posiblemente de forma mas sencilla.
LA BARRA DE ESTADO
La barra de estado puede albergar hasta 16 paneles, que pueden contener texto o gráficos.
También pueden contener información del Hardware, tal como el estado de la tecla Bloqueo
de Mayúsculas, Bloqueo del teclado numérico, tecla Insert activada, tecla Scroll Lock
activada, o mostrar la fecha y la hora
Las dimensiones de cada panel pueden configurarse como fijas o ajustadas al tamaño del
texto o imagen que presentan.
Pagina: 102
En este control las imágenes no es necesario introducirlas previamente en un ImageList.
Pueden introducirse directamente sobre el cuadro de diálogo que sale pulsando el botón
derecho del ratón - propiedades - en la ventana correspondiente a paneles. Acepta imágenes
tipo Bit-map o .ICO. Los paneles pueden combinar una gráfico y un texto.
Para añadir un panel en tiempo de ejecución basta con añadirlo a la colección Panels del
control StatusBar mediante la sentencia :
Donde PanelNuevo es el nombre con el que se va a conocer ese panel que acabamos de crear.
PanelNuevo debe declararse como variable objeto Panel donde sea necesario según el ámbito
que le queramos dar. De esta forma, una vez creado, nos podremos referir a ese panel
simplemente citándolo por su nombre (En este caso, PanelNuevo)
Si no se pone alguna de las propiedades opcionales intermedias, deben mantenerse las comas
separadoras.
Set PanelNuevo = statusbar1.Panels.Add(pepe, "Contenido del Key " & Str(pepe), "Texto " &
Str(pepe), , LoadPicture("C:\vb\icons\comm\net09a.ico"))
Estos son los controles gráficos mas importantes. Verá a lo largo del curso que existen otros, y
más que podrá encontrar entre diferentes suministradores de controles, ya que VB ha dejado
una puerta abierta para realizar controles a medida. Existen varias empresas de software
dedicadas a la fabricación de controles personalizados, y en el aspecto de controles gráficos,
podrá encontrar una amplia gama de fabricantes y controles. Puede obtener muchos controles
en el CD-ROM que acompaña a varias revistas especializadas en programación VB, y a través
de la red Internet.
Pagina: 103
FIN del cuarto capítulo de VISUAL BASIC - Guía del Estudiante.
Copyright Luis Suárez Bernaldo 1998. Este texto es de libre difusión para fines educativos.
Prohibida la copia total o parcial para usos comerciales. San Sebastián de los Reyes (Madrid,
España) , Junio de 1998
Pagina: 104
Tal como indica su nombre, estos controles son listas. Repase el control ListBox para recordar
sus propiedades.
DriveListBox
Este control permite elegir una unidad de disco válida en tiempo de ejecución. Utilice este
control para mostrar una lista de todas las unidades válidas del sistema de un usuario. Puede
crear cuadros de diálogo que permitan al usuario abrir un archivo de una lista en cualquier
unidad disponible.
Posee las propiedades típicas de cualquier control VB respecto a su geometría y color. Las
Propiedades mas destacables de este control son : Drive, List, ListCount y ListIndex
List (n) devuelve el texto que define a la unidad colocada en el lugar n. El número n comienza
por 0. Por ejemplo, en la figura anterior, List1.list(1) devolverá c :[MS-DOS_6]
ListCount proporciona información acerca del número de unidades de disco disponibles (En el
ejemplo, List1.ListCount será 3, que corresponde a los tres discos disponibles - disco C :,
disco A : y disco D : )
ListIndex devuelve el índice del disco seleccionado en la lista (0 para el primero, n-1 para el
último)
DirListBox.
Aparte de las propiedades geométricas de todos los controles, el DirListBox presentas las
siguientes propiedades particulares :
Pagina: 105
Path
Devuelve o establece la ruta de acceso actual. No está disponible en tiempo de diseño.
donde
El valor de la propiedad Path es una cadena que indica una ruta de acceso, como
C:\WINDOWS\SYSTEM. El valor predeterminado es la ruta de acceso actual
Nota El valor que devuelve Path es distinto del de List (ListIndex). Path devuelve siempre
un mismo camino, bien el que se le haya impuesto mediante esta misma propiedad Path, y si
no se le ha impuesto con anterioridad, el que tenga por defecto. List (ListIndex) devuelve el
camino completo del directorio seleccionado, y, como era de esperar, cambia cada vez que
cambiamos la selección del directorio.
Al igual que cualquier lista, el DirListBox tiene las propiedades List, ListCount y ListIndex.
ListIndex devuelve el valor del índice del directorio seleccionado. El valor devuelto es cero
cuando está seleccionado el primer directorio de los situados al final del árbol, 1 para el
siguiente, etc. Toma el valor -1 cuando se selecciona el directorio inmediatamente superior al
último nivel, el valor -2 cuando se selecciona el directorio situado 2 niveles jerárquicos por
encima del último nivel, etc.
List (n) devuelve una cadena de caracteres con el camino completo del elemento cuyo orden
sea el señalado entre paréntesis. Si en vez de n colocamos el ListIndex nos devolverá,
logicamente, el camino del elemento seleccionado.
FileListBox
Como se puede apreciar, cuando el número de ficheros supera el número que puede
presentar, aparecen automáticamente las flechas de scroll verticales.
Path
Pagina: 106
Devuelve o establece la ruta de acceso de su directorio actual. No está disponible en tiempo
de diseño. Este directorio puede ser el que se le haya impuesto mediante esta propiedad Path,
o el que tenga por defecto. (El directorio por defecto sería el del ejecutable de la aplicación)
ListCount
ListIndex
Devuelve un número con el índice del elemento seleccionado. Como todas las listas, devuelve
-1 si no hay ningún elemento seleccionado. El primer elemento de una lista tiene el índice = 0.
Filename
List (n)
Variable = List1.List (5) Variable = nombre del fichero que ocupa el 5º lugar en la lista.
Si en lugar de n ponemos el valor de ListIndex :
Pattern
Devuelve o establece un valor que indica los nombres de archivo mostrados en
un control FileListBox en tiempo de ejecución.
valor: Expresión de cadena que indica una especificación de archivo, como *.* o *.FRM. La
cadena predeterminada es *.*, que obtiene una lista de todos los archivos. Además de utilizar
caracteres comodín, también puede especificar varios modelos, separándolos con caracteres
punto y coma (;). Por ejemplo, con *.EXE; *.BAT se obtendría una lista con todos los archivos
ejecutables y todos los archivos por lotes de MS-DOS.
Comentarios
Pagina: 107
Al modificar el valor de la propiedad Pattern se genera un evento PatternChange.
El atributo Archive de un fichero indica si se ha variado ese fichero después de la última copia
de seguridad.
El atributo Hidden indica si el fichero se trata de un fichero oculto.
El atributo Normal indica que el fichero es un fichero “normal” (No está oculto ni es de
sistema).
El atributo System de un fichero indica que el fichero es un fichero de sistema.
Sintaxis
objeto.Archive [= booleano]
objeto.Hidden [= booleano]
objeto.Normal [= booleano]
objeto.System [= booleano]
Las sintaxis de la propiedades Archive, Hidden, Normal y System tiene la siguiente partes:
objeto :Nombre del FileListBox
booleano :Una expresión booleana (True / False) que especifica el tipo de archivos
presentados.
El Directorio Actual
Se llama directorio Actual al directorio que está actualmente en uso, bien porque haya sido
forzado el control correspondiente a tener ese directorio en su propiedad Path, bien porque, al
no haberse forzado ninguno, utilice el directorio por defecto.
El directorio por defecto es el último que se ha seleccionado por algún procedimiento. Por
ejemplo, al arrancar una aplicación, el directorio por defecto será el mismo donde se encuentra
Pagina: 108
el ejecutable. Pero si a lo largo de la aplicación cambiamos el directorio, seleccionando otro
mediante un CommonDialog, ese directorio es el que queda por defecto. Asegúrese en sus
aplicaciones que siempre elige la propiedad Path antes de presentar ficheros o directorios a
través de los controles anteriores, para evitar que pueda mostrarle ficheros de un directorio no
deseado.
Puede comprobar cual es el directorio actual. La función CurDir nos devuelve el directorio
actual.
Puede darse el caso de que desee conocer el directorio actual de varias unidades de disco.
Por ejemplo, puede estar trabajando en el directorio C:\CursoVB\Ejemplos y ser este el
directorio actual en el disco C :, y tener un disquete en la unidad A : en el que la última vez que
trabajó fue en el directorio A :\ApVB\Tema1 y ese es su directorio por defecto en el disco A.
Para conocer el directorio actual del disco C : no necesitó especificar la unidad, ya que era
precisamente la unidad C la unidad actual. Para conocer el directorio actual de la unidad A
emplearía la expresión :
Decíamos que el disco C era la unidad actual. También podemos cambiar la unidad actual,
mediante la sentencia ChDrive seguida de una letra (entre comillas dobles)
También podemos forzar a que un directorio sea el directorio por defecto. La sentencia que
tendremos que usar en ChDir.
Podemos incluso crear un directorio. Usaremos para ello la sentencia MkDir. Esta sentencia
crea el directorio con el nombre indicado, sobre el directorio actual.
¡ Cuidado ! Visual-Basic no le advertirá que puede borrar algo que no desea. Asegúrese muy
bien mediante un aviso al usuario cada vez que elimine un directorio.
Vamos a ver ahora como podemos ver los nombres de los ficheros existentes en un
determinado directorio. Muy sencillo, con un FileListBox. Efectivamente, así podría ser para
presentarlos en pantalla. Sin embargo, si deseamos imprimir la lista de ficheros existentes,
guardarla en un fichero, etc., tenemos una forma que facilita esta labor. Igual que en DOS. La
función Dir
A esta función le debemos añadir como parámetro el criterio de búsqueda, criterio formado por
los caracteres o comodines que deseemos. Dir devuelve solamente el nombre de un fichero,
por lo que tendremos que repetirla tantas veces como ficheros tenga el directorio. Pero
solamente tendremos que introducir el criterio de búsqueda la primera vez.
Pagina: 109
En el siguiente ejemplo, sacaremos por impresora los nombres de los ficheros existentes en el
directorio actual : (Este código lo meteremos en el procedimiento click de un botón de
comando)
Ya sabemos sacar el directorio. Vamos a ver que otras cosas se pueden hacer con ficheros.
Función Kill. A poco Inglés que sepa se habrá dado cuenta que esta función sirve para
quitarse algo de enmedio. Esta función borra un fichero del disco.
Kill “C:\CursoVB\Ejemplos\Ejemplo1.txt”
Si tenemos un TextBox llamado Text1 donde vamos a introducir el nombre (con su Path) del
fichero origen, otro TextBox donde introduciremos el nombre (con su Path) que queremos dar a
la copia, para copiar ese fichero ejecutaremos la sentencia :
Observe la necesidad de dobles comillas para especificar que es, precisamente lo escrito en el
código, lo que indica el origen y el destino. En el caso anterior no llevaba dobles comillas,
debido a que era el contenido de un TextBox lo que se usaba para indicar el origen y el
destino.
Donde nombrerutaantiguo es una expresión de cadena que indica el nombre del fichero (con
su path) al que se le quiere cambiar el nombre, y nombrerutanuevo es una expresión de
cadena que especifica el nombre nuevo y, si se desea mover de directorio, la nueva ubicación
del archivo y la unidad de disco. El nombre y ubicación especificados en nombrerutanuevo no
pueden ser los de un archivo existente.
Pagina: 110
nombrerutanuevo y nombrerutaantiguo tienen distintas rutas de acceso y el mismo nombre de
archivo, Name coloca el archivo en la nueva ubicación, sin cambiar el nombre del archivo. Por
medio de Name se puede mover un archivo de un directorio o carpeta a otro, pero no se puede
mover un directorio o carpeta.
Si se utiliza Name con un archivo abierto se produce un error. Antes de cambiar el nombre de
un archivo, se debe cerrar.
Existe una función que le permite conocer el volumen de un fichero : FileLen. Mediante esta
instrucción podrá saber, por ejemplo, si un fichero le va a caber en lo que le queda libre de un
disquete, el tiempo previsto para enviarlo por módem, etc.
La sintaxis es la siguiente :
Variable = FileLen("C:\CursoVB\Ejemplos\Ejemplo1")
Otra función para el tratamiento de ficheros es FileDateTime, que le permite conocer la fecha
y hora de creación o de la última modificación de un fichero.
(Observe que de esta función se obtiene una variable de cadena.) Puede aprovechar esta
función para borrar o hacer Backup de determinados ficheros que tengan mas de un tiempo de
permanencia, sustituir ficheros por versiones mas recientes, etc.
Podemos obtener y modificar los atributos de un fichero. Los atributos de un fichero se refieren
a si son de solo lectura, ficheros ocultos, de sistema, si ha sido modificado desde la última vez
que se ha realizado un Backup,
Para conocer los atributos de un fichero, utilizaremos la función GetAttr. Esta función
devuelve un número, que representa la suma de los atributos de un archivo, directorio o
carpeta o una etiqueta de volumen.
Donde nombreruta es una expresión de cadena que especifica un nombre de archivo, con su
Path y unidad de disco.
El valor devuelto por GetAttr es un número, igual a la suma de los siguientes valores de
atributos:
0 vbNormal Normal.
1 vbReadOnly Sólo lectura.
Pagina: 111
2 vbHidden Oculto.
4 vbSystem Archivo de sistema.
16 vbDirectory Directorio o carpeta.
32 vbArchive El archivo ha sido modificado después de efectuar la última
copia
de seguridad.
Donde nombreruta es una expresión de cadena que especifica un nombre de archivo, con su
Path y unidad de disco, y atributos es una o varias de las constantes o valores anteriores, cuya
suma especifica los atributos de archivo.
Existe una función, que no tiene nada que ver con la anterior, aunque puede parecerlo por su
parecido semántico y que también devuelve atributos, pero de otro tipo. Esta función es
FileAttr
Función FileAttr
1 Entrada
2 Salida
4 Aleatorio
8 Añadir
32 Binario
La Ayuda de VB dice que tipoinformación puede ser =2 para que FileAttr devuelva información
sobre el selector de archivos del sistema operativo. Algunas veces la información de ayuda de
VB promete cosas que, sin dudar de que sean ciertas, son difíciles de comprobar.
Esta función no tiene una gran aplicación práctica, ya que comprueba la forma en la que
hemos abierto un archivo. Información que conocemos desde el mismo momento de abrirlo.
Pagina: 112
Visual Basic - Guía del Estudiante Cap. 5 Cont.
EL PORTAPAPELES. EL OBJETO CLIPBOARD
OBJETO CLIPBOARD
Sintaxis Clipboard
El objeto Clipboard se usa para manipular el texto y los gráficos del Portapapeles. Este objeto
puede usarse para permitir que el usuario corte, copie y pegue texto y gráficos en la
aplicación.
El objeto Clipboard puede contener varias unidades de datos siempre y cuando cada una
tenga un formato diferente. Por ejemplo, se puede usar el método SetData para poner un
mapa de bits en el Clipboard con el formato CF_BITMAP y después usar el método SetText
con el formato CF_TEXT para poner texto en el Clipboard. Después se puede usar el método
GetText para recuperar el texto o el método GetData para recuperar el gráfico. Los datos del
Clipboard se pierden cuando se colocan otros datos con el mismo formato en el Clipboard
desde el código o mediante un comando de menú.
SetText
Pone una cadena de texto en el objeto Clipboard usando el formato del objeto Clipboard
especificado. No acepta argumentos con nombre.
Sintaxis
formato Opcional. Una constante o valor que especifica uno de los formatos del
Portapapeles reconocidos por Visual Basic, como se describe a continuación :
SetData
formato Opcional. Una constante o valor que especifica uno de los formatos del
Pagina: 113
objeto Clipboard reconocidos por Visual Basic, como se describe mas
adelante. Si formato se omite, SetData determina el formato gráfico
automáticamente.
NOTA 1. Esta información está obtenida de la ayuda de VB. Observe que dice que el gráfico
puede ser la propiedad Picture de un Form, Image o PictureBox.
NOTA 2. También existe un error en la forma de meter una imagen en el Portapapeles con el
método Load Picture. La información dice que se introducirá de la siguiente forma :
Clipboard.SetData LoadPicture(“C:FIESTA.BMP)
Cuando vaya a introducir un fichero de mapa de bits (.BMP) ES NECESARIO poner que el
fichero es del tipo 8 :
Clipboard.SetData LoadPicture(“C:FIESTA.BMP), 8
ya que si no, el Portapapeles contendrá solamente un cuadro negro. Si introduce otro tipo de
ficheros, ( .WMF) no es necesario poner el número de tipo de fichero.
GetData
Devuelve un gráfico del objeto Clipboard. No acepta argumentos con nombre.
formato
Opcional. Una constante o valor que especifica el formato gráfico de Clipboard, como
se describe mas adelante. La constante o valor debe ir entre paréntesis. Si formato es
0 o se omite, GetData usa automáticamente el formato apropiado.
Pagina: 114
Si en el objeto Clipboard no hay ningún gráfico que coincida con el formato esperado,
no se devuelve nada. Si en el objeto Clipboard sólo hay una paleta de colores, se crea
un DIB de tamaño mínimo (1 x 1).
GetText
Devuelve una cadena de texto del objeto Clipboard. No acepta argumentos con
nombre.
formato
Opcional. Un valor o constante que especifica el formato del objeto Clipboard, como se
describe mas adelante. La constante o valor debe ir entre paréntesis.
Si en el objeto Clipboard no hay ninguna cadena de texto que coincida con el formato
esperado, se devuelve una cadena vacía ("").
Paste
Sintaxis objeto.Paste
Objeto es el nombre del Panel Contenedor OLE donde se quiere depositar el contenido
del Portapapeles.
Comentario
PasteOK
Sintaxis objeto.PasteOK
Objeto es el nombre del contenedor OLE donde se quiere pegar el contenido del
portapapeles.
Comentario
Cuando el valor de esta propiedad es True, el contenido del Portapapeles del sistema
se puede pegar en el control contenedor OLE.
Pagina: 115
La propiedad OLETypeAllowed se usa para especificar el tipo del objeto (vinculado o
incrustado) que se quiere pegar en el control contenedor OLE. Una vez que un objeto
se ha pegado en el control contenedor OLE, se puede verificar el valor de la propiedad
OLEType para determinar el tipo de objeto que ha sido creado.
Esta propiedad puede usarse si se quiere que la aplicación implemente un comando
Pegar en un menú Edición. Si PasteOK es False, el comando del menú se deshabilita;
si no, puede habilitarse. Los comandos de menú se habilitan y se deshabilitan
estableciendo su propiedad Enabled a True o False, respectivamente.
GetFormat
Devuelve un entero que indica si un elemento del objeto Clipboard coincide con un
formato especificado. No acepta argumentos con nombre.
formato
Requerido. Un valor o constante que especifica el formato del objeto Clipboard, como
se describe mas adelante. La constante o valor debe ir entre paréntesis.
El método GetFormat devuelve True si algún elemento del objeto Clipboard coincide
con el formato especificado. Si no, devuelve False.
Para los formatos vbCFDIB y vbCFBitmap, la paleta de colores que se encuentre en el
Clipboard se usa para presentar el gráfico.
Clear
Sintaxis Clipboard.Clear
Copy
Copia el objeto de un control contenedor OLE al Portapapeles del sistema.
Sintaxis objeto.Copy
Comentario
Pagina: 116
Cuando se copia un objeto en el Portapapeles del sistema, todos los datos y la información de
vinculación asociados con el objeto se copian en el Portapapeles del sistema. En el
Portapapeles del sistema se pueden copiar objetos vinculados y objetos incrustados.
Este método puede usarse para implementar un comando Edición Copiar en un menú.
EJERCICIO
Se propone el siguiente ejercicio, donde pueden verse todas las posibilidades del
Portapapeles.
Option Explicit
Pagina: 117
Msg = " El Portapapeles contiene texto y un archivo de mapa de bits."
Case 5
Msg = " El Portapapeles contiene texto y un archivo DIB."
Case 8
Msg = " El Portapapeles contiene solamente un archivo MetaFile."
Case 9
Msg = " El Portapapeles contiene texto y un archivo MetaFile."
Case Else
Msg = "No hay nada en el Portapapeles."
End Select
Label1.Caption = Msg ' Muestra el mensaje.
End Sub
Pagina: 118
Visual Basic - Guía del Estudiante Cap. 5 Cont.
EL EDITOR DE MENUS
El Menú o Barra de Menú es la segunda línea de cualquier ventana Windows, donde pueden
verse distintos nombres. La Barra de Menú es un componente de un Formulario.
La Barra de Menú puede tener tantas palabras como se desee, y sobre cada palabra, puede
desplegarse un Menú desplegable con mas palabras. Sobre cada una de estas puede a su vez
desplegarse otro conjunto de palabras, etc. con lo que se puede conseguir una cantidad de
palabras tan grande como necesitemos.
Para cada palabra se produce el evento click. Cada palabra de la Barra de Menú lleva anexo
un único procedimiento, que se ejecutará al hacer click sobre la palabra. Pero en las palabras
que sirven para desplegar un menú no tiene sentido que se ponga ningún código en su
procedimiento, ya que están ahí justamente para desplegar otras palabras. Será en las
palabras finales donde se colocará el código correspondiente.
En las figuras anteriores pueden verse tres formas distintas de ver el mismo Menú. En la
primera figura el Menú está sin desplegar. En la segunda figura puede verse un árbol de Menú
largo, desplegado en su totalidad. En la tercera puede verse el Menú desplegable de la
palabra Archivo de la Barra de Menú. Puede apreciarse en este menú desplegable una línea
que separa las palabras Guardar Como y SALIR. Esta línea separadora es muy práctica para
separar dos temas distintos dentro de un Menú desplegable. Tan distintos como las
operaciones de Abrir y Guardar respecto a la última orden del menú desplegable que es SALIR
de la aplicación.
Para crear un menú debe usarse el Editor de Menú, que se encuentra en la Barra de Menú de
VB en Herramientas | Editor de menús. Le aparecerá el siguiente cuadro. (En principio
vacío)
Pagina: 119
Cada palabra del menú tiene su Caption (La palabra que aparece en el menú), su Name
(Nombre), y puede tener Index (si existen varias palabras con el mismo Name). Para
introducir estas propiedades basta con teclearlas directamente en cada una de las casillas al
efecto del cuadro del editor de menús. Para colocar el cursor de escritura en una u otra casilla,
puede hacerse bien con el cursor del ratón, bien con el tabulador. Para pasar a la siguiente
línea de edición (crear una nueva palabra), basta con pulsar ENTER.
Existen otras propiedades aparte del Caption y Name que se introducen directamente en las
casillas al efecto.
HelpContextID Igual que esta propiedad en el resto de los controles, permite introducir un
número de contexto para la ayuda de Windows.
Enabled. Habilitado. Si se quita la marca de esa casilla, esa palabra aparecerá por
defecto deshabilitada. Esta propiedad puede leerse y cambiarse en tiempo de ejecución, por lo
que esta propiedad puede usarse para deshabilitar ciertas funciones de la aplicación,
dependiendo de la evolución de la propia aplicación. La presentación en el menú cuando está
deshabilitada es con color pálido.
Visible. Como su nombre indica, que sea visible o no lo sea. Puede cambiarse en
tiempo de ejecución.
WindowList Indica si esa palabra es la que va a mostrar todos los formularios abiertos en
una aplicación de documentos múltiples (MDI). Al hacer click sobre esta palabra, se
desplegará un submenú con todos los Caption de los Formularios hijo abiertos en ese
momento. Solamente puede existir una palabra en un menú con esta propiedad activada. Esta
propiedad no puede variarse en tiempo de ejecución.
Para cambiar una de estas propiedades en tiempo de ejecución, basta con citar por su nombre
a esa palabra (por su Name, no por su Caption), e igualar a True o False su valor :
nmuDocumentos.Visible = False
El nombre usado para nombrar a una de las palabras del menú puede ser cualquiera. Sin
embargo es prudente usar un nombre que nos pueda identificar, por una parte, que ese
nombre corresponde a una de las palabras del menú, y por otra, a que palabra se refiere. La
Pagina: 120
solución puede ser cualquiera. El autor de estos apuntes propone poner las letras mnu (o
menu - recomiendo no usar acentos e los Names de VB), seguido del Caption de esa palabra.
Otras propiedades
Shortcut Atajo. Esta propiedad admite varias combinaciones de teclas para acceder al
procedimiento click de esa palabra sin necesidad de usar el ratón. Las combinaciones de
teclas posibles se muestran haciendo click en la flecha hacia abajo que tiene esa casilla. Se
desplegará una lista con todas ellas. Para elegir una de estas combinaciones, basta con hacer
click sobre la línea que la contiene. Esta combinación de teclas aparecerá en el menú, al lado
de la palabra (Véase figura siguiente, SALIR Ctrl + X)
El menú editado con los datos de la figura anterior tendrá esta forma en tiempo de ejecución :
Observe que tiene cuatro palabras en la línea superior, y que “colgando” de la primera aparece
un menú desplegable. Para conseguir un menú desplegable fíjese en la figura del Editor, en la
parte de abajo donde están todos los Caption de las palabras del menú. Observará que
algunas de ellas (&Edicion, Documentos, Ayuda - Hay otra que no se vé, &Archivo) están
completamente a la izquierda de la ventana, y las demás están separadas de la parte
izquierda por unos guiones. Las palabras que están completamente a la izquierda son las que
figurarán en la barra de menú de forma permanente. Las que están separadas (tabuladas)
corresponden a las que aparecerán en los menús desplegables. Como es lógico, un menú
desplegable debe colgar de una palabra de las de la barra de menú. La palabra de la que
cuelga el submenú es la palabra sin tabular inmediatamente anterior.
Para tabular las palabras, hay que hacer click en el botón en forma de flecha a la derecha que
está sobre la ventana de edición :
Situandonos sobre una de las líneas ya editadas, y haciendo click sobre el botón con flecha
hacia la izquierda, quitamos la tabulación.
Pagina: 121
Los botones con flecha hacia arriba o abajo nos permiten variar el orden de las líneas ya
editadas.
Quedan un par de cosas. Una de ellas es el carácter & que está delante de los Caption de
Archivo y Edición. Este carácter nos permite acceder al procedimiento click de esa palabra
pulsando la tecla Alt + la tecla correspondiente a la letra que está detrás del carácter &.
Justamente la letra que está subrayada en la palabra del menú.
Otra cosa. Puede verse en el menú desplegado de la figura anterior una línea entre Guardar
Como y SALIR. Esta línea, que solamente tiene efectos estéticos, se logra introduciendo
como Caption un guión ( - ). El editor de menús solamente le permite el guión en una palabra
de menú desplegable (Tabulada). No se olvide de poner el Name incluso para este guión.
POPUP MENÚS
Para crear un menú emergente o PopUpMenu es necesario tener en el menú de ese formulario
una palabra de la que se despliegue un submenú con las mismas palabras que queremos que
aparezcan en el PopUpMenu.
Por ejemplo, en el menú que hemos editado como ejemplo anteriormente, existía una palabra
Edición, de la que se desplegaba el Submenú Copiar, Cortar y Pegar. Si analizamos la edición
realizada, las palabras tenían el siguiente Caption y Name :
Edición mnuEdicion NO
Copiar mnuCopiar SI
Cortar mnuCortar SI
Pegar mnuPegar SI
Recuerde que las palabras del menú que estaban tabuladas son las que aparecían en el menú
desplegable. Esas mismas serán las que aparezcan en el PopUpMenu.
Para ello utilizaremos el Método PopupMenu. Este método pesenta un menú emergente en
un objeto MDIForm o Form en la posición actual del mouse o en las coordenadas
especificadas.
Pagina: 122
La sintaxis de este método es la siguiente :
Para combinar la los valores de indics de posición y comportamiento basta con sumar los
valores.
Nota El parámetro indics no tiene efecto en las aplicaciones que se ejecuten bajo Microsoft
Windows versión 3.0 o anteriores.
negrita. Parámetro opcional que especifica el nombre de un control menú del menú
emergente para presentar su título en negrita. Si se omite, ningún control del menú aparece en
negrita.
Nota. Este argumento funciona solamente en las aplicaciones que se ejecuten bajo Windows
95. La aplicación ignora este argumento cuando se ejecute bajo versiones de 16 bits de
Windows o Windows NT 3.51 y anteriores.
La forma mas habitual de presentar un menú emergente es mediante el botón derecho del
ratón. Concretamente en el editor Word que estoy utilizando para escribir estos apuntes ocurre
cuando se levanta el botón derecho del ratón. Es decir, en el evento MouseUp, con la
condición de que Button=2. Imaginemos que queremos presentar en un menú emergente las
palabras Cortar, Copiar y Pegar del ejemplo anterior, que colgaban en el menú de la palabra
Edición. (Vea mas atrás). Queremos también que la palabra Copiar salga resaltada en negrita.
Iríamos al procedimiento MouseUp del Formulario y escribiríamos :
Pagina: 123
If Button = 2 Then
PopupMenu mnuEdicion, , , , mnuCopiar
End If
End Sub
Observe que se ha omitido el nombre del Formulario (Opcional), el parámetro indics, y las
coordenadas x e y (el menú emergente aparecerá donde esté situado el cursor del ratón).
Observe también que las comas separadoras de los parámetros hay que colocarlas.
Si queremos presentar un menú emergente es necesario tener ese menú en el menú del
formulario. El problema puede ser que no queramos que esté en la barra de menú. No es
problema. Ponga la propiedad Visible del elemento del menú desde el que se va a desplegar el
submenú a False. No se verá ya en la barra de menú ni esa palabra ni el submenú que de ella
se despliega. Eso sí, las palabras del submenú deben tener la propiedad Visible = True. Si les
pone esa propiedad a False, no se verán en el menú emergente. Puede aprovechar esta
circunstancia para hacer menús emergentes con mas o menos elementos, según las
necesidades de su aplicación. También puede poner la propiedad Enabled a False si así lo
precisa. No puede activar la propiedad WindowList en un elemento que forma parte de un
menú emergente.
Pagina: 124
El intercambio dinámico de datos es una utilidad de Windows que utiliza Visual Basic, y nos
permite crear aplicaciones que tomen datos una de otras.
Para pasar datos de una aplicación a otra se necesitan al menos, dos aplicaciones (lógico),
una que se deje leer, y la otra (u otras), que quieran leer la información en aquella.
Puede darse el caso que una aplicación esté recibiendo datos de otra aplicación, y a su vez
envíe datos a una tercera.
La aplicación servidor debe estar funcionando antes de que la aplicación cliente le pida la
información. Si no es así, se generará un error.
Para indicar que un formulario es origen de información para un intercambio DDE debemos
decírselo en sus propiedades LinkMode y LinkTopic.
Cuando queremos que uno de estos controles sea el destino de un intercambio DDE debemos
indicarlo en sus propiedades LinkMode, LinkTopic, LinkItem, e indicarle el tiempo de espera
para un intercambio en la propiedad LinkTimeout.
Propiedad LinkMode
Para un control, la propiedad LinkMode le permite que inicie una conversación DDE con una
aplicación servidor, (origen), y cómo iniciarla. Tiene 4 valores posibles :
Pagina: 125
3=Notify Cuando existe un cambio en los datos de la aplicación origen, ésta
notifica a la aplicación destino que el dato ha cambiado, pero no le
envía el dato nuevo. En el control de la aplicación destino donde debe
llevarse la información, se genera el evento LinkNotify, en cuyo
procedimiento podremos escribir el código necesario dependiendo de
nuestra aplicación. Para traer la información, debe ejecutarse la orden
LinkRequest. (Véase mas adelante)
objeto.LinkMode [= número]
donde número es un entero que especifica el tipo de conexión. (0, 1, 2 ó 3 según se ha visto)
y objeto es el nombre del control.
Propiedad LinkTopic
Esta propiedad es de lectura y escritura, tanto para los controles como para los formularios.
Cuando un control destino quiere establecer una comunicación DDE “llama” a la aplicación
origen, y dentro de ella, al formulario que contiene el control cuya información debe ser
traspasada. (Nótese que la aplicación origen puede tener varios formularios). Al ese formulario
podría llamarle por su nombre, (por su Name), pero no lo hace así. Le llama por un nombre
que le debemos poner al formulario en su propiedad LinkTopic. A este nombre se le
denomina Tema.
El nombre de la aplicación origen será el nombre del de proyecto de Visual Basic sin la
extensión .VBP (si la aplicación se está ejecutando en el entorno de desarrollo de Visual
Basic), o el nombre de la aplicación de Visual Basic sin la extensión .EXE (si se ejecuta como
un archivo ejecutable independiente).
El tema será el mismo al que “responde” el formulario donde se encuentra el control que
contiene la información a traspasar.
( DDE es una utilidad de Windows. Windows establece que el estándar de un vinculo DDE es
Aplicación | Tema ! elemento. Véase para mas detalles el manual de Windows, enlaces DDE)
Propiedad LinkItem
Esta propiedad es de lectura y escritura, es decir, tanto sirve para saber el nombre del control
origen de los datos, como para establecerlo en tiempo de ejecución.
Pagina: 126
Sintaxis objeto.LinkItem [= cadena]
donde cadena es el nombre del control origen que tiene los datos y objeto es el nombre del
control al que le estamos poniendo la propiedad LinkItem.
Propiedad LinkTimeout
Devuelve o establece la cantidad de tiempo que un control espera una respuesta a un mensaje
DDE.
donde número es una expresión numérica que especifica el tiempo de espera en décimas de
segundo.
El tiempo de respuesta DDE desde aplicaciones origen varía. Use esta propiedad para ajustar
el tiempo que un control destino espera la respuesta de una aplicación origen. Si se usa
LinkTimeout de forma correcta se puede evitar la generación de un error por Visual Basic si
una aplicación origen tarda mucho en responder.
Nota La plazo mayor de tiempo que un control puede esperar es 65.535 décimas de segundo,
es decir, sobre 1 hora y 49 minutos. Al establecer LinkTimeout a 1 se indica al control que
espere la respuesta en una conversación DDE durante el mayor plazo de tiempo. El usuario
puede forzar que el control deje de esperar presionando la tecla ESC..
Evento LinkNotify
Ocurre cuando el origen ha cambiado el dato definido por el vínculo DDE si la propiedad
LinkMode del control destino está establecido a 3 (Notificar).
End Sub
Método LinkRequest
Pide a la aplicación origen de una conversación DDE que actualice el contenido de un control
Label, PictureBox o TextBox.
Sintaxis objeto.LinkRequest
Si la propiedad LinkMode del objeto está definida como 1 (Automático), la aplicación origen
actualiza objeto automáticamente y LinkRequest no es necesario. Si la propiedad LinkMode
del objeto está definida como 2 (Manual) , la aplicación origen actualiza objeto sólo cuando se
usa LinkRequest.
Pagina: 127
Si la propiedad LinkMode del objeto está definida como 3 (Notify), el origen notifica al destino
que los datos han cambiado invocando el método LinkNotify. El destino debe entonces usar el
método LinkRequest para actualizar los datos.
Método LinkSend
Sintaxis objeto.LinkSend
Objeto debe ser un control PictureBox de un objeto Form que sea origen de una conversación
DDE.
Método LinkPoke
Sintaxis objeto.LinkPoke
Pagina: 128
EL CONTROL PERSONALIZADO MICROSOFT COMM
PROPIEDADES
CommPort
Indica el número del puerto serie usado. Admite los valores de 1 a 255. Cambiando esa
propiedad podemos cambiar el puerto de comunicación que vamos a usar (Un PC tiene
normalmente 2 puertos serie : El Com1 y el Com2. Puede tener sin grandes problemas
Hardware hasta 4 (Com3 y Com4) Si le damos a ese valor un número de puerto inexistente,
dará error.
Indica la velocidad, paridad, número de bits y bits de stop (parada) que se van a usar en la
comunicación.
50 100 110 300 600 1200 2400 4800 9600 14400 19200 y 28800
Pagina: 129
de parada se ponen automáticamente a 1,5 (Típico también del sistema Baudot.)
(No es posible programar 1,5 bits de parada. Sólo lo hace cuando se programan 5 bits
de información y lo hace automáticamente).
Handshaking
El Control de Flujo puede hacerse de dos formas : Una mediante las señales auxiliares del
puerto (RTS, CTS, DSR, DTR), que son cables adicionales que tendrán una tensión positiva
respecto a los 0V del equipo si esa señal está activada, o una tensión negativa si no lo está.
Este tipo de control del flujo de información es el típico para comunicarse el ordenador con un
módem.
Existe otra forma de controlar el flujo de información : mediante señales especiales que se
envían por los dos cables que transportan la información. Mediante estas dos señales
podemos controlar que el ordenador envíe información o deje de enviarla. De igual forma,
podemos indicarle al módem que envíe o no envíe. Estas señales especiales se denominan X-
ON y X-OFF.
La propiedad Handshaking controla la forma de realizar este proceso. Puede tomar los
siguientes valores :
InBufferSize
Mediante esta propiedad establecemos el tamaño del Buffer (almacén de datos) de entrada.
Este Buffer sirve para poder recibir datos sin que tenga que intervenir la aplicación
continuamente para controlar el puerto de entrada.
OutBufferSize
Pagina: 130
deberá poner un Buffer grande. Tanto mas grande cuanta mayor sea la velocidad de
transferencia de datos.
Puede conocerse el número de caracteres presentes en el Buffer de salida (los que aún están
por transmitir), consultando el valor de la propiedad OutBufferCount.
RThreshold, SThreshold
Estas dos propiedades especifican el número de caracteres que deben estar presentes en los
Buffers de Recepción y Transmisión respectivamente, para que se produzca el evento
OnComm relativo a recepción y transmisión de caracteres. (Eventos EvReceive y EvSend) Si
el valor de una de estas propiedades está a 0, no se produce el evento OnComm
correspondiente.
El valor que se debe dar a estas dos propiedades depende de la aplicación y del tiempo que
queramos que la aplicación está atendiendo al puerto de comunicaciones. Concretamente para
la propiedad RThreshold debemos pensar muy bien el valor que se le pone. Si ponemos un
valor corto (1 es el mínimo), cada vez que reciba un carácter se producirá el evento
OnComm. (Vea la descripción de eventos mas adelante). Al producirse este evento, ejecutará
el procedimiento asociado a él, lo que hará perder tiempo a la aplicación, impidiéndole realizar
otras funciones. Si se pone un valor muy alto, el puerto no avisará que tiene caracteres
recibidos hasta que reciba un número igual al programado en esta propiedad, por lo que no
podremos procesar los datos recibidos hasta que el buffer tenga ese número de caracteres en
su interior. En número adecuado dependerá del tipo de aplicación que vayamos a realizar. En
cualquier caso, este número será inferior al número programado para la longitud del buffer,
(InBufferSize)
InputLen
Por defecto, cuando se lee el Buffer de recepción, se leen todos los caracteres, quedando el
Buffer vacío. Si se le asigna a esta propiedad un valor distinto de 0, cada vez que leamos el
Buffer de recepción leerá un número de caracteres igual a esa cantidad, permaneciendo los
caracteres restantes en el Buffer a la espera de una nueva lectura. Asignándole el valor 0
(Valor por defecto), el buffer se lee completo.
ParityReplace
NullDiscard
Cuando se recibe el carácter nulo (00000000) puede ser que no sirva para nada a efectos de
nuestra aplicación, o que este carácter sea un dato mas. Esta propiedad acepta los valores
True / False. Si es True se desprecia el carácter Nulo. Si es False, se toma como un carácter
mas.
CTSTimeout
Es el tiempo (en milisegundos) que permanece esperando la señal CTS (Señal CTS -
Dispuesto para enviar), señal de entrada al ordenador que debe estar presente antes de que el
puerto comience a enviar información. El tiempo se mide desde que se pone activa la señal de
Pagina: 131
salida RTS (Petición de envío). Si se supera este tiempo entre el instante de activación de la
señal RTS y la recepción de la señal CTS, se produce el evento CTSTO. Poniendo 0 en esta
propiedad, se deshabilita, y en estas condiciones no se producirá nunca el evento CTSTO.
CDTimeout
Es el tiempo máximo de espera (en milisegundos) desde que se activa la señal DTR hasta que
se recibe la señal CD (Carrier Detect - Detección de portadora). Este tiempo solamente tendrá
importancia en ciertas aplicaciones donde se espere recibir CD continuamente. No tendrá
sentido cuando la aplicación se queda en espera a recibir una comunicación, pero sin saber
cuando la tiene que recibir. Si transcurre el tiempo programado en esta propiedad, ocurrirá el
evento CDTO. Poniendo el valor 0 se deshabilita esta propiedad y no se producirá nunca el
evento CDTO.
DSRTimeout
Similar a la anterior, pero en vez de esperar la señal CD se espera la señal DSR. Esta
propiedad sí tiene sentido, ya que si, por ejemplo, estamos conectados con un módem, y
nuestra aplicación se pone a la espera de recibir alguna llamada, activa la salida DTR, y
espera recibir inmediatamente la respuesta de que el módem está dispuesto, mediante la línea
DSR. Si transcurre el tiempo programado sin recibir la señal DSR se producirá el evento
DSRTO . Poniéndola a 0, se deshabilita esta propiedad y nunca ocurrirá el evento DSRTO.
RTSEnable
Activa (Pone a 1) la señal RTS (Request To Send - Petición de envío) Esta señal debe
ponerse a 1 para indicar al módem (o al equipo que va a recibir nuestra comunicación) que
deseamos enviar datos. Debe estar activada durante toda la transmisión de datos.
Cuando se pone la propiedad Handshaking a 2 (control con RTS / CTS) ó 3 (Control con
RTS / CTS y con X-ON / X-OFF) no debemos preocuparnos de poner a 1 la señal RTS, pues lo
hace automáticamente el puerto de comunicaciones. Esta propiedad está ahí para aplicaciones
donde no se emplee ese tipo de Handshaking y necesitemos activar algo antes de transmitir.
(Caso por ejemplo de transmisión de datos por radio, donde podemos usar esta señal de salida
para activar el PTT (Push To Talk - Pulse para hablar) y poner el transmisor en marcha)
DTREnable
Activa (Pone a 1) la salida DTR (Data Terminal Ready - Terminal de Datos Listo). Esta señal
se emplea para decirle al módem que el terminal (Ordenador) está preparado para recibir
datos.
Se hace la misma observación que para la propiedad anterior respecto a los valores de la
propiedad Handshaking
Interval
Indica el tiempo (en milisegundos) del intervalo entre una y otra comprobación del estado de
recepción del puerto. El valor mínimo es de 55 ms.
El análisis del puerto de comunicación no tiene nada que ver con la generación del evento
OnComm. Este evento se producirá cuando se cumplan las condiciones para ello,
independientemente del tiempo programado en esta propiedad. La comprobación del puerto
cada intervalo de tiempo marcado por esta propiedad solamente afecta a averiguar el estado
de las líneas auxiliares CD, DSR y CTS, y para saber el número de caracteres existentes en
los Buffers de transmisión y recepción.
Pagina: 132
Las siguientes propiedades no difieren en nada respecto a otros controles :
PortOpen
Abre el puerto de comunicación. Puede tener los valores True (Para abrirlo) y False (Para
cerrarlo) Si tenemos un MSComm con Nombre (Name) MSComm1, para abrirlo ejecutaremos
la siguiente sentencia :
MSComm1.PortOpen = True
MSComm1.PortOpen = False
InBufferCount.
Nos permite averiguar cuantos caracteres tenemos en el Buffer de entrada. Con el mismo
MSComm anterior, comprobaremos el número de caracteres sin leer con la sentencia :
caracteressinleer = MSComm1.InBufferCount
OutBufferCount
Nos permite conocer cuantos caracteres quedan por transmitir en el Buffer de salida.
Emplearemos la sentencia :
caracteressinenviar = MSComm1.OutBufferCount
Output
Envía caracteres al Buffer de salida. Debe existir un signo igual ( = ) entre Output y lo que se
envía al Buffer. Para enviar la frase Curso de Visual Basic ejecutaremos la sentencia :
MSComm1.Output = variable
Input
Devuelve el evento mas reciente que ha ocurrido para generar el evento general OnComm
(Vea mas adelante). Esta propiedad no está disponible en tiempo de diseño y es de sólo
lectura en tiempo de ejecución.
Sintaxis NombredelMSComm.CommEvent
Pagina: 133
Break
Devuelve un valor (True / False) que indica que se ha recibido la señal Break.
variable = MSComm1.Break
CDHolding
variable = MSComm1.CDHolding
CTSHolding
Devuelve el estado de la línea de control CTS (Dispuesto para enviar) Si es True, esa entrada
está activada, si es False, la entrada está desactivada.
variable = MSComm1.CTSHolding
DSRHolding
Devuelve el estado de la línea de control DSR (Data Set Ready ) Si es True, esa entrada está
activada, si es False, la entrada está desactivada.
variable = MSComm1.DSRHolding
Esto quiere decir que para escribir el código apropiado en el procedimiento del MSComm será
necesario analizar qué evento se ha producido y colocar, mediante una sentencia If .. Then el
código apropiado para cada uno de los eventos que se produzcan.
End If
Los eventos del Comm pueden identificarse por una constante o un número. La constante,
como todas las de Visual Basic, tiene una expresión bastante difícil. Se pone entre paréntesis
el número que identifica a ese evento. Este número debe declararse como Integer.
ComEvCD (5) Cambio en la línea CD. Para conocer el estado actual de esa línea
(Activado/Desactivado) deberemos invocar la propiedad CDHolding
Pagina: 134
ComEvCTS (3) Cambio en la línea CTS. Igual que la anterior, este evento solamente
nos indica que ha existido un cambio. Para averiguar el estado en que
se encuentra esta línea, debemos invocar la propiedad CTSHolding
ComEvDSR (4) Cambio en la línea DSR. Igual que las anteriores. Debemos invocar la
propiedad DSRHolding para averiguar su estado actual.
ComEvSend (1) Cuando quedan en el búfer de transmisión menos caracteres que los
indicados en la Propiedad SThreshold
Pagina: 135
de salida.
NOTA ADICIONAL
El puerto de comunicaciones.
TxD Transmisión de datos. Es una salida del ordenador. Por ella salen los datos en serie.
RxD Recepción de datos. Es una entrada del ordenador. Por ella entran los datos en serie.
RTS Request To Send. Petición de envío. Es una salida del ordenador. El ordenador pone a
1 esta señal cuando quiere enviar datos.
CTS Clear To Send. Dispuesto para enviar. Es una entrada del ordenador. Si está a 1
significa que el ordenador puede enviar datos pues el módem (o el dispositivo que
vaya a recibirlos) está preparado para hacerlo.
DSR Data Set Ready. Dispositivo de datos preparado. Es una entrada del ordenador. Le
indica que el módem está encendido y listo para funcionar.
DTR Data Terminal Ready. Terminal de datos listo. Es una salida del ordenador. Indica que
está listo para trabajar. Suele emplearse para indicar al módem que el ordenador está
dispuesto para recibir información.
Otra señal (disponible sólo en los ordenadores que tengan conector de 25 pines, y no en todos)
es la señal RING (timbre del teléfono) Es una entrada del ordenador. Le indica que está
sonando el timbre de la línea telefónica del módem.
3 TxD 2
2 RxD 3
7 RTS 4
8 CTS 5
Pagina: 136
6 DSR 6
5 GND 7
1 CD 8
4 DTR 20
RING 22
Tierra de protección 1
Pagina: 137
METODOS GRAFICOS
Se denominan métodos gráficas a aquellos métodos que nos permiten dibujar o representar
gráficos ya existentes en un objeto, o que nos permiten analizarlos o borrarlos. Los métodos
gráficos de que dispone Visual Basic son :
METODO Line
(Con esta sintaxis trazará una línea desde las coordenadas absolutas x1,y1
(origen) a las coordenadas también absolutas x2,y2. El color de la línea será el
especificado en color. Los parámetros BF se explican mas adelante.
(Con esta sintaxis trazará una línea desde las coordenadas absolutas x1,y1
hasta las coordenadas relativas a (x1,y1), x2,y2. Es decir, al poner la palabra
Step (paso) antes de las coordenadas finales, le estamos indicando que las
coordenadas que siguen a Step son relativas. Relativas ¿respecto a quien?.
Relativas a las coordenadas de comienzo de la línea. Esta última expresión
haría lo mismo que la siguiente expresión :
Podemos darnos cuenta por la descripción anterior que la palabra Step (palabra reservada de
Visual Basic) indica que las coordenadas que le siguen son relativas a algo. Veamos la tercera
forma de colocar una línea :
Con esta expresión trazará una línea entre las coordenadas relativas (x1, y1),
y las coordenadas relativas (x2,y2). En principio es fácil entender que (x2,y2)
son relativas al punto (x1,y1), pero ¿Respecto a quién son relativas las
coordenadas (x1,y1) ? Son relativas a la posición del puntero de dibujo en el
instante anterior a ejecutar esta sentencia, es decir al CurrentX, CurrentY que
existiese antes de ejecutar la sentencia.
Color es el número de color, que se puede poner en cualquiera de las posibles formas que
permite VB. Si no se especifica color, pondrá el color por defecto, que es el valor de la
propiedad ForeColor del objeto.
BF es un parámetro opcional. En realidad este parámetro sirve para que en vez de hacer una
línea haga un rectángulo. La expresión :
Pagina: 138
dibuja un rectángulo entre los puntos (x1,y1) y (x2,y2).
La expresión :
dibuja un rectángulo relleno del mismo color de la línea (en este caso verde) con esquinas en
las coordenadas (x1,y1) y (x2,y2)
Para dibujar líneas unidas, comience la línea siguiente en el punto final de la línea anterior.
Cuando se ejecuta Line, las propiedades CurrentX y CurrentY toman el valor del punto final de
la línea.
METODO Circle
En la expresión anterior, objeto es el objeto donde se dibujará el circulo. Puede ser, como en
el caso de la línea, un Formulario, un PictureBox o el objeto Printer. Si se omite, se asume
que se refiere al Formulario que tenga el enfoque en ese momento.
(x, y) son las coordenadas del punto central del círculo, elipse o arco. Las unidades de
medida vendrán determinadas por las propiedades ScaleMode o ScaleWidth / ScaleHeight del
objeto.
Radio Este parámetro es requerido. Indica el radio del círculo, elipse o arco, en el mismo
sistema de unidades de medida.
Color Este parámetro es opcional. Es el número del color, expresado en cualquiera de las
formas aceptadas por Visual Basic. Si se omite, se utiliza el valor de la propiedad ForeColor.
Inicio, Final Valor opcional. Cuando se dibuja un arco o parte de un círculo o elipse, inicio y
fin especifican (en radianes) la posición inicial y final del arco. El rango de ambas es de - 2 pi
radianes a 2 pi radianes. El valor predeterminado de inicio es 0 radianes; el de final es de 2 pi
radianes.
Aspecto Este valor nos convertirá la circunferencia en una elipse. Recuerde que una elipse
es una circunferencia generalizada. Lógicamente, este parámetro es opcional. El valor
predeterminado es 1.0, lo que crea un círculo perfecto (no elíptico) en la pantalla. Si utilizamos
en esta propiedad el valor 2 obtendremos una elipse con el radio horizontal de doble valor que
el vertical. Si empleamos 0.5 obtendremos otra elipse, con el radio vertical doble respecto al
horizontal.
Pagina: 139
Para rellenar la circunferencia y conseguir un círculo, establezca las propiedades FillColor y
FillStyle del objeto en el que se dibuja el círculo o elipse. Sólo se puede rellenar una figura
cerrada. La figuras cerradas son círculo, elipses o porciones de tipo circular (arcos con líneas
de radio dibujadas en ambos lados).
Los valores de Inicio y Final son siempre positivos. El sentido de cuenta de los ángulos es en
sentido contrario a las agujas del reloj. Si le añadimos a Inicio o a Final un signo menos
delante, lo que hace es dibujar un radio desde el centro del circulo hasta el inicio de la
circunferencia (si le hemos puesto un - a Inicio) o hasta el final del arco (si le hemos puesto
un - a Final). Se le pueden poner a ambos y cerramos la figura. Es decir, si queremos que
además de hacer el arco, dibuje los radios, pondremos el signo menos ( -) delante de Inicio y
de Final, a sabiendas que VB siempre entenderá los valores de Inicio y Final como positivos.
NOTA. No se líe con la información que aporta VB para este tema. ¡¡¡Está mal !!!
Puede omitir un argumento opcional en medio de la sintaxis, pero debe incluir la coma del
argumento antes de poner el argumento siguiente. Si omite un argumento adicional del final,
no utilice comas tras el último argumento que especifique.
Cuando se ejecuta Circle, las propiedades CurrentX y CurrentY toman el valor del punto
central.
METODO Cls
Borra los gráficos y el texto generados en tiempo de ejecución de los controles Form, Image o
PictureBox. Observe que el objeto Printer no tiene método Cls.
Sintaxis objeto.Cls
Cls borra el texto y los gráficos generados en tiempo de ejecución por instrucciones gráficas y
de presentación. Los mapas de bits de fondo definidos usando la propiedad Picture y los
controles dispuestos en un Form en tiempo de diseño no se ven afectados por Cls. Los
gráficos y el texto colocados en controles Form, Image o PictureBox mientras la propiedad
AutoRedraw es True no se ven afectados si AutoRedraw se establece a False antes de llamar
a Cls. Es decir, el texto y los gráficos de los controles Form, Image o PictureBox pueden
mantenerse manipulando la propiedad AutoRedraw del objeto con el que se trabaja.
Después de llamar a Cls, las propiedades CurrentX y CurrentY del objeto se restablecen a 0.
METODO PaintPicture
Presenta el contenido de un archivo gráfico (.BMP, .WMF, .EMF, .ICO o .DIB) en un objeto
Form, PictureBox o Printer. La imagen deberá estar en un Formulario o en un control Image.
NO puede usarse este método para dibujar una imagen contenida en un fichero (Vea mas
adelante la función LoadPicture)
Puede sacar mucho partido a la propiedad PaintPicture. Piense solamente que puede volcar
una imagen .BMP al objeto Printer (a la impresora). Esto puede permitirle dibujar un logotipo
en un listado, factura, etc.
Sintaxis
objeto.PaintPicture Imagen, x1, y1, anchura1, altura1, x2, y2, anchura2, altura2, Opecod
Pagina: 140
La sintaxis del método PaintPicture tiene las siguientes partes:
objeto es el objeto donde queremos colocar el gráfico. Es opcional. Si se omite, se asume que
el objeto es el formulario que tenga el enfoque.
x1, y1 Parámetro requerido. Indican las coordenadas destino (eje x y eje y) del objeto en las
que se ponemos el origen de la imagen. Las propiedad ScaleMode, o ScaleWidth y
ScaleHeight del objeto determinan las unidades de medida que se usan. Recuerde que las
coordenadas en VB crecen desde la esquina superior izquierda. Los valores x1 e y1
determinan el punto del objeto donde se colocará la esquina superior izquierda del gráfico que
vamos a introducir.
altura1 Opcional. Indica la altura destino de la imagen. La propiedad ScaleMode del objeto
determina las unidades de medida que se usan. Si altura destino es mayor o menor que la
altura origen (altura2), imagen se amplía o se comprime respecto al original. Si se omite, se
usa la altura origen.
x2, y2 Parámetro opcional. Indican las coordenadas (eje x y eje y) de la zona de recorte
dentro de la imagen origen. Esto de la zona de recorte significa que podemos cortarle a la
imagen origen un trozo, tanto en sentido vertical como en horizontal.
anchura2 Opcional. Indica la anchura de la imagen origen. Este parámetro se usa para
establecer la relación entre la anchura de la imagen final y la anchura de la imagen origen.
Si al realizar la copia de la imagen a Objeto, esta nos sale muy grande, podemos, bien rebajar
el parámetro anchura1 o aumentar anchura2, puesto que la medida real del ancho de la
imagen final estará en relación directa con el cociente anchura1/anchura2
altura2 Opcional. Lo mismo que para anchura2, pero referido a la altura en este caso.
Opecod Opcional. Valor Long o código que se usa sólo con mapas de bits. Define una
operación bit a bit (por ejemplo, operador Not o Xor) que se realiza sobre imagen al dibujarla
sobre objeto. Para obtener la lista completa de los operadores bit a bit, busque el tema BitBlt
en el archivo de Ayuda de Windows SDK (WIN31WH.HLP).
NOTA Como caso práctico, el autor de este texto suele guardar la imagen en una variable tipo
Picture. Se desconoce el ancho de esa imagen, que vendrá dado por la anchura real del
Bitmap. Puede conocerse la anchura y altura de la imagen consultando la anchura y altura de
la variable :
AnchodelaImagen = VariableImagen.Width
AlturadelaImagen = VariableImagen.Height
Muchas veces, la imagen que se introduce en la variable tipo Picture es distinta en una
ocasión u otras, por lo que desconocemos a priori que dato debemos poner a anchura1 y a
anchura2. Todo tiene solución. Con el código siguiente el ancho y alto de la imagen se
mantendrá constante independientemente de la anchura y altura que tenga el Bitmap original.
Pagina: 141
objeto.PaintPicture Imagen, x1, y1, anchura1, altura1, , , VariableImagen.Width, _
VariableImagen.Height
donde hemos omitido x2, y2 de forma intencionada, pero observe que hemos seguido
respetando su sitio con las comas como separadores. El último parámetro, Opecod se ha
omitido, pero como es el último, no hace falta dejarle las comas.
Pueden omitirse tantos argumentos finales como se desee. Si se omite uno o varios
argumentos finales, no se usan comas a partir del último argumento especificado. Si se quiere
especificar un argumento opcional, se deben especificar todos los argumentos opcionales que
aparecen antes en la sintaxis.
METODO Point
Devuelve, como entero Long, el color rojo - verde - azul (RGB) del punto especificado de un
objeto Form o control PictureBox.
Sintaxis objeto.Point(x, y)
donde
objeto Opcional. Nombre del Formulario o PictureBox donde se va a analizar el color. Si
objeto se omite se asume que el objeto es el formulario que tenga el enfoque.
x, y Parámetro requerido. Valores Single que indican las coordenadas horizontal (eje x) y
vertical (eje y) del punto según la propiedad ScaleMode del objeto Form o control PictureBox.
Deben colocarse entre paréntesis.
Estas coordenadas se refieren a las coordenadas del objeto que contiene el gráfico, con origen
(0,0) en la esquina superior izquierda del mismo.
Si el punto definido por las coordenadas x e y está fuera de objeto, el método Point devuelve
el valor -1.
METODO Pset
objeto Opcional. Nombre del objeto (Formulario, PictureBox o Printer). Si se omite objeto, se
asume como objeto el Formulario que tenga el enfoque.
(x, y) Requeridos. Valores de simple precisión que indican las coordenadas horizontales (eje
x) y verticales (eje y) del punto a establecer.
Estas coordenadas se refieren a las coordenadas del objeto destino, con origen (0,0) en su
esquina superior izquierda.
Color Parámetro opcional. Valor entero largo que indica el color RGB especificado para el
punto. Si se omite, se utiliza el valor de la propiedad ForeColor. Puede utilizar la función RGB
o la función QBColor para especificar el color.
Pagina: 142
El tamaño del punto dibujado depende del valor de la propiedad DrawWidth. Cuando
DrawWidth es 1, PSet establece un píxel al color especificado. Cuando DrawWidth es mayor
que 1, se centra el punto en las coordenadas especificadas.
La forma en que se dibuja el punto depende de los valores de las propiedades DrawMode y
DrawStyle.
Cuando se ejecuta PSet, las propiedades CurrentX y CurrentY toman el valor del punto
especificado en los argumentos.
Vacíe un píxel con el método PSet especificando las coordenadas del píxel y utilizando el valor
de la propiedad BackColor como argumento color.
Como complemento a los Métodos gráficos, bueno será comentar las formas posibles de
introducir colores en VB y otras propiedades que tienen relación con los métodos gráficos.
NOTA ADICIONAL
Colores en Visual Basic.
(Este texto es repetición del expuesto en el capitulo del CommonDialog)
Visual Basic acepta para especificar un color, tres procedimientos: Mediante el número de
color, mediante la sentencia RGB ( rojo, verde, azul ) o mediante la función QBColor.
Por número
El número que representa el color en VB está formado por la suma de la componente roja, la
componente verde y la componente azul. Podríamos verlo muy bien en numeración
Hexadecimal:
Color = Hex XX YY ZZ
Donde ZZ es un número Hexadecimal que representa la cantidad del color rojo. El mínimo
estaría en 0 (H00) y el máximo en 255 (HFF)
YY representaría la cantidad de color verde y XX la de color azul, ambos con los mismos
límites explicados para el rojo.
Una mezcla de un poco de rojo (HB1), otro poco de verde (H56) y otro poco de azul (H1F)
daría el siguiente número:
Hex(1F56B1) = 2053809
Se puede expresar el color, poniendo simplemente RGB (rojo, verde, azul), donde rojo es un
número entre 0 y 255 que indica la cantidad de color rojo que se aporta al color, verde un
número comprendido entre 0 y 255 indicando la cantidad de verde, y lo mismo para azul.
Esta es la forma mas sencilla de poner la propiedad color, y con la que mejor controlaremos el
mismo.
Pagina: 143
Devuelve o establece el código de color RGB correspondiente a un número de color.
Sintaxis Objeto.QBColor(color)
0 Negro 8 Gris
1 Azul 9 Azul claro
2 Verde 10 Verde claro
3 Aguamarina 11 Aguamarina claro
4 Rojo 12 Rojo claro
5 Fucsia 13 Fucsia claro
6 Amarillo 14 Amarillo claro
7 Blanco 15 Blanco brillante
Static i As Integer
i=i+1
If i = 16 Then i = 0
Label1.caption = i
Label1.BackColor = QBColor(i)
SavePicture (Instrucción)
imagen es el nombre del objeto que contiene los gráficos que se van a guardar en el archivo,
mas su propiedad Picture o Image y expcadena es el nombre del archivo gráfico que se va a
guardar.
LoadPicture (Función)
Pagina: 144
Sintaxis Objeto.LoadPicture ([expcadena])
Donde Objeto es el nombre del Formulario, PictureBox o control Image que se va a rellenar
con el gráfico, y el argumento expcadena es el nombre del archivo gráfico que se quiere
cargar.
Usando LoadPicture sin argumento se borran los gráficos de los formularios y los controles
PictureBox e imagen.
Los formatos gráficos reconocidos por Visual Basic incluyen archivos de mapas de bits (.BMP),
archivos de icono (.ICO), archivos de longitud codificada (.RLE) y Metarchivo (.WMF).
Para cargar gráficos para presentarlos en un control PictureBox, Image o como fondo de un
formulario, el valor devuelto por LoadPicture debe ser asignado a la propiedad Picture del
objeto en el se quiere presentar la imagen. Por ejemplo:
Para asignar un icono a un formulario, se asigna el valor devuelto por la función LoadPicture a
la propiedad Icon del objeto Form:
Los iconos también pueden ser asignados a las propiedades DragIcon de todos los controles
excepto los controles Timer y Menú. Por ejemplo:
Para cargar gráficos en el Portapapeles del sistema se usa LoadPicture de la forma siguiente:
Puede también meter una imagen en una variable, y luego poner en uno de los controles
citados anteriormente la imagen guardada en la variable. Este método le permite presentar
una imagen muy rápidamente, ya que no necesita acceder al disco para buscar una imagen,
pero emplea mucha memoria RAM, ya que la variable (o variables) conteniendo la(s)
imágenes están en la RAM.
Option Explicit
Dim MiVariable1 As Picture, MiVariable2 As Picture
Pagina: 145
Mediante este programa lo que hemos hecho fue guardar dos imágenes en sendas variables,
en el momento de cargar el formulario, imágenes que se pasan posteriormente al control
Picture1 con los botones de comando Command1 y Command2
DrawMode (Propiedad)
Donde objeto es el nombre del Formulario, PictureBox, objeto Print, o los controles Shape o
Line, y número es un entero que especifica el aspecto, según la siguiente lista:
1 Blackness.
2 Not Merge PenInverso del valor 15 (Merge Pen).
3 Mask Not PenCombinación de los colores comunes del color de fondo y el inverso del
Pen.
4 Not Copy PenInverso del valor 13 (Copy Pen).
5 Mask Pen NotCombinación de los colores comunes al Pen y al inverso de la muestra.
6 InvertInverso del color de muestra.
7 Xor PenCombinación de los colores en el Pen y en el color de la muestra, pero no de
ambos.
8 Not Mask PenInverso del valor 9 (Mask Pen).
9 Mask PenCombinación de los colores comunes al Pen y a la presentación.
10 Not Xor PenInverso del valor 7 (Xor Pen).
11 NopNadano hay cambios. De hecho, este valor desactiva el dibujado.
12 Merge Not PenCombinación del color de muestra y el inverso del color del Pen.
13 Copy Pen (Predeterminado)Color especificado por la propiedad ForeColor.
14 Merge Pen NotCombinación del color del Pen y el inverso del color de muestra.
15 Merge PenCombinación del color del Pen y el color de muestra.
16 Whiteness.
Use esta propiedad para producir efectos visuales con controles Shape o Line o al dibujar con
métodos gráficos. Visual Basic compara cada píxel de la plantilla de dibujo con el píxel
correspondiente del fondo existente y después aplica operaciones a nivel de bit. Por ejemplo,
el valor 7 (Xor Pen) usa el operador Xor para combinar un píxel del dibujo con un píxel del
fondo.
El efecto exacto de un valor DrawMode depende del modo en el que el color de una línea
dibujada en tiempo de ejecución se combina con los colores de la pantalla. Los valores 1, 6, 7,
11, 13 y 16 producen los mejores resultados.
DrawStyle (Propiedad)
Donde objeto es el nombre del Formulario, PictureBox, objeto Print sobre el que se va a
dibujar, y número es un entero que especifica el estilo de línea, tal como se describe a
continuación:
0 (Predeterminado) Continuo.
1 Rayas.
2 Puntos.
Pagina: 146
3 Raya - punto.
4 Raya - punto - punto.
5 Transparente.
6 Continuo interior.
Si DrawWidth se define con un valor mayor que 1, los valores de DrawStyle entre 1 y 4
producen una línea continua (el valor de la propiedad DrawStyle no cambia). Si DrawWidth se
define como 1, DrawStyle produce el efecto para cada valor descrito en la tabla anterior.
DrawWidth (Propiedad)
Donde objeto es el nombre del Formulario, PictureBox, objeto Print sobre el que se va a
dibujar, y tamaño es una expresión numérica comprendida entre 1 y 32.767 que representa la
anchura de la línea en pixeles. El valor predeterminado es 1, es decir, un píxel de ancho.
Puede incrementar el valor de esta propiedad para aumentar la anchura de la línea. Si el valor
de la propiedad DrawWidth es mayor que 1, los valores de 1 a 4 en la propiedad DrawStyle
producirán una línea continua (el valor de DrawStyle no se modifica). Si se establece 1 en
DrawWidth, DrawStyle producirá los resultados mostrados en la tabla de esta propiedad.
FillColor (Propiedad)
Devuelve o establece el color usado para rellenar formas; FillColor también se usa para
rellenar círculos y cuadros creados con los métodos gráficos Circle y Line.
Donde objeto es el nombre del Formulario, PictureBox, objeto Print sobre el que se va a
dibujar, y valor es un valor o constante que determina el color de relleno, con cualquiera de
los criterios de VB para definir el color.
De forma predeterminada, FillColor está definido como 0 (Negro).
Comentarios
FillStyle (Propiedad)
Devuelve o establece el modelo usado para rellenar controles Shape así como los círculos y
los cuadros creados con los métodos gráficos Circle y Line.
Donde objeto es el nombre del Formulario, PictureBox, objeto Print sobre el que se va a
dibujar, y número es un entero que especifica el estilo de relleno, tal como se describe
a continuación:
0 Continuo.
1 (Predeterminado) Transparente.
2 Línea horizontal.
3 Línea vertical.
4 Diagonal hacia arriba.
Pagina: 147
5 Diagonal hacia abajo.
6 Cruzado.
7 Diagonal Cruzada.
AutoRedraw (Propiedad)
Donde objeto es el nombre del Formulario, PictureBox, objeto Print sobre el que se va a
dibujar, y booleano es una expresión booleana que especifica la forma en la que objeto es
vuelto a dibujar, tal como se describe a continuación:
True Activa el redibujado automático de un objeto Form o control PictureBox. Los gráficos
y el texto se escriben en la pantalla y en una imagen almacenada en memoria. El objeto no
recibe eventos Paint; se vuelve a dibujar cuando es necesario, usando la imagen almacenada
en memoria.
Esta propiedad es importante cuando se trabaja con los siguientes métodos gráficos: Circle,
Cls, Line, Point, Print y PSet. Al establecer AutoRedraw a True la salida de estos métodos se
vuelve a dibujar automáticamente en un objeto Form o en un control PictureBox cuando, por
ejemplo, se cambia de tamaño al objeto o se vuelve a presentar después de haber estado
oculto por otro objeto.
Se puede establecer AutoRedraw en el código en tiempo de ejecución para alternar entre
dibujar gráficos persistentes (como color de fondo o cuadrícula) y gráficos temporales. Si se
define AutoRedraw a False, la salida anterior se convierte en parte del fondo de la pantalla.
Cuando AutoRedraw se define a False, los gráficos de fondo no se eliminan si se borra el área
de dibujo con el método Cls. Al volver a establecer AutoRedraw a True y después usar Cls se
borran los gráficos de fondo.
Pagina: 148
CONTROLES ESPECIALES SOLO PARA LA VERSION DE 32 BITS
Existen una serie de controles que solamente pueden utilizarse con la versión de Visual Basic
de 32 bits. Estos controles permiten realizar aplicaciones con la interface gráfica típica de
W95.
Control ImageList
El Control Image List es un almacén de imágenes para poder usarlas posteriormente en otro
control. El control ImageList no presenta directamente las imágenes que almacena. En el
Capitulo 4 puede ver mayor información respecto a este control.
Este control permite realizar una barra de herramientas. La barra de herramientas es, como ya
conocerá, una barra donde existen varios iconos. Estos iconos realizan una determinada
función. Normalmente se ponen en la barra de herramientas los iconos que representan las
acciones mas frecuentes de una aplicación. Esto facilita la operación al no tener que desplegar
menús para buscar la operación a realizar.
Como el espacio que ocupan los iconos es grande, es también bastante normal que no estén
representados en la barra de herramientas todas las funciones posibles de la aplicación, sino
como decíamos, solamente las mas frecuentes. Pero ocurre que la función que para un
usuario es muy frecuente, para otro no lo es, por lo que también es habitual poder programar
los iconos que aparecen en la barra de herramientas.
Para introducir el Toolbar es necesario que esté presente en la caja de herramientas el control
personalizado Microsoft Windows Common Controls (COMCTL32.OCX).
El control Toolbar es un contenedor de un array de iconos. Estos iconos forman botones sobre
los que se puede insertar código en sus propiedades. A cada botón se le denomina Button y a
la colección de botones se le denomina Buttons. Cada Button es un elemento de la colección
Buttons y por lo tanto podemos referirnos a cada uno de ellos por el índice que tiene dentro
de la colección.
Los iconos de cada uno de los botones del Toolbar debe introducirse previamente en un
control ImageList. Como se ha visto, un control ImageList es un almacén de imágenes, que
podemos usar en cualquier parte de la aplicación. Una de esas partes es la confección de la
barra de herramientas. Por lo tanto, es necesario introducir un control ImageList en cualquier
aplicación que use un control Toolbar. Todas las imágenes del Toolbar deben estar en un
único ImageList.
La barra de herramientas puede realizarse en tiempo de diseño (este sería el caso para
cuando no existiese variación ni elección de botones a lo largo de la ejecución de la
aplicación)
o en tiempo de ejecución (caso que correspondería con una aplicación que tuviese una barra
de menú programable o que variase esta barra de menú dependiendo de cada operación que
se esté ejecutando en la aplicación).
Para realizar la barra de herramientas en tiempo de diseño, basta con visualizar el cuadro de
propiedades que aparece pulsando el botón derecho del ratón sobre el control Toolbar.
Aparecerá un cuadro de diálogo como este :
Pagina: 149
Puede ver que en el cuadro ImageList aparece el nombre de un ImageList. Al desplegar la lista
aparecerán todos los ImageList que existan en el formulario. El ImageList debe estar en el
mismo formulario que el Toolbar. Deberá elegirse el ImageList que contenga las imágenes de
los iconos que queremos introducir en el Toolbar.
Este cuadro nos permite también introducir la forma que adoptará el puntero del ratón cuando
entre en el Toolbar MousePointer) si el Toolbar aparece por defecto habilitado o deshabilitado
(Enabled) y si muestra o no un rótulo programable al pasar el ratón por encima de cada botón
del Toolbar. (ShowTips). La propiedad AllowCustomize permite, si es True, cambiar el orden de
los botones e introducir separadores (vea evento DobleClick).
En el cuadro botones podemos introducir los datos deseados para cada uno de los botones que
compondrán la colección Buttons.
Para insertar un nuevo botón hay que hacer click sobre Insertar botón e insertará un nuevo
botón inmediatamente después del que figura en la propiedad Index (en la figura del ejemplo,
lo insertaría en segundo lugar, no en el último lugar como podría creerse). También podemos
eliminar un botón haciendo click sobre Eliminar botón.
El Caption (opcional) es la palabra que figurará debajo del icono del botón.
Pagina: 150
Un botón se identifica por su índice. ( Toolbar1.buttons(1) )
La propiedad Key es un nombre que se puede añadir a cada botón. Esta propiedad sirve para
identificar el botón que se ha pulsado, pero no para nombrar al botón.
La propiedad Value es el valor por defecto, con el que aparecerá el botón al comienzo de la
aplicación. (Unpressed, no pulsado, Pressed, pulsado).
ToolTipText es el texto que aparecerá al lado del botón cada vez que se ponga el cursor del
ratón sobre el botón. Para que aparezca debe estar habilitada la propiedad ShowTips.
El control Toolbar también puede realizarse en tiempo de ejecución. Para introducir u botón en
el Toolbar hay que crear el botón y añadirlo a la colección Buttons de Toolbar. Podemos
hacerlo en una sola instrucción :
NombreBotón puede ser cualquier nombre (es el nombre del objeto botón)
NombreToolbar es el nombre del Toolbar
Indice es el número de orden de ese botón dentro del Toolbar
Key es el valor de la propiedad Key del botón. Este valor debe ser único para cada botón.
Style es un número del 0 al 4 con el tipo de botón. Vea lista mas arriba
Imagen es el número de la imagen para ese botón, dentro del ImageList que las contiene.
Los botones pueden habilitarse y deshabilitarse usando la propiedad Enabled (True / False).
Recuerde que los botones se identifican por su índice :
Toolbar1.Buttons(Indice).Enabled = False
Con la lectura de la propiedad Key, y la sentencia Case o If ... Then podemos iniciar la parte de
la aplicación asociada a cada botón.
ButtonClick
Este evento se produce cada vez que se hace click sobre un botón del Toolbar. Pasa como
parámetro el índice del botón pulsado. Podremos saber que botón se ha pulsado mediante
sentencias condicionales :
Pagina: 151
If Button.Index = 1 Then . . . .
If Button.Index = 2 Then . . . .
Click
Este evento se produce cuando se hace click sobre cualquier botón del Toolbar, pero no pasa
parámetros. Podemos utilizarlo cuando se quiera realizar una operación común para todos los
botones (Que suene un Beep, por ejemplo)
DobleClick
Este evento solamente se produce cuando se hace doble click en la parte del Toolbar donde no
hay botones, y la propiedad AllowCustomize esté a True. Si se hace doble click sobre un botón
se produce solamente el evento click (dos veces). Haciendo doble click en una zona libre de
botones, con la propiedad AllowCustomize = True nos permite cambiar el orden de los botones
e introducir separadores.
Change
Se produce solamente cuando se ha realizado algún cambio del orden por el procedimiento
anterior.
DragDrop, DragOver
Igual que el resto de los controles Pasa como parámetro el índice del botón, la tecla de
mayúsculas, y las posiciones x e y del ratón.
Este control solamente funciona en la versión de VB de 32 Bits. Pero para 16 bits puede
hacerse una cosa parecida (y mas sencilla) utilizando un control Picture como contenedor de
tantos controles Image como necesitemos. Dado que el control Picture dispone de propiedad
Align y puede servir como contenedor de otros controles, puede realizarse una barra de
herramientas similar a esta, y posiblemente de forma mas sencilla.
LA BARRA DE ESTADO
La barra de estado puede albergar hasta 16 paneles, que pueden contener texto o gráficos.
También pueden contener información del Hardware, tal como el estado de la tecla Bloqueo de
Mayúsculas, Bloqueo del teclado numérico, tecla Insert activada, tecla Scroll Lock activada, o
mostrar la fecha y la hora
Pagina: 152
Las dimensiones de cada panel pueden configurarse como fijas o ajustadas al tamaño del
texto o imagen que presentan.
Para añadir un panel en tiempo de ejecución basta con añadirlo a la colección Panels del
control StatusBar mediante la sentencia :
StatusBar1.Panels.Remove (n)
StatusBar1.Panels(3).Visible = False
La Barra de Estado puede servir para presentar información acerca del proceso de la
aplicación (para eso se ha pensado), pero también puede servir para introducir comandos
como si se tratase de varios botones de comandos. La Barra de Estado tiene varios eventos,
entre ellos el evento click. Eso sí, se produce el mismo evento click independientemente del
panel sobre el que hayamos picado con el ratón. Solamente queda conocer el panel sobre el
que se ha hecho click y, mediante sentencias condicionales If ... End If añadir el código
necesario dependiendo del panel que se haya pulsado. En el ejemplo siguiente, la operación a
realizar es escribir en un Label la operación que se desea realizar :
PROGRESS BAR
Es similar al control Gauge, pero mas bonito. Tiene las mismas propiedades y se trabaja con él
de la misma forma que con el Gauge.
Pagina: 153
Las propiedades mas destacables del ProgressBar son :
Pagina: 154
FICHEROS EN VISUAL BASIC
- Secuenciales
- Aleatorios (Random)
- Binarios
FICHEROS SECUENCIALES
Este tipo de ficheros nos permite guardar información de cualquier longitud. En este tipo de
ficheros, la información se guarda colocando un carácter tras otro. La forma de leerlos es,
igualmente, carácter tras carácter. (Byte tras byte). Son los mas sencillos de manejar, y los
utilizados para guardar texto en ASCII. Permiten guardar datos en un fichero con un
determinado nombre, "machacando" la información de otro posible fichero que ya estuviese en
el disco con el mismo nombre, o añadir la información nueva a continuación de la ya existente.
Para abrir un fichero secuencial para guardar información, debemos ejecutar la siguiente
instrucción:
Numerocanal debe ser un número comprendido entre 1 y 255. Representa el número del canal
por donde introduciremos los datos. Normalmente se llama también número de archivo. No
puede haber mas de un archivo abierto con un número de archivo determinado.
Close # Numerocanal
Si no se especifica Numerocanal (la instrucción Close a secas) se cerrarán todos los ficheros
abiertos actualmente.
Print
Introduce la información de forma secuencial, byte tras byte tal como se
comentó. Sirve para guardar textos. Por ejemplo si deseamos guardar en ese
fichero el contenido de una caja de texto llamada Text1, basta con ejecutar la
siguiente instrucción:
Cuando los datos se han introducido con la instrucción Print, es decir, cuando hemos
introducido texto letra tras letra, la forma de acceder a ese texto es muy sencilla:
Pagina: 155
Se abre el archivo con la instrucción Open
Se utiliza la instrucción Input o Line Input para sacar los datos del fichero.
Por ejemplo, Input (1, #1) extrae un carácter del fichero abierto como #1. El número máximo
de caracteres a extraer de un golpe mediante la instrucción Input está limitado a 65.534.
Verá un poco mas adelante la propiedad LOF de los ficheros secuenciales. LOF devuelve un
valor igual a la longitud total del fichero. Si ejecutamos la instrucción :
leeremos el fichero de una única vez. Este procedimiento puede ahorrarle cierto tiempo a la
hora de la lectura. (Por lo dicho anteriormente, este procedimiento de leer todo el fichero de
un golpe solamente se podrá hacer si la longitud del fichero (LOF(1)) es inferior a 65.534
bytes. Tenga esto presente cuando vaya a leer un fichero que no sabe que longitud tiene. Para
curarse en salud, le recomiendo que lea los ficheros secuenciales carácter a carácter.
Input(1,#X) pues tarda poco mas que leyéndolo de un golpe.
Sólo se utilizará la instrucción Input con archivos abiertos en modo Input o Binary. (Se verán
a continuación) A diferencia de la instrucción Input #, (la veremos a continuación, pues es la
instrucción que deberá utilizar para leer archivos escritos con la instrucción Write ), Input
devuelve todos los caracteres que lee, incluyendo puntos y coma, retornos de carro, avances
de línea, comillas y espacios iniciales.
Existe una instrucción, Input$ , que asume que el dato a leer es un String. (Cadena de
caracteres). Puede ahorrar un poco de memoria usando esta instrucción en lugar de Input.
Nota Se proporciona otra función (InputB) para su uso con datos de byte incluidos en archivos
de texto. En lugar de especificar el número de caracteres a devolver, número especifica el
número de bytes.
La instrucción Line Input se utiliza para extraer una línea completa. Tiene la siguiente
sintaxis:
Mediante esta instrucción se extrae una línea completa (los caracteres delimitados entre dos
retornos de carro), y se le asigna esa cadena a Variable
La instrucción Line Input # lee un carácter cada vez en un archivo hasta que encuentra un
retorno de carro (Chr(13)) o una secuencia retorno de carro-continuación de línea (Chr(13) +
Chr(10)). Las secuencias de retorno de carro-continuación de línea no se tienen en cuenta y no
se añaden a la cadena de caracteres. Cuando lea un archivo mediante Line Input # y lo quiere
presentar en un TextBox o en el Printer, deberá introducirlos para evitar que le salga todo el
texto en una única línea.
Con lo que se ha explicado, ya puede realizar un pequeño edito de textos. Este sencillo editor
tiene un TextBox llamado TBTexto, donde podemos escribir el texto que queramos (con la
Pagina: 156
propiedad MultiLine = True y ScrollBars = Vertical), tres botones llamados BAbrir (1), (2 a y b)
y (3), para abrir el fichero y poner su contenido en TBTexto, y dos BGuardar para guardar,
uno abriendo el fichero For Append y el otro abriéndolo For Output. En este último, al guardar
el texto borramos el contenido que del fichero, si ya existiera. En el primero, lo anexamos al
final del mismo . Para conocer el nombre del fichero, ponemos un CommonDialog llamado
CD1, con un filtro CD1.Filter = “Ficheros de Texto |*.txt”
Para abrir el fichero, y depositar su contenido en TBTexto pondremos este código en BAbrir :
Cuando el fichero es mayor de 64 kilobytes, el leerlo de un golpe puede dar problemas. Mejor
dicho, no funciona. Deberemos leerlo en ese caso, carácter a carácter o línea a línea.
Pagina: 157
Los Botones de Guardar tienen el código :
INSTRUCCIÓN WRITE
La otra forma de introducir datos en un fichero secuencial es Write. Mediante esta instrucción,
no se puede introducir texto, sino datos, aunque esos datos sean de texto.
Write
Puede introducir varias informaciones, que posteriormente se podrán leer de
forma separada con la instrucción Input #. Esta forma de introducir datos en
un fichero secuencial permite realizar un fichero con distintos datos que se
pueden leer en el propio fichero, puesto que se guardan en ASCII, y leerlos
mediante el programa de una forma muy sencilla. Hacemos, en realidad, una
pequeña base de datos. (Verá a lo largo de su vida profesional que lo de
pequeña no es cierto, pues es la forma mas sencilla de guardar datos cuando
la cantidad de estos datos no es muy grande)
Lo que estamos haciendo en realidad al escribir datos mediante la instrucción Write es escribir
estos datos en un fichero secuencial, utilizando una coma como separador entre los distintos
datos. Un fichero secuencial con datos introducidos mediante la instrucción Write tendrá esta
forma :
Observe que el contenido de este fichero se diferencia algo de una simple sucesión de
caracteres. Tiene varias partes separadas por una coma. Cada una de ellas es un dato.
Imaginemos una aplicación, con la que introducimos datos de libros. La aplicación es un único
formulario donde podemos introducir la información mediante varios TextBox. Existe un Botón
de comando con el siguiente código:
Pagina: 158
EDITORIAL = LIBRETBEDITORIAL.Text
PRECIO = LIBRETBPREC.Text
EXISTENCIAS = LIBRETBEX.Text
Si introduce los datos del ejemplo anterior, se creará un fichero que tiene esta apariencia:
Si realizamos otra introducción de datos, con la segunda línea del ejemplo anterior, los datos
existentes en ese fichero no se borrarán, dado que lo hemos abierto con Append. Quedará de
la siguiente forma:
¿Que pasaría si leemos este fichero con la instrucción Input o Line Input # vista
anteriormente ? Pues simplemente que lo leeríamos tal como está, con sus comas y comillas
dobles. No sería la forma mas adecuada, ya que lo que queremos es obtener sucesivos datos
de autores, títulos, editoriales, precios y existencias.
Para sacar estos datos debemos leerlos con la instrucción Input #. Esta instrucción saca los
datos que hemos metido, es decir, elimina las comillas y la coma que servían de separadores.
En nuestro ejemplo, podríamos hacerlo de esta forma, aprovechando los mismos TextBox:
'Abrimos el fichero
LIBRETBTITULO.Text = TIT
LIBRETBAUTOR.Text = AUT
LIBRETBEDITORIAL.Text = NED
LIBRETBPREC.Text = PRE
LIBRETBEX.Text = EXS
' Refrescamos los TextBox
Refresh
Pagina: 159
' Esto produce una pequeña parada
Do While DETENERSE = True
A=A+ 1
If A = 100000 Then DETENERSE = False: A = 0
Loop
' terminó la parada y vuelve a leer datos
Loop
Close #1
End Sub
Observe que los nombre de las variables en el proceso de lectura tienen distintos nombres a
los utilizados durante la escritura. Como en el fichero no se guarda ninguna referencia al
respecto, lo único que importa es que el número de variables para la lectura sea igual al
número de variables que se utilizó para la escritura, y que el orden de las variables sea
correcto. Si por ejemplo, el número de variables usadas en la introducción de datos fuese
distinta al número de variables usado en la lectura, Visual Basic nos daría un error.
Observe también que se ha introducido un temporizador. Sirve para ver los sucesivos títulos
que tenemos en nuestra base de datos tan sui generis. Se ha pretendido presentar unos datos
de esta pequeña base de datos sin complicarnos mucho la vida. Mas adelante veremos como
presentarlos de una forma correcta. Este tipo de ficheros no es el mas adecuado para construir
grandes bases de datos, es complicado manejar ficheros de mas de unas pocas líneas, por lo
que para tener muchos datos, este tipo de ficheros no es recomendable. Sin embargo, para
tener una línea única, o un número bajo de líneas de datos, este tipo de fichero Simplifica
notablemente las aplicaciones. Tiene además una gran ventaja : podemos verlo con un
procesador de textos ASCII (Block de Notas, por ejemplo) y cambiarle los datos con ese
mismo procesador. Piense en los típicos archivos .INI que acompañan a casi todas las
aplicaciones informáticas para la personalización de las mismas y verá la utilidad de estos
sencillos ficheros secuenciales.
En esta pequeña aplicación mostrábamos las informaciones sucesivamente según las íbamos
leyendo del fichero. Interrumpíamos momentáneamente la lectura para presentar cada
información durante un instante, ya que como tenemos cinco datos distintos en cada registro y
cinco TextBox para presentarlos, deberemos presentar una información tras otra. Esto no
parece en principio una solución práctica para una base de datos, donde lo que interesa es
disponer de todos los datos para usarlos cuando sea necesario. Esto nos lleva a crear una
matriz para albergar todos los datos de la base, ya que los ficheros secuenciales se leen y se
les tiene que extraer toda la información de un golpe, ya que no permiten ir a leer hacia atrás.
Por lo tanto, si deseamos disponer de todos los datos, deberemos guardarlos en la memoria,
en una matriz. Imagínese que estamos tratando datos de varios miles de libros en el ejemplo
anterior. Si la información de cada campo es medianamente extensa, no tendríamos memoria
RAM suficiente en el ordenador para albergarlos. Esto nos lleva a pensar en otro tipo de
archivo que veremos a continuación, los Random (aleatorios), que permiten leer solamente los
registros que nos interesan.
Pero volvamos a nuestra aplicación de librería, donde hemos hecho una variación, los campos
PRECIO y EXISTENCIAS los vamos a tratar ahora como números (Integer). También se ha
introducido otro campo tipo texto, para introducir la edición. El fichero creado tras introducir
varios libros quedó de la siguiente forma :
Pagina: 160
"LA METAMORFOSIS","KAFKA","PLAZA&JANES", “4ª”,3400,101
"VB4 PARA WINDOWS95","GARY CORNELL","MCGRAWHILL",”1ª”,6500,25
Observe que los dos últimos campos (correspondientes a PRECIO y EXISTENCIAS) no están
entre comillas, pues no se trata de texto, sino de números.
(Observe también la gran ventaja de tener una base de datos con datos completamente
legibles)
Se han introducido alguna variaciones en el programa. Entre ellas, se crea una matriz de
variables de 5 x n (n=número de registros). También se le añaden unos botones para poder
recorre toda la base de datos.
El programa necesita que le introduzcamos el nombre del fichero que alberga la base de
datos. Por sencillez no se ha usado ningún CommonDialog y se introduce directamente el
nombre de este fichero en un TextBox llamado TBNombreFichero
Donde las variables TITULO, AUTOR, EDITORIAL y EDICION serán del tipo String y PRECIO
y EXISTENCIAS serán de tipo numérico. Podemos saberlo, ya que en una línea cualquiera del
fichero anterior :
los cuatro primeros parámetros van entre comillas dobles, ya que son datos tipo texto, y los
dos últimos van sin comillas, como corresponde a datos numéricos.
Pero existe otra forma mejor (al menos un poco mas complicada) para leer estos datos, y
evitar el problema que teníamos antes de tener que hacer un temporizador para poder ver,
Pagina: 161
aunque solo sea un momento, los datos. Podemos meter los datos a una matriz que tenga
tantas columnas como datos (campos) (en el ejemplo 6, cuatro String y dos numéricos), y
tantas filas como apuntes (registros) tengamos.
Para ello, antes de nada debemos definir un tipo de variable, mediante la instrucción Type.
Parece que no nos basta con los tipos de variable que trae VB (Long, String, Integer ...) y es
cierto. La variable que necesitamos no es de ningún tipo de esos. Está compuesta por varias
secciones, y cada una de ellas puede ser de un tipo distinto. Este tipo de definiciones debe
hacerse en un módulo (Véase instrucción Type en la ayuda de VB), por lo que se ha creado un
módulo llamado LIBREMD2.BAS, con el siguiente código :
Type REGISTROLIBRO
AUTOR As String
TITULO As String
EDITORIAL As String
EDICION As String
PRECIO As Integer
EXISTENCIAS As Integer
End Type
Esto es lo que se llama DEFINIR una variable. Es como hacerse un traje a medida. Y dese
cuenta de que es un tipo de variable (REGISTROLIBRO) formado por varias partes (AUTOR,
TITULO, Etc.) Observe que DEFINIR una variable NO es lo mismo que DECLARAR
En el apartado de Declaraciones del General del formulario declaramos las variables, entre
ellas una variable, REGISTROLIBROS, de la cual decimos que va a ser una matriz mediante
los paréntesis que la acompañan, y además declaramos que va a se similar a
REGISTROLIBRO ya definida en el módulo.
Dim NR As Integer
Dim REGISTROLIBROS() As REGISTROLIBRO
Dim NRP As Integer
En el ejemplo preparado podemos escribir y leer datos. Veamos de nuevo como se escriben
El código del procedimiento click del botón BIntroducir1 es :
‘(Observe que para introducir el precio y las existencias se transformó el contenido del TextBox
a ‘un valor numérico mediante la instrucción Val.)
Pagina: 162
Al leer los datos, lo primero es que no conocemos el número de registros existentes. Como
cada registro va en una línea del fichero, si contamos el número de retornos de carro (Chr(13))
obtendremos el número de registros. Esta operación es la primera que se realiza en el
procedimiento click del botón LEER :
‘ Abre el fichero, lo lee entero y cuenta el número de retornos de carro. Existirán tantos
apuntes (registros) como retornos de carro existan, ya que cada registro ocupa una línea.
‘Leemos los registros del 1 al NR, y cada campo del fichero lo vamos asignando a los
elementos ‘que componen la matriz.
For I = 1 To NR
Input #1, REGISTROLIBROS(I).TITULO
Input #1, REGISTROLIBROS(I).AUTOR
Input #1, REGISTROLIBROS(I).EDITORIAL
Input #1, REGISTROLIBROS(I).EDICION
Input #1, REGISTROLIBROS(I).PRECIO
Input #1, REGISTROLIBROS(I).EXISTENCIAS
Next I
Close #1
‘NRP = Número del Registro Presentado. Lo hacemos igual a 1 para presentar, de momento, el
‘número 1
Pagina: 163
NRP = 1
LIBRETBTITULO.Text = REGISTROLIBROS(NRP).TITULO
LIBRETBAUTOR.Text = REGISTROLIBROS(NRP).AUTOR
LIBRETBEDITORIAL.Text = REGISTROLIBROS(NRP).EDITORIAL
LIBRETBEDICION.Text = REGISTROLIBROS(NRP).EDICION
LIBRETBPREC.Text = REGISTROLIBROS(NRP).PRECIO
LIBRETBEX.Text = REGISTROLIBROS(NRP).EXISTENCIAS
End Sub
Observe que es muy sencillo trabajar con ficheros secuenciales para bases de datos. El
inconveniente es la cantidad de memoria necesaria para la matriz de datos. También tienen un
gran inconveniente: solamente se pueden leer de hacia adelante. Un fichero secuencial hay
que leerlo de una sola vez. Esto que no es ningún inconveniente para un fichero de texto, o
incluso para un fichero de datos que leemos una única vez, es un problema cuando leemos un
dato situado en un punto de ese fichero, y luego tenemos que leer un dato colocado en una
posición anterior. En este caso, deberemos terminar de leerlo, y volver a comenzar por el
principio. Este es un gran inconveniente para hacer bases de datos con ficheros secuenciales.
No solamente hemos visto una forma de crear una base de datos, sino que hemos visto como
movernos a lo largo de los registros. Verá esto con mucho mas detalle cuando demos bases
de datos. Este tipo de bases de datos son la Tipo Texto que verá mas adelante.
Pagina: 164
EOF
Indica el fin del fichero (End Of File). EOF será False hasta que encuentre el final del
fichero secuencial. Habrá observado instrucciones tales como:
LOC
Devuelve la posición de lectura/escritura actual en un archivo abierto.
LOF
Sintaxis LOF(numeroarchivo)
SEEK
Sintaxis Seek(númeroArchivo)
Observaciones
Pagina: 165
FICHEROS ALEATORIOS (RANDOM)
Un fichero aleatorio es un conjunto de registros, todos ellos de la misma longitud, que nos
permite guardar varias colecciones de datos.
Tal como habíamos visto en los ficheros secuenciales, el almacenar una serie de colecciones
de datos en un fichero secuencial era muy fácil, pero bastante difícil de almacenarlas en la
memoria cuando el número de estas colecciones superaba una cierta cantidad.
Los ficheros aleatorios permiten almacenar información en registros que pueden ser fácilmente
leídos, pudiendo leer los registros uno a uno, sin necesidad de leerlos todos. En los archivos
secuenciales, la información de varios datos podíamos introducirla mediante la instrucción
Write, y conseguíamos un registro de la forma: (Recuérdese el ejemplo de los datos de un
libro)
"Título","Autor","Editorial","Edición","Precio","Existencias"
Los ficheros aleatorios nos permiten guardar una información similar a la anterior, referida a
cualquier número de libros, y para leerla no es necesario leer todo el fichero, sino simplemente
acceder a los registros que nos interesen. También permite realizar el cambio de un registro de
una forma sencilla, sin alterar los demás.
Todo esto tiene un precio: En los archivos secuenciales, podíamos introducir informaciones de
cualquier longitud. En los archivos aleatorios cada dato tiene una longitud asignada, longitud
que no se puede sobrepasar, y si la información que debemos almacenar tiene menos que la
longitud preestablecida, perderemos esa capacidad sobrante.
Un fichero aleatorio (Random), una vez abierto, puede utilizarse para leer o escribir datos.
Para escribir datos en un fichero aleatorio, primero debemos definir el registro, es decir, en el
caso de los libros visto anteriormente, un registro va almacenar los datos del titulo, autor,
editorial, etc. Para "saber" como se colocan estos datos dentro del registro será necesario
definirlo. Podemos hacerlo con la instrucción Type en un módulo:
Type Registro
Titulo As String * 30 Asignamos 30 caracteres para el título
Autor As String * 30 Otros 30 para el autor
Editorial As String * 15 Asignamos 15 caracteres para editorial
Edición As String * 6 Asignamos 6 caracteres para Edición
Precio As String * 4 Asignamos 4 caracteres para el precio
Existencias As String * 3 Tres caracteres para existencias.
Pagina: 166
End Type
Observe la diferencia de esta definición con la que hacíamos en los ficheros secuenciales. En
aquellos no poníamos la longitud de cada sección. Aquí es necesario, ya que la longitud de un
registro (y también de cada campo) es fija.
Ya una vez definido como es Registro, podemos decir que una variable es del tipo definido
para Registro, es decir :
Entonces MiVariable ya puede almacenar los datos de Titulo, Autor, Editorial, Edición, Precio y
Existencias, colocando un dato tras otro, sin ninguna separación, en el mismo orden que lo
habíamos definido para Registro. No es necesario utilizar separaciones ya que el programa
sabe que longitud tiene cada dato y el orden de colocación. Lo sabe porque se lo hemos dicho
al definir Registro. Si los datos a introducir son :
el registro correspondiente a este libro tendrá una forma mas o menos así :
donde se ha sustituido el carácter nulo por una barra ( / ) con el fin de hacerlo visible en el
texto. Si se molesta en contar los caracteres que tiene el registro observará que son 88, que es
la suma de 30 + 30 + 15 + 6 + 4 + 3 que son los caracteres asignados a cada uno de las partes
que forman el registro (Título, Autor, etc.) Para hablar con propiedad, a esas partes que
componen el registro lea vamos a llamar CAMPOS. Un Registro está formado por varios
Campos, y cada Campo contiene una información.
Imagínese que introducimos otro libro. El primer campo de ese nuevo registro se colocará en
el fichero inmediatamente después del último campo existente, sin ningún tipo de separación.
No hace falta esa separación, pues VB conoce donde finaliza un registro y comienza otro, ya
que la longitud total del registro se le ha introducido en la instrucción para abrir el fichero, que
repetimos aquí por comodidad :
(Si se omite el dato LongitudRegistro VB colocará la longitud por defecto, 128 caracteres)
LongitudRegistro deberá ser igual o mayor que la suma de caracteres de cada uno de los
campos declarados en la instrucción Type, que también reproducimos :
Type Registro
Titulo As String * 30 Asignamos 30 caracteres para el título
Autor As String * 30 Otros 30 para el autor
Editorial As String * 15 Asignamos 15 caracteres para editorial
Edición As String * 6 Asignamos 6 caracteres para Edición
Precio As String * 4 Asignamos 4 caracteres para el precio
Existencias As String * 3 Tres caracteres para existencias.
End Type
Pagina: 167
¿Deberá ser igual o mayor, o estrictamente igual ? La respuesta es igual o mayor. Pero si
declaramos en la instrucción Open que el registro es mayor que la suma de los caracteres de
todos los campos que lo componen, estaremos perdiendo espacio de disco duro, tanto como la
diferencia entre lo declarado en la instrucción Open menos la suma de los caracteres de cada
uno de los campos. Y esa cifra, multiplicada por el número de registros existentes. Por lo tanto
debe declararse en la instrucción Open exactamente la suma de los caracteres de todos los
campos. En el ejemplo anterior era bastante fácil, ya que todos los campos eran del tipo String
(cadena de caracteres) y cada carácter ocupa un byte. La cosa se complica si uno o varios de
los campos son de tipo numérico, porque nos obligará a recordar cuantos bytes ocupa un
integer, un Long, etc. Si hubiésemos declarado en la instrucción Type Precio as Long,
Existencias as Integer deberíamos tener en cuenta que un Long (número entero entre
-2.147.483.648 y 2.147.483.647, inclusive) ocupa 4 bytes y un integer (número entero entre
-32.768 y 32.767) ocupa 2 bytes. Se reproduce a continuación la longitud en Bytes de cada
uno de los tipos de datos. No se moleste en aprendérsela de memoria, pues en la Ayuda de
Visual Basic puede encontrarla como Resumen de tipos de datos. Pero fíjese en algo tan
curioso como que un dato tipo Boolean que solamente puede tomar 2 valores (Sí / No) ocupa 2
bytes frente a un dato tipo Byte, que puede tomar 256 valores y ocupa solamente un Byte.
Ya le estoy viendo tomando buena nota de cuanto ocupa cada variable. Y echando números
para saber la longitud real de la variable y no perder ningún byte del disco duro
desaprovechándolo sin información. ¿No habrá algo que nos lo facilite ? Sí, lógicamente. La
instrucción LEN
LEN nos da la longitud de un texto (Var=Len (“Hola que tal”), o de una variable
Var=Len(Variable)
Podemos usarla para conocer la longitud total de la variable MiVariable
Ni que decir tiene que si se abre ese fichero en varias partes del programa con distintas
instrucciones Open el valor de LongitudRegistro debe ser igual en todas ellas.
Pagina: 168
una variable en la parte que corresponda del programa, dependiendo del ámbito que se le
quiera dar a esa variable, diciendo que será del tipo de la declarada mediante la instrucción
Type.
A partir de este momento, el programa sabe que REGLIBROS es una variable que tiene 6
campos (Titulo, Autor, Editorial, Edición, Precio y Existencias) y que cada campo tiene los
caracteres especificados en la instrucción Type.
Ahora nos cabe una pregunta ¿Cuantos registros tiene un fichero Random? La respuesta es
sencilla. Basta conocer la longitud del fichero mediante la instrucción LOF si el fichero ya está
abierto, o con la instrucción FILELEN si no lo está, y dividir el dato obtenido con cualquiera de
las dos instrucciones anteriores por el valor LongitudRegistro.
Una vez abierto el fichero Random podemos leer y escribir datos en él. Para escribir datos
utilizaremos la instrucción Put. La sintaxis de Put es la siguiente:
Puede omitirse NumeroRegistro. En este caso, el número de registro que se escribirá será el
siguiente al último registro escrito.
Type Registro
Titulo As String * 30 Asignamos 30 caracteres para el título
Autor As String * 30 Otros 30 para el autor
Editorial As String * 15 Asignamos 15 caracteres para editorial
Edición As String * 6 Asignamos 6 caracteres para Edición
Precio As String * 4 Asignamos 4 caracteres para el precio
Existencias As String * 3 Tres caracteres para existencias.
End Type
Luego REGLIBROS tendrá 6 campos (Titulo, Autor, Editorial, Edición, Precio y Existencias),
cada uno de una longitud determinada, la definida en la instrucción Type.
Antes de introducir REGLIBROS en el fichero habrá que decir que valor tiene. Pero cada
campo que lo compone tendrá un valor. Podríamos hacer una aplicación en la que, a través
de varios TextBox, le introdujésemos los valores de los campos, y el número de registro en el
cual queremos escribir. El nombre de cada uno de los TextBox para cada uno de los datos es
el siguiente :
Pagina: 169
La aplicación deberá introducir en cada campo el valor (string) existente en cada uno de esos
TextBox. El valor de la variable REGLIBROS lo compondremos de la siguiente forma :
REGLIBROS.Titulo = TBTITULO.Text
REGLIBROS.Autor = TBAUTOR.Text
REGLIBROS.Editorial = TBEDITORIAL.Text
REGLIBROS.Edicion = TBEDICION.Text
REGLIBROS.Precio = TBPRECIO.Text
REGLIBROS.Existencias = TBEXISTENCIAS.Text
De esta forma, REGLIBROS ya tiene un valor que se puede escribir en el fichero mediante la
instrucción Put.
Pagina: 170
El formulario de esa aplicación tendrá esta forma :
Observe que ya se le han introducido otros controles (TextBox para introducir el nombre del
fichero, otro para el número de registro, botones para leer, escribir, abrir el fichero
(EXAMINAR), un par de botones para subir o bajar el número de registro y un botón para salir
de la aplicación. El TextBox para introducir el nombre del fichero se llama
TBNOMBREFICHERO y en el que debemos introducir el número de registro a leer o escribir
TBLEERESCR.
El Botón EXAMINAR cierra cualquier fichero que pudiese estar abierto, abre el fichero indicado
en TBNOMBREFICHERO, calcula el número de registros y escribe este número en el Label
con nombre LNUMFICH. El código de su procedimiento Click es el siguiente :
Veamos como se escribe un registro. Analicemos el código del procedimiento click del botón
ESCRIBIR
Pagina: 171
Para leer los datos de un fichero Random utilizaremos la instrucción Get. Su sintaxis es la
siguiente :
Puede omitirse NumeroRegistro. En este caso, el número de registro que se leerá será el
siguiente al último registro leído.
La Instrucción Get leerá un registro completo. Ese registro contendrá varios campos, y
seguramente nos interesará conocer el valor de cada campo dentro de ese registro. Variable
es una variable que contendrá todos los campos. En nuestra aplicación de biblioteca, Variable
tiene por nombre REGISTROLIBRO (El mismo que tenía para la instrucción Put de escribir. Es
pura comodidad del programador. Puede tener cualquier otro nombre)
Para obtener el contenido de cada campo, realizaremos un proceso similar al empleado para
la escritura, pero al revés. En nuestra aplicación, pretendemos poner el contenido de cada
campo en los mismos TextBox que se utilizaron para escribirlos. Veamos el contenido del
procedimiento click del botón LEER
En los ficheros Random tienen especial importancia las funciones Seek y Loc.
Mediante la Función Loc podemos conocer la el último registro manipulado, bien por lectura,
escritura. Si abrimos el fichero y no se ha hecho ninguna lectura o escritura de registros, el
número devuelto por la función Loc es 0.
Variable tomará un valor igual al número del registro escrito o leído por última vez.
Mediante la Función Seek podemos conocer el próximo registro que será manipulado en una
operación de lectura o escritura. Si abrimos el fichero y no se ha hecho aún ninguna operación
de lectura o escritura, Seek devuelve el valor 1.
ATENCION
¡¡¡ Seek puede ser una función (lee un Dato) o una instrucción (fuerza un dato) ! ! !
Instrucción Seek
Pagina: 172
La instrucción Seek establece el próximo registro a leer o escribir en un fichero Random.
Sintaxis
EOF
Devuelve un valor que indica si se ha llegado al final de un archivo.
Sintaxis EOF(Numerocanal)
En archivos Random, EOF devuelve False hasta que se haya ejecutado una instrucción Get y
no haya podido leer el registro completo, en cuyo caso devolverá True.
La función EOF no suele emplearse en ficheros Random, ya que en estos nos movemos a
base de registros, y es muy fácil controlar cuantos registros existen en el fichero y en que
registro nos encontramos o nos vamos a mover, mediante las funciones LOF, LOC y SEEK
Recuerde Para obtener la longitud de un archivo que no está abierto utilíce la función
FileLen.
Pagina: 173
FICHEROS BINARIOS
Un fichero binario es una sucesión de bytes, uno tras otro, que puede almacenar cualquier tipo
de información. Cuando se explicaban los ficheros secuenciales, decíamos que eran los mas
adecuados para introducir información de un texto, con los Random podíamos realizar una
base de datos de forma sencilla, a base de controlar los registros y sus campos. Con un
fichero binario podemos almacenar cualquier información. (texto y cualquier tipo de datos) .
Como siempre en VB, Numerocanal puede ser un número comprendido entre 1 y 255, que
define ea fichero. No pueden existir al mismo tiempo 2 ficheros abiertos con el mismo Numero
de canal.
Una vez abierto un fichero se binario, podemos leer o escribir datos en él.
Para escribir uno o varios caracteres en un fichero binario, usaremos la instrucción Put.
y en este caso siempre escribirá el número de bytes declarado. ¡ Cuidado ! Si los datos a
introducir sobrepasan el número de bytes declarados para Variable, los datos sobrantes no se
escribirán en el fichero. Si los datos a escribir en el fichero fuesen menos que los declarados
para Variable, la diferencia se rellenará con el byte nulo ( 0 ).
Pero en este caso debemos volver a decir ¡ Cuidado !, si no conocemos el número de bytes
que vamos a escribir, puede que “machaquemos” parte de la información que ya tenemos en
el fichero, pues la instrucción Put va a colocar los bytes que componen Variable en la posición
especificada por Posición y siguientes, hasta que quepa toda la cadena de bytes que le
queremos introducir. Si la posición en la que introducimos esos bytes es una posición
intermedia, y no controlamos bien el número de bytes a introducir y las informaciones que ya
existen en el fichero en las posiciones colindantes con las que vamos a introducir los datos, es
muy probable que perdamos esa información al introducir la nueva.
Pagina: 174
lo separan :
¿Qué pasará si el dato Posición indica una posición mayor que la que tiene realmente el
fichero ? Simplemente que rellenará las posiciones intermedias que se formarán con un byte
(puede verlo con el Block de Notas ÿÿÿ)
Un fichero binario es, como se decía al principio, una sucesión de bytes, que no tiene ningún
tipo de separación entre bytes. Cada dato (byte o conjunto de bytes) que introduzcamos en un
fichero binario se escribirá en el fichero tal y como se introducen. Machacando información ya
existente si no se controla bien donde se mete. Por lo tanto, aunque parece que los ficheros
binarios pueden ser mucho mas versátiles que los secuenciales y los Random, exigen mucho
mas control que los anteriores. Limite el uso de este tipo de ficheros a las aplicaciones en que
sea realmente imprescindible.
Donde Posición es el número del primer byte leído, que como en el caso de Put, si se omite,
tomará como valor el byte siguiente al usado en la última instrucción Get. Variable es el
nombre de una variable que contendrá los datos leídos.
Pueden leerse uno o varios Bytes, pero ahora surge un pequeño problema. ¿Como le decimos
cuantos bytes debe leer ? Sencillamente los especificados al declarar la variable .
Imaginemos que la declaración de la variable fue :
Con Variable declarada de esta forma, leerá 10 bytes a partir del byte Posición. (Incluido)
De esta forma, siempre leeremos un número determinado de caracteres (10 en el caso del
ejemplo). Esta es una limitación para el uso de Get. Esta función viene muy bien en aquellas
aplicaciones en las que tenemos que extraer un número fijo de bytes (En la práctica, en la
mayor parte de las aplicaciones se extrae de uno en uno)
Pero pueden existir aplicaciones en las que sea necesario leer una vez un número de
caracteres, y otra vez otro. Ese problema lo tenemos resuelto con la instrucción Input.
Mediante la instrucción Input podemos leer el número de caracteres que queramos, pero no
podemos controlar el byte de comienzo. Por lo tanto deberemos ayudarnos de la instrucción
Seek para posicionar el puntero de lectura encima del primer byte que queramos leer :
Por ejemplo, si queremos leer 35 bytes de un archivo binario, abierto con el número de canal
1, comenzando por el byte 48 (el 48 será el primer byte leído), ejecutaremos las dos siguientes
instrucciones :
Seek (1), 48
Variable = Input (35, #1)
Pagina: 175
Al igual que se hizo para los ficheros secuenciales y Random, vamos a ver con un ejemplo
práctico como se manejan los ficheros binarios.
Con el botón ABRIR se abre el fichero deseado. Si no existe en el disco, lo crea, ya que la
instrucción
Open Nombrefichero For Binary As # Numerocanal
intenta abrir un fichero existente llamado Nombrefichero, y si este no existe, lo crea. Si existe
el fichero, presenta todo su contenido en el TextBox inferior, para poder tener una referencia
de que lugar ocupan los distintos caracteres (un fichero binario puede guardar cualquier byte,
por lo que si abre un fichero generado con cualquier programa puede ser que muchos de los
bytes no contengan información de un carácter, por lo que le recomendamos haga esta
práctica con un fichero creado por la misma práctica)
El botón CERRAR cierra el fichero. SALIR sale de la aplicación. El TextBox superior (variable)
sirve para introducir la variable a escribir en el fichero, o para presentar la variable leída en
caso de lectura . El TextBox posición sirve para indicar la posición del primer byte. Posición por
defecto presenta la posición que se extrae mediante la función Seek cada vez que se hace
una lectura o escritura en el fichero. Longitud de la variable permite introducir esa longitud,
para leer mediante la instrucción Input.
El botón ESCRIBIR escribe el dato Variable en el fichero, LEER (GET) lee un único byte, y
LEER (INPUT) lee una cadena de caracteres, de longitud la especificada en el TextBox
Longitud de la variable.
Se enumera a continuación el código de cada uno, dejando para las explicaciones del profesor
en clase, o el estudio del alumno, la interpretación de cada una de susu partes.
FORMULARIO. DECLARACIONES
Option Explicit ‘Obliga a declarar todas las variables
Dim LONGVAR As Integer ‘Se declara la variable LONGVAR
Dim COMIENZA As Long ‘Se declara la variable COMIENZA
Dim TESTO As String ‘Se declara la variable TESTO
Dim pospordef As Long ‘Se declara la variable pospordef
Pagina: 176
BOTON ABRIR
Private Sub BABRIR_Click()
CD1.ShowOpen ‘CD1 es un CommonDialog para buscar el fichero
Open CD1.filename For Binary As #1 ‘Abre el fichero indicado en CD1
TESTO = Input(LOF(1), #1) ‘Lee de un golpe el fichero y lo mete en la variable TESTO
TBFICHERO.Text = TESTO ‘Presenta el fichero en el TextBox TBFICHERO
End Sub
BOTON CERRAR
Private Sub BCERRAR_Click()
Close ‘La instrucción Close cierra todos los ficheros abiertos
End Sub
BOTON ESCRIBIR
Private Sub BESCRIBIR_Click()
TBVAR2.BackColor = RGB(255, 0, 0) ‘Pone el TB long. De la variable en rojo
Dim escribe As String ‘Declara la variable escribe como string, sin limitación
escribe = TBVAR1.Text ‘Pasa el contenido de TBVAR a la variable escribe
Put #1, Val(TBVAR3), escribe ‘Instrucción Put. Val(TBVAR3) es la posición del 1er
byte
pospordef = Seek(1) ‘Analiza donde quedó el puntero del fichero
Lvar5 = Str(pospordef) ‘y pone este valor en la etiqueta Lvar5
End Sub
Pagina: 177
pospordef = Seek(1) ‘analiza la nueva posición por defecto
Lvar5 = Str(pospordef) ‘y la presenta en Lvar5
End Sub ‘
BOTON SALIR
Private Sub BSALIR_Click()
End ‘Sale de la aplicación.
End Sub
DIR
Devuelve el nombre de un archivo, directorio o carpeta que concuerda con el patrón o atributo
de archivo especificado o la etiqueta de volumen de una unidad de disco.
vbNormal 0 Normal.
vbHidden 2 Oculto.
vbSystem 4 Sistema
vbVolume 8 Etiqueta de volumen; si se especifica se ignoran todos los atributos
vbDirectory 16 Directorio o carpeta.
En Microsoft Windows, Dir permite el empleo de los caracteres comodín '*' (múltiples
caracteres) y '?' (un solo carácter) para especificar varios archivos.
La primera vez que se llama a la función Dir se debe especificar el nombreruta, de lo contrario
se produce un error. Si además se especifican atributos de archivo, se debe incluir el
nombreruta.
Dir devuelve el primer nombre de archivo que coincide con el nombreruta. Para obtener más
nombres de archivo que coincidan con el nombreruta, se debe volver a llamar a Dir sin
argumentos.
Cuando no hay más nombres de archivo coincidentes, Dir devuelve una cadena de caracteres
de longitud cero. Cuando se devuelve una cadena de longitud cero, en las siguientes llamadas
se debe especificar nombreruta o se producirá un error. Se puede cambiar el nombreruta sin
haber obtenido todos los nombres de archivo que coinciden con el nombreruta actual. Sin
embargo, no se puede llamar a la función Dir.
FILECOPY
Copia un archivo.
Pagina: 178
Sintaxis FileCopy fuente, destino
fuente Expresión de cadena que especifica el nombre de un archivo a copiarse puede incluir
el directorio o carpeta y la unidad de disco..
destino Expresión de cadena que especifica el nombre del archivo de destino se puede incluir
el directorio o carpeta y la unidad de disco.
FILEDATATIME
Devuelve una fecha que indica la fecha y hora en que un archivo fue creado o modificado por
última vez.
El argumento con nombre nombreRuta es una expresión de cadena que especifica un nombre
de archivo. Se puede incluir el directorio o carpeta y la unidad de disco.
FILELEN
Si el archivo especificado está abierto cuando se llama la función FileLen, el valor devuelto
representa el último tamaño de ese archivo cuando se guardó la ultima vez en el disco.
Para obtener la longitud de un archivo abierto, utilice la función LOF.
GETATTR
Devuelve un número, que representa los atributos de un archivo, directorio o carpeta o una
etiqueta de volumen.
El argumento con nombre nombreRuta es una expresión de cadena que especifica un nombre
de archivo se puede incluir el directorio o carpeta y la unidad de disco.
Valores devueltos
0 vbNormal Normal.
1 vbReadOnly Sólo lectura.
2 vbHidden Oculto.
4 vbSystem Archivo de sistema.
16 vbDirectory Directorio o carpeta.
32 vbArchive El archivo ha sido modificado después de efectuar la última copia de
seguridad.
SETATTR
Pagina: 179
Establece los atributos de un archivo.
Las constantes y valores de atributos son los mismos que para la instrucción GetAttr
FREEFILE
Devuelve el siguiente número de archivo disponible para ser usado con la instrucción Open.
Sintaxis FreeFile[(númerodeintervalo)]
Pagina: 180
Visual Basic - Guía del Estudiante Cap. 9
EL DRAG & DROP (Arrastrar y Soltar)
LA FUNCION SHELL
LA FUNCION COMMAND PARA PASAR PARAMETROS
El Drag & Drop es una forma visual de representar el movimiento de algo. Para ello se toma
algo de una parte de la interface gráfica, mediante la operación de colocar el puntero del ratón
y pulsar su botón izquierdo sobre ese algo que se quiere tomar. Sin dejar de pulsar el botón
izquierdo del ratón se desliza (se arrastra) el puntero del ratón hasta el punto de la interface
gráfica donde lo queremos dejar. Ese punto puede ser un control o un formulario. Una vez en
el punto de destino se suelta el botón del ratón y se “deja caer” lo que habíamos tomado en el
punto de origen. El efecto de “tomar” algo de un control le denominaremos DragOver, y el
efecto de dejar caer le denominaremos DragDrop.
El Drag & Drop tiene un efecto visual muy didáctico. Pero NO HACE otra cosa. Es decir, no
toma nada del control origen ni lo suelta al llegar a destino. Esa acción de tomar algo en el
origen o soltarlo al llegar al destino debemos realizarla mediante código en los eventos
adecuados (MouseDown, DragOver , DragDrop), dando los valores adecuados a las
propiedades DragMode y DragIcon, y utilizando el método Drag.
PROPIEDAD DragMode
Donde número puede tomar los valores 0 (Manual) ó 1 (Automático). El valor predeterminado
es el 0.
Cuando esta propiedad está a 0 (Manual) se debe emplear el Método Drag para iniciar una
operación Drag & Drop. Si está a 1, la operación de arrastrar y soltar se inicia
automáticamente cada vez que hacemos click sobre el botón izquierdo del ratón, teniendo el
puntero del mismo sobre el control. Los controles contenedores OLE sólo se arrastran
automáticamente cuando no tienen el enfoque.
Parece en principio mas práctico tener esta propiedad a 1. Sin embargo la realidad es distinta.
Se controla mucho mejor el Drag & Drop poniendo esta propiedad a 0 (Manual), pese a que en
este caso deberemos utilizar el método Drag para iniciar el proceso.
El poner esta propiedad en automático conlleva también el hecho de que el control no toma el
foco haciendo click sobre él, ya que no sabe si lo que quiere hacer es llevarle el foco o iniciar
una operación de Drag & Drop.
PROPIEDAD DragIcon
Devuelve o establece el icono que se presenta como puntero del ratón durante una operación
de arrastrar y soltar.
Esta propiedad va a marcar el icono que aparezca durante la operación Drag & Drop
desplazándose a lo largo de la ventana. Si no se especifica esta propiedad, el desplazamiento
Pagina: 181
se expresa mediante un rectángulo del tamaño del control origen, cosa que resulta bastante
desagradable en cualquier aplicación. Debe ponerse por lo tanto un icono en esta propiedad.
Para Nota. Cuando quiera colocar un icono animado en la propiedad DragIcon (una hoja de
papel que oscila al moverse, una hoja de papel que se destruye - ejemplos tomados de W95-),
debe usar varios iconos en secuencia. Por lo tanto debe cambiar la propiedad DragIcon a lo
largo del tiempo que dura el arrastre. Puede utilizar para ello un temporizador (control Timer) o
basarse en las coordenadas del formulario por donde se mueve (para eso introducen en el
evento DragOver del Formulario). Dado que el cambio debe ser rápido, no es conveniente
acceder al disco (mediante la función LoadPicture) cada vez que tiene que cambiar la imagen
del icono. Como para simular un movimiento tan sencillo son suficientes pocas imágenes, (8
por ejemplo) puede crear otras tantas variables tipo Picture, cargar las imágenes al comienzo
de la aplicación (con la función LoadPicture) y cuando necesite el movimiento animado del
icono, cargar las 8 imágenes secuencialmente desde esas variables, para simular el
movimiento
NCO.DragIcon = Variable1
NCO.DragIcon = Variable2
......
NCO.DragIcon = Variable8
Esto le ocupará mas memoria. Es el precio a pagar por la rapidez y la buena presentación de
una aplicación.
METODO Drag
Inicia, termina o cancela una operación de arrastre de cualquier objeto excepto los controles
Line, Menu, Shape o Timer.
NombreControlOrigen es el nombre del control donde se inició la operación Drag & Drop.
TipoAcción es un valor o una constante que especifica la acción a realizar, según se describe a
continuación :
El uso del método Drag para controlar una operación de arrastrar y soltar sólo se requiere
cuando la propiedad DragMode del control origen tiene el valor Manual (0). Sin embargo, Drag
puede usarse con objetos cuya propiedad DragMode tenga el valor 1 (o vbAutomatic).
En versiones anteriores de Visual Basic, Drag era un método asíncrono y las instrucciones
siguientes se ejecutaban incluso aunque la acción de arrastre no hubiera terminado. En Visual
Pagina: 182
Basic versión 4.0, Drag es un método síncrono y las instrucciones siguientes no se ejecutan
hasta que la acción de arrastre no haya terminado.
Usando el método Drag puede controlar exactamente cuando quiere que se produzca el inicio
del Drag & Drop y el final. El autor de esta Guía del Estudiante vuelve a recomendar que
ponga la propiedad DragMode = 0 (Manual). Entre otras razones por la siguiente :
Como decíamos al principio, el Drag & Drop solamente es una manifestación visual de algo
que se está produciendo, pero ese algo deberemos programarlo. Por ejemplo, es muy típico
llevar un dato de una casilla a otra (de un TextBox a otro p.e.) mediante una operación D & D.
El dato debemos llevarlo a una variable que nos permita, al final de la operación, introducir
ese dato en el TextBox final. (No olvide declarar la variable en el lugar correspondiente para
que sea válida en ambos controles). La acción de llevar el dato a la variable debemos hacerla
en el procedimiento mas adecuado. Puede ser por ejemplo, el procedimiento MouseDown del
control origen, ya que cualquier operación de D & D comienza haciendo click en el control
origen. Si tiene la propiedad DragMode de ese control en Manual, en el momento de hacer
Click, ese control toma el foco y, caso de un TextBox, puede arrastrar con el ratón para
cambiar el texto, cosa que no podría hacer si pone DragMode=1.
EVENTO DragOver
Cuando una operación de arrastrar y soltar está en progreso y el cursor del ratón pasa por
encima de un control o un formulario, se produce el evento DragOver de ese control o
formulario.
Donde :
origen = Control que se está arrastrando. O dicho de forma mas ortodoxa, control en el que se
inició la operación de Drag & Drop. Dentro de este procedimiento puede hacer referencia a sus
propiedades y métodos con este argumento. Por ejemplo, Source.Visible = False. Caso de
que el Control Origen fuese parte de un array de controles, el Index de ese control se tiene en
índice
x, y Número que especifica la posición horizontal (x) y vertical (y) actual del puntero del
mouse dentro del control o formulario destino. Estas coordenadas se expresan siempre en
términos del sistema de coordenadas del destino tal y como se establece en las propiedades
ScaleHeight, ScaleWidth, ScaleLeft y ScaleTop.
estado Entero que nos indica el estado de transición del control que se está arrastrando en
relación al formulario o control destino:
0 = Entra. Este valor se produce en el instante en el que entra el cursor del ratón a
este control o Formulario. Se genera también en el control origen en el instante que se
pulsa el botón del ratón, iniciándose de esta forma el D & D.
1 = Deja Este valor se produce cuando el cursor sale del control o Formulario.
Pagina: 183
2 = Sobre Este valor se produce cuando el cursor se está moviendo sobre el control o
el Formulario destino.
En el siguiente ejemplo, se declaran 6 variables tipo Picture que van a almacenar seis iconos
distintos :
En General - Declaraciones
Dim pepe as string
Dim icono1 As Picture, Icono2 As Picture, Icono3 As Picture
Dim Icono4 As Picture, Icono5 As Picture, Icono6 As Picture
El Form1.Load se cargan los valores de estas variables con seis iconos existentes en el disco.
El icono asignado al control origen (Text1) es Icono4.
Set icono1 = LoadPicture("C:\vb\icons\dragdrop\drag1pg.ico")
Set Icono2 = LoadPicture("C:\vb\icons\dragdrop\drag2pg.ico")
Set Icono3 = LoadPicture("C:\vb\icons\dragdrop\drag3pg.ico")
Set Icono4 = LoadPicture("C:\vb\icons\dragdrop\drop1pg.ico")
Set Icono5 = LoadPicture("C:\vb\icons\dragdrop\dragfldr.ico")
Set Icono6 = LoadPicture("C:\vb\icons\dragdrop\dropfldr.ico")
Text1.DragIcon = Icono4
EVENTO DragDrop
Ocurre cuando se completa una operación de arrastrar y soltar como resultado de arrastrar un
control sobre un formulario o control y liberar el botón del mouse o utilizar el método Drag con
su argumento acción establecido a 2 (Drop).
Pagina: 184
Estos parámetros son idénticos a los del Procedimiento DragOver ya comentados
Utilice un procedimiento de evento DragDrop para controlar qué ocurre tras completarse una
operación de arrastrar. Por ejemplo, puede mover el contenido del control origen a un nuevo
lugar o copiar un archivo de un lugar a otro, depositar un valor sobre un control etc.
Recuerde que la operación Drag & Drop no hace otra cosa que lo que se puede ver en la
interface gráfica. Debe poner en este Procedimiento (DragDrop) el código necesario para que
se realice la operación deseada.
LA FUNCION SHELL
La función Shell se utiliza para ejecutar un programa ajeno a la aplicación que se está
ejecutando. Imaginemos que tenemos una aplicación Visual Basic que necesita, por ejemplo,
establecer una comunicación telefónica, y que esa comunicación telefónica nos la realiza un
programa desarrollado en C++ , llamado MARCADOR.EXE que funciona perfectamente y no
queremos desaprovechar. Imaginemos que ese programa tiene la posibilidad de introducirle el
número telefónico que debe marcar como un parámetro. Este parámetro se le introduce,
supongamos, añadiendo el número al nombre del programa ejecutable. Por ejemplo:
MARCADOR.EXE 1234567
En nuestra aplicación Visual Basic introduciremos una línea invocando la función Shell seguida
del nombre (y Path) del ejecutable y del parámetro que le vamos a introducir al ejecutable:
donde:
rutaDeAcceso es el nombre del programa por Ejecutar (con su Path) y cualquier argumentos
o conmutadores (switches) de línea de comando requeridos; puede incluir directorio o carpeta
y unidad de disco. También puede ser el nombre de un documento que se ha asociado con un
programa ejecutable.
Pagina: 185
original.
vbMinimizedFocus 2 La ventana se muestra como un icono con foco.
vbMaximizedFocus 3 La ventana se maximiza con foco.
vbNormalNoFocus 4 La ventana vuelve al tamaño y posición más recientes. La
ventana activa actual permanece activa.
vbMinimizedNoFocus 6 La ventana se muestra como un icono. La ventana activa
actual permanece activa.
Comentarios
Si la función Shell ejecuta con éxito el archivo nombrado, devuelve la identificación de la tarea
(ID) del programa iniciado. La ID de la tarea es un número exclusivo que identifica el programa
en ejecución. Este número debe ser un Long. Si la función Shell no puede iniciar el programa
nombrado, ocurrirá un error. Si desea conocer el ID de la tarea, realice una aplicación con un
botón (cmbCalculadora) y un label (label1). Ponga en ese botón en su procedimiento click, el
siguiente código. - Observe que esta aplicación inicia la calculadora de Windows -
Posiblemente lo único que le importe sea el ejecutar esa aplicación, sin dar mayor importancia
al ID de la tarea. Utilice una línea con la siguiente expresión :
Shell ("C:\windows\calc.exe"), 1
(Observe en las dos formas de ejecutar la función Shell, que la colocación de los paréntesis y
la coma separadora es distinto.
Nota La función Shell ejecuta otros programas de manera asíncrona. Esto quiere decir que
no se puede esperar que un programa iniciado con Shell termine su ejecución antes de que se
ejecuten las instrucciones que siguen a la función Shell en la aplicación. Esto es un gran
inconveniente de la función Shell. Excepto en contadas ocasiones, siempre es necesario
conocer cuando se ha terminado de ejecutar el programa iniciado mediante Shell. Y no es ese
el único problema. La mayoría de los programas DOS que se ejecutan con Shell no se cierran
automáticamente. Esto significa que si podemos evitar el uso de Shell debe evitarse. Pero si
es completamente necesario, tampoco pasa nada. Pero hay que controlar, tanto la terminación
del proceso DOS como su cierre.
Podemos usar para ello APIs. No las hemos explicado todavía. Por eso, y adelantar un poco
como se trabaja con ellas, vamos a presentar, sin grandes explicaciones, lo que hay que hacer
para poder detectar que se ha terminado de ejecutar el programa DOS y para cerrarlo. Verá
mas APIs mas adelante.
El programa DOS elegido para este ejemplo es el popular ARJ.EXE, un compresor de datos
que, sin ánimo de publicidad, es uno de los mejores que existen. Pero trabaja solamente en
DOS. Se utiliza un Procedimiento que he llamado ExecCmdNoFocus, para detectar que el
proceso abierto para comprimir o descomprimir ha finalizado, y proceder a cerrarlo.
Pagina: 186
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal _
bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode _
As Long) As Long
Dim hProcess As Long 'handle del proceso donde se invoca la función Shell
Dim RetVal As Long 'Valor donde la función GetExitCode coloca el resultado
Dim winHwnd As Long ' manipulador de la ventana que contenga el Caption
‘Finalizado - ARJ
Dim RetValls As Long 'valor de retorno de PostMessage
Do
GetExitCodeProcess hProcess, RetVal
Sleep 100
'en este apartado comprueba si está abierta la ventana "Finalizado - ARJ"
winHwnd = FindWindow(vbNullString, "Finalizado - ARJ")
If winHwnd <> 0 Then
RetValls = PostMessage(winHwnd, WM_CLOSE, 0&, 0&)
End If
Loop While RetVal = STILL_ACTIVE
End Sub
La ventana DOS del ARJ tiene el Caption Finalizado - ARJ cuando ya ha terminado el
proceso. En el procedimiento ExecCmdNoFocus se analiza si esa ventana está presente
(prueba de que ARJ ya ha terminado, pues antes de terminar tiene otro Caption).
Para llamar a ese procedimiento hay que citarle por su nombre ( ExecCmdNoFocus) que
como lo hemos declarado Public en un Módulo, podemos llamarle desde cualquier parte de la
aplicación. Debemos pasarle el parámetro CmdLine, que será el programa que vamos a
ejecutar con Shell y los parámetros adicionales que este programa necesite (En este caso, el
programa es ARJ.EXE y a continuación debe indicársele el nombre del archivo ya
comprimido, a continuación a para que añada mas ficheros a ese archivo, y a continuación el
nombre de ese fichero o ficheros a añadir :
Pagina: 187
NO se preocupe si no lo entiende ahora. Es difícil.
LA FUNCION COMMAND
Command (Función)
Devuelve parte del argumento de la línea de comandos utilizada para lanzar Microsoft Visual
Basic o un programa ejecutable desarrollado con Visual Basic.
Cuando se inicia Visual Basic desde la línea de comandos, la parte de la línea de comandos
que sigue a /CMD se pasa al programa como un argumento de la línea de comandos. En el
siguiente ejemplo, cmdlineargs representa la información de argumento devuelta por la función
Command.
VB /CMD cmdlineargs
MyApp cmdlineargs
En la ventana Código, puede usted cambiar el texto devuelto por Command eligiendo
Opciones del proyecto en el menú Herramientas.
Veamos con un par de ejemplos como se pueden usar estas dos funciones:
Marcador Telefónico
Esta aplicación debe marcar un número telefónico. El número a marcar se le pasará como
parámetro tras el nombre de la aplicación. La aplicación ya compilada se llamará
MARCADOR.EXE. Para marcar un número debemos poner, en la línea de Comando de
Windows:
Marcador.exe 1234567
o como ya sabemos, introducirle el parámetro mediante una llamada con la función Shell
desde otra aplicación:
Como no vamos a realizar llamada alguna, sino comprobar que esto puede funcionar, nuestra
pequeña aplicación tendrá solamente un Label llamado FRMARCADORL1 donde
presentaremos el número a marcar. Todo el código necesario se lo metemos en el
procedimiento Activate del formulario:
Pagina: 188
También podemos pasar parámetros a un ejecutable, mediante el Drag & Drop de Windows.
Hemos visto mas atrás como podemos hacer Drag & Drop en una aplicación VB. Pero como
comentábamos, el D&D no es una función de VB, sino de Windows. Y Windows lo utiliza en su
Explorador de Windows para pasar como parámetro a una aplicación el nombre del fichero
que arrastremos hacia el icono que representa a esa aplicación. Como estoy seguro que se ha
liado, vamos con un ejemplo.
Si Vd. hace un editor de textos (Editor.EXE) que soporta un formato determinado (por ejemplo
el RichTextFormat RTF), para ejecutar su programa y meterle como parámetro el nombre del
fichero Carta.RTF de forma que al arrancar lea directamente el fichero Carta.RTF, basta con ir
al Explorador de Windows, abrir la carpeta que contenga Carta.RTF, arrastrar el nombre de
ese fichero y llevarlo al icono que representa a Editor.EXE, que imaginemos que le ha
preparado un acceso directo. Suelte el botón del ratón y su editor se ejecutará, y además, le
meterá como parámetro el nombre del fichero Carta.RTF (con su Path correspondiente) Si Ud.
había previsto la captura del Command tal como se explicó mas atrás, y ha preparado su
aplicación para que tome el contenido de Command y entienda que tiene que abrir y cargar
ese fichero, su aplicación Editor.EXE cargará automáticamente ese fichero. Observe que esta
es la forma de trabajar de los procesadores de texto usados normalmente (Word, WordPerfect,
Write, etc.)
Lo que se va a explicar en este capítulo le será bastante familiar aunque nunca haya reparado
en ello. Posiblemente haya utilizado un procesador de texto en el que está escribiendo una
carta, y antes de terminar de escribir esa carta, comienza a escribir otro documento, y
posiblemente otro, y tenga los tres documentos en la pantalla al mismo tiempo, bien en
ventanas escalonadas, (cascada), bien en ventanas en forma de mosaico, o simplemente
tapando unas a otras completamente. Los tres documentos están en su procesador de textos,
y puede actuar sobre uno u otro simplemente eligiendo el deseado mediante el mecanismo
Pagina: 189
que le proporciona su procesador de textos. Este sistema no es ni mas ni menos que una
interface de documentos múltiples. En programación, a este tipo de aplicaciones las
denominamos MDI
Para crear una aplicación MDI debe hacerse mediante un Formulario Padre al que se le
añaden tantos Formularios Hijo como documentos tengamos. Al formulario padre le
denominamos Formulario MDI, y a los formularios hijo en Visual Basic se les denomina
formularios MDIChild. En esta Guía del Estudiante se usarán indistintamente una u otra
denominación.
La única diferencia entre un formulario normal y un formulario Hijo es que éste tiene la
propiedad MDIChild a true.
Para realizar una aplicación MDI, lo primero que hay que hacer es introducir en ella un
formulario MDI. Para introducirlo, basta con hacer click en Insertar | Formulario MDI de la
barra de menú. Solamente se puede tener un formulario MDI en una aplicación. Puede
observar que una vez que ha introducido uno, la palabra Formulario MDI del submenú Insertar
queda deshabilitada.
Una vez que tiene un formulario MDI puede introducir tantos formularios hijo como desee.
Para que un formulario sea formulario hijo basta con poner a True su propiedad MDIChild.
Aparte de las propiedades de un formulario normal, un formulario MDI tiene las siguiente
propiedades :
Load NombreFormularioHijo
ActiveForm Mediante esta propiedad podemos conocer el formulario activo dentro de una
aplicación de documentos múltiples. (El formulario activo es aquel que tiene el foco)
MiVariable = ActiveForm.caption
ScrollBars Hace que el Formulario MDI (padre) muestre barras de Scroll para presentar
en toda su extensión a un formulario hijo, cuando las dimensiones de áste superan las de
aquel.
Aparte de estas propiedades que diferencian un Formulario MDI de un Formulario normal, los
Formularios MDI presentan otras particularidades.
Pagina: 190
El control Picture puede trabajar como contenedor de otros controles. Por lo tanto, para poder
introducir cualquier control (TextBox, Label, CommandButton ...) será necesario introducir un
control Picture, y sobre el, poner los controles que se necesiten.
Barra de Título. La Barra de Título del Formulario MDI se conserva siempre. Pero si el
Formulario Hijo insertado dentro de él está maximizado (ocupa toda la extensión del
Formulario MDI), a la barra de título se le añadirá la barra de Título del Formulario Hijo entre
paréntesis.
Para hacer que un Formulario sea un formulario hijo basta con ponerle su propiedad MDIChild
a True.
Puede preparar los formularios hijo uno a uno e introducirlos dentro del formulario MDI según
las necesidades de la aplicación. Este sería el caso de una aplicación con varias pantallas,
todas ellas colocadas sobre una pantalla fija (Formulario MDI) del que se aprovecha quizás
alguna parte como parte común de toda la aplicación (Menú, Título, Barra de herramientas
montada sobre un Picture, etc.)
Puede también darse el caso de introducir un número indeterminado de ventanas iguales para
realizar varias veces la misma función, pero sobre ventanas diferentes. (Caso del procesador
de texto que tiene varias ventanas de texto, cada una con un documento. Lo que
desconocemos a priori es el número de documentos que vamos a editar)
Para el primer caso, será necesario crear cada una de las ventanas, e introducirlas y quitarlas
según pida la aplicación.
En segundo caso, bastará con crear un formulario hijo con todas las partes necesarias para su
correcto funcionamiento, y luego, realizar tantas “fotocopias” de ese formulario como ventanas
necesitemos. Lo que introducimos en la aplicación son precisamente esas “fotocopias”, pero
no el original, que lo seguimos manteniendo intacto para volver a copiarlo si fuese necesario.
En realidad una Clase es la definición de un objeto Visual Basic. Un objeto Visual Basic puede
ser un Formulario, un control, un objeto de acceso a datos.
Después de toda esta teoría, ¿podemos saber como se crea una Clase de un formulario ? O
dicho de manera mas coloquial, ¿Cómo se crea un Formulario para poder hacer varias
“fotocopias” de él ?
La respuesta es obligatoriamente mas sencilla que la teoría. Con el formulario vacío que
tengamos en el proyecto (Insertemos un Formulario si fuese necesario) pongámosle todos los
controles que deseemos. Le podemos poner un Menú y cambiar a nuestro antojo todas sus
propiedades. Entre ellas, la propiedad MDIChild. Si vamos a introducir las Instancias de ese
Formulario en un Formulario MDI esa propiedad debe estar a True, y por lo tanto sus
Instancias saldrán igualmente con esa propiedad a True. Pongámosle un nombre y ya está
creada la clase. Supongamos que ese nombre es FormularioHijo
Para crear ahora Instancias de ese Formulario podemos hacerlo de dos formas :
Pagina: 191
Declarar una variable tipo Objeto. No se asuste. Para declarar que una variable es un
Formulario basta con declararla de la siguiente forma :
Esta variable debe declararla en sitio adecuado para su aplicación, y el ámbito de esa variable
objeto será el mismo que para cualquier tipo de variable. (Vea Ambito de las Variables) La
sentencia a utilizar para la declaración será Dim, Private, Public o Global tal como se explicó
para las variables.
Una vez declarada como variable puede hacerla igual a un objeto existente que servirá de
modelo (Una Clase) que estará definida por un nombre: (P.e. FormularioHijo)
Una vez creado la instancia del formulario debemos cargarlo en el Formulario Padre. Para
cargarlo debemos emplear la sentencia Load MiVentana, con lo que quedará cargado en la
memoria, pero, dependiendo de como está la propiedad AutoShowChildren del Formulario
Padre se mostrará o no se mostrará. Para que se muestre, independientemente de como esté
esa propiedad, basta con ejecutar MiVentana.Show. En realidad mediante el método Show
un formulario no solamente se muestra, sino que también se carga en la memoria si no
estuviese previamente cargado. Por lo tanto podíamos habernos ahorrado la instrucción
anterior para cargarlo Load MiVentana
Es muy práctico poner un Caption distinto a cada formulario que se introduzca, caso de
introducirse varios formularios hijo iguales. El Caption es una propiedad y por lo tanto todas las
instancias heredan el Caption de la Clase. Sería prudente distinguir un formulario de otro
mediante su Caption, es decir mediante su barra de título.
Para ello podemos crear un contador en el mismo procedimiento en el que creamos una nueva
instancia, y poner el Caption de cada nuevo Formulario siguiendo un orden numeral.
Pagina: 192
Referencias a los Formularios. ActiveForm y Me
Si queremos nombrar un Formulario Hijo dentro de una aplicación MDI el primer problema con
el que nos encontramos es que todos los formularios hijo (Instancias de la misma Clase) tienen
el mismo nombre. Por lo tanto no podemos nombrarlas con ese nombre, ya que la aplicación
no sabría a cual de ellas nos referimos.
Si el código donde vamos a nombrar ese formulario está fuera de él (P.e. en el Formulario
Padre) deberemos referirnos al formulario hijo mediante ActiveForm. ActiveForm nos va a
indicar cual es el formulario que está actualmente activo. Un formulario está activo cuando
estamos trabajando sobre él. En ese momento tiene el foco. Permanece activo desde que
hacemos click con el ratón sobre cualquiera de sus partes, hasta que activamos otro
formulario. Es sencillo reconocer cual es el formulario activo pues tiene su barra de título con
el color vivo.
Cada vez que hacemos una operación sobre una parte de un formulario éste se pondrá activo.
Por ejemplo, si el formulario es un documento de texto, y contiene el texto en un RichTextBox
de nombre RTB1, si queremos hacer una operación con el texto desde un botón colocado en el
formulario padre (poner en negrita el texto seleccionado), haríamos lo siguiente :
ActiveForm.RTB1.SelBold = True
ya que siempre estaremos seguro de que el Formulario Activo es aquel en el que acabamos de
seleccionar el texto.
Si el botón donde hemos puesto el botón no es el formulario padre, sino el hijo, tenemos un
problema similar. Su nombre será (con los ejemplos anteriores) MiVentana, y pueden existir
varios formularios con ese nombre, tantos como documentos hayamos introducido. No
podemos por tanto nombrarlo con su nombre, pues hay (o puede haber) varios. Tampoco lo
podemos nombrar con ActiveForm, ya que esta propiedad corresponde al Formulario Padre.
La solución es nombrarle mediante Me. Me siempre se refiere al formulario que contiene al
procedimiento donde está esa palabra. Por lo tanto, si tenemos un botón en el formulario hijo
con la instrucción :
Me.RTB1.SelBold = True
Mediante el método Arrange podemos distribuir los formularios hijo dentro del formulario
padre. Pueden colocarse en cascada, mosaico horizontal, mosaico vertical o como iconos.
donde
Pagina: 193
Las ventanas o los iconos se pueden distribuir incluso si el objeto MDIForm está minimizado.
Los resultados son visibles cuando el objeto MDIForm se maximiza.
Cuando tenemos varios formularios hijo, unos ocultan a los otros. Mucho mas si los
formularios están maximizados. Podemos colocar un formulario hijo en la parte frontal del
montón de formularios (para que se vea completamente) o llevarle a la posición mas atrás
mediante el Método ZOrder.
ZOrder es un método que no solamente se puede emplear con formulario hijo, sino con
cualquier instancia. Puede emplearlo también con cualquier control. Pero lea detenidamente la
Ayuda de este método, ya que no todos los controles la admiten.
Al explicar el Editor de menús casi se pasó por alto una propiedad del menú : WindowList.
Cuando se activa esta propiedad (Puede activarse para una sola palabra del menú. Si se
pretende activar para mas de una dará un error), esa palabra que tiene activada la propiedad
WindowList mostrará al hacer click sobre ella, en un menú desplegable, el Caption (Barra de
Título) de todos los formularios hijo cargados en ese instante en la aplicación. Pueden estar
incluso minimizados.
El Objeto Printer
Pagina: 194
El objeto Printer le permite comunicarse con una impresora del sistema (inicialmente la
impresora predeterminada). Este es uno de los Objetos de VB que no tiene representación
gráfica en la pantalla, tanto en tiempo de diseño como de ejecución.
El objeto Printer gestiona el envío de información a la impresora, tanto para imprimir textos
como gráficos. Para Visual Basic el objeto Printer es como otro objeto cualquiera. Si
queremos imprimir algo en la impresora, debemos escribir el código VB necesario para
escribirlo en el objeto Printer, lo mismo que si estuviésemos escribiendo en un formulario.
Form1.Print "ABCD"
Printer.Print “ABCD”
Para enviar gráficos al objeto Printer se procede de igual forma que si estuviésemos
dibujando en un formulario
Form1.Circle (200, 150), 50, , , , 0.5 Esta instrucción dibuja una elipse centrada en
el punto x=200, y=150 del formulario Form1
Printer.Circle (200, 150), 50, , , , 0.5 Esta instrucción dibuja una elipse centrada en
el punto x=200, y=150 del objeto Printer
Parece en principio algo raro hablar de las coordenadas x e y del objeto Printer. Posiblemente
porque el objeto Printer es un objeto que no podemos “ver”. Pero imaginemos que el objeto
Printer es una hoja de papel. La misma hoja que aparecerá escrita una vez que le enviemos el
texto (o los gráficos) que queremos imprimir. Esa hoja de papel tendrá unas dimensiones que
deberemos indicar al objeto Print. La forma de indicarle las dimensiones del papel varían
dependiendo del driver de impresora usado.
El driver de la impresora sabrá que el papel que tiene es un DIN A4, DIN A3, etc., que tiene
unas medidas prefijadas. Centrémonos en lo mas habitual, una impresora que tenga un papel
DIN A4 cuyas medidas son 210 x 297 mm.
El driver de impresora “sabe” que ese es el tamaño de su papel. Ahora solamente nos falta
que nuestra aplicación lo sepa también. Para ello vamos a indicarle mediante un par de
sentencias las medidas de ese papel : ScaleWidth y ScaleHeight
Si le decimos :
le estamos diciendo a nuestro programa que el papel mide 2100 unidades de ancho y 2970
unidades de alto. (Estamos suponiendo que el papel está colocado en posición vertical). Si
tiene 2100 unidades de ancho, y el ancho real del papel es de 210 mm, nuestra unidad de
medida será de 0,1 mm. Es decir, le decimos a nuestro programa que el papel tiene 2100
décimas de milímetro de ancho, y 2970 décimas de milímetro de alto. La precisión con la que
podemos colocar un punto sobre el papel será por tanto 0,1 mm. Podríamos hacerla mayor
(0,01 mm.) si pusiésemos Printer.ScaleWidth = 21000 y Printer.ScaleHeight = 29700.
Para el trabajo ordinario de imprimir listados o dibujar gráficos tipo barras, es mas que
suficiente una precisión de 0,1 mm. Si lo que queremos es un dibujo mas exacto (Dibujar
fotolitos de circuitos impresos, p.e. ) esta precisión de 0,1 mm. no nos bastaría, debiendo llegar
a una precisión del orden de 0,01 mm. Pero todo ello está condicionado por el número de p.p.i.
Pagina: 195
(puntos por pulgada) que nuestra impresora es capaz de dar.
Nota.- Una impresora tiene unos márgenes sobre los que no puede escribir. Por lo tanto,
cuando decíamos que el papel tiene 210 mm. de ancho, en realidad ya estamos cometiendo un
pequeño error, ya que la impresora no puede escribir en todo el ancho, pues los 2 - 3 mm de
cada lado no lo imprime. Deberemos entonces poner las propiedades ScaleWidth y
ScaleHeight del Printer de acuerdo con la superficie real de escritura de nuestra impresora. Le
adelanto que no le va a ser fácil enterarse de qué márgenes deja sin imprimir. Le recomiendo
que imprima una línea desde Printer.CurrentX=0 a Printer.CurrentX= (un número superior a
Printer.Scalewidth). Mida con un escalímetro el ancho real de la impresión.
El objeto Printer almacenará toda la información sin pasarla a la impresora hasta que se le
envíe la instrucción Printer.EndDoc o se le envíe un salto de página mediante la instrucción
Printer.NewPage.
El objeto Printer, al igual que otros objetos de Visual Basic tiene sus propiedades y métodos.
Nota El efecto de las propiedades del objeto Printer depende del controlador suministrado por
el fabricante de la impresora. Algunos valores de la propiedad pueden no tener efecto, o varios
valores distintos de la propiedad pueden tener todos el mismo efecto. Los valores fuera del
rango aceptado pueden producir error. Para obtener más información, vea la documentación
del fabricante del controlador concreto.
ColorMode
Devuelve o establece un valor que determina si una impresora de color imprime en color o en
blanco y negro. No disponible en tiempo de diseño.
Copies
Devuelve o establece un valor que determina el número de copias que se van a imprimir.
Donde número debe ser una expresión numérica que especifique el número de copias que se
van a imprimir. Este valor debe ser un entero. El valor por defecto es 1.
CurrentX CurrentY
Sintaxis
Para forzar las coordenadas del cursor de escritura del objeto Printer :
Pagina: 196
Printer.CurrentX [= x] Printer.CurrentY [=y]
Para conocer las coordenadas del cursor de escritura del objeto Printer
Comentarios
Las coordenadas se miden a partir de la esquina superior izquierda del objeto. El valor de la
propiedad CurrentX es 0 en el borde izquierdo de un objeto, y el valor de la propiedad
CurrentY es 0 en el borde superior. Las coordenadas se expresan en las unidades de medida
definidas por las propiedades ScaleHeight y ScaleWidth. Si se han introducido estas
propiedades (como recomendábamos mas atrás), la propiedad ScaleMode se pone
automáticamente a User. Si no se establecen, ScaleMode puede estar en Twips, Point,
Pixeles, caracteres, .... unidades que supongo le serán mucho mas difícil de controlar que si
Vd. dice desde el principio que el papel de su impresora tiene unas medidas de 2100 por 2970
(Printer.ScaleWidth = 2100, Printer.ScaleHeight = 2970) Haciéndolo de esta última forma,
cuando queramos dibujar una línea entre dos puntos de nuestro papel DIN A4 bastará con
medir las coordenadas de inicio y final de línea, eso sí, usando como unidad de medida la
décima de milímetro. Por ejemplo, una línea a 5 mm del borde superior, que comience a 20
mm. Del borde izquierdo y termine a 10 mm del borde derecho, se dibujaría con la siguiente
instrucción :
Si queremos escribir datos en una columna, que está a 30 mm. de la parte izquierda de la
hoja, comenzaremos a escribir cada fila de esa columna con un CurrentX de 300. Para ello
primero fijaremos el punto de inicio mediante CurrentX y a continuación usaremos el método
Print :
CurrentX y CurrentY se quedan con los valores establecidos por el último método gráfico o
método Print usado.
Cuando se está dibujando sobre el objeto Printer, los métodos gráficos Circle y Line
establecen los siguientes valores para CurrentX y CurrentY :
DeviceName
Devuelve el nombre del dispositivo permitido por un controlador. Esta propiedad es solo de
lectura
Pagina: 197
Sintaxis Printer.DeviceName
Cada controlador de impresora acepta uno o más dispositivos por ejemplo, HP LaserJet III es
un nombre de dispositivo.
DrawMode
DrawStile
0 (Predeterminado) Continuo.
1 Rayas.
2 Puntos.
3 Raya - punto.
4 Raya - punto - punto.
5 Transparente.
6 Continuo interior.
Observaciones
Si DrawWidth se define con un valor mayor que 1, los valores de DrawStyle entre 1 y 4
producen una línea continua (el valor de la propiedad DrawStyle no cambia). Si DrawWidth se
define como 1, DrawStyle produce el efecto para cada valor descrito en la tabla anterior.
DrawWidth
tamaño es una expresión numérica comprendida entre 1 y 32.767 que representa la anchura
de la línea en pixeles. El valor predeterminado es 1, es decir, un píxel de ancho.
Comentarios
Puede incrementar el valor de esta propiedad para aumentar la anchura de la línea. Si el valor
de la propiedad DrawWidth es mayor que 1, los valores de 1 a 4 en la propiedad DrawStyle
producirán una línea continua (el valor de DrawStyle no se modifica). Si se establece 1 en
DrawWidth, DrawStyle producirá los resultados mostrados en la tabla de esta propiedad.
DriverName
Devuelve el nombre del controlador de un objeto Printer. Esta propiedad es solo de lectura
Sintaxis Printer.DriverName
Cada controlador tiene un nombre único. Por ejemplo, el DriverName de varias impresoras
Hewlett-Packard es HPPCL5MS. El DriverName es normalmente el nombre de archivo del
Pagina: 198
controlador sin la extensión.
Duplex
Devuelve o establece un valor que determina si las páginas se imprimen por los dos lados (si
la impresora tiene esta característica). No disponible en tiempo de diseño.
Donde valor es un valor o constante que especifica el tipo de impresión, tal como se describe
a continuación
Con impresión a doble cara horizontal, la parte superior de ambas caras de la hoja están en el
mismo borde de la hoja. Con impresión a doble cara vertical, la parte inferior de una página
está en el mismo borde de la hoja que la parte superior de la página siguiente. Véase el gráfico
existente en la ayuda de VB para la propiedad Duplex
FillColor
Devuelve o establece el color usado para rellenar formas; FillColor también se usa para
rellenar círculos y cuadros creados con los métodos gráficos Circle y Line.
Donde valor es un valor o constante que determina el color de relleno. El valor puede
introducirse como RGB o con las constantes QB color
ejemplos
FillColor = QBColor(8)
FillColor = RGB (255,0,0)
El color predeterminado es el 0 (Negro).
FillStyle
Devuelve o establece el modelo usado para rellenar dibujos (círculos y los cuadros creados
con los métodos gráficos Circle y Line.
Donde número Un entero que especifica el estilo de relleno, tal como se describe a
continuación
Valor Descripción
0 Continuo.
1 (Predeterminado) Transparente.
2 Línea horizontal.
3 Línea vertical.
4 Diagonal hacia arriba.
5 Diagonal hacia abajo.
Pagina: 199
6 Cruzado.
7 Diagonal Cruzada.
Font
Devuelve o establece el objeto Font (letra) del objeto Printer. Este objeto Font tiene a su vez
sus propiedades (Name, Size, Bold, Italic ... )
Podemos forzar la fuente a usar por el objeto Printer con un CommonDialog, igualando la
propiedad Name del objeto Font del Printer a la propiedad FontName del CommonDialog
Printer.Font.Name = CD1.FontName
Tipofuente = Printer.Font.Name
FontCount
FontName
(El Objeto Printer admite esta propiedad como Font.Name o FontName indistintamente)
Fonts
Devuelve todos los nombres de fuente disponibles para el dispositivo de presentación actual o
la impresora activa.
Sintaxis Printer.Fonts(índice)
La propiedad Fonts funciona de forma conjunta con la propiedad FontCount, que devuelve el
número de nombres de fuente disponibles para el objeto. Las fuentes disponibles en Visual
Basic varían de acuerdo con la configuración del sistema, y los dispositivos de presentación y
de impresión. Use las propiedades Fonts y FontCount para obtener información sobre las
fuentes disponibles para pantalla o impresora.
Por ejemplo, si queremos ver en Label1 todas las fuentes disponibles para el objeto Printer,
estableceremos el siguiente código :
For i = 1 To Printer.FontCount
Label1.Caption = Label1.Caption + " " + Printer.Fonts(i)
Next i
FontSize
Pagina: 200
Devuelve o establece el tamaño de la fuente a utilizar para el texto mostrado en un control o
en una operación de dibujo o impresión en tiempo de ejecución.
Donde puntos es una expresión numérica que especifica el tamaño de fuente a utilizar, en
puntos.
Puede utilizar esta propiedad para dar al texto el tamaño que desee. El valor predeterminado
lo determina el sistema. Para cambiar este valor, especifique el nuevo tamaño de la fuente en
puntos.
El valor máximo de FontSize es 2160 puntos.
Nota Las fuentes disponibles en Visual Basic varían dependiendo de la configuración del
sistema y de los dispositivos de presentación e impresión. En las propiedades relacionadas
con las fuentes sólo pueden establecerse valores para los que exista una fuente.
Devuelve o establece los estilos de fuente en los siguientes formatos: Negrita, Cursiva,
Tachada y Subrayada.
FontTransparent
Devuelve o establece un valor que determina si el texto y los gráficos de fondo de un objeto
Printer, se muestran en el espacio situado entre los caracteres.
ForeColor
Devuelve o establece el color de escritura para impresoras en color. El cambio de color afecta
solamente al texto que se envíe después de realizar el cambio.
Pagina: 201
hDC
Sintaxis Printer.hDC
Height Width
Devuelven o establecen las dimensiones del objeto Printer. No están disponibles en tiempo de
diseño.
Donde número indica las dimensiones del papel configurado para el dispositivo de impresión.
No disponibles en tiempo de diseño. Si se establecen en tiempo de ejecución, los valores de
estas propiedades se utilizarán en lugar del de la propiedad PaperSize.
Para el objeto Printer, estas propiedades se miden siempre en twips. Si establece las
propiedades Height y Width para un controlador de impresora que no admite su uso, no se
producirá ningún error, y el tamaño del papel continuará siendo el mismo.
¡¡¡ Es mas recomendable utilizar la propiedad PaperSize para establecer las dimensiones
del papel. !!!
Orientation
Devuelve o establece un valor que indica si los documentos se imprimen con orientación
vertical u horizontal. No disponible en tiempo de diseño.
Page
Devuelve el número de página actual.
Pagina: 202
Sintaxis Variable = Printer.Page ‘Variable contiene el número de la pág.
actual
Nota La salida de los métodos gráficos que no quepa en la página actual no genera una
página nueva, sino que se recorta para ajustarla a la zona de impresión de la página.
PaperBin
Devuelve o establece un valor que indica la bandeja predeterminada para la alimentación de
papel durante la impresión. No disponible en tiempo de diseño.
No todas las opciones están disponibles en todas las impresoras. Consulte la documentación
de la impresora para obtener descripciones más específicas de estas opciones.
PaperSize
Devuelve o establece un valor que indica el tamaño de papel para la impresora actual. No
disponible en tiempo de diseño. El valor predeterminado es el establecido en la configuración
de la impresora en Windows. Con esta propiedad no se debe jugar alegremente. El valor que
se le dé a esta propiedad será el tamaño de ese papel “ficticio” que comentábamos mas atrás.
valor es un valor o constante que especifica el tamaño del papel, según se describe a
continuación
Constante Valor Descripción
vbPRPSLetter 1 Carta, 8 ½ x 11 .
vbPRPSLetterSmall 2 Carta pequeña, 8 ½ x 11 .
vbPRPSTabloid 3 Tabloide, 11 x 17 .
vbPRPSLedger 4 Libro, 17 x 11 .
Pagina: 203
vbPRPSLegal 5 Legal, 8 ½ x 14 .
vbPRPSStatement 6 Declaración, 5 ½ x 8 ½ .
vbPRPSExecutive 7 Ejecutivo, 7 ½ x 10 ½ .
vbPRPSA3 8 A3, 297 x 420 mm
vbPRPSA4 9 A4, 210 x 297 mm
vbPRPSA4Small 10 A4 pequeño, 210 x 297 mm
vbPRPSA5 11 A5, 148 x 210 mm
vbPRPSB4 12 B4, 250 x 354 mm
bPRPSB5 13 B5, 182 x 257 mm
vbPRPSFolio 14 Folio, 8 ½ x 13 .
vbPRPSQuarto 15 Cuarto, 215 x 275 mm
vbPRPS10x14 16 10 x 14 .
vbPRPS11x17 17 11 x 17 .
vbPRPSNote 18 Nota, 8 ½ x 11 .
vbPRPSEnv9 19 Sobre #9, 3 7/8 x 8 7/8 .
vbPRPSEnv10 20 Sobre #10, 4 1/8 x 9 ½ .
vbPRPSEnv11 21 Sobre #11, 4 ½ x 10 3/8 .
vbPRPSEnv12 22 Sobre #12, 4 ½ x 11 .
vbPRPSEnv14 23 Sobre #14, 5 x 11 ½ .
vbPRPSCSheet 24 Hoja tamaño C
vbPRPSDSheet 25 Hoja tamaño D
vbPRPSESheet 26 Hoja tamaño E
vbPRPSEnvDL 27 Sobre DL, 110 x 220 mm
vbPRPSEnvC3 29 Sobre C3, 324 x 458 mm
vbPRPSEnvC4 30 Sobre C4, 229 x 324 mm
vbPRPSEnvC5 28 Sobre C5, 162 x 229 mm
vbPRPSEnvC6 31 Sobre C6, 114 x 162 mm
vbPRPSEnvC65 32 Sobre C65, 114 x 229 mm
vbPRPSEnvB4 33 Sobre B4, 250 x 353 mm
vbPRPSEnvB5 34 Sobre B5, 176 x 250 mm
vbPRPSEnvB6 35 Sobre B6, 176 x 125 mm
vbPRPSEnvItaly 36 Sobre, 110 x 230 mm
vbPRPSEnvMonarch 37 Sobre monarca, 3 7/8 x 7 ½ .
vbPRPSEnvPersonal 38 Sobre, 3 5/8 x 6 ½ .
vbPRPSFanfoldUS 39 Doblado estándar EE.UU., 14 7/8 x 11 .
vbPRPSFanfoldStdGerman 40 Doblado estándar alemán, 8 ½ x 12 .
vbPRPSFanfoldLglGerman 41 Doblado legal alemán, 8 ½ x 13 .
vbPRPSUser 256 Definido por el usuario
Port
Devuelve el nombre del puerto a través del cual se envía un documento a una impresora.
El sistema operativo determina el nombre del puerto, como por ejemplo LPT1: o LPT2:.
PrintQuality
Pagina: 204
valor es un valor o una constante que especifica la resolución de la impresora, según se
describe a continuación :
Además de los valores negativos predefinidos, también puede indicarse en valor un número
positivo de puntos por pulgada, como por ejemplo 300.
ScaleHeight, ScaleWidth
Donde valor es una expresión numérica que especifica la medida horizontal o vertical. Este
valor va a determinar el número de unidades de medida que tiene el papel, NO su medida. Es
decir, podemos decir, mediante estas propiedades, que el papel tiene 2100 unidades de ancho
y 2970 unidades de alto. Si el papel es un DIN A4 (Medidas 210 x 297 mm) esa unidad de
medida sería precisamente una décima de milímetro. Podríamos haber elegido otros valores,
con lo que esa unidad de medida ya no serían décimas de mm. Sería una unidad de medida
cualquiera, pero el papel seguiría siendo DIN A4 y seguiría teniendo las mismas medidas
reales.
ScaleLeft, ScaleTop
donde valor es una expresión numérica que especifica la coordenada horizontal o vertical. El
valor predeterminado es 0.
Pagina: 205
Resumiéndolo en palabras mas sencillas. Si, con las medidas de los ejemplos anteriores
(ScaleWidth = 2100, ScaleHeight = 2970) ponemos Printer.ScaleLeft = - 1050 estamos
diciendo que la coordenada horizontal absoluta en la parte izquierda de la hoja es de -1050. Si
el ancho del papel es de 2100, la coordenada X absoluta del eje central del papel será
entonces 0. Y la coordenada X de la parte derecha del papel será + 1050. Por lo tanto, si
ejecutamos el método gráfico :
dibujará un circulo de radio 300, con el centro en el eje vertical de la hoja (Coordenada X=0) a
una altura de 1000 (Coordenada Y=1000) de la parte superior del papel.
ScaleMode
Devuelve o establece un valor que indica la unidad de medida de las coordenadas de un
objeto al utilizar métodos gráficos, o al situar controles.
donde valor es un número entero que especifica la unidad de medida, según se describe a
continuación
0 User. Indica que una o más de las propiedades ScaleHeight, ScaleWidth, ScaleLeft y
ScaleTop tienen valores personalizados.
1 (Predeterminado) Twip (1440 twips por pulgada lógica; 567 twips por centímetro
lógico).
2 Punto (72 puntos por pulgada lógica).
3 Píxel (la unidad mínima de la resolución del monitor o la impresora).
4 Carácter (horizontal = 120 twips por unidad; vertical = 240 twips por unidad).
5 Pulgada.
6 Milímetro.
7 Centímetro.
Recomendación del autor de esta Guía del Estudiante. Una vez mas recomiendo que
controle la posición de los métodos gráficos y método Print fijando las unidades de medida
mediante ScaleHeight, ScaleWidth, (Si le es práctico, emplee ScaleLeft y ScaleTop para que
le coincida el punto central del papel con las coordenadas 0,0 y así usaría coordenadas
positivas y negativas) y cada vez que escriba o dibuje, coloque el “cursor” de escritura
mediante las propiedades CurrentX y CurrentY
TrackDefault
Devuelve o establece un valor que determina si el objeto Printer apunta siempre a la misma
impresora, o si la impresora a la que apunta cambia cuando se modifica la impresora
predeterminada en el Panel de control del sistema operativo. No disponible en tiempo de
diseño.
Donde lógico es una expresión booleana que determina la impresora a la que apunta el objeto
Printer, según se describe a continuación.
Pagina: 206
True (Predeterminado) El objeto Printer cambia la impresora a la que apunta al modificar la
impresora predeterminada en el Panel de control del sistema operativo.
False El objeto Printer continúa apuntando a la misma impresora cuando se modifica la
impresora predeterminada en el Panel de control del sistema operativo.
TwipsPerPixelX, TwipsPerPixelY
Sintaxis Printer.TwipsPerPixelX
Printer.TwipsPerPixelY
En general, las rutinas del API de Windows requieren las medidas en píxels. Puede utilizar
estas propiedades para convertir rápidamente las dimensiones sin cambiar el valor de la
propiedad ScaleMode de los objetos.
Zoom
Donde numero es una expresión numérica que evalúa en el porcentaje de ajuste de la salida
impresa. El valor predeterminado es 0, que especifica que la página impresa aparece con su
tamaño normal.
Comentarios
La colección Printers le permite consultar las impresoras disponibles de forma que pueda
especificar la impresora predeterminada de la aplicación. Por ejemplo, se puede querer saber
cual de las impresoras disponibles usa un controlador de impresoras determinado. El siguiente
código comprueba todas las impresoras disponibles para saber la primera impresora cuya
orientación de página sea vertical:
Dim X As Printer
For Each X In Printers
If X.Orientation = vbPRORPortrait Then
' la define como predeterminada.
Set Printer = X
' Sale del bucle.
Exit For
End If
Next
Pagina: 207
Usando la instrucción Set se designa una de las impresoras de la colección Printers como
impresora predeterminada. El ejemplo anterior designa la impresora identificada por la variable
de objeto X, como impresora predeterminada de la aplicación.
Nota Si la colección Printers se usa para especificar una impresora concreta, como
Printers(3), sólo se puede tener acceso a sus propiedades de modo lectura. Para leer y escribir
las propiedades de una impresora concreta, primero se tiene que definir como impresora
predeterminada de la aplicación.
Circle
Dibuja un círculo, elipse o arco sobre un objeto. No acepta argumentos con nombre.
Sintaxis Printer.Circle Step (x, y), radio, color, inicio, final, aspecto
EndDoc
Sintaxis Printer.EndDoc
KillDoc
Sintaxis Printer.KillDoc
Line
NewPage
Pagina: 208
Sintaxis Printer.NewPage
PaintPicture
Presenta el contenido de un archivo gráfico (.BMP, .WMF, .EMF, .ICO o .DIB) en un objeto
Printer. No acepta argumentos con nombre.
Sintaxis
Printer.PaintPicture imagen, x1, y1, anchura1, altura1, x2, y2, anchura2, altura2, opecod
Puede ver mas información acerca de este método en el capítulo 7 Métodos Gráficos
Tab(n) Se utiliza para situar el punto de inserción en un número de columna absoluto, donde n
es el número de columna. Utilice Tab sin argumentos para situar el punto de inserción en la
línea siguiente, al principio de la zona de impresión.
Nota.- El uso de los tabuladores puede traerle mas problemas que ventajas. Los pasos de
tabulación dependen de cada impresora, y lo que es peor, de la programación de la propia
impresora. Por lo tanto, al usar Tab no controlamos del todo la posición de las columnas. Es
mucho mas práctico (y seguro) usar Printer.CurrentX y Printer.CurrentY para posicionar el
“puntero” de escritura del Objeto Printer.
Las instrucciones :
Printer.Print “Hola”
Printer.Print “¿Qué tal ?” generarán la siguiente salida por impresora :
Hola
¿Qué tal ?
Pagina: 209
Si pusiésemos
Printer.Print “Hola ” ;
Printer.Print “¿Qué tal ?” la salida por impresora sería :
Nota Debido a que el método Print imprime normalmente con caracteres de espaciado
proporcional, es importante recordar que no hay relación entre el número de caracteres
impresos y el número de columnas de anchura fija que tales caracteres ocupan. Por ejemplo,
una letra ancha, como W, ocupa más de una columna de anchura fija, mientras que una letra
estrecha, como I, ocupa menos. Para tener en cuenta los casos en el que se utilizan caracteres
con una anchura mayor que la media, deberá asegurarse de que las columnas de las tablas se
encuentren lo bastante lejos unas de otras. Como alternativa, puede utilizar en la impresión
una fuente de anchura fija (como Courier) para hacer que cada carácter utilice sólo una
columna.
Para controlar perfectamente el punto donde se escribirá el siguiente carácter, utilice las
propiedades CurrentX y CurrentY. Es mucho mas práctico que usar, por ejemplo, el Tabulador
Tab(n)
Si usa Tab(n) con una determinada impresora, puede verse con la desagradable sorpresa que
en otra impresora no funciona de la misma forma. Como al desarrollar una aplicación nunca
sabe sobre que impresora va a imprimir, es mejor que no utilice Tab(n), sustituyéndolo por
CurrentX.
Método TextWidth
Donde AnchodelTexto es una variable tipo Long que indicará el ancho (en las unidades de
medida definidas para el objeto Printer - Twips, Pixels, mm, o como siempre recomendaré, las
establecidas mediante ScaleWidth y ScaleHeight) y Textoaescribir es una variable tipo String
que contiene el texto a escribir.
Si la cadena de texto cuya longitud de impresión queremos analizar contiene retornos de carro,
TextWidth devuelve la anchura de la línea más larga.
Mediante este método puede escribir columnas de datos, mucho mejor que usando el Tab(n).
Suponga que quiere escribir en una columna, los datos Dato(1), Dato(2), ....Dato(N) que son
números. Quiere escribirlos de tal forma que la parte derecha del número quede alineada,
como hacemos casi siempre para poder sumarlos con facilidad. Supongamos que hemos
establecido las Propiedades Printer.ScaleWidth = 21000 y Printer.ScaleHeight = 29700. Damos
por hecho que el papel es un DIN A-4 (210 x 297 mm) por lo que estamos usando, como
unidad de medida en ambas coordenadas la centésima de mm.
Si queremos que las cifras queden alineadas en una columna cuya parte final sea 5000 (la
parte final de esa columna quedará a 50 mm. del margen izquierdo del papel), deberemos
calcular la longitud de cada cifra, y poner, como inicio de escritura de esa cifra 5000 - ancho :
Pagina: 210
Ancho = Printer.TextWidth (Str(Dato(I))) ‘Calculamos el ancho (para el Printer)
de cada
Printer.CurrentX = 5000 - Ancho ‘dato. Lo restamos a 5000 para que queden
Printer.CurrentY = K +(300 * I) ‘alineados por atrás. La coordenada Y
Printer.Print Str(Dato(I)) ‘será una constante K mas 3 mm
Next I
Observe que el ancho de una determinada cadena de caracteres no tiene porqué ser la misma
para un Formulario que para el Printer. Dependerá del tipo de fuente y del tamaño de esa
fuente que usemos en cada caso. Por eso, debe poner siempre Printer.TextWidth,
Form1.TextWidth, etc.
Método TextHeight
Este método es idéntico al anterior, pero relativo a la altura. No vamos a alargar la explicación
dada la similitud con el anterior. Este método nos permite separar adecuadamente las líneas
de un escrito. Es muy útil sobre todo cuando utilizamos distintos tipos de letra dentro del
mismo escrito.
Método PSet
Step Opcional. Palabra reservada que especifica que las coordenadas son relativas
a la posición gráfica actual proporcionada por las propiedades CurrentX y CurrentY.
color Opcional. Valor entero largo que indica el color RGB especificado para el punto. Si se
omite, se utiliza el valor de la propiedad ForeColor. Puede utilizar la función RGB o la función
QBColor para especificar el color.
El tamaño del punto dibujado depende del valor de la propiedad DrawWidth. Cuando
DrawWidth es 1, PSet establece un píxel al color especificado. Cuando DrawWidth es mayor
que 1, se centra el punto en las coordenadas especificadas.
La forma en que se dibuja el punto depende de los valores de las propiedades DrawMode y
DrawStyle.
Cuando se ejecuta PSet, las propiedades CurrentX y CurrentY toman el valor del punto
especificado en los argumentos.
Vacíe un píxel con el método PSet especificando las coordenadas del píxel y utilizando el valor
de la propiedad BackColor como argumento color.
FUNCION DoEvents
Pagina: 211
Cede el control de la ejecución al sistema operativo, para que éste pueda procesar otros
eventos. También nos permite conocer el número de formularios abiertos en una aplicación.
Sintaxis DoEvents
Cede el control al sistema operativo
Sintaxis variable=DoEvents
variable contendrá un número indicando el número de formularios abiertos en
este momento.
La función DoEvents devuelve también el número de formularios abiertos por una versión
única de Visual Basic, como la versión estándar de Visual Basic. DoEvents devuelve 0 en el
resto de las aplicaciones.
El control no se devuelve hasta que el sistema operativo haya terminado de procesar los
eventos en cola y que (sólo para Microsoft Windows) se hayan enviado todas las teclas en la
cola SendKeys.
Si partes de su código consumen demasiado tiempo de procesamiento, use periódicamente
DoEvents para ceder el control al sistema operativo, de manera que eventos como la entrada
por el teclado o los clics del mouse (ratón) se puedan procesar sin grandes retrasos. Utilice
esta función sobre todo, cuando tenga bucles demasiado largos que puedan interrumpir la
entrada de datos por teclado o ratón.
EJEMPLO
Pagina: 212
Se declara la variable PARAR como booleana en las declaraciones del Form1
El botón COMENZAR introduce un bucle que no pararía nunca. También pone Label1 de color
Verde.
Si no hubiésemos puesto DoEvents en una parte del bucle del contador, nunca se podría
acceder al Procedimiento KeyPress del formulario, pues el programa lo único que haría será
dar vueltas en el bucle indefinidamente.
Lo mismo ocurriría con el botón ROJO. Al estar el programa haciendo el bucle continuamente,
nunca podríamos entrar el Procedimiento Click de este botón.
Los botones FORM2, cierra Form2, FORM3, cierra Form3, lo único que hacen es mostrar u
ocultar Form2 y Form3 a efectos de poder comprobar cuantos formularios tenemos abiertos.
Pagina: 213
Por último SALI nos saca del programa. Observe que si no hubiésemos puesto DoEvents en
el medio del bucle, tampoco podríamos salir del programa, puesto que el sistema operativo no
podría comprobar que hemos hecho Click en este botón.
Realice esta pequeña práctica con la línea DoEvents del botón COMENZAR activada y
desactivada (Con una comilla simple). Prepárese para, en este último caso, detener la
aplicación pulsando Ctr-Pausa, pues de otra forma no la podrá detener.
Pagina: 214
(El siguiente tema ha sido tomado parcialmente de las páginas de Mundo Visual - Visual
Basic.)
Presentación Modal de formularios. Ventana modal
Se dice que un Formulario o cualquier tipo de ventana se presenta de forma Modal cuando un
elemento de ese formulario o ventana toma el foco en el momento de mostrarse, y exige que
se realice alguna gestión sobre ella antes de permitir que otra parte de la aplicación tome de
nuevo el foco. La actuación que generalmente exige un formulario o ventana es ocultarse.
Para ver esto, cree una aplicación con dos formularios. El primero (Form1) puede ser el
formulario donde se realizan todas las operaciones de la aplicación. El segundo (Form2) puede
ser el típico formulario donde se presenta la información del fabricante de la aplicación, al que
se accede normalmente desde el menú, con la palabra Acerca de...
Cree un menú en el primer formulario con esa palabra y ponga este formulario como
formulario inicial de la aplicación. En el procedimiento click de este menú ponga el siguiente
código :
Form2.Show 1
El 1 detrás de la expresión Show indica que el formulario Form2 debe mostrarse de forma
Modal, lo que significa que no se podrá volver a operar con ningún elemento de Form1 hasta
que se oculte o descargue el formulario Form2. Ponga en este Form2 el típico botón de
Aceptar, cuyo código puede ser simplemente :
Me.Hide
Lo dicho para un formulario puede aplicarse para otro tipo de ventanas. El MessageBox y la
ventana del CommonDialog son dos ejemplos de ventanas modales. Veamos la primera :
1 - El aviso es sí, que tiene por objetivo mostrar una información de interés.
2 - El aviso con espera de respuesta, que muestra una información esperando que el usuario
seleccione una de las respuestas posibles para que el programa la trate.
Una caja de mensaje, puede ser por ejemplo, la instrucción MsgBox "Hola". Por defecto, la
caja de mensaje será similar a esta:
Pagina: 215
Podemos modificar estos parámetros para alcanzar nuestros objetivos, por eso, vamos a
escribir ahora este código: MsgBox "Hola", ,"Ejemplo" .
El resultado es:
Habrá observado en la expresión anterior que se ha utilizado vbCrLf (Visual Basic Carriage
Return Line Feed, VB retorno de carro y avance de línea) Vea mas adelante la aclaración de
esta expresión. Con ella logramos introducir un salto de línea.
Supongo que se habrá percatado de que entre el mensaje y el título de la ventana, hemos
escrito dos comas, esto es porque entre las comas, debe ir un número que representará el
icono a mostrar. Existen cuatro iconos diferentes además de la posibilidad de no mostrar
ninguno. Los iconos son:
(Sólo en W32. En Windows 3.xx dispone de otros diferentes, aunque con el mismo significado)
Para mostrar el icono en cuestión o para que Visual Basic lo entienda, es necesario escribir lo
siguiente:
Pagina: 216
El resultado es:
Ahora bien, es posible que queramos mostrar algún otro botón que o bien no sea el de Aceptar
o que además del botón de Aceptar haya más botones. Para este propósito, tenemos los
siguientes parámetros:
Aceptar vbOKOnly ó 0
Aceptar y Cancelar vbOKCancel ó 1
Anular, Reintentar, Ignorar vbAbortRetryIgnore ó 2
Sí, No y Cancelar vbYesNoCancel ó 3
Sí y No vbYesNo ó 4
Reintentar y Cancelar vbRetryCancel ó 5
Aplicación modal vbApplicationModal ó 0 (Es la caja de mensaje sin
icono)
La forma de hacer esto es sumar al parámetro del icono que queremos mostrar el valor de los
botones que deseamos que aparezcan.
Así por ejemplo:
MsgBox "Hola" & vbCrLf & "Esto es un ejemplo.", VbQuestion + vbYesNo , "Ejemplo"
El resultado es:
Aún así, es posible que deseemos que el Focus lo adquiera otro un botón determinado. Por
ejemplo, en este caso el Focus lo tiene el botón Sí, pero es posible que deseemos que lo tenga
el botón No por ejemplo. Esto se consigue con los siguientes parámetros:
Primer botón predeterminado vbDefaultButton1 ó 0
Segundo botón predeterminadovbDefaultButton2 ó 256
Tercer botón predeterminado vbDefaultButton3 ó 512
Por ejemplo: MsgBox "Hola" & vbCrLf & "Esto es un ejemplo.", VbQuestion + vbYesNo +
vbDefaultButton2, "Ejemplo"
El resultado es:
Pagina: 217
Si no se señala el botón predeterminado, Visual Basic seleccionará el primer botón. En caso
de seleccionar como predeterminado un botón que no existe, (por ejemplo el tercero), Visual
Basic seleccionará el primero.
Ahora bien, si decidimos mostrar un mensaje esperando una respuesta, o queremos saber que
botón ha pulsado el usuario, esto lo podemos conseguir mediante el siguiente código de
respuestas:
Aceptar vbOK ó 1
Cancelar vbCancel ó 2
Anular vbAbort ó 3
Reintentar vbRetry ó 4
Ignorar vbIgnore ó 5
Sí vbYes ó 6
No vbNo ó 7
If Resp = 6 Then
MsgBox "Ha pulsado SI"
Else
MsgBox "Ha pulsado NO"
End If
Si pulsamos el botón Sí obtendremos una acción, y si pulsamos el otro botón otra acción.
Ahora bien, para elegir o seleccionar un evento o acción, el usuario debe saber combinar los
códigos, sabiendo que un MsgBox posee la siguiente sintaxis principal:
InputBox
El InputBox o caja de entrada es otra de las partes más utilizadas para la interacción del
usuario con la aplicación. Es importante que el usuario interactúe con la aplicación para ser el
protagonista de esta.
Pagina: 218
El InputBox nos permite sacar una caja donde el usuario pasará un parámetro, valor o dato
para que el programa lo trate y lo ejecute.
El mensaje que quiere que aparezca se realiza de forma casi idéntica al MessageBox. Puede
escribirse varias líneas de texto seguidas por la constante de Visual Basic vbCrLf o salto de
línea o párrafo.
Val almacenará el texto escrito por el usuario, que puede ser una cantidad, cadena string, …
etc.
Por ejemplo:
Dim Val As String
(El usuario teclea el nombre - Mundo Visual - y hace click en Aceptar. A continuación se
muestra el MsgBox - 2ª línea del código anterior )
Ahora bien, podemos determinar un texto predeterminado a la caja de entrada, como por
ejemplo:
Es importante determinar que si el usuario elige el botón Cancelar, el programa devolverá una
cadena de caracteres igual a 0, es decir, Val ="".
Pagina: 219
La caja de entrada puede ser sin embargo más personalizada mediante dos parámetros como
son la posición de la ventana de entrada de datos en la pantalla. Estos parámetros se ponen a
continuación del ValorPredeterminado.
Por ejemplo:
Salto de página
Repaso: Hemos visto en este capítulo el uso de MsgBox, y InputBox, los cuales nos van a
servir de gran utilidad en nuestros proyectos Visual Basic.
Pagina: 220
El control RichTextBox es una caja de texto con mas prestaciones que el TextBox. Este
control solamente está implementado en la versión de 32 bits. No está normalmente en la caja
de herramientas, por lo que habrá que ir a Herramientas | Controles Personalizados. El
icono que presenta en la caja de herramientas es el siguiente :
Frente a la rigidez del TextBox, este control nos permite escribir un texto utilizando distintos
tipos de fuentes en el mismo texto, e introducir mas de 65.536 caracteres, límite máximo del
TextBox. Aparte de estas, tiene otras características respecto a la forma de guardar y leer el
texto en un fichero, que le convierten en una herramienta muy útil para el diseño de
aplicaciones en las que haya que introducir documentos de texto.
Propiedades
El RichTextBox tiene todas las propiedades del TextBox, y además otras que son las que le
dan las características excepcionales a este control. Las tres siguientes propiedades son
idénticas para ambos controles :
En el ejemplo, el texto seleccionado es ejemplo nos permitirá, texto que hemos seleccionado
con el ratón. Las propiedades anteriores tomarán estos valores para ese texto seleccionado :
Pagina: 221
SelText = ejemplo nos permitirá
Recuerde que estas propiedades son tanto de lectura como de escritura. Es decir, puede
seleccionar un texto con el ratón y analizar ese texto seleccionado, o seleccionar el texto
dándole valores a estas propiedades.
Las diferencias entre uno y otro control comienzan ahora. En un RichTextBox, con un texto
seleccionado, podemos cambiar el tipo de letra, su tamaño, su color, etc.
Usemos para ello las siguientes propiedades, que solamente las tiene el RichTextBox :
Estas propiedades son del tipo Booleano (True/False) y nos permitirán poner el texto
seleccionado en Negrita, Cursiva, Tachada y Subrayada respectivamente.
Si el texto seleccionado está en la parte final del texto, o si el cursor de escritura está al final
del escrito y no se ha seleccionado ningún texto, la propiedad elegida permanecerá vigente
para la escritura que se realice a partir de ese punto.
Al igual que las otras propiedades, si el texto seleccionado está al final del texto, o si el cursor
de escritura está al final del escrito, la propiedad elegida permanecerá vigente para la escritura
que se realice a partir de ese punto.
SelRTF
Devuelve o establece el texto (en formato .RTF) de la selección actual de un control
RichTextBox. No está disponible en tiempo de diseño.
TextRTF
Devuelve o establece el texto de un control RichTextBox, incluido todo el código .RTF.
Pagina: 222
Sintaxis objeto.TextRTF [= cadena]
OTRAS PROPIEDADES
El RichTextBox tiene otras propiedades, unas similares a las del resto de controles, otras con
ciertas particularidades.
Appearance
Plano o tridimensional, como en el resto de los controles.
AutoVerbMenu
Propiedad Booleana que indica si se presenta un menú emergente cuando el usuario hace
click con el botón derecho del ratón. El menú emergente muestra los comandos típicos de
cortar, copiar y pegar. Si esta propiedad está a True muestra el menú. False no lo muestra.
BorderStyle
Sin borde o con borde (None o Fixed Single)
BulletIndent
Devuelve o establece la cantidad de sangría utilizada en un control RichTextBox cuando
SelBullet se establece a True.
donde entero es un entero que determina la cantidad de sangría. Estas propiedades utilizan las
unidades de modo de escala del objeto Form que contiene el control RichTextBox.
NOTA. Hay que establecer la propiedad BulletIndent antes de establecer como True la
propiedad SelBullet. Por ejemplo :
RTB1.BulletIndent = 2500
RTB1.SelBullet = True
Estas dos líneas de código realizan una sangría de 2500 (en las unidades en las que estemos
midiendo el Formulario que contiene al RichTextBox) y convierte en viñeta el párrafo que
estuviese seleccionado.
La propiedad BulletIndent devuelve Null si la selección abarca múltiples párrafos con distintos
ajustes de margen.
SelBullet
Devuelve o establece un valor que determina si un párrafo del control RichTextBox que
contiene la selección actual o el punto de inserción tiene el estilo de viñeta. No está disponible
en tiempo de diseño.
Pagina: 223
Si queremos leer la propiedad, es decir, si queremos saber si un párrafo tiene estilo de viñeta,
usaremos la siguiente sintaxis :
Variable = NombreRichTextBox.SelBullet
DisableNoScroll
Devuelve o establece un valor que determina si están desactivadas las barras de
desplazamiento en el control RichTextBox.
Enabled
Propiedad Booleana. Activa o desactiva el RichTextBox
FileName
Esta propiedad devuelve o establece el nombre del fichero .RTF cargado en el RichTextBox. Si
ejecutamos la línea de código :
Variable = RTB1.Filename
obtendremos en Variable el nombre (y Path) del fichero que tenemos cargado en el RTB
HideSelection
Devuelve o establece un valor que determina si el texto seleccionado aparece resaltado
cuando un control pierde el enfoque.
Puede usar esta propiedad para indicar el texto resaltado mientras otro formulario o cuadro de
diálogo tiene el enfoque; por ejemplo, en una rutina de revisión ortográfica.
Locked
Igual que le ocurre al TextBox, si ponemos esta propiedad a True impedimos que se pueda
cambiar el texto existente en el RichTextBox mediante el teclado.
Pagina: 224
MaxLength
Esta propiedad marca el número máximo de caracteres que puede contener. Si se pone a 0
(Predeterminado) admite cualquier número de caracteres.
MousePointer
Igual que para el resto de los controles.
Multiline
Igual que para el TextBox. Si está a True (predeterminado) el RichTextBox puede contener
varias líneas. Si está a False, una solo.
OLEDragMode
OLEDropMode
Estas dos propiedades son similares a la DragMode de otros controles. Se verán con mas
detalle al estudiar el Drag & Drop.
RightMargin
Devuelve o establece el margen derecho del texto en un control RichTextBox.
Donde valor es una expresión numérica que especifica el espacio en Twips desde el margen
derecho del texto al margen derecho del control. Esta propiedad se utiliza para impedir que la
línea de texto sobrepase el margen derecho del RichTextBox
Cuando esta propiedad tiene el valor 0 (predeterminado), las líneas de escritura pueden
superar el límite del RichTextBox. Si se le da un valor bajo (1 por ejemplo), las líneas se
ajustan al ancho del RTB, introduciendo retornos de carro automáticos.
ScrollBars
Pone barras de desplazamiento al RichTextBox.
Esta propiedad puede establecerse a 0 (None, ninguna), a 1 (Horizontal), 2 (Vertical) o 3 (Both,
ambas). Cuando las barras de desplazamiento no son necesarias, bien porque hay pocas
líneas, bien porque hay pocos caracteres por línea, las barras de desplazamiento están
desactivadas.
Las barras de desplazamiento pueden desactivarse mediante la propiedad DisableNoScroll.
SelAlignment
valor = Un entero o una constante que determina la alineación del párrafo, como se describe a
continuación.
Pagina: 225
La propiedad SelAlignment determina la alineación de todos los párrafos que tienen texto en
la selección actual o del párrafo que contiene el punto de inserción si no hay texto
seleccionado.
Para distinguir entre los valores de Null y 0 al leer esta propiedad en tiempo de ejecución, use
la función IsNull con la instrucción If...Then...Else. Por ejemplo:
SelProtected
Devuelve o establece un valor que determina si está protegida la selección actual. No está
disponible en tiempo de diseño.
valor es un valor de tipo Variant que determina si la selección actual está protegida, como se
describe a continuación
Valor Descripción
Null La selección contiene un mezcla de caracteres protegidos y no protegidos.
True Todos los caracteres de la selección está protegidos.
False Ninguno de los caracteres de la selección está protegido.
El texto protegido tiene igual apariencia que el texto normal, pero el usuario final no puede
modificarlo. Es decir, el texto no se puede cambiar en tiempo de ejecución. Esto le permite
crear formularios con el control RichTextBox y tener zonas que pueda modificar el usuario
final.
SelCharOffset
Devuelve o establece un valor que determina si el texto del control RichTextBox aparece en la
línea base (normal), como un superíndice sobre la línea base o como un subíndice por debajo
de la línea base. No está disponible en tiempo de diseño.
desplazamiento = un entero que determina a qué distancia de la línea base del texto se
separan los caracteres de la selección actual o que siguen al punto de inserción, como se
describe a continuación.
Valor Descripción
Null Ninguno. La selección tiene una mezcla de caracteres con desplazamientos
diferentes.
0 Normal. (Predeterminado) Todos los caracteres aparecen en la línea base de
texto normal.
Entero positivo Superíndice. Los caracteres aparecen por encima de la línea base en el
número de twips especificado.
Entero negativo Subíndice. Los caracteres aparecen por debajo de la línea base en el número
de twips especificado.
SelTabCount, SelTabs
Pagina: 226
Sintaxis
NombreRTB.SelTabCount [= contador]
NombreRTB.SelTabs(índice) [= ubicación]
Las sintaxis de las propiedades SelTabCount y SelTabs constan de las siguientes partes:
Restablezca la propiedad TabStop de los otros controles cuando el control RichTextBox pierda
el enfoque.
El control RichTextBox cuenta con unos métodos especiales para abrir un fichero y guardar el
texto que contiene un poco especiales. Estos métodos (SaveFile y LoadFile) se pueden usar
solamente cuando queremos guardar o leer el texto en formato .RTF. Con ellos no es
necesario abrir el fichero (con Open Nombrefichero .....) ni cerrarlo, pero siempre para guardar
o leer texto en formato RTF. Podemos leer o guardar el texto de un RichTextBox como texto
plano (Como los ficheros ASCII .TXT). Para ello debemos utilizar los métodos Open
Nombrefichero For Input / Output vistos en el capítulo de ficheros.
METODO SaveFile
Guarda el contenido de un control RichTextBox en un archivo.
Donde nombre_ruta (Parámetro requerido) es una expresión de cadena que define la ruta de
acceso y el nombre del archivo que va a recibir el contenido del control, y tipo_archivo es un
entero o una constante que especifica el tipo de archivo cargado, como se describe a
continuación :
Pagina: 227
0 rtfRTF El control RichTextBox guarda su contenido como un archivo .RTF.
1 rtfText El control RichTextBox guarda su contenido como un archivo de texto.
Ejemplo
RTB1.SaveFile “C :\CursoVB\mitexto.rtf”, 0
Guarda el contenido del RichTextBox RTB1 en un fichero llamado mitexto.rtf que está en el
directorio CursoVB, con formato RTF
Aparte del método SaveFile, puede utilizar la función Print de Visual Basic y las propiedades
TextRTF y SelRTF del control RichTextBox para escribir archivos .RTF. Por ejemplo, puede
guardar el contenido de un control RichTextBox en un archivo .RTF de este modo:
METODO LoadFile
Donde nombre_ruta (Parámetro requerido) es una expresión de cadena que define la ruta de
acceso y el nombre del archivo que se va a cargar en el control, y tipo_archivo es un entero o
una constante que especifica el tipo de archivo cargado, como se describe a continuación
Al cargar un archivo con el método LoadFile, el contenido del archivo cargado reemplaza a
todo el contenido del control RichTextBox. Esto hace que cambien los valores de las
propiedades Text y rtfText.
También puede usar la función Input de Visual Basic y las propiedades TextRTF y SelRTF del
control RichTextBox para leer archivos .RTF. Por ejemplo, puede cargar el contenido de un
archivo .RTF en el control RichTextBox de este modo:
METODO Find
Donde :
cadena (Necesario) Una expresión de cadena que desea buscar en el control.
inicio (Opcional) Un índice de caracteres de tipo Integer que determina dónde comienza
la búsqueda. Cada carácter del control tiene un índice entero que lo
identifica de forma única. El primer carácter de texto del control tiene
un índice 0.
fin (Opcional) Un índice de carácter de entero que determina dónde termina la
Pagina: 228
búsqueda.
Opciones (Opcional) Una o más valores o constantes utilizadas para especificar
características opcionales, como se describe a continuación.
METODO GetLineFromChar
Donde pos_carácter (Requerido) es un entero largo que especifica la posición del carácter
cuya línea desea identificar. El índice del primer carácter del control RichTextBox es 0.
Utilice el método GetLineFromChar para averiguar qué línea del texto de un control
RichTextBox contiene una determinada posición de carácter. Es posible que necesite hacerlo
porque puede variar el número de caracteres de cada línea, lo que hace muy difícil averiguar
qué línea del texto contiene un determinado carácter, identificado por su posición en el texto.
METODO SelPrint
Sintaxis NombreRTB.SelPrint(hdc)
Donde hdc es el contexto de dispositivo del dispositivo que va a utilizar para imprimir el
contenido del control.
Pagina: 229
Si hay texto seleccionado en el control RichTextBox, el método SelPrint sólo enviará el texto
seleccionado al dispositivo de destino. Si no hay texto seleccionado, se enviará el contenido
completo del control RichTextBox al dispositivo.
El método SelPrint no imprime texto desde el control RichTextBox. En su lugar, envía una
copia del texto con formato a un dispositivo que pueda imprimirlo. Por ejemplo, puede enviar
el texto al objeto Printer utilizando código como éste:
RichTextBox1.SelPrint(Printer.hDC)
Observe que la propiedad hDC del objeto Printer se utiliza para especificar el argumento de
contexto de dispositivo del método SelPrint.
Nota Si utiliza el objeto Printer como destino del texto desde el control RichTextBox, deberá
inicializar en primer lugar el contexto de dispositivo del objeto Printer imprimiendo algo como
una cadena de longitud cero.
METODO Span
donde :
hacia_adelante (Opcional) Una expresión booleana que determina en qué sentido se mueve
el punto de inserción, como se describe mas adelante.
True Los caracteres incluidos en la selección son los que no aparecen en el argumento
juego_caracteres. La selección se detiene en el primer carácter encontrado que aparece en el
argumento juego_caracteres.
False (Predeterminado) Los caracteres incluidos en la selección son los que aparecen en el
argumento juego_caracteres. La selección se detiene en el primer carácter encontrado que no
aparece en el argumento juego_caracteres.
El método Span se utiliza principalmente para seleccionar fácilmente una palabra o una frase
en el control RichTextBox.
Si el método Span no encuentra los caracteres especificados basándose en los valores de los
argumentos, el punto de inserción o la selección actual permanece sin cambios.
El método Span no devuelve datos.
METODO Upto
Pagina: 230
Mueve el punto de inserción hasta el primer carácter (sin incluirlo) que sea miembro del
conjunto de caracteres especificado en un control RichTextBox.
Donde :
Valores
True (Predeterminado) Mueve el punto de inserción hacia delante, hacia el final del texto.
False Mueve el punto de inserción hacia atrás, hacia el principio del texto.
El Portapapeles y el RichTextBox
Imagínese que seleccionamos un texto en un RichTextBox y ese texto lo metemos al
portapapeles. Dado que el texto está escrito en RTF, ¿Como nos lo guarda el Portapapeles ?
La solución es que puede guardarlo en las dos versiones. En formato de texto plano (Guarda
estrictamente los caracteres ASCII del texto seleccionado) o como texto enriquecido (RTF),
guardando en este caso, además del texto limpio y puro, la información del tipo de letra,
tamaño, color, etc. típicas del formato RTF.
Para ello debemos indicarle al portapapeles en qué formato queremos guardarlo. La línea de
código :
guarda en el portapapeles todo el contenido del RichTextBox (llamado RTB1 en los ejemplos)
en formato RTF
Las líneas :
Pagina: 231
APENDICE
Propiedad Appearance
rtfFlat 0 Uniforme. Pinta sin efectos visuales.
rtfThreeD 1 (Predeterminado). 3D. Pinta con efectos tridimensionales.
Método Find
rtfWholeWord 2 Determina si una coincidencia se basa en una palabra completa o en
parte de una palabra.
rtfMatchCase 4 Determina si una coincidencia se basa en el uso de mayúsculas y
minúsculas de la cadena especificada además del texto de la cadena.
rtfNoHighlight 8 Determina si una coincidencia aparece resaltada en el control
RichTextBox.
Propiedad Selalignment
rtfLeft 0 (Predeterminado) Izquierda. El párrafo se alinea a lo largo del margen
izquierdo.
rtfRight 1 Derecha. El párrafo se alinea a lo largo del margen derecho.
rtfCenter 2 Centro. El párrafo se centra entre los márgenes izquierdo y derecho.
Propiedad Scrollbars
rtfNone 0 (Predeterminado) Ninguna.
rtfHorizontal 1 Sólo barra de desplazamiento horizontal.
rtfVertical 2 Sólo barra de desplazamiento vertical.
rtfBoth 3 Barras de desplazamiento horizontal y vertical.
El FORMATO RTF
Pagina: 232
Cuando se edita un texto mediante un procesador de textos, el fichero resultante se guarda
don un formato distinto para cada procesador. De esta forma, un texto editado en WP no es
compatible con el P.T. AmiPro, con Word o con cualquier otro. Los fabricantes de estos
procesadores de textos han tenido que incluir una herramienta capaz de convertir un formato a
otro para poder alcanzar la compatibilidad entre ellos que el mercado exigía.
El Formato de Texto Enriquecido pretende ser un nexo de unión entre todos los procesadores
de texto, para poder intercambiar ficheros editados en uno u otro. De hecho, las últimas
versiones de los mas importantes procesadores de textos incluyen la posibilidad de guardar y
buscar el texto en este formato. (WP, Word)
Este formato consiste en guardar mediante caracteres ASCII plenamente legibles tanto el texto
escrito como los tipos de letra, tamaño, saltos de carro, etc. Veamos un ejemplo comparativo
del mismo texto, guardado en ASCII y RTF
Este es un texto utilizado para explicar el Formato de Texto Enriquecido (RTF). El Formato de
Texto Enriquecido es un formato de intercambio de textos entre distintos procesadores. Es,
en
esencia, una idea para crear una forma común de intercambiar textos.
El RTF guarda los datos codificados en ASCII, es decir, el fichero resultante es legible
plenamen-
te ya que los caracteres que utiliza son ASCII, pero lleva una determinada codificación para
poder
cambiar de letra, de tamaño, etc.
Puede guardar gráficos tal como lo haría cualquier procesador de textos.
Fin
Estos textos de guardaron desde un RichTextBox. Algunas líneas están truncadas, pues en el
RTF original eran mas largas que las de este texto.
Puede observarse que codifica los acentos, los saltos de línea, etc., pero todo ello usando
caracteres ASCII plenamente legibles.
MUY IMPORTANTE
Observe que el fichero .RTF comienza por {\rtf Cuando tenga que importar un texto
hacia un RichTextBox, puede que ese texto esté en formato RTF o como Texto Plano
(Fichero ASCII puro) Para saber si el texto está en RTF analice los Cinco primeros
caracteres del texto a importar. Si son {\rtf es que está en presencia de un texto
RTF.
Pagina: 233
Para saber si un fichero contiene texto enriquecido, basta con abrirlo como un
fichero secuencial, (recuerde que un fichero .RTF tiene solamente caracteres ASCII)
y leer los cinco primeros caracteres.
LA AYUDA DE WINDOWS
Toda aplicación bien terminada debe tener una ayuda. Cualquier aplicación realizada en Visual
Basic puede tenerla, usando para ello los recursos que brida Windows.
Pagina: 234
El recurso de Windows es el programa WINHELP.EXE Todas las ayudas de aplicaciones
Windows se muestran mediante este programa. Windows dispone de otra utilidad, el programa
HC.EXE (Help Compiler) que puede adaptar el fichero .RTF donde escribirá la ayuda, a un
formato capaz de ser interpretado por el WINHELP.EXE Lo vamos viendo todo paso a paso.
Antes de comenzar a explicar como se realiza una ayuda Windows vamos a comentar el
formato de archivos RTF. Este formato posiblemente le sea familiar debido a que el control
RichTextBox puede guardar y leer ficheros en ese formato. Las siglas RTF vienen
precisamente de Rich Text Format, en castellano, Formato de Texto Enriquecido.
El Formato de Texto Enriquecido pretende ser un nexo de unión entre todos los procesadores
de texto, para poder intercambiar ficheros editados en uno u otro. De hecho, las últimas
versiones de los mas importantes procesadores de textos incluyen la posibilidad de guardar y
buscar el texto en este formato. (WP, Word)
Este formato consiste en guardar mediante caracteres ASCII plenamente legibles tanto el texto
escrito como los tipos de letra, tamaño, saltos de carro, etc. Veamos un ejemplo comparativo
del mismo texto escrito en Word, guardado en RTF y en ASCII :
Texto1
Este texto está escrito en Word. Observe que podemos poner letra negrita, letra cursiva, letra
subrayada. Podemos cambiar el color de las letras, rojo, verde, azul. Podemos cambiar el
tamaño de las letras a tamaño mas grande , mas pequeño, etc.
Fin Texto 1
Texto1
Este texto est escrito en Word. Observe que podemos poner letra negrita, letra cursiva, letra
subrayada. Podemos cambiar el color de las letras, rojo, verde, azul. Podemos cambiar el
tamaño de las letras a tamaño mas grande, mas pequeño, etc.
Fin Texto 1
Y ahora el mismo texto en formato RTF. En este formato hubo que seccionar las líneas para
poder mostrarlas en una hoja, ya que RTF utiliza líneas sin retornos de carro. Se han
seccionado las líneas terminándolas con un guión bajo y comenzando en la línea siguiente
también con un guión bajo.
Pagina: 235
{\nofwords38}{\nofchars220}{\*\company }{\vern57431}}\margl1701\margr1701\_
_margt1417\margb1417 \deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\formshade_
_ \fet0\sectd \linex0\headery709\footery709\colsx709\endnhere {\*\pnseclvl1
\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstar_
_t1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\_
_pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5
\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcl_
_tr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\_
_pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pn_
_start1\pnindent720\pnhang
{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{_
_\pntxtb (}{\pntxta )}}\pard\plain \qj\widctlpar \f5\fs20\lang1034 Texto1
\par
\par Este texto est\'e1 escrito en Word. Observe que podemos poner letra _
_{\b negrita}, letra {\i cursiva}, letra {\ul subrayada}. Podemos cambiar_
_ el color de las letras, {\cf6 rojo}, {\cf4 verde}, {\cf2 azul}. Podemos _
_cambiar el tama\'f1o de las letras a {
\fs24 tama\'f1o mas grande}, {\fs16 mas peque\'f1o}, etc.
\par
\par
\par Fin Texto 1
\par \pard \widctlpar
\par }
Como puede observar, el RTF incluye el texto escrito casi en ASCII, pero añadiendo una serie
de datos respecto al tipo de letra, codifica los acentos, las eñes, y hasta incluye, tomándolo del
ordenador, el nombre del operador que lo ha escrito. Estas informaciones también se guardan
cuando se archiva un texto en el formato propio del procesador de textos, pero lo hace en
binario, por lo que no lo podemos visualizar. El formato RTF, dentro de que mete toda esa
información adicional, lo archiva con caracteres ASCII.
La utilidad que tiene Windows para presentar las ayudas utiliza precisamente este formato
RTF. Por ello, debemos disponer de un procesador de textos que pueda guardar el texto escrito
en este formato. (Word, WP5, WP6 y otros) Los ejemplos de estos apuntes se han realizado
en Word.
Antes de decidirnos a escribir el fichero de ayuda debemos pensar muy bien lo que vamos a
poner en él. Pensemos ante todo a que personas va dirigida la aplicación, sus posibles
conocimientos de informática y de otros temas que estarán relacionados con la aplicación. Es
decir, planifiquemos la ayuda antes de comenzar a hacerla.
Escriba el texto de ayuda con Word y guárdelo en formato RTF, en cualquier directorio, pero
preferentemente en uno que no se mezcle con otros ficheros para poder localizarlo mejor.
Cree si es necesario un directorio exclusivo para la ayuda. Imaginemos que lo creamos y es el
C :\DIRAYUDA, donde guardamos el fichero de ayuda con el nombre AYUDA1.RTF
Pero al compilador HC.EXE hay que suministrarle la información para que pueda trabajar. Esa
información se la damos en un fichero que le pasaremos como parámetro, que debe tener
extensión .HPJ y que meteremos en el mismo directorio donde tengamos el fichero de ayuda
AYUDA1.RTF
Pagina: 236
Este fichero estará editado en ASCII puro. Puede editarlo con el EDIT de MS-DOS o con el
Block de Notas de Windows. Imaginemos que lo vamos a llamar FICHAYUD.HPJ y como se
dijo, se meterá en el mismo directorio donde está el fichero de ayuda. (C :\DIRAYUDA) El
nombre que decida para este fichero con extensión .HPJ será el que tenga el fichero de ayuda
(Que se obtendrá de la compilación y tendrá por extensión .HLP) Tendrá, de momento, dos
líneas.
[FILES]
AYUDA1.RTF
HC C:\DIRAYUDA\ FICHAYUD.HPJ
La compilación no suele dar problemas sobre todo en un fichero de ayuda tan simple de una
única página. Al compilar, obtenemos un fichero con el mismo nombre que el fichero .HPJ y
extensión .HLP, (FICHAYUD.HLP en nuestro caso) que lo dejará en el directorio donde
estuviera el programa HC.EXE. (Posiblemente el C :\VB\HC) Debe moverlo a otro directorio
donde no estorbe y lo podamos localizar sin problemas. Movámoslo al C :\DIRAYUDA
Vayamos a nuestra aplicación VB y abramos el menú de Herramientas | Opciones para sacar
el cuadro de Opciones. Vaya a la pestaña de Proyecto y busque el directorio y nombre del
fichero .HLP haciendo click sobre el cuadrado con tres puntos (...) que está a la derecha del
TextBox de Archivo de Ayuda. Se le abrirá un CommonDialog para buscarlo.
NOTA : Para evitar liarse con los directorios, es medida siempre prudente llevarse el
compilador de ayudas HC.EXE al directorio donde tengamos el fichero .RTF y el .HPJ.
Haga click en Aceptar y ejecute la aplicación. Pulse F1. ¡SORPRESA ! Tenemos en pantalla la
ventana de ayuda de Windows con el fichero que habíamos escrito. F1 ha invocado a
WINHELP.EXE y este programa presentó el fichero de ayuda asociado con el proyecto.
Observe que el texto se adapta a las dimensiones de la ventana. Y si supera en vertical las
dimensiones de la ventana, aparecen barras de scroll verticales. Puede de esta forma recorrer
todo el fichero de ayuda.
Sin embargo este procedimiento no sería el mas indicado para una información de ayuda
extensa. Deberemos poner varias páginas. Si lo hacemos así, al pulsar F1 siempre aparecerá
Pagina: 237
la página 1. Si aparece siempre la página 1, pongamos en esta primera página el índice de
temas, y en las páginas sucesivas cada uno de los temas. Ya veremos como acceder a cada
una de las páginas haciendo click sobre la línea del índice que contiene el título del tema
deseado. Tal y como lo hace con cualquier aplicación Windows.
Volvamos al editor Word y abramos el fichero que habíamos creado de una página, y añádale
mas páginas introduciendo avances de página manuales (Se introducen con Control + Intro)
INDICE
1 - Introducción a la aplicación
2 - Acceso a la Base de Datos
3 - Introducción de datos
4 - Lectura de datos
Introducción a la Aplicación
Introducción de datos
Lectura de datos
Ya tenemos hecho un fichero de ayuda con varias páginas. No es suficiente esto, ya que
WINHELP.EXE , pulsando F1, solamente nos mostrará la página 1. Debemos hacer algo para,
una vez en la página 1, que nos estará mostrando el índice, poder acceder a cada una de las
páginas haciendo click sobre la línea del índice que contiene el tema de interés.
Para ello debemos poner un identificador a cada una de las páginas. Este identificador debe
ser único, es decir, no pueden existir dos páginas con el mismo identificador.
Para introducir un identificador en una página, una vez que tenga el fichero de ayuda
terminado, sitúese con el cursor al comienzo del título de la primera página (después del
índice), justamente al lado de Introducción a la Aplicación . Inserte en ese punto una Nota al
pié (Abra el Menú Insertar | Nota al Pié del Word) Le aparecerá esta ventana :
Pagina: 238
Introduzca una almohadilla (#) en el TextBox Marca personal. Haga click sobre Aceptar.
INDICE
1 - Introducción a la aplicación
2 - Acceso a la Base de Datos
3 - Introducción de datos
4 - Lectura de datos
- - - - - - - - - - - - - - - - - - - - - salto de página manual - - - - - - - - - - - - - - - - - - - - - - - -
#
Introducción a la Aplicación
(Observe que estamos simulando la ventana de Word. Donde ve - - salto de página manual - -
entienda que estamos simulando lo que Vd. ve en la ventana real)
#
Introducción
#
Acceso
#
Meterdatos
#
Leerdatos
Pagina: 239
En la parte inferior puede ver los identificadores que se han asociado a cada página. ¿Qué
podemos hacer para asociar estos identificadores a las líneas correspondientes del índice ?
Muy sencillo, y es el siguiente paso que debe hacer :
INDICE
1 - Introducción a la aplicación
2 - Acceso a la Base de Datos
3 - Introducción de datos
4 - Lectura de datos
Habrá observado en las aplicaciones Windows que para seleccionar un tema hay que poner el
puntero del ratón sobre la línea deseada, que está en color verde, y en ese momento el
puntero se convierte en una mano. En nuestra aplicación ocurrirá lo mismo. Seleccione todas
las líneas que quiere asociar a cada uno de los identificadores (Una a una o todas a la vez,
dependiendo de como las tenga dispuestas), y vaya al menú Formato | Fuentes . Le
aparecerá el cuadro de diálogo. Vaya al TextBox Subrayado de ese cuadro de diálogo y elija
Doble.
Pagina: 240
del editor Word. Verá también todos los caracteres de control del documento. Si lo prefiere,
vaya al menú Herramientas | Opciones y sobre la pestaña Ver seleccione Texto oculto.
Proceda de igual forma con todas las líneas del índice. Cuando termine, guarde el documento
en formato RTF y compílelo de la forma explicada mas atrás. Posiblemente ahora le salgan
errores de compilación, pues el compilador comprueba que todos los identificadores se
corresponden en el índice y en las páginas. Si le falta algún pie de página o un salto de carro
manual le dará error. También le dará un error, mejor dicho una observación, indicándole que
hay párrafos ocultos. Es lógico, ha detectado los textos ocultos que contiene el fichero. Ni
caso. Le habrá creado el archivo .HLP y le sugiero que lo pruebe, moviéndolo al directorio
C :\DIRAYUDA y ejecutando la aplicación. Pulse F1 y le saldrá la página con el índice y las
líneas del índice en verde. Si lo ha hecho todo perfectamente, al seleccionar una y otra línea le
aparecerá la página correspondiente.
Ventanas Emergentes
INDICE
1 - Introducción a la aplicación
2 - Acceso a la Base de Datos
3 - Introducción de datos
4 - Lectura de datos
- - - - - - - - - - - - - - - - - - - - - salto de página manual - - - - - - - - - - - - - - - - - - - - - - - -
#
Introducción a la Aplicación
Observe unas palabras que están subrayadas. Imagínese que esas palabras tienen un
significado que queremos explicar con mayor detalle. Puestos en nuestro caso, queremos
explicar con mas detalle lo que es una aplicación, una Base de Datos, introducir y leer.
Pretendemos que, al hacer click sobre una de estas palabras se abra, dentro de la ventana de
ayuda, otra ventana con la explicación de lo que es esa palabra concreta. Por lo tanto,
debemos introducir esas informaciones a base de introducir nuevas páginas en el documento
#
Introducción
#
Acceso
#
Meterdatos
#
Leerdatos
Pagina: 241
Word donde editamos el fichero de ayuda. Añádalas de la misma forma insertándoles un pie
de página y el identificador deseado, de la misma forma que se explicó mas atrás. Recuerde
que el identificador debe ser único.
Una vez terminado de introducir todas las nuevas páginas, vaya a las palabras o frases que
quiere explicar con el texto de esas páginas, selecciónelas y deles el atributo de subrayado
simple (Hágalo de forma similar a cuando hizo lo del subrayado doble, pero esta vez SIMPLE)
Introduzca inmediatamente después de la palabra o frase un texto oculto con el nombre del
identificador seleccionado para la página deseada en esa palabra. Guarde el documento Word
y vuelva a compilar como anteriormente. Ejecute la aplicación y compruebe como vamos
avanzando en el tema de las ayudas de Windows.
Podemos usar la tecla F1 para acceder al índice de la ayuda de una aplicación y movernos a
lo largo de la ayuda seleccionando una u otra información. A veces resulta práctico seleccionar
directamente la ayuda correspondiente a la función de un control. Para poder hacer esto,
asociaremos una de las páginas del documento Word anterior al número que figura en la
propiedad HelpContextID. Cuando ese control tenga el foco, al pulsar F1 saldrá como página
por defecto la página asociada mediante la propiedad HelpContextID.
Para establecer esta relación vayamos al fichero con extensión .HPJ que servía para introducir
los datos al Help Compiler. En nuestro caso se llamaba FICHAYUD.HPJ y tenía por el
momento, solamente dos líneas.
[FILES]
AYUDA1.RTF
En estas dos líneas le introducíamos el nombre del fichero de ayuda [FILE]. Añadamos ahora
en otro apartado [MAP] la relación entre los identificadores de página y los números de
contexto de la propiedad HelpContextID de cada uno de los controles que la tengan activada
(valor distinto a 0). Se escribirá el nombre del identificador de página, y separado por un
espacio o un tabulador, el número de contexto :
[MAP]
Identificador1 1
Identificador2 2
Identificador3 3
Identificador4 4
En este caso, cuando un control que tiene en su propiedad HelpContextID el número 3 tiene el
foco, al pulsar F1 aparecerá como página por defecto la correspondiente a la explicación con
identificador nombre Identificador3. Lo mismo ocurrirá con el resto de los identificadores.
Puede que las ayudas que quiera aportar a cada uno de los controles sea muy breve, caso por
ejemplo de la que puede introducir en los TextBox para indicar al usuario lo que se va a hacer
con el dato concreto que se va a meter en ese TextBox. Y que esas ayudas breves sean muy
numerosas y tal vez cambiantes de un usuario a otro. Esto complicaría su fichero de ayuda
original, al que debería introducir muchas páginas nuevas. Puede editar estas pequeñas
ayudas en otro documento Word, de la misma forma que se ha descrito, y darle un
determinado nombre (AYUDA2.RTF para nuestro ejemplo) y añadirlo como otro fichero en la
lista [FILES]. Colóquelo tras el fichero anterior, pues el que lleva el índice debe ser el primero
Pagina: 242
que figure en la lista. Debe añadir la relación entre los nombres de identificador que haya
puesto en ese nuevo fichero y los números de contexto de cada control.
[FILES]
AYUDA1.RTF
AYUDA2.RTF
[MAP]
Identificador1 1
Identificador2 2
Identificador3 3
Identificador4 4
(Vea función Shell. No se olvide del 1 final, pues si no lo pone la ayuda le saldrá minimizada.
Puede poner también un 4)
Habrá observado que la ventana de ayuda tiene, en la barra de título el siguiente texto : Ayuda
de Windows. Si deseamos personalizarlo y poner el nombre de nuestra aplicación, basta con
añadir un par de líneas al fichero FICHAYUD.HPJ. Las correspondientes al apartado
[OPTIONS]. Este apartado debe ir en primer lugar del fichero, y puede llevar la información
de la barra de título y el CopyRight. Estos dos parámetros se introducen de la siguiente forma :
[OPTIONS]
TITLE= Nuestra Aplicación VB - Fichero de Ayuda
COPYRIGHT= Nombre del Autor(a)
[FILES]
AYUDA1.RTF
AYUDA2.RTF
[MAP]
Identificador1 1
Identificador2 2
Identificador3 3
Pagina: 243
Identificador4 4
Para introducirlo por el primer procedimiento, inserte el gráfico en el texto Word y proceda
como siempre.
Para introducirlo por el segundo método, tiene tres posibilidades : Introducir el gráfico en el
centro de la ventana de ayuda, introducirlo a la izquierda con texto a su derecha o a la derecha
con texto a su izquierda.
Se han resaltado en negrita las tres opciones. Recuerde la llaves donde se encierra la posición
y el nombre (y path) del gráfico.
Debe tener cuidado al introducir gráficos, ya que el compilador (HC.EXE) trabaja en DOS, y
me da la impresión de que no utiliza mas que los primeros 640 Ks. de memoria. Con un gráfico
de 470 Ks. usado en la preparación de estos apuntes fue incapaz de compilarlo, dando error
de memoria insuficiente. (Y no es que el Ordenador no tenga RAM suficiente)
Historial
La Ayuda de Windows nos permite recordar todas las páginas sobre las que se hizo una
consulta. Esto puede ser muy útil, pues tenemos muy accesible los temas que hemos
consultado, para poder realizar una nueva lectura de los mismos si fuese necesario.
Para obtener la ventana de historial, basta con hacer click en la barra de menú de la ventana
de Ayuda en Opciones | Mostrar Ventana de Historial.
Pero para que se pueda mostrar el historial, es necesario darle un nombre a las páginas, y
será ese nombre el que figure en la ventana de historial. Ese nombre es distinto del
identificador de página, aunque no hay ningún problema porque sea el mismo. Ponga como
nombre de la página una palabra que identifique esa página de una forma única.
Para poner el nombre a la página, vaya al comienzo de cada página e introduzca una nota al
pié de la misma forma que cuando ponía el identificador. En este caso el símbolo a introducir
Pagina: 244
en la Marca personal es el $. Proceda a introducir el nombre en la parte de abajo de la pantalla
de Word.
Palabras Clave
La Ayuda de Windows nos permite accede a una página usando como criterio de búsqueda
ciertas palabras que ponemos como clave. Por ejemplo, si queremos que aparezca nuestra
página de ejemplo que habla de Acceso a la Base de Datos, cuando el usuario busca una de
las siguientes palabras : Tablas, Base, Registro, y a la de Lectura de Datos cuando busque
Obtener, Leer y Visualizar
Volvamos al editor Word, a las dos páginas nombradas y al lado de las notas al pié anteriores,
introduzca otra, esta con la Marca personal K. En la parte inferior de la pantalla, donde pone el
nombre de la nota al pie, ponga introduzca las palabras clave para cada una de ellas,
separadas con una coma. Salve el fichero RTF y vuelva a compilar. Ejecute la aplicación y
saque la Ayuda. Observará que el botón Búsqueda de la ventana de ayuda está habilitado.
Haga click en este botón y verá que esas palabras ya figuran en la lista.
Lo mismo que hacíamos con las palabras, bien las del índice, a las que con un subrayado
doble les introducíamos un enlace a una página, o con cualquier palabra o frase de una
página, que mediante un subrayado simple les introducíamos un enlace a una ventana
emergente, lo mismo podemos hacer con la referencia a un gráfico. (Vea un poco mas arriba,
las referencias a los gráficos del tipo {bmc c:\dirayuda\grafico1.bmp} ). Si seleccionamos esa
referencia y le ponemos el atributo de doble subrayado, al acercar el puntero del ratón a ese
gráfico (en la ayuda) nos mostrará una mano, y haciendo click sobre el gráfico sacará la
página correspondiente. Si le ponemos el atributo de subrayado simple, nos sacará una
ventana emergente. Eso sí, en cualquiera de los dos casos, deberemos poner, a continuación
de la referencia al gráfico, con texto invisible, el indicador de página que especifique la página
o ventana emergente que queremos mostrar.
Páginas en secuencia
Si tenemos una ayuda muy larga y la queremos leer toda, con lo que sabemos deberíamos ir
al índice y desde allí acceder a la página 1, leerla, volver al índice, acceder a la página 2,
leerla, volver al índice ....
Para evitar este proceso, y acceder secuencialmente a cada una de las páginas, podemos
asignar a cada una de las páginas un código de secuencia, que podrá estar formado por
caracteres alfanuméricos. Este código de secuencia será el que marque el orden de aparición
de las páginas. Pero el orden de aparición será según el código ASCII de los caracteres que
formen ese código, comenzando por la izquierda. Por lo tanto puede ocurrirle la paradoja de
que aparezca primero la página 100 que la 65. Es decir, si los códigos están formados por
números aparecerán primero todas las páginas que comiencen por 1, aunque el valor
numérico de una de ellas sea superior a otra que comience por 2, 3, 4, ...
Para asignar este código de secuencia deberemos introducir otra nota al pié para cada página,
en este caso con la marca personal + (signo mas). También deberemos indicarle al WinHelp
que deseamos sacar los botones (<<) y (>>) para desplazarnos por las páginas. Esto se
consigue añadiendo una nueva sección al archivo .HPJ que se denomina [CONFIG] y le
introduciremos en esta sección la expresión BrowseButtons()
[OPTIONS]
TITLE= Nuestra Aplicación VB - Fichero de Ayuda
COPYRIGHT= Nombre del Autor(a)
[FILES]
Pagina: 245
AYUDA1.RTF
AYUDA2.RTF
[MAP]
Identificador1 1
Identificador2 2
Identificador3 3
Identificador4 4
[CONFIG]
BrowseButtons()
Encabezado de páginas
Habrá observado en la ayuda de Visual basic que una o dos líneas en la parte superior de la
ventana de ayuda se conservan allí continuamente aunque nos desplacemos hacia abajo
mediante los cursores de desplazamiento. Esas líneas son el Encabezado de página. Para
conseguir esto en nuestra ayuda deberemos escribir las líneas que queramos que se
conserven como encabezado de página al principio de cada página, seleccionarlas con el
cursor del ratón y abrir el menú Formato | Párrafo (Se supone que está utilizando el
procesador de texto Microsoft Word) donde le aparecerá un cuadro de diálogo con dos
solapas, Sangría y Espacio y Presentación. Elija Presentación y dentro de esta solapa,
active la casilla Conservar con el Siguiente. Las líneas que hubiera seleccionado se le
conservarán como Encabezado de página.
VENTANAS MULTIPLES
Con frecuencia es útil emplear varias ventanas para mostrar la información de una aplicación.
El ejemplo que tenemos mas a mano es el de la Ayuda de Visual Basic. Cuando tenemos
seleccionada la ayuda de un control, se pueden observar al menos dos palabras que nos
llevan a una segunda ventana: Propiedades y Eventos. Cuando elegimos una de estas
informaciones aparece una segunda ventana que nos muestra la información pedida, sin
perder la información que tenemos en la primera ventana.
Pagina: 246
Para poder presentar esta segunda ventana es necesario primero definirla. Para ello volvamos
a nuestro fichero .HPJ y le añadiremos un nuevo apartado : WINDOWS, donde introduciremos
el nombre de la nueva ventana, el título de la misma (El título que aparecerá en su parte
superior), y, entre paréntesis, su posición y dimensiones.
El fichero .HPJ quedará de la siguiente forma, tras introducirle dos nuevas ventanas :
[OPTIONS]
TITLE= Nuestra Aplicación VB - Fichero de Ayuda
COPYRIGHT= Nombre del Autor(a)
[FILES]
AYUDA1.RTF
AYUDA2.RTF
[MAP]
Identificador1 1
Identificador2 2
Identificador3 3
Identificador4 4
[CONFIG]
BrowseButtons()
[WINDOWS]
Ventana2 = “Titulo de esta Ventana”, (PosiciónX, PosiciónY, DimensiónX, DimensiónY)
Ventana3 = “Titulo de esta Ventana”, (PosiciónX, PosiciónY, DimensiónX, DimensiónY)
El Objeto App
Introducimos aquí un nuevo objeto Visual Basic. El objeto App es un objeto global al que se
accede con la palabra clave App. (No se líe. El objeto App no es ni mas ni menos que un
conjunto de datos acerca de la aplicación) Determina o especifica información sobre el título
de la aplicación, la ruta de acceso de su archivo ejecutable y los archivos de Ayuda, y si está
ejecutándose una instancia anterior de la aplicación. Este objeto tiene solamente propiedades.
No tiene ni Eventos ni Métodos. Una de sus propiedades es HelpFile, propiedad que es de
lectura y escritura. Es decir, podemos obtener el nombre del fichero de ayuda de una
aplicación consultando el valor de esa propiedad del Objeto App. En el ejemplo siguiente
introducimos el nombre del fichero de ayuda en el Label1
Label1.caption= App.HelpFile
En este capítulo hemos citado como compilador del fichero de ayuda al programa HC.EXE que
habitualmente se encuentra en el directorio C :\ . . . . \ VB\HC. Este compilador trabaja
perfectamente con ficheros .RTF creados con las versiones primeras del Word.
Pagina: 247
Si Ud. realiza los ficheros .RTF con el Word para Windows95 (Word 6.0), no habrá tenido
ningún problema con lo descrito anteriormente. Si tiene Word de office97 (W97) habrá
observado que al compilar la ayuda con el HC.EXE le sale un error. No se preocupe. Es que el
fichero RTF creado por W97 es distinto del creado por W95, lo cual, aparte de dar una idea de
como se trabajan los temas de compatibilidad entre procesadores que deberían ser
compatibles, nos obliga a buscar otro compilador de ayudas.
No lo intente con el HCP.EXE. Tampoco vale. Busque por Internet un fichero llamado
HCW.EXE, compilador que tiene además la ventaja de que trabaja en Windows. Usa el mismo
fichero .HPJ y acepta los ficheros .RTF creados con W95 y W97
El aspecto de este compilador de ayudas es el siguiente :
Aparte de este compilador, existen otros que funcionan de forma similar. No vamos a explicar
cada uno de los compiladores que podamos encontrar, que como se dijo hay bastantes y ( creo
que) shareware. Lo importante es que todo lo dicho respecto a la edición de los ficheros :RTF
y .HPJ sigue siendo válida para estos compiladores. Existen algunos compiladores que
también crean el fichero .HPJ. Es comprensible no intentar examinar uno a uno en esta Guía
del Estudiante.
Pagina: 248
El Objeto App
Este objeto, como se dijo mas atrás, es el objeto Visual Basic que contiene diversas
informaciones acerca de la Aplicación.
Estas informaciones son las Propiedades del objeto App. Este objeto no tiene Métodos ni
Eventos.
Comments (Propiedad)
Devuelve o establece una cadena que contiene comentarios sobre la aplicación en ejecución.
Es de sólo lectura en tiempo de ejecución.
Sintaxis App.Comments
CompanyName (Propiedad)
Devuelve o establece un valor de tipo String que contiene el nombre de la empresa o del
creador de la aplicación en ejecución. Es de sólo lectura en tiempo de ejecución.
Sintaxis App.CompanyName
EXEName (Propiedad)
Devuelve el nombre raíz (sin la extensión) del archivo ejecutable que se está ejecutando
actualmente. Si se utiliza en el entorno de desarrollo, devuelve el nombre del proyecto.
Sintaxis App.EXEName
Esta propiedad se establece bien en el cuadro de Opciones, bien al guardar el archivo .EXE
FileDescription (Propiedad)
Devuelve o establece un valor de tipo String que contiene información de los archivo de la
aplicación en ejecución. Es de sólo lectura en tiempo de ejecución.
Sintaxis App.FileDescription
HelpFile (Propiedad)
Ya comentada mas atrás. Especifica el nombre (con su Path) del fichero de ayuda. Se
introduce en tiempo de diseño en el cuadro de Opciones. Puede cambiarse en tiempo de
ejecución.
Pagina: 249
hInstance (Propiedad)
Sintaxis App.hInstance
Para aplicaciones hechas en 16 bits, el número devuelto es un integer. Para las hechas en 32
bits, un Long. Cuando se trabaja en un proyecto dentro del entorno de desarrollo de Visual
Basic, la propiedad hInstance devuelve el controlador de la instancia de Visual Basic.
LegalCopyright (Propiedad)
Devuelve o establece un valor de tipo String que contiene información de derechos de autor
sobre la aplicación en ejecución. Es de sólo lectura en tiempo de ejecución.
Sintaxis App.LegalCopyright
LegalTrademarks (Propiedad)
Devuelve o establece un valor de tipo String que contiene información de marca registrada
sobre la aplicación en ejecución. Es de sólo lectura en tiempo de ejecución.
Sintaxis App.LegalTrademarks
Establezca esta propiedad en tiempo de diseño usando el cuadro de diálogo Opciones de EXE.
Path (Propiedad)
Especifica la ruta de acceso del archivo .VBP de proyecto cuando se ejecuta la aplicación
desde el entorno de desarrollo o la ruta de acceso del archivo .EXE cuando se ejecuta la
aplicación como un archivo ejecutable.
Esta propiedad es sumamente útil. Cuando se realiza una aplicación, no es prudente obligar al
usuario a meterla dentro de un determinado directorio impuesto por el programador. Si no es
así, no sabremos en qué directorio está el ejecutable, y es muy conveniente saberlo, sobre
todo cuando se utilizan ficheros auxiliares de inicialización, que deberían estar en el mismo
directorio de la aplicación. Si queremos abrir el fichero MiAplicacion.INI que estará
obligatoriamente en el mismo directorio de la aplicación (aunque no conocemos su nombre),
solamente tenemos que poner la línea de código : Open App.Path & “\MiAplicacion.INI” For
Input as # 1, sin importarnos cual es el nombre real de ese directorio.
PrevInstance (Propiedad)
Devuelve un valor que indica si hay ya en ejecución una instancia anterior de una aplicación.
Pagina: 250
Sintaxis App.PrevInstance
ProductName (Propiedad)
Sintaxis App.ProductName
Establezca esta propiedad en tiempo de diseño usando el cuadro de diálogo Opciones de EXE.
Revision (Propiedad)
Sintaxis App.Revision
El valor de la propiedad Revision está dentro del rango 0 a 9999.Esta propiedad proporciona
información sobre la versión de la aplicación en ejecución. Esta propiedad se establece en
tiempo de diseño usando el cuadro de diálogo Opciones de EXE.
StartMode (Propiedad)
Devuelve o establece un valor que determina si una aplicación se inicia como proyecto
independiente o como servidor de automatización OLE. De sólo lectura en tiempo de
ejecución.
TaskVisible (Propiedad)
Pagina: 251
Title (Propiedad)
Valor será una expresión de cadena que especifica el título de la aplicación. La longitud
máxima de valor es 40 caracteres.
Esta propiedad está disponible en tiempo de diseño en el cuadro de diálogo del comando
Crear EXE del menú Archivo.
Todos estos datos figuran en el archivo de proyecto (.VBP). Puede verse editándolo con el
Block de Notas de Windows, e incluso pueden modificarse estas propiedades directamente
sobre ese archivo.
Pagina: 252
(CommandButton_Click, Form_Load, ...). Un control puede tener por lo tanto, muchos
procedimientos asociados. Uno a cada uno de sus eventos.
Si queremos realizar una determinada tarea en un programa, y esta tarea se repite muchas
veces en ese programa, podemos, por ejemplo, repetir el código tantas veces como sea
necesario en los puntos del programa que así lo pidan. Esto nos llevaría a escribir líneas y
líneas repetidas en nuestras aplicaciones, con el consiguiente incremento de trabajo y del
volumen de la aplicación.
Podemos hacer otra cosa mas práctica y elegante. Escribir ese código una sola vez, creando
con él un Procedimiento. Este Procedimiento tendrá un nombre, y cada vez que queramos que
se ejecute ese código bastará con nombrar por ese nombre al Procedimiento.
En esta ventana debe teclear el nombre que quiere dar al Procedimiento. En tipo debe elegir
Procedimiento (Veremos mas adelante la Función) y en el Ambito debe elegir Public o Private
dependiendo del ámbito que quiera darle :
NombreProcedimiento
Modulo1.NombreProcedimiento
Si se ha insertado en un Formulario, desde ese Formulario basta con citarle por su nombre.
Desde otro Formulario o Módulo, hay que citarlo mediante el nombre del Formulario donde
está insertado, seguido del nombre del procedimiento, separados por un punto.
Private. Si elige este ámbito, sólo se podrá acceder a ese Procedimiento desde el Formulario
o Módulo donde se haya insertado.
La caja de opción (Check) que pone Todas las variables locales como estáticas nos va a
poner todas las variables declaradas dentro del procedimiento como estáticas (No ponen a
Pagina: 253
cero o nulo su valor cuando salimos y volvemos a entrar en ese procedimiento). Puede
ahorrarnos un poco de código.
Funciones
Una función es una forma especial de realizar un procedimiento. En realidad es un
procedimiento al que le pasamos una o varios parámetros con los que realizará una operación
(cualquier operación, no tiene porqué ser matemática) y obtendrá un resultado de esos
parámetros. Este resultado puede leerse desde otra parte de la aplicación.
Para insertar una Función se procede de igual forma que para un Procedimiento, pero
marcando el botón de opción Tipo Procedimiento en la caja de diálogo de la figura anterior.
Para llamar a una Función son válidos igualmente los criterios expuestos para los
Procedimientos.
Se dijo anteriormente que a una Función se le pasan uno o varios parámetros con los que va a
realizar alguna operación. Al declarar la Función, hay que decirle el nombre de los parámetros
que se le van a pasar, de que tipo son (String, Integer, Boolean, ...) y cómo se le van a pasar
(ByVal, ByRef, ParamArray). Esto hay que introducírselo en la propia declaración
End Function
La función MiFuncion sabe que debe recibir dos parámetros, y que el primero será una cadena
de caracteres y el segundo un integer. Los nombres Variable1 y Variable2 son los nombres que
usa la Función internamente. No tienen porqué coincidir con los nombres que tengan las
variables que contienen esos valores en otras partes del programa.
Pagina: 254
Una función siempre da un resultado. Este resultado se le puede sacar mediante una variable
o tomarlo directamente de la función.
Imaginemos que lo que va a hacer la función de este ejemplo es tomar una cadena de
caracteres (Variable1) y obtener de ella otra cadena con los caracteres iniciales de la primera,
tantos caracteres como nos indique la segunda variable (Variable2)
Ya se habrá dado cuenta de que debemos emplear Left para obtener los caracteres iniciales
de una cadena. Nuestra función quedará de la forma :
Donde resultado debe ser una variable declarada de tal forma que el ámbito de esa variable
la haga visible en esta función y el la parte del programa donde se va a usar. Para llamar a la
función, basta con citarla por su nombre y luego tomar el valor de la variable resultado.
Esta es una forma de hacerlo. Sin embargo existe otra mas elegante :
(Observe que hemos añadido la expresión As String al final de la declaración. Esto quiere
significa que le estamos diciendo a la función que su resultado es un String, y que además
puede obtenerse el resultado de esta función usando solamente el nombre de la función)
Pruebe esto con una pequeña aplicación. En un formulario, ponga un TextBox (Text1) donde
va a introducir la cadena original, otro TextBox donde va a introducir el número de caracteres a
tomar, y un Label (Label1) donde va a ver el resultado. Ponga un Botón de comando
(Command1) donde llamará a la función. Inserte una función (MiFuncion) en ese formulario :
Puede pensar que para hacer esta cosa tan elemental no merece la pena hacer una función.
Efectivamente. Bastaría con poner en el botón Command1_Click el siguiente código :
Pagina: 255
y funcionaría igual. Lógicamente, una función debe introducirse cuando vaya a realizar un
código un poco mas complejo, y sobre todo, cuando se va a repetir en muchos procedimientos.
Hemos visto que los parámetros de la función pueden pasarse Por Valor (ByVal), caso del
ejemplo anterior, y Por Referencia (ByRef). ¿Cuál es la diferencia? La diferencia es que si le
pasa un valor por valor (ByVal) ese valor, aunque lo cambie la función internamente, ese
cambio no se manifiesta fuera de ella. Si se pasa por referencia (ByRef), y la función cambia
el valor de esa variable, ese cambio se mantiene fuera de la función.
Veamos esto de una forma muy sencilla : Vamos a hacer una función que multiplica dos
números. Pero dentro de la función vamos a cambiar uno de esos números, sumándole 2. Una
vez realizada la operación presentamos el valor de los dos factores en dos Label a ver si ha
cambiado. Insertemos dos funciones, MultiplicaA y MultiplicaB. En MultiplicaA le introducimos
los datos Por Valor y en MultiplicaB por Referencia.
Las dos funciones son idénticas, excepto en la forma de pasarle los parámetros. Pongamos un
Botón de Comando para multiplicarlo con MultiplicaA y otro con MultiplicaB. Al final del
procedimiento click de cada uno de ellos presentamos las dos variables que se pasan a la
función en sendos Label. Cuando se usa MultiplicaA el valor de X1 (pepe en el
CommandButton) se mantiene. En MultiplicaB cambia al valor pepe+2
Tras esto, se pone en Label2 el valor pepe + 2 (se mantienen el cambio realizado en la
función MultiplicaB x1 = x1 + 2
No queda ahí la cosa. Un valor puede pasarse también por ParamArray. En principio parece
que esto ya es para nota. No es para tanto.
Vamos a ver que sucede cuando queremos realizar una suma. La suma de los importes de
varios productos de un ticket de compra. En principio no sabemos cuantos productos va a
Pagina: 256
comprar un cliente, por lo tanto no sabemos a priori cuantos parámetros le tenemos que
pasar. Para pode pasar un número indeterminado de parámetros se los pasamos como
PamArray :
Se pueden pasar uno o mas parámetros como Optional. Las condiciones para los parámetros
opcionales es que ocupen los últimos lugares y que sean del tipo Variant
Los parámetros los tomamos de tres TextBox (TB1, TB2 y TB3, siendo este último el que es
opcional. En un botón de comando ponemos este código :
La forma natural de salir de una función es cuando se ejecuta todo su código. Al final siempre
tiene la sentencia End Function
Pagina: 257
Se puede salir de una función antes de que termine. Por ejemplo, si se cumple una
determinada condición, se puede salir de la función mediante la sentencia Exit Function
LA FUNCION Main ()
Todo lo que hemos visto hasta ahora de funciones se basa en declarar una función, ponerle un
nombre, declarar los parámetros que se han de pasar y escribir el código correspondiente.
Windows dispone de una serie de funciones preescritas (en código máquina) que están ahí
para que las aproveche cualquier programa. Estas funciones se llaman API (Interfaz para
Programación de Aplicaciones) y están en las innumerables DLLs que tiene Windows. Dado
que ya están escritas, y que tienen un código que permite hacer cosas que sería imposible o al
menos muy complicado hacerlas con Visual Basic, es muy interesante utilizarlas.
Precaución : Las APIs son distintas para 16 y 32 bits. Cuando estemos desarrollando
aplicaciones para poder compilarlas en 16 o 32 bits, debe tomarse la precaución de usar
la Compilación Condicional que se verá mas adelante. Existe otro inconveniente. Hay
APIs para 32 bits que no tienen su homónimo en 16 bits.
Dado que estos apuntes tienen logicamente un alcance limitado, y el tema de APIs es enorme,
se recomienda recurrir a un libro específico de APIs. Este no puede ser otro que el siguiente :
Para usar una función API lo primeros que tenemos que hacer es declararla en nuestra
aplicación. La declaración debe hacerse en la sección de declaraciones de un formulario o
módulo. En la declaración debe figurar la librería donde está escrita esa función, y el número y
orden de los parámetros que hay que pasarle. Una declaración sencilla podría ser la de la
función API Sleep :
Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
En esta declaración lo que le estamos diciendo es que, en la librería kernel32 está escrita una
función llamada Sleep (Es el nombre que figura entre comillas en la declaración) y que le
tenemos que pasar un parámetro, concretamente el tiempo que queremos que se pare la
aplicación, expresado en milisegundos. Nos dice la declaración que el parámetro se le pasa
Por Valor (ByVal) y que ese dato debe ser un Long, es decir, si se lo pasamos como una
variable, esa variable debe ser del tipo Long. Una vez declarada esta función, en la sección de
declaraciones de un módulo, podremos acceder a ella en cualquier parte de la aplicación
usando una línea de código como esta :
Sleep (500) y la aplicación se detendrá media segundo cuando llegue a esa línea
ó Sleep (tiempo) donde tiempo es una variable tipo Long que contiene el tiempo (en
milisegundos) que queremos detener el programa.
Esta API es muy sencilla. Por eso comenzamos por ella. La hay mas complicadas. Por
ejemplo, la que obtiene el número de serie del disco duro : GetVolumeInformation
Pagina: 258
_ As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, _
lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal _
nFileSystemNameSize As Long) As Long
Aquí ya se ha complicado un poco la cosa. Pero tras un análisis detenido veremos que esa
complicación es sólo aparente.
En primer lugar vemos que la librería donde está esta función es, como en la función Sleep, el
kernel32 (Kernel = Núcleo). Esto quiere decir que la librería kernel32 contiene varias
funciones. Pero ¿qué es la librería kernel32 ? Ni mas ni menos que una DLL llamada
kernel32.dll que puede encontrar en el directorio C :\WINDOWS\SYSTEM.
En tercer lugar, vemos que la declaración de esta función termina con la expresión As Long.
Esto significa que esta función devuelve un dato, y es concretamente, un Long. Por lo tanto,
habrá que obtener ese dato que nos devuelve, lo utilicemos o no. Concretamente, esta función
devuelve un 0 si ha existido algún problema para obtener el número del disco, o un número
distinto de 0 si lo ha obtenido. Las demás constantes deberemos declararlas en el
procedimiento donde vamos a usar la función (o en otro lugar, si así lo exige el ámbito que les
queramos dar, pero generalmente, en el mismo procedimiento), e invocar la función pasándole
los parámetros correctos :
En el ejercicio realizado para hacer estos apuntes, este código se metió en el procedimiento
click de un botón de comando.
‘Declaramos las variables. Observe que no tienen por qué tener el mismo nombre que en la
‘declaración de la función.
Estas variables son las que se van a pasar como parámetros a la función. La correspondencia
entre el nombre del parámetro y cada una de las variables es la siguiente :
Pagina: 259
If res = 0 Then ' ha ocurrido un error y no puede leer el VOL
MsgBox ("Ha ocurrido un error al intentar arrancar la aplicación.")
Else 'lo ha leído perfectamente
VOLUM = Trim(Str(serialnum)) 'convertimos un Long en String
'si tiene menos de 12 caracteres, le añadimos los ceros necesarios por la izquierda
If Len(VOLUM) < 12 Then VOLUM = String(12 - Len(VOLUM), "0") & VOLUM
' lo presentamos en el TextBox TBVOL
TBVOL.Text = VOLUM
End If
Podemos presentar en otros TextBox o Label el resto de los parámetros que nos devolverán un
dato. Salen, para el PC del autor de estos apuntes :
volbuf = MS-DOS_6
componentlength = 255
sysflags = 16390
sysname = FAT
Vemos que no es tan complicado operar con funciones API. Esta última que hemos visto
puede tener utilidad para comprobar si el ordenador en el que se está ejecutando la aplicación
es el mismo para el que se preparó esa aplicación. Pese a que es algo complicada, hemos
podido con ella. Para trabajar con APIs solamente es necesario conocer la sintaxis exacta
de la declaración. Pero parece en principio un poco difícil, a sabiendas de que deben existir
varios cientos de APIs. SOLUCION : Que VB nos aporte un chuleta con todas las
declaraciones.
Esta chuleta no es otro que el Visor de Texto API (API Text Wiever en Inglés). Este es un
programa que se distribuye con Visual Basic y que se instala al tiempo que este, formando
parte del mismo grupo de programas. Haciendo clic en su icono aparece esta ventana :
Haciendo Click sobre la palabra Archivo de la Barra de Menú, aparecen unos ficheros que
contienen las declaraciones de las funciones API :
Pagina: 260
Win32Api.txt
Winmmsys.txt
Estos dos ficheros son los que suministra Microsoft con VB4. (Para la versión de 32 bits) El
primero contiene las declaraciones de las funciones API no relacionadas con el tema
multimedia. El segundo contiene las declaraciones de las API relacionadas con este tema de
multimedia.
Si ha adquirido el libro de Appleman puede tener otro fichero : Api32.txt. El autor de este libro
asegura que es mucho mas completo que el fichero que entrega Microsoft. De hecho contiene
bastantes mas declaraciones.
Estos ficheros están en ASCII. Puede convertirlos a una base de datos ACCESS y el acceso
será un poco mas rápido. No olvide que también le ocupará un sitio respetable en el disco duro
de su ordenador.
Para obtener una o varias declaraciones, seleccione las funciones en la ventana de arriba del
visor, haga click en Agregar y esa función le pasará para la ventana de abajo. Una vez que
tenga en esa ventana todas las funciones que necesita, haga click en el botón Copiar y las
declaraciones completas le pasarán al portapapeles.
Una vez que ya sabemos donde se pueden copiar las declaraciones de las APIs, veamos una
que nos permitirá obtener la hora desde el sistema operativo :
Ahora nos surge una duda ¿Qué es SYSTEMTIME ? Es una variable que hay que declararla
con la instrucción Type, igual que hacíamos con las variables con varios campos en los
ficheros tipo Random. Repase este capítulo si no lo tiene claro.
Para poder declarar esta variable, podemos obtener su declaración del mismo Visor de Texto
API
Para ello, en la ventana Tipo API en vez de figurar Declaraciones debe poner Tipos. Busque
esta opción desplegando la ventana con la flecha que tiene a la derecha. Busque ahora la
variable cuya declaración quiere conocer. Repitiendo el proceso anterior, se llevará en el
portapapeles la declaración de la variable :
Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Haga un pequeño ejercicio para obtener la fecha y hora usando un API :
Para ello debemos introducir un módulo donde definiremos la variable SYSTEMTIME y donde
podemos declarar la función GetSystemTime :
Pagina: 261
Módulo 1 Declaraciones
_____________
Option Explicit
Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Ahora en un Formulario, ponemos 8 TextBox (uno para cada datos) y un botón de comando,
donde ponemos el siguiente código :
Este programa nos mostrará la hora (hasta milésimas de segundo), la fecha y el día de la
semana.
Este capítulo no ha hecho mas que abrir una pequeña ventana al mundo de las APIs. Diríamos
con mas propiedad que solamente ha rozado un capítulo tan extenso. Pero unos apuntes no
pueden llegar nunca a exponer un tema tan extenso. Cómprese el libro citado anteriormente
(cuesta unas 10.000 Pts. Pero serán las 10.000 Pts. mejor gastadas por un programador de
VB) y sobre todo, practique. Le recomiendo lo que otras veces : paciencia. Al final salen..
Pagina: 262
Visual Basic - Guía del Estudiante Cap. 16
(Este Capítulo fue escrito por el compañero Juanjo Boza. Gracias, Juanjo)
OLE
16.1. Introducción.
Hasta ahora hemos visto varias formas de comunicar aplicaciones en Windows (el
portapapeles, SendKeys y DDE), todas ellas nos permiten alguna funcionalidad extra entre
aplicaciones, pero se quedan bastante cortas frente a lo que puede hacer OLE (Object Linking
and Embedding: Vinculación e incrustación de objetos).
OLE no es algo particular de VB, sino de Windows, por lo tanto se puede hacer entre dos
aplicaciones que no estén hechas en VB (Delphi , Visual C++, etc.), así como por supuesto
Visual Basic. Lo que nos va a permitir VB es usar las capacidades OLE de Windows, e incluso
crear aplicaciones OLE que ofrezcan servicios a otras: una calculadora realizada en VB podría
Pagina: 263
ser dotada de características OLE, para que se pudieran hacer operaciones matemáticas
desde otro programa que no posea estas características.
Compartir información entre aplicaciones distintas, que por tanto tendrán sus documentos
en formatos distintos. Incrustaremos o vincularemos objetos de un tipo en objetos de otro
(desde Word por ejemplo se puede hacer desde el menú Insertar, Objeto, con lo que nos
aparece una pantalla para seleccionar el tipo de objeto). Esto es bastante útil, ya que con
los antiguos programas en MS-DOS compartir datos entre un programa de contabilidad y
una hoja de cálculo o una base de datos era muy complejo, ya que tenían que tener
formatos compatibles, o bien hacer un programa que convirtiera datos de un formato a otro.
Usar características de otras aplicaciones para que no debamos programarlas en la nuestra
otra vez (automatización OLE).
Es importante tener en cuenta que con OLE lo que hacemos es usar capacidades de otras
aplicaciones, por lo tanto si nuestra aplicación quiere usar el diccionario de Word, sólo
funcionará en los ordenadores donde esté instalado Word, además para poder usar OLE la
aplicación debe estar preparada para ello, es decir podemos usar OLE con Word porque Word
está hecho pensado para ofrecer servicios OLE.
Además OLE es mucho más robusto que DDE a la hora de producirse errores: si usamos una
característica de Word, OLE se ocupa de abrir Word si no lo está, realizar las operaciones que
sean y al final cerrar Word si no se está usando para nada más. Como contrapartida OLE tiene
como principales inconvenientes que gasta bastantes recursos del sistema, ya que para
realizar una sola operación con Word, se debe cargar completo, no se puede cargar sólo una
parte (la que nos haga falta) y que las aplicaciones que ofrecen servicios OLE pueden tener
errores que no dependen de nuestro programa.
16.2. Terminología con OLE.
La vinculación e incrustación de objetos (OLE) es una tecnología que permite que los
programadores de aplicaciones basadas en Windows creen aplicaciones que puedan presentar
datos de muchas diferentes aplicaciones y permite que los usuarios editen dichos datos desde
la aplicación con la que fueron creados. En algunos casos, el usuario puede incluso editar los
datos desde dentro de la aplicación Visual Basic. Los siguientes términos y conceptos son
fundamentales para comprender el uso de OLE en Visual Basic:
Objetos
Un objeto hace referencia a una unidad discreta de datos suministrados por una aplicación.
Una aplicación puede ofrecer muchos tipos de objetos. Por ejemplo, una aplicación de hoja de
cálculo puede ofrecer una hoja de trabajo, una hoja de macro, un gráfico, una celda o un rango
de celdas, todos como tipos diferentes de objetos.
Automatización OLE
Algunas aplicaciones proporcionan objetos que aceptan automatización OLE. Visual Basic se
puede usar para manipular los datos de estos objetos desde el programa. Algunos objetos que
aceptan automatización OLE también aceptan vinculación e incrustación.
Clase
La aplicación que proporciona los datos del objeto y el tipo de datos que el objeto contiene
determina la clase del objeto. La lista de los nombres de las clases disponibles por la
aplicación se puede obtener seleccionando la propiedad Class en la ventana Propiedades y
haciendo clic en el botón "Propiedades".
Aplicación contenedora
Una aplicación que recibe y presenta los datos de un objeto es una aplicación contenedora.
Por ejemplo, una aplicación Visual Basic que use un control contenedor OLE para incrustar o
vincular datos de otra aplicación es una aplicación contenedora.
Pagina: 264
Objetos vinculados
Los datos asociados con un objeto vinculado están almacenados por la aplicación que
suministra el objeto. La aplicación sólo almacena referencias de vinculación que presentan
una instantánea de los datos origen.
Cuando se vincula un objeto, cualquier aplicación que contenga un vínculo con dicho objeto
puede tener acceso a los datos del objeto y modificarlos. Por ejemplo, si se vincula un archivo
de texto con una aplicación Visual Basic, el archivo de texto puede ser modificado por
cualquier aplicación vinculada con él. La versión modificada aparece en todos los documentos
vinculados con este archivo de texto. En la aplicación Visual Basic, el control contenedor OLE
se usa para crear el objeto vinculado.
Objetos incrustados
Cuando se crea un objeto incrustado, todos los datos asociados con el objeto están contenidos
en el objeto. Por ejemplo, si una hoja de cálculo fuera un objeto incrustado, todos los datos
asociados con las celdas estarían contenidos en el control contenedor OLE o en el objeto
insertable, incluyendo las fórmulas necesarias. El nombre de la aplicación que ha creado el
objeto se guarda de forma conjunta con los datos.
Si el usuario selecciona el objeto incrustado mientras trabaja con la aplicación Visual Basic, la
aplicación de hoja de cálculo se inicia automáticamente de forma que el usuario pueda editar
sus celdas. Cuando un objeto se incrusta en una aplicación, ninguna otra aplicación tiene
acceso a los datos del objeto incrustado. Los objetos incrustados se pueden usar cuando se
quiera que la aplicación mantenga datos que han sido producidos y mantenidos por otra
aplicación.
Servidor OLE
Una aplicación que proporciona sus objetos a otras aplicaciones. Estos objetos se pueden
utilizar en aplicaciones de Visual Basic. También se llama servidor de automatización OLE.
Verbo
Especifica una acción que puede realizarse sobre un objeto, como editar.
Pagina: 265
Fig. 16-1. Insertar un objeto OLE en Word.
mostrar como icono (ver figura 16-2), en cuyo caso lo que nos aparecerá en nuestro
documento será un icono, sobre el que si hacemos doble clic se abre la aplicación
correspondiente (en nuestro caso PaintBrush con la imagen que hayamos elegido).
Vincular (ver figura 16-3), con OLE los objetos pueden ser de dos tipos,
incrustados o vinculados; incrustados (si no marcamos la casilla de Vincular)
significa que el objeto OLE aparece dentro de nuestra aplicación (de nuestro
documento de Word, o en el futuro dentro de nuestro formulario de VB), y se
pueden hacer modificaciones del objeto ahí mismo (se le llama edición in-situ)
haciendo doble clic sobre el objeto, así este se activa y la mayoría de las veces nos
cambia la barra de menús para incluir las opciones de la aplicación en la que está
hecha el objeto (PaintBrush), además en este caso en nuestra aplicación (Word)
obtenemos una copia del objeto original, pero si cambia el objeto original en
nuestra aplicación no se reflejará; sin embargo si el objeto es vinculado si cambia el
objeto original cambia en nuestro documento (o al revés, si cambia en nuestra
aplicación, es el original lo que estamos modificando), además en el caso de estar
vinculado no soporta edición in-situ, sino que al hacer doble clic sobre el objeto
para activarlo y poder modificarlo, se invoca a la aplicación original en que está
hecha el objeto, en nuestro caso PaintBrush, donde se realizan todos los cambios.
Pagina: 266
.
Fig. 16-2. La ventana de insertar objeto.
Pagina: 267
Fig. 16-4. Edición in-situ de un objeto incrustado.
Nótese en la figura 16-4. que se está editando una imagen incrustada, ya que aunque nos
aparecen opciones de PaintBrush (la paleta de colores y la barra de menús de PaintBrush)
estamos dentro de Word aún como indica la barra de título de la ventana. Cuando hayamos
terminado de modificar la imagen pinchando con el ratón fuera de la imagen, se desactiva el
objeto y Word recupera su aspecto habitual; además si ahora abrimos la imagen original que
insertamos en el documento de Word, vemos que no ha cambiado; sin embargo, si elegimos
vincular el objeto y hacemos cambios en él, notaremos que:
Al hacer doble click sobre el objeto para editarlo nos pasamos automáticamente a
PaintBrush, donde hacemos los cambios y al volver se actualiza el documento de Word.
La imagen original ha cambiado, así como el documento de Word.
Pagina: 268
Del mismo modo que antes podemos elegir vicular o incrustar el objeto, mostrarlo como
icono,..pero debemos tener en cuenta que no todas las aplicaciones soportan todas las
opciones ni edición in-situ, para saber que opciones admite una aplicación para OLE hay que
ver la documentación que venga con la aplicación en particular.
En la figura 16-6 podemos ver un clip avi con sonido que se reproduce dentro del formulario.
Para ver la diferencia entre objetos vinculados e incrustados en VB, insertemos dos
documentos de Word en un formulario y hagamos doble clic en cada uno de ellos,
observaremos:
En uno de ellos (el documento incrustado) los cambios se harán en el mismo formulario.
En el objeto incrustado se invoca a Word para hacer los cambios, y al cerrar el documento
se pregunta si se desean grabar los cambios, en caso afirmativo se actualiza el contenido
en el formulario de VB.
La siguiente vez que ejecutemos el proyecto de VB, el documento vinculado mantiene los
cambios realizados, pero el documento incrustado no (no hemos grabado los cambios de
ninguna forma).
Pagina: 269
Fig. 16-7. Un formulario VB con dos objetos OLE de Word, uno incrustado y otro vinculado.
En la figura 16-7 vemos dos objetos Word en un formulario de VB, el primero de ellos está
incrustado y el segundo está vinculado, al hacer doble clic sobre el primero se ha activado (in-
situ), apareciéndonos la regla de Word sobre el documento y dos de las barras de
herramientas de Word, el documento se puede editar directamente sobre el formulario, pero no
se puede grabar directamente (habrá que hacerlo por código); pero si activamos el segundo
nos vamos a Word.
AppIsRunning
Booleana, devuelva True si la aplicación que ha creado el control OLE está activa y False
en otro caso.
AutoActivate
Devuelve o establece cuando se activa el objeto OLE, hasta ahora nuestro objeto
(videoclip, documento Word, etc.) se activaba cuando el usuario hacía doble clic sobre el
objeto, esto se puede cambiar dando a esta propiedad los siguientes valores:
Pagina: 270
Constante Valor Descripción
VbOLEActivateManual 0 El objeto no se activa automáticamente, la
forma de hacerlo en este caso será con el
método DoVerb
vbOLEActivateGetFocus 1 El objeto se activa cuando recibe el foco (no
todas las aplicaciones lo permiten)
vbOLEActivateDoubleclick 2 El objeto se activa cuando el usuario hace
doble clic sobre él
vbOLEActivateAuto 3 El objeto se activa cuando recibe el foco o se
hace doble clic sobre él
AutoVerbMenu
Propiedad Booleana que devuelve o establece un valor que determina si se muestra un
menú emergente que contenga los verbos del objeto cuando el usuario hace clic en el
control contenedor OLE con el botón secundario del Mouse. Si vale True el objeto no recibe
eventos Click ni MouseDown.
Class
A veces se le denomina ID programático, determina la clase de objeto, según a que
aplicación esté asociado el objeto, normalmente es algo de la forma
nombre_de_aplicación.documento.versión o nombre_de_aplicación.versión, por ejemplo
Excel.Sheet.5 o Excel.Chart.5
Data
Devuelve o establece un controlador de un objeto de memoria o de un objeto de interfaz de
dispositivo gráfico (GDI) que contiene datos con un formato especificado. Esta propiedad se
define para enviar datos a la aplicación que haya creado un objeto. Antes de usar la
propiedad Data, se debe definir la propiedad Format para determinar el tipo de datos
contenidos en el objeto de memoria u objeto GDI. La lista de los formatos aceptados por un
objeto puede obtenerse usando las propiedades ObjectGetFormats y ObjectAcceptFormats.
Estableciendo esta propiedad a 0 se libera al memoria asociada con el controlador.
Para enviar o recibir datos de una aplicación es más fiable y sencillo hacerlo con
automatización OLE si la otra aplicación lo permite (con la propiedad Object se puede
acceder al objeto, así como con las funciones CreateObject y GetObject.
DataSource, DataField
Igual que para cualquier control que disponga de estas propiedades (ver capítulo 16, el control
data).
DataText
Se usa para enviar o recoger datos de una aplicación, se usa en combinación con la propiedad
Format para establecer el formato de los datos.
Si se usa la versión de 16 bits de Visual Basic, la cadena DataText tiene que ser menor que
64K. Si se usa la versión de 32 bits de Visual Basic, la cadena DataText puede ser tan
grande como la memoria disponible permita.
Es preferible usar automatización OLE para el traspaso de datos si la otra aplicación lo
permite.
Ej.:
Pagina: 271
Dim Msg, NL, TB ' Declara variables.
TB = Chr(9) ' Carácter Tab.
NL = Chr(10) ' Carácter Nueva línea.
End If
End Sub
Sub Form_Load ()
Tendremos una aplicación que asociamos a Microsoft Graph en tiempo de ejecución, que al
pulsar el botón de comando le enviamos datos distintos para que nos muestre el gráfico
asociado. Para poder hacer esto en general, tendremos que saber que formato de datos
acepta la otra aplicacción.
DisplayType
Booleana, devuelve o establece si un objeto muestra su contenido (0) o un icono (1). Se puede
cambiar en tiempo de diseño o de ejecución, siempre y cuando no se haya creado aún el
objeto, a partir de cuyo momento ya no se puede cambiar.
FileNumber
Se incluye por compatibilidad con la propiedad Action, en su lugar se deben usar los métodos
SaveToFile y ReadFromFile. Devuelve o establece el número de archivo en el que se va a
guardar o cargar un objeto, o el último número usado en una de estas acciones.
Format
Devuelve o establece el formato cuando se envían y se obtienen datos de una aplicación que
ha creado un objeto.
Para obtener la lista de los formatos de datos aceptados, se usan las propiedades
ObjectAcceptFormats, ObjectAcceptFormatsCount, ObjectGetFormats y
ObjectGetFormatsCount. Se debe tener en cuenta que a veces la lista de formatos que un
objeto admite no es la misma que la lista de formatos que ofrece.
Ej:
Pagina: 272
HostName
Devuelve o establece el nombre del host de la aplicación Visual Basic leíble por usuario, es
una cadena de caracteres. Se debe tener en cuenta que no todas las aplicaciones
devuelven algo en esta propiedad.
LpOleObject
Devuelve la dirección del objeto. Se usa cuando se hacen llamadas al API de Windows que
requieran la dirección de un objeto OLE. Sl valor es 0 si actualmente no se presenta ningún
objeto, si se hace una llamada a una API que a su vez hace llamadas al control contenedor
OLE, los resultados son impredecibles.
MiscFlags
Devuelve o establece un valor que determina el acceso a una o varias características
adicionales del control contenedor OLE. Puede tomar los siguientes valores:
Object
Se usa para controlar un objeto de automatización OLE. El uso de esta propiedad es el
siguiente:
objeto.Object[.propiedad | .método]
ObjectAcceptFormats
Devuelve la lista de formatos que un objeto puede aceptar. Se usa conjuntamente con la
propiedad ObjectAcceptFormatsCount, que devuelve el número de formatos que acepta
el objeto. Es una matriz de cadenas de texto que se pueden usar para fijar el formato de
los datos que se envían a una aplicación (o se reciben)
Si el control contenedor OLE no contiene un objeto, cuando se intenta tener acceso a esta
propiedad se produce un error.
Ej:
Pagina: 273
Si tenemos un formulario con un documento Word vinculado, con el siguiente código
enviamos una cadena de texto al documento en formato RTF, para ello el objeto deberá
antes estar activo (con doble click en el objeto OLE)
OLE1.Format = OLE1.ObjectAcceptFormats(1) 'Rich Text Format
OLE1.DataText = "hola"
Debemos tener en cuenta que esta matriz como es habitual en VB empieza a numerarse en
0.
ObjectAcceptFormatsCount
Nos devuelve el número de formatos que acepta un objeto. Para saber el nombre de cada
uno usamos la propiedad anterior.
ObjectGetFormats
Devuelve una lista de los formatos que el objeto puede proporcionar. Se usa junto con las
propiedades ObjectGetFormatsCount y Format para fijar el formato de datos que se
reciban de la aplicación asociada al objeto.
ObjectGetFormatsCount
Devuelve el número de formatos que el objeto ofrece para recibir datos de él.
ObjectVerbFlags
Devuelve el estado del menú para cada verbo de la matriz ObjectVerbs.
Su uso es el siguiente
objeto.ObjectVerbFlags(número)
donde número indica el elemento de la matriz del que queremos saber el estado.
Cuando se presenta un menú que contenga los verbos del objeto, comprueba el valor de
esta propiedad para ver como se presenta cada elemento.
ObjectVerbs
Devuelve la lista de verbos que un objeto acepta.
Su uso es el siguiente:
objeto.ObjectVerbs(número)
Pagina: 274
ObjectVerbs es una matriz de cadenas distintas de cero. Esta propiedad se usa de forma
conjunta con la propiedad ObjectVerbsCount para obtener los verbos aceptados por un
objeto. Dichos verbos se usan para determinar la acción que se va a ejecutar cuando un
objeto se activa con el método DoVerb. La lista de verbos de la matriz varía de objeto a
objeto y depende de las condiciones actuales.
Cada objeto puede aceptar su propio juego de verbos. Los siguientes valores representan
verbos estándar aceptados por todos los objetos:
Valor Acción
0 La acción predeterminada del objeto.
-1 Activa el objeto para edición. Si la aplicación que ha creado el
objeto acepta edición in-situ, el objeto se activa dentro de el
control contenedor OLE.
-2 Abre el objeto en una ventana de la aplicación distinta. Si la
aplicación que ha creado el objeto acepta activación in situ, el
objeto se activa en su propia ventana.
-3 En objetos incrustados, oculta la aplicación que ha creado el
objeto.
-4 Si el objeto acepta edición in-situ, activa el objeto para activación
in-situ y muestra las herramientas de la interfaz de usuario. Si el
objeto no acepta activación in situ, el objeto no se activa y se
produce un error.
-5 Si el usuario cambia el enfoque al control contenedor OLE, crea
una ventana para el objeto y prepara el objeto para ser editado.
Si el objeto no acepta activación por un clic del Mouse se
produce un error.
-6 Se usa cuando el objeto se activa para edición para desestimar
el registro de los cambios que la aplicación del objeto puede
deshacer.
La lista de verbos que un objeto acepta puede variar, dependiendo del estado del objeto.
Para actualizar la lista de verbos que un objeto acepta, se usa el método FetchVerbs. Se
debe actualizar la lista de verbos antes de presentarla al usuario.
ObjectVerbsCount
Devuelve el número de verbos aceptados por un objeto. Se usa en conjunto con la
propiedad ObjectVerbs y el método FetchVerbs.
OLEDropAllowed
Pagina: 275
Devuelve o establece un valor booleano que determina si un control contenedor OLE puede
ser un destino para operaciones OLE de arrastrar y soltar (drag and drop).
Si vale True, al arrastrar un objeto que puede estar vinculado o incrustado, aparece un
icono de soltar cuando el puntero del mouse se mueve sobre el control contenedor OLE.
Soltar el objeto en el control contenedor OLE tiene el mismo efecto que pegar el objeto
desde el Portapapeles del sistema con el método Paste.
Si vale False (valor predeterminado) no aparece ningún icono de soltar sobre el control
contenedor OLE cuando se arrastra un objeto que puede estar vinculado o incrustado.
Arrastrar el objeto en el control contenedor OLE no tiene ningún efecto sobre el control.
Se debe tener en cuenta que la propiedad MousePointer determina la forma del puntero del
mouse cuando la propiedad OLEDropAllowed es True. Si el valor de la propiedad
MousePointer es 0 (predeterminado), Visual Basic mostrará el icono estándar de
arrastrar y soltar para la acción que está realizando.
OLEType
Indica si el control contenedor OLE contiene un objeto o para determinar el tipo de objeto
que contiene. Puede tomar los siguientes valores:
OLETypeAllowed
Devuelve o establece el tipo de objeto que el control contenedor OLE puede contener.
Puede tomar los siguientes valores:
Pagina: 276
predeterminado.
Parent
Como cualquier otro control.
PasteOK
Vale True si el contenido del portapapeles se puede pegar dentro del control contenedor
OLE, y False en otro caso. Se puede usar para habilitar o deshabilitar la opción Pegar
de un menú de nuestra aplicación.
Picture
Igual que para otros controles que tienen esta propiedad devuelve un gráfico mostrado en
el control. No está disponible en tiempo de diseño y es de sólo lectura en tiempo de
ejecución.
SizeMode
Controla como se presenta el objeto dentro del control contenedor OLE. Puede tomar los
siguientes valores:
Cuando SizeMode se define como 2 (Automático) el evento Resize se invoca antes de que
el control contenedor OLE cambie automáticamente de tamaño. Los argumentos
alturanueva y anchuranueva del procedimiento de evento Resize indican el tamaño de
presentación óptimo del objeto (este tamaño viene determinado por la aplicación que ha
creado el objeto), pero se pueden cambiar el tamaño del control cambiando los valores
de los argumentos alturanueva y anchuranueva del procedimiento de evento Resize.
SourceDoc
Devuelve o establece el nombre de archivo que se usa cuando se crea un objeto. Esta
propiedad se mantiene por compatibilidad con la propiedad Action de versiones
anteriores de Visual Basic. En su lugar se usan los métodos CreateEmbed y CreateLink.
Pagina: 277
Cuando un objeto vinculado ha sido creado, la propiedad SourceItem se concatena con la
propiedad SourceDoc. En tiempo de ejecución, la propiedad SourceItem devuelve una
cadena vacía ("") y la propiedad SourceDoc devuelve la ruta completa del archivo
vinculado, seguida de una exclamación (!) o una barra diagonal inversa(\) y seguida de
SourceItem. Por ejemplo:
"C:\EXCEL\PRUEBA.XLS!R1C1:R30C15"
SourceItem
Devuelve o establece los datos dentro del archivo vinculado cuando se crea un objeto
vinculado. Es de tipo cadena de caracteres.
UpdateOptions
Devuelve o establece un valor que especifica cómo se actualiza un objeto cuando los datos
vinculados han sido modificados. Los valores que se pueden usar son los siguientes:
Cuando los datos del objeto cambian, se produce el evento Updated. Se debe tener en
cuenta que no todas las aplicaciones que ofrecen objetos OLE permitirán todas las
posibilidades.
Verb
Devuelve o establece un valor que especifica una operación que se va a realizar cuando un
objeto es activado usando la propiedad Action. Esta propiedad se incluye por
compatibilidad con la propiedad Action de versiones anteriores. En su lugar se debe usar
el método DoVerb.
Pagina: 278
Cierra un objeto y termina la conexión con la aplicación que suministró el objeto. Sólo es
aplicable a objetos incrustados, sobre los objetos vinculados no tiene efecto. Para ver su
comportamiento podemos crear un proyecto con dos formularios, en el primero de ellos
insertamos una imagen de PaintBrush incrustada, y en el segundo ponemos un botón de
comando que al hacer clic sobre él cierra el objeto del primer formulario (en el código
del su evento clic pondremos Form1!ole1.close). Al arrancar el programa mostramos
los dos formularios, si abrimos el objeto del primer formulario, lo podremos cerrar
pulsando el botón del segundo formulario.
Copy
Copia el objeto de un control contenedor OLE al Portapapeles del sistema, el objeto puede
ser incrustado o vinculado (la información de vinculación también se copia en el
portapapeles). Para ello el objeto debe estar activo, o se producirá un error de ejecución.
CreateEmbed
Crea un objeto incrustado en un control contenedor OLE. Su formato es el siguiente:
donde:
docorigen es el nombre del archivo del documento usado como plantilla para el objeto
incrustado. Si no se especifica, debe ser una cadena vacía ("").
clase es un argumento opcional, que indica el nombre de la clase del objeto incrustado,
solamente tiene utilidad si no se especifica un nombre de archivo para docorigen.
Cuando se crea un objeto nuevo, la aplicación asociada con los nombres de clase (por
ejemplo, EXCEL.EXE) tiene que haber sido registrada correctamente en el sistema
operativo. (El programa de instalación de la aplicación debe registrar la aplicación
correctamente).
CreateLink
donde docorigen es el archivo a partir del que se crea el objeto y elemorigen especifica los
datos dentro del archivo que se va a vincular con el objeto, por ejemplo un rango de
celdas en una hoja de Microsoft Excel.
Cuando se crea un objeto con este método, el control contenedor OLE presenta una
imagen del archivo especificado por la propiedad SourceDoc. Si se guarda el objeto,
sólo se guardan las referencias de vinculación porque el control contenedor OLE sólo
contiene una imagen metarchivo de los datos y no los datos originales actuales.
Pagina: 279
Cuando se crea un objeto nuevo, la aplicación asociada con los nombres de clase (por
ejemplo, EXCEL.EXE) tiene que haber sido registrada correctamente en el sistema
operativo. (El programa de instalación de la aplicación debe registrar la aplicación
correctamente).
Delete
Elimina el objeto especificado del control contenedor OLE y libera la memoria asociada con
él. Los objetos se eliminan automáticamente cuando se cierra el formulario o cuando el
objeto se reemplaza por un nuevo objeto.
DoVerb
Abre un objeto para una determinada operación, como edición. Su formato es:
objeto.DoVerb (verbo)
Drag
Igual que para cualquier control que acepte operaciones de arrastrar y soltar (drag and
drop)
FetchVerbs
Pagina: 280
Actualiza la lista de verbos aceptados por un objeto. Su formato es:
objeto.FetchVerbs
InsertObjDlg
Presenta el cuadro de diálogo Insertar objeto. Su formato es:
objeto.InsertObjDlg
Permite que el usuario cree un objeto vinculado o uno incrustado eligiendo el tipo de objeto
(vinculado o incrustado) y la aplicación que proporciona el objeto.
Para determinar el tipo de objeto que se puede crear usando este cuadro de diálogo
(vinculado, incrustado o cualquiera), se usa la propiedad OLETypeAllowed.
Cuando se crea un objeto nuevo, la aplicación asociada con los nombres de clase (por
ejemplo, EXCEL.EXE) tiene que haber sido registrada correctamente en el sistema
operativo. (El programa de instalación de la aplicación debe registrar la aplicación
correctamente).
Move
Igual que para cualquier control (para mover un control dentro de un formulario).
Paste
Copia datos desde el Portapapeles en un control contenedor OLE.
Para usar este método, se debe definir la propiedad OLETypeAllowed y verificar el valor
de la propiedad PasteOK.
PasteSpecialDlg
Presenta el cuadro de diálogo Pegado especial. Su formato es:
objeto.PasteSpecialDlg
Se usa para permitir que el usuario pegue un objeto desde el Portapapeles del sistema,
presentando al usuario varias opciones, incluyendo si se pega un objeto vinculado o uno
incrustado.
Para determinar el tipo de objeto que se puede crear usando este cuadro de diálogo
(vinculado, incrustado o cualquiera), se usa la propiedad OLETypeAllowed.
ReadFromFile
objeto.ReadFromFile numarchivo
Pagina: 281
Refresh
Igual que para cualquier control (fuerza el redibujado del objeto)
SaveToFile
Guarda un objeto en un archivo de datos. Su formato es:
objeto.SaveToFile numarchivo
Este método se usa para guardar objetos OLE. Si el objeto es vinculado (OLEType =
vbOLELinked, 0), en el archivo especificado sólo se guarda la información de
vinculación y una imagen de los datos. Los datos del objeto se mantienen por la
aplicación que ha creado el objeto. Si el objeto es incrustado (OLEType =
vbOLEEmbedded, 1), los datos del objeto se mantienen por el control contenedor OLE
y se pueden guardar desde la aplicación Visual Basic.
SaveToOle1File
Igual que SaveToFile, pero guarda un objeto en formato OLE 1.0
SetFocus
Igual que para cualquier control
ShowWhatsThis
Igual que para cualquier control
Update
Obtiene los datos actuales desde la aplicación que suministra el objeto y presenta dichos
datos como un gráfico en el control contenedor OLE, es decir, actualiza el contenido del
control contenedor OLE desde la aplicación que suministra el objeto (recordemos que no
todas las aplicaciones actualizan solas la información).
ZOrder
Igual que para cualquier control
16.3.5. Eventos del control contenedor OLE.
Click
Igual que para cualquier otro control, con la salvedad de que dependiendo de la propiedad
AutoActivate se puede activar el objeto al recibir este evento
DblClick
Igual que para cualquier otro control, con la salvedad de que dependiendo de la propiedad
AutoActivate se puede activar el objeto al recibir este evento
DragDrop
Igual que para cualquier otro control. Se debe tener en cuenta que si la propiedad
OLEDropAllowed se establece como True, el control contenedor OLE no recibe
eventos DragDrop o DragOver.
DragOver
Igual que para cualquier otro control.
GotFocus
Pagina: 282
Igual que para cualquier otro control, con la salvedad de que dependiendo de la propiedad
AutoActivate se puede activar el objeto al recibir este evento
KeyDown
KeyPress
KeyUp
LostFocus
MouseDown
MouseMove
MouseUp
Iguales que para cualquier otro control.
ObjectMove
Se produce inmediatamente después de que el objeto dentro de un control contenedor OLE
se mueva o ajuste su tamaño mientras el objeto está activo.
donde:
left indica la coordenada del borde izquierdo del control contenedor OLE después
de moverse o ajustar su tamaño.
top indica la coordenada del borde superior del control contenedor OLE después
de moverse o ajustar su tamaño.
width indica el ancho del control contenedor OLE después de moverse o ajustar su
tamaño.
height indica la altura del control contenedor OLE inmediatamente después de
moverse o ajustar su tamaño.
Resize
Igual que para cualquier otro control.
Updated
Se produce cuando los datos del objeto han sido modificados. Este evento puede usarse
para determinar si los datos del objeto han sido modificados desde que fue guardado por
última vez, definiendo una variable global en el evento Updated que indique que el
objeto necesita ser guardado; después de guardar el objeto, se debe reinicializar la
variable.
Pagina: 283
donde código especifica cómo ha sido actualizado el objeto, puede tomar los siguientes
valores:
Esta propiedad establece un valor que determina si un formulario incorpora los menús de
un objeto del formulario en la barra de menús del formulario. No está disponible en tiempo
de ejecución. Los valores que puede tomar son True (predeterminado) que fuerza que
cuando un objeto del formulario está activo para edición, los menús de ese objeto se
muestran en la barra de menús del formulario y False, que hace que los menús de objetos
del formulario no se muestran en la barra de menús del formulario.
Si se decide que aparezcan los menús del objeto activo, podemos determinar si queremos
que aparezcan además algunas opciones de nuestro propio menú con la siguiente
propiedad.
Se debe tener en cuenta que no se pueden negociar menús entre un formulario MDI y un
objeto del formulario MDI.
Valor Descripción
0 Ninguno. El menú no se muestra en la barra de menús cuando el objeto
está activo. Es el valor predeterminado.
1 Izquierda. El menú se muestra a la izquierda de la barra de menús
cuando el objeto está activo.
2 Medio. El menú se muestra en medio de la barra de menús cuando el
objeto está activo.
3 Derecha. El menú se muestra a la derecha de la barra de menús
cuando el objeto está activo.
Pagina: 284
Si la propiedad NegotiateMenus se establece como False, el valor de la propiedad
NegotiatePosition no tendrá ningún efecto.
Ej:
En las figura 16-8 el objeto incrustado no está activo, con lo que en el formulario aparece su
propio menú, cuyos dos elementos de nivel superior son Menú Principal 1 y Menú Principal 2.
En la figura 16-9 el objeto incrustado (un documento de Word) está activo para edición, con lo
que aparecen las barras de botones de Word (tipo de letra, etc.) y los menús de Word;
Pagina: 285
además, en la parte derecha del menú nos aparece la segunda opción de nivel superior de
nuestro formulario, para ello se marcó antes la propiedad NegotiatePosition de este menú
como 3 (derecha), dejando el primer menú con su valor por defecto (0, es decir no aparecer en
el menú). Por supuesto la propiedad NegotiateMenus del formulario se dejó con su valor por
defecto (True).
El funcionamiento es simple:
En el menú formato si cuando se elija la opción de abrir archivo se desea cargar la imagen
que se seleccione en la lista de archivos en el PictureBox en el control contenedor OLE (lo
mismo para grabar la imagen) Ver figura 16-10.
Pagina: 286
El dibujo se puede grabar como objeto OLE o como mapa de bits, teniendo en cuenta que
si se guarda como objeto OLE, no se puede cargar directamente en el PictureBox más
adelante.
Téngase en cuenta que por simplificar se ha usado Drag and Drop automático, con lo que para
activar el objeto para edición no podemos hacer doble click, sino que con el botón derecho del
ratón debemos sacar el menú contextual del objeto, y elegir la opción Editar.
Obviamente este programa es muy simple, y se enlaza con PaintBrush, que no es muy potente
en el tratamiento de imágenes, pero sirve para darnos cuenta de como podemos usar
capacidades de otra aplicación dentro de nuestro formulario.
El código de este programa es el siguiente:
VERSION 4.00
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 6090
ClientLeft = 465
ClientTop = 945
ClientWidth = 9120
Height = 6780
Left = 405
LinkTopic = "Form1"
ScaleHeight = 6090
ScaleWidth = 9120
Top = 315
Width = 9240
Begin VB.VScrollBar VScroll1
Height = 5490
LargeChange = 100
Left = 3900
TabIndex = 6
Top = 0
Width = 240
End
Begin VB.HScrollBar HScroll1
Height = 240
LargeChange = 100
Left = 0
TabIndex = 5
Top = 5475
Width = 3915
End
Begin VB.PictureBox Picture1
DragIcon = "Form1.frx":0000
DragMode = 1 'Automatic
Height = 2790
Left = 4425
ScaleHeight = 2730
ScaleWidth = 4380
TabIndex = 3
Top = 2700
Width = 4440
End
Begin VB.FileListBox File1
Height = 2595
Left = 6525
TabIndex = 2
Top = 0
Width = 2340
End
Pagina: 287
Begin VB.DirListBox Dir1
Height = 2055
Left = 4500
TabIndex = 1
Top = 525
Width = 1890
End
Begin VB.DriveListBox Drive1
Height = 315
Left = 4500
TabIndex = 0
Top = 0
Width = 1890
End
Begin VB.Label Label1
Height = 240
Left = 4950
TabIndex = 7
Top = 0
Width = 3915
End
Begin VB.OLE OLE1
DragIcon = "Form1.frx":0442
DragMode = 1 'Automatic
Height = 5490
Left = 0
OLEDropAllowed = -1 'True
OLETypeAllowed = 1 'Embedded
TabIndex = 4
Top = 0
Width = 3915
End
Begin VB.Menu mnuarchivo
Caption = "&Archivo"
Begin VB.Menu mnuabrir
Caption = "&Abrir"
End
Begin VB.Menu mnuguardar
Caption = "&Guardar"
End
Begin VB.Menu mnusalir
Caption = "&Salir"
End
End
Begin VB.Menu mnuformato
Caption = "&Formato"
Begin VB.Menu mnuaimagen
Caption = "&Abrir como imagen"
Checked = -1 'True
End
Begin VB.Menu mnuaole
Caption = "A&brir como Objeto OLE"
End
Begin VB.Menu mnugimagen
Caption = "Guardar como &imagen"
Checked = -1 'True
End
Begin VB.Menu mnugOLE
Caption = "Guardar como Objeto &OLE"
End
End
Pagina: 288
End
Attribute VB_Name = "Form1"
Attribute VB_Creatable = False
Attribute VB_Exposed = False
Option Explicit
Dim altura As Long, ancho As Long
Dim archivo As String
Private Sub Dir1_Change()
File1.Path = Dir1.Path
End Sub
End Function
fin:
MsgBox Error(Err)
End Sub
If mnuaimagen.Checked Then
Picture1.Picture = LoadPicture(archivo)
Else
i = FreeFile()
Open archivo For Binary As i
OLE1.ReadFromFile i
Close #i
End If
End Sub
Pagina: 289
End Sub
If mnugimagen.Checked Then
SavePicture Picture1.Image, archivo
Else
i = FreeFile()
Open archivo For Binary As #i
OLE1.SaveToFile i
Close #i
End If
End Sub
Pagina: 290
Picture1.Picture = Clipboard.GetData
Picture1.SetFocus
End If
End Sub
Tiene estas formas cuando está en la caja de herramientas y cuando está en el formulario
respectivamente.
(Se muestra con los botones activados. Pueden estar desactivados y entonces tienen un color
gris pálido)
Este control es un control OCX. Ha sido diseñado para poder reproducir ficheros de sonido,
(*.waw), presentar ficheros de vídeo, (*.avi) y otras funciones multimedia. Para habilitar el que
puede hacer una u otra función hay que indicárselo en su propiedad DeviceType, propiedad
que explicaremos sin mas preámbulos.
Propiedad DeviceType
Especifica el tipo de dispositivo MCI que se va a abrir.
El argumento dispositivo$ (un String) indica el tipo de dispositivo multimedia que se va a abrir.
Puede tomar los valores:
AVIVideo, para reproducir ficheros AVI. Lógicamente necesita algo para poder mostrar un
fichero de vídeo: el reproductor AVI de Windows. El MMControl se lo presentará
automáticamente cuando tiene que reproducir un vídeo.
CDAudio, para reproducir un disco CD que tengamos en la disquetera. Pasa lo mismo que
antes. Deberá tener un dispositivo de reproducción de sonidos en su PC y una unidad de CD
Pagina: 291
DAT, Graba y reproduce cintas DAT. Debe tener una unidad de cinta DAT instalada en su PC.
DigitalVideo,
MMMovie,
Other,
Overlay,
Scanner,
Sequencer, para trabajar con un secuenciador MIDI
VCR,
Videodisc. Para reproducir videodiscos
WaveAudio. Para reproducir un fichero de audio en formato .WAW
Propiedad Command
Con la propiedad DeviceType el control MCI ya sabe que dispositivo tiene que controlar. Pero
no hará nada de momento. Para que haga algo debemos introducirle órdenes. Y estas órdenes
se le introducen mediante la propiedad Command
La primera orden que debemos introducirle es que abra el dispositivo. Mediante el comando
Open
MMControl.Command = “Open”
Mediante esta sentencia, el control MCI ya está operativo. Dependerá por supuesto, del estado
de otras propiedades, el que ejecute o no otra instrucción. Pero esta es la primera que debe
ejecutar para poder trabajar. Por eso es frecuente ver la orden Open en el Load del formulario
que contienen al control MCI.
Lo contrario a Open será Close. Cierra el control MCI y por lo tanto cualquier posibilidad de
que pueda trabajar.
MMControl.Command = “Close”
Observará en el ejemplo siguiente que el dispositivo MCI solo se cierra ejecutando el comando
Close. Por ejemplo, cuando sale de la aplicación con un End, el dispositivo sigue funcionando.
Tenga esto en cuenta, pues es muy habitual olvidarse de ello. Ponga el comando Close en el
QueryUnload del formulario que lo contiene. Es prudente también que antes de Close, le
introduzca el comando Stop.
Veamos una orden que supongo estará deseoso de usar: Play. Este comando inicia la
ejecución. Si el dispositivo es el CD de audio, se pondrá a reproducirlo
MMControl.Command = “Play”
Suponga que estamos reproduciendo el CD. Queremos hacer una pausa. El comando
adecuado para ello es Pause
MMControl.Command = “Pause”
Pero si deseamos parar definitivamente la reproducción del CD, usaremos el comando Stop
MMControl.Command = “Stop”
Y ahora deseamos sacar el CD de la unidad de discos. Para esa función usaremos Eject
Pagina: 292
MMControl.Command = “Eject”
Seguiremos mas adelante con la propiedad Command. Tiene algunas órdenes mas y las
veremos mas adelante. Para comprobar lo dicho anteriormente, vamos a hacer una pequeña
aplicación que reproduce un CD.
Todavía no funciona. Debemos abrir el control. Podemos hacerlo en el Load del formulario :
Inserte el disco de los Tres Tenores en la disquetera y haga click en el tercer botón (Play)
Ahora comenzará a darse cuenta para que sirven los controles MCI.
Observará que funciona perfectamente con los botones del propio control, sin necesidad de
poner los comandos Play, Pause, Stop. Eject, etc. y que los botones se habilitan o deshabilitan
dependiendo del estado de ejecución, pausa, o parada del CD. Esta funcionalidad se activa
porque el control MCI tiene las propiedades Autoenable y Enabled a True.
Imagínese que lo que quiere hacer es una aplicación muy personalizada. Entonces pondrá una
serie de botones cada uno con un comando. Y e el procedimiento click de ese botón pone el
comando que corresponda. Deberá poner el control MCI, pero puede ponerle su propiedad
visible = False y ya tiene la personalización hecha.
Pagina: 293
Ya tenemos un reproductor de CDs personalizado. No es una gran cosa como programa
multimedia pero podrá ilustrarnos para seguir estudiando el control MCI.
MMControl1.TimeFormat = 0
Ltracks = MMControl1.Tracks
MMControl1.Track = Val(TBTrack)
Pagina: 294
LTrack = MMControl1.Track
LLenght = MMControl1.Length
SegunDD = Val(LLenght) \ 1000
MinutosDD = SegunDD \ 60
SegundosDD = SegunDD Mod 60
LDDisco = MinutosDD & " min. " & SegundosDD & " seg."
LTrackPosition = MMControl1.TrackPosition
SegunI = Val(LTrackPosition) \ 1000
MinutosI = SegunI \ 60
SegundosI = SegunI Mod 60
LInicio = MinutosI & " min. " & SegundosI & " seg."
LTrackLenght = MMControl1.TrackLength
SegunD = Val(LTrackLenght) \ 1000
MinutosD = SegunD \ 60
SegundosD = SegunD Mod 60
LDuracion = MinutosD & " min. " & SegundosD & " seg."
LPosition = MMControl1.Position
SegunT = Val(LPosition) \ 1000
MinutosT = SegunT \ 60
SegundosT = SegunT Mod 60
LPosicion = MinutosT & " min. " & SegundosT & " seg."
Timer1.Enabled = True
End Sub
Los botones Comienza en y Solo Esta nos ilustran acerca de la propiedades From y To
Por eso, el botón Solo Esta tiene tiempo de origen [Val(LTrackPosition)] y de final
[Val(LTrackPosition) + Val(LTrackLenght)] mientras que la de Comienza en solamente tiene
tiempo de origen :
Pagina: 295
Private Sub BComienzaen_Click()
MMControl1.Command = "Stop"
MMControl1.From = Val(LTrackPosition)
MMControl1.Command = "Play"
End Sub
Observe que antes de decirle el tiempo de origen (en que instante debe comenzar), le hemos
dado el comando de parar (Stop). Es muy prudente poner esta instrucción cuando debemos
estar seguros de que no está ejecutando el CD. Si lo está, lo para. Si no lo está, no pasa nada.
Podemos incluso sacar el disco de la disquetera. Veamos el código del botón Expulsar CD
El comando Eject no solamente sirve para sacar el CD. Si está fuera lo mete. Puede de esta
forma hacer un botón con el código anterior que saque y meta el disco. Para mayor
comprensión puede cambiarle el Caption al botón dependiendo si lo que va a hacer es
introducir el CD o extraerlo.
Pero que pasaría si por cualquier circunstancia, no se puede expulsar en ese momento el CD?
Propiedad CanEject
Determina si el dispositivo MCI abierto puede expulsar su medio. Esta propiedad no está
disponible en tiempo de diseño y es de sólo lectura en tiempo de ejecución.
Al igual que CanEject, existen otras propiedades que nos indican si se puede realizar en ese
momento una determinada operación. Es muy útil analizar estas propiedades antes de
proceder a ejecutar una determinada operación. Por ejemplo, deberíamos ver si podemos
iniciar la ejecución de un disco (o de un fichero de sonido) antes de darle el comando Play.
Muy sencillo. Leamos el valor de la propiedad CanPlay
Propiedad CanPlay
Determina si el dispositivo MCI abierto es capaz de reproducir. Esta propiedad no está
disponible en tiempo de diseño y es de sólo lectura en tiempo de ejecución.
Propiedad CanRecord
Determina si el dispositivo MCI abierto puede grabar. Esta propiedad no está disponible en
tiempo de diseño y es de sólo lectura en tiempo de ejecución.
Pagina: 296
Los valores devueltos son True o False, con el mismo criterio de las anteriores.
Propiedad CanStep
Determina si el dispositivo MCI abierto puede avanzar una trama cada vez. Esta propiedad no
está disponible en tiempo de diseño y es de sólo lectura en tiempo de ejecución.
Los valores devueltos son True o False, según el criterio de las propiedades anteriores.
Comentarios Actualmente, sólo los dispositivos MCI MMMovie, Overlay y VCR pueden
avanzar de trama en trama. Como no hay ninguna forma de comprobar si un dispositivo puede
avanzar paso a paso, los programas establecen el valor de esta propiedad comprobando si el
tipo del dispositivo es MMMovie, Overlay o VCR durante el procesamiento de un comando
Open.
Observación. Estas propiedades se han probado en el ejercicio que acompaña a este capítulo
y siempre han devuelto True. Incluso al leer CanPlay con el CD extraído. El autor de esta Guía
del Estudiante debe incluirlas, y también advertir lo observado. La razón posiblemente esté en
la gran variedad de equipos multimedia existentes, que posiblemente no funcionen todos de la
misma forma.
Pero existe otra forma de comprobar el estado del control MCI. La propiedad Mode.
Propiedad Mode
Devuelve el modo actual de un dispositivo MCI que está abierto. Esta propiedad no está
disponible en tiempo de diseño y es de sólo lectura en tiempo de ejecución.
Variable puede tomar uno de estos valores o constantes, dependiendo del estado del control.
Podemos de esta forma averiguar el estado del control MCI antes de efectuar cualquier
operación con él.
Propiedad Wait
Determina si el control Multimedia MCI espera a completar el siguiente comando MCI antes de
devolver el control a la aplicación. Esta propiedad no está disponible en tiempo de diseño.
Si Wait está a False, el control MCI no espera a que se complete el comando MCI antes de
devolver el control a la aplicación. Si está a True sí espera.
Pagina: 297
El valor que asigne a esta propiedad sólo se usará con el siguiente comando MCI. Los
comandos MCI subsiguientes pasan por alto la propiedad Wait hasta que le asigne otro valor
(diferente o idéntico).
Propiedad Shareable
Determina si el mismo dispositivo MCI puede estar compartido por más de un programa.
Si esta propiedad se pone a False ningún otro control o aplicación puede tener acceso a este
dispositivo. Si se pone a True pueden abrir este dispositivo mas de un control o aplicación.
Cuidado. Esta propiedad es mejor que esté siempre a False. Si necesita que varios controles
abran el mismo dispositivo es que su aplicación es para nota. Se entiende que lo abran
simultáneamente. Puede abrir el dispositivo por cuantos controles desee, pero no al mismo
tiempo. Para este caso, la propiedad Shareable debe estar a False. Recuerde esta
observación cuando pretenda abrir el control MCI y éste no le haga caso a su comando Open.
Nos quedan por lo tanto tres valores estudiables para la propiedad DeviceType que
reproducimos de nuevo:
AVIVideo, para reproducir ficheros AVI. Lógicamente necesita algo para poder mostrar un
fichero de vídeo: el reproductor AVI de Windows. El MMControl se lo presentará
automáticamente cuando tiene que reproducir un vídeo.
Pagina: 298
Este es un reproductor de ficheros de sonido Wav, secuenciador MIDI y reproductor de videos
Avi. Dispone de teclas para elegir el fichero a reproducir, para ejecutar, y en el caso del
secuenciador MIDI, una tecla para parar, una etiqueta para mostrar la duración del sonido, y
una barra de desplazamiento para ver la evolución de la ejecución. La forma de reproducir un
fichero es idéntica en los tres apartados : se elige un fichero con el botón Elegir. (Observe que
en vez de poner botones de comando hemos puesto etiquetas para poder cambiarles el color
de fondo) Aparece un CommonDialog para elegir el fichero. Se elige y el nombre de ese
fichero pasa al Combo que está esa sección. Se pueden meter tantos ficheros como queramos
en el combo. Se elige uno y la etiqueta Ejecutar se pone verde. Ahora se hace click sobre esa
etiqueta y se ejecuta el Avi, Wav o Mid correspondiente.
Se enumera a continuación el código de cada uno de los botones (labels) del programa.
CD1= CommonDialog
Pagina: 299
‘Es fundamental poner Wait a True para evitar que ejecute las instrucciones siguientes una tras
‘otra sin esperar a que termine una para que empiece la siguiente. Pruebe a quitar esta línea.
‘Comenzará la ejecución (Play), Inmediatamente se parará (Stop) y volverá al principio del
‘fichero (Prev) Al estar Wait a True, espera que se termine la ejecución para parar, y una vez
‘que ha terminado el proceso de parar, se va al principio del fichero.
MMControl1.Command = "Play"
MMControl1.Command = "Stop"
MMControl1.Command = "Prev"
End If
End Sub
Pagina: 300
If LEjecutar2.BackColor = RGB(0, 255, 0) Then
Dim TTotal As Long
MMControl1.DeviceType = "Sequencer"
' Si el dispositivo está abierto, lo cierra.
If Not MMControl1.Mode = mciModeNotOpen Then
MMControl1.Command = "Close"
End If
' Abre el dispositivo
MMControl1.filename = ComboMidi.Text
MMControl1.Command = "Open"
MMControl1.Command = "Play"
MMControl1.TimeFormat = mciFormatMilliseconds
TTotal = MMControl1.Length
LDuracion = TTotal / 1000 & " Seg."
GG1.Max = TTotal / 1000
End If
End Sub
Pagina: 301
LEstado = "Pausa"
Case 530
LEstado = "Preparado"
End Select
End Sub
Este control Timer permite analizar (Cada segundo, pues su propiedad Interval esta puesta a
1000) el estado del control MCI, el tiempo de fichero ejecutado, y actualiza la posición de la
barra del control Gauge (GG1)
Y con esto hemos visto todo lo que se puede ver en un curso de VB como este, del control
MCI. Lo demás ya sería para nota. Como es para nota el conocer que todo esto se puede
hacer igual SIN el control MCI. Es decir, CON APIS.
Por eso, se está preparando un libro que se dedica exclusivamente a las Apis de Multimedia, y
a los formatos de audio / vídeo, en el que participa el autor de esta Guía del Estudiante. No
está aún editado, ya que se está comprobando con W98 y WindowsNT. El listón está muy alto
y no valen las prisas. Lógicamente, también se lo recomiendo.
En esta ocasión daremos una idea de como se usan las Apis en multimedia, con un ejemplo
que puede ser bastante completo para empezar. Y que no garantizamos que funcione mas que
con VB5 y W95.
Hagamos una pequeña aplicación para reproducir CDs, ficheros WAV y ficheros MIDI (MID).
Esta aplicación lleva un control de volumen de la señal del CD. No se han puesto mas
controles de volumen para las otra fuentes.
Este programa tiene un módulo para hacer las declaraciones de las Apis y el formulario de la
figura.
Pagina: 302
Vayamos al módulo con las declaraciones :
Option Explicit
Se han destacado en negrita los nombres de las funciones. Mediante estas declaraciones le
estamos diciendo a nuestro programa qué DLL tiene que usar (winmm.dll) y qué funciones de
ella vamos a usar.
Continuemos con los procedimientos del formulario. Observe que las explicaciones al código
están en letra cursiva.
Veamos como ejecutar un CD desde el principio. Usamos para ello la función mciSendString,
que como casi indica su nombre, envía una cadena al dispositivo MCI
Pagina: 303
If TBPista = "" Then TBPista = "1" ‘TBPista es un TextBox para meter la pista inicial
If TBHasta <> "" Then ‘TBHasta es otro TB para meter la pista final
‘Usamos los comandos From y To igual que con el control MCI
Resultado = mciSendString("Play cd From " & Str(TBPista) & " To " & Str(TBHasta), 0&, 0, 0)
Else
Resultado = mciSendString("Play cd From " & Str(TBPista), 0&, 0, 0)
End If
End Sub
Observe que siempre llamamos cd a la sesión de ejecución del CD, ya que le pusimos ese
nombre con el alias.
Veamos ahora como podemos ejecutar un fichero Wav. De dos formas, con dos funciones
distintas. La primera, con la función sndPlaySound.
No se ha previsto parar la ejecución de los ficheros Wav, debido a que generalmente son muy
cortos (se emplean normalmente para sonidos de pequeña duración, debido a su gran tamaño)
Veamos ahora como podemos interpretar una secuencia MIDI (Ficheros *.Mid). También con
mciExecute
Pagina: 304
‘NombreFicheroMIDI se declaró en la sección de declaraciones del formulario para que su
‘ámbito sea toda la aplicación, ya que necesitamos el nombre del fichero que se está
‘ejecutando para poder pararlo, operación que realizamos en otro procedimiento
iResult = mciExecute("Play " & NombreFicheroMIDI)
End Sub
Para parar la ejecución del fichero MIDI (Aquí sí hay que preverlo, ya que con muy pocos K’as
podemos tener mucho tiempo de música)
Vayamos ahora al tema del volumen, que afecta solamente al CD, tal como se citó al
comenzar.
El valor máximo de HScroll2 se cambia de un instante a otro. Se hace igual al valor actual de
HScroll1 menos un 10%. Lo mismo para el valor mínimo.
El parámetro uDeviceID es el ID del dispositivo que queremos variar su volumen. Para el caso
del CD es el valor 1..
El parámetro dwVolume es un número compuesto por 4 Bytes. Los dos primeros Bytes
corresponden al volumen del canal de la izquierda, y los otros dos, al canal de la derecha. El
valor de esos 4 bytes puede ir desde el mínimo (0) hasta el máximo (&HFFFF = 65535). Tiene
cierta complicación el enlazar los dos valores, ya que el dato hay que metérselo en decimal.
Pagina: 305
Label1 = lpdwVolumen ‘En Label1 presentará el valor del volumen
End Sub
Haga una práctica con esto y observará lo difícil que es controlar este número en decimal. No
lo es tanto en Hexadecimal, por lo que podría añadir esta conversión :
Esta forma de sumar dos números (Ojo, que no es sumar, sino concatenar) no tiene porque ser
la única. Pero son matemáticas, no Visual Basic.
Existe otras funciones para el volumen de las otras fuentes de sonido midiOutSetVolume y
waveOutSetVolume respectivamente para las salida del secuenciador MIDI y la reproducción
de ficheros Wav. Las correspondientes para ver el volumen actual son midiOutGetVolume y
waveOutGetVolume.
Pagina: 306
Visual Basic - Guía del Estudiante - Capitulo 18
CORRECCION DE ERRORES Y DEPURACION DE PROGRAMAS - EL OBJETO ERROR
OPTIMIZACION – DISTRIBUCION DE APLICACIONES
Una vez que conocemos gran parte del Visual Basic, y que seguramente habremos hecho
alguna aplicación, es momento de pararnos en una de las cosas que un programador nunca
debe olvidar: Un programa no solo debe funcionar, sino que debe funcionar bien.
Pagina: 307
Parece que esta afirmación carece de sentido o que al menos es una afirmación gratuita. Sin
embargo es un defecto muy común entre programadores noveles, quizás por la alegría que da
el trabajo terminado, olvidarse de algo tan fundamental como la calidad del programa, y perder
por ello la alegría que da el trabajo bien hecho.
Corrección de Errores.
Denominamos Corrección de errores al proceso de la programación en la que se analizan y
corrigen los errores existentes en el código o en el funcionamiento del programa.
Podemos por tanto dividir los errores en errores de código y errores de funcionamiento.
Habrá notado el error de bulto consistente en que A:\MiFicher.Txt debe ir entre comillas dobles.
Este tipo de error se detecta generalmente al ejecutar el código. En este caso, Visual Basic nos
dará el mensaje de error “Error de Sintaxis” nada mas terminar de escribir la línea. Errores
como este, o el típico If sin End If seguro que se los ha encontrado repetidas veces y no
vamos a ahondar mas en ellos. Se corrige el error sintáctico en el momento y el problema
queda resuelto. Pero volvamos a la línea de código anterior, esta vez ya bien escrita:
Al estar escrita correctamente, esta línea no nos puede dar error de sintaxis. Pero, ¿Que
ocurre cuando estamos ejecutando el programa que contiene esa línea, y en el momento de
ejecutarla no tenemos metido un disquete en la unidad A:? O piense lo que ocurriría si
tenemos un disquete en A:, pero no existe en él el fichero MiFicher.Txt. No existe ningún error
de sintaxis. El programa puede funcionar correctamente si, en el momento de la ejecución de
esa línea, tenemos un disco en la unidad A: y éste contiene un fichero llamado MiFicher.Txt.
Sin embargo no puede funcionar si no tenemos metido el disquete, o si este no tiene el
mencionado fichero.
Existen dos tipos de errores de ejecución: Errores Interceptables y Errores que no se pueden
interceptar.
Los errores interceptables son aquellos que Visual Basic conoce. Los dos errores anteriores
son de este tipo. Son errores no interceptables, aquellos que Visual Basic no puede detectar.
No porque no los conozca, sino porque el propio error deja sin trabajar a Visual Basic o incluso
al sistema operativo. Afortunadamente el sistema operativo está muy protegido, pero no por
ello dejan de ocurrir estos errores. ¿Recuerda la frase “El programa xxx ha causado un error
de protección general en el Módulo..... “ Bueno, acaba de producir un error No Interceptable.
Pagina: 308
Podrá advertir que este bucle no se termina nunca, ya que n no podrá alcanzar nunca el valor
2000 ya que cada vez que llega a 1000 le cambiamos su valor a 0. Este tipo de error, mas
normal de lo que parece, ni lo detecta VB ni produce una caída del sistema operativo. Sin
embargo es un error, pero en este caso será el propio programador quien se tenga que dar
cuenta de él, ya que VB no puede ayudarnos debido a que el código, línea a línea, está
perfectamente escrito.
Vemos por tanto que VB solamente nos ayudará en los errores de sintaxis, durante el tiempo
de diseño, y los errores interceptables en tiempo de ejecución.
Errores Interceptables.
Los errores interceptables pueden producirse cuando está ejecutando una aplicación, tanto
en el entorno de Visual Basic como en modo autónomo. Algunos de estos errores pueden
ocurrir también en tiempo de diseño o en durante la compilación.
Un error interceptable es, como decíamos anteriormente, un error que Visual Basic conoce.
Para conocerlos, VB dispone de un objeto que vamos a ver a continuación. El Objeto Error
Objeto Error
Contiene información sobre errores en tiempo de ejecución.
El Objeto Error tiene Propiedades y Métodos. Las propiedades del objeto Error las establece
quien genera el error. Por ejemplo, si el error se genera durante la ejecución, será VB quien
genera las propiedades del objeto Error. Pero puede ser también el programador quien genere
el error. Lo veremos mas adelante
Propiedad Description
Devuelve o establece una cadena descriptiva asociada a un error.
Propiedad HelpContext
Propiedad HelpFile
Pagina: 309
Devuelve o establece la ruta completa del archivo de Ayuda de Microsoft Windows que debe
mostrarse al producirse el error.
Variable = Err.HelpFile
Propiedad LastDLLError
Devuelve un código de error de sistema producido por una llamada a una biblioteca de
vínculos dinámicos (DLL). Sólo aparece en los sistemas operativos Microsoft Windows de 32
bits.
Propiedad Number
Esta es la propiedad mas importante del Objeto Error. Por ello es la propiedad predeterminada.
Permite conocer el número del error producido. También nos permite establecer el número de
error, cuando nos interesa provocar un error mediante código, con el método Raise
Variable = Err
Source
Método Clear
Borra los valores de todas las propiedades del objeto Err.
Sintaxis Err.Clear
Pagina: 310
Puede utilizar Clear para borrar explícitamente el objeto Err una vez que se ha tratado un
error. Visual Basic llama al método Clear automáticamente siempre que se ejecuta alguna de
las instrucciones siguientes:
De aquí se desprende que un error no “sale” del procedimiento en el que se generó. Para salir
de un procedimiento el programa debe pasar necesariamente por una instrucción Exit Sub. En
ese momento, desaparecen todas las propiedades del Objeto Error.
Método Raise
Genera un error en tiempo de ejecución.
Número Requerido. Entero de tipo Long que identifica la naturaleza del error.
Origen Opcional. Expresión de cadena que indica el objeto o aplicación que ha generado
originariamente el error.
Descripción Opcional. Expresión de cadena que describe el error.
ArchivoAyuda Opcional. Ruta del archivo de Ayuda de Microsoft Windows en el que se
encuentra la información sobre el error.
ContextoAyuda Opcional. Identificador de contexto que especifica el tema del archivo
indicado en ArchivoAyuda que contiene la información de ayuda del error.
Todos los argumentos son opcionales, excepto Número. Sin embargo, si utiliza Raise sin
especificar algunos argumentos, y si los valores de las propiedades del objeto Err no se han
borrado, tales valores se conservarán para el error actual.
Decíamos al principio del Objeto Error que sus propiedades las establece quien las generó.
Con el Método Raise se genera un error. Y vea que se pueden establecer sus propiedades.
RutinaErrores:
El nombre de la rutina debe ocupar él solo una línea. Se accede directamente a la rutina
cuando citamos su nombre en el código del procedimiento donde está la Rutina.
Para citarla, debemos usar ese nombre, quitando el carácter dos puntos final. Podemos
llamarla mediante la sentencia GoTo. Veamos un pequeño ejemplo. Es un botón de comando,
y un TextBox. Si el TextBox (Text1) mantiene su texto original (Text1) hacemos que el
programa pase por la rutina. Si lo hemos variado, hacemos que no pase:
Pagina: 311
Else
MsgBox "No pasa por la Rutina"
Exit Sub
End If
Rutina:
MsgBox "Sí pasó por la Rutina"
End Sub
La rutina es en realidad un trozo de código del procedimiento que se ejecutará, bien porque
hayamos dirigido allí la ejecución del programa (mediante GoTo) o bien porque el programa
pase por la rutina al ejecutarse. Observe el Exit Sub que tiene en la parte Else del If - Then. Si
no lo ponemos, el programa pasará por la rutina una vez ejecutada la sentencia condicional If
- Else - End If, igual que si se tratase de cualquier otra parte del programa. Para evitar que
pase por ella, ponemos ese Exit Sub que hará que el programa salga del procedimiento sin
llegar al final.
En el ejemplo anterior, la condición para que pasase por la rutina era que se cumpliese una
determinada condición en Text1. Para que pase por una rutina, al darse la condición de que ha
ocurrido un error, usaremos la instrucción On Error GoTo
Hay un dicho entre los programadores de Visual Basic. Los programadores se dividen en tres
grupos. Los que nunca usan GoTo. Los que usan GoTo sin saber usarla y los que usan GoTo
sabiendo usarla, pero de estos últimos hay muy pocos.
Pagina: 312
Instrucción On Error GoTo
Activa una rutina de tratamiento de errores y especifica la ubicación de la misma en un
procedimiento. También puede utilizarse para desactivar una rutina de tratamiento de errores.
Rutina:
MsgBox "Sí pasó por la Rutina"
End Sub
Cuando insertamos la línea On Error GoTo Rutina, el programa sabe que nada mas
producirse un error, debe ir a la rutina señalada. En esa rutina tomaremos las medidas
adecuadas para que se subsane el error producido. Así por ejemplo, si en una línea le decimos
al programa que vaya a leer un fichero de la unidad A:, puede ocurrir que la unidad no tenga
metido el disco. O que lo tenga metido pero que no exista el fichero en ese disco.
La rutina de corrección de errores debe contemplar cada uno de esos dos casos, y actuar de
forma distinta en uno y en otro.
Si estuviese metido el disco, pero no tuviera un fichero llamado Mificher.Txt, daría este error:
Pagina: 313
Se ha producido el Error ‘53’ de tiempo de ejecución. No se ha encontrado el archivo
En realidad estos errores no son de programa, sino de una utilización incorrecta del programa,
ya que debería estar metido el disco, y que contuviese un fichero llamado Mificher.Txt. Pero
en programación hay que prever estas eventualidades. Y lo lógico sería poner un aviso
diciéndole al usuario que la unidad A: no está preparada (caso 1) o que el disco no contiene el
fichero buscado (caso 2)
Instrucción Resume
Hemos visto en el apartado anterior la sentencia On Error Resume Next, de la que decíamos
que “pasaba” del error y continúa en la línea siguiente a la que provocó el error. Es así ya que
la Instrucción Resume hace desaparecer el error mediante código (Pone Err.Numbber = 0). Si
le añadimos Next el programa sigue ejecutándose en la línea siguiente a la que generó el
error.
La Instrucción Resume puede tener las siguientes sintaxis:
Ya que conocemos las instrucciones On Error GoTo y Resume, veamos en el ejemplo anterior
como resolvemos el problema de que no exista disco en la unidad A: o que en el disco no
exista el fichero buscado:
EJEMPLO
Activemos la detección de errores e introduzcamos una rutina que detecte el error ocurrido y
que haga lo que tenga que hacer en cada caso:
RutinaErrores:
If Err.Number = 71 Then ‘No hace falta poner Err.Number. Basta con Err
MsgBox "La Unidad A no tiene ningún disco. Introduzca uno"
Resume ‘Al poner Resume (sin mas) el programa seguirá ejecutándose
‘en la misma línea que provocó el error. Como hemos
intercalado
Pagina: 314
‘un MsgBox, que lleva implícita una espera a que se le haga
click
‘en su botón, durante esa espera el usuario puede cambiar el
disco
‘y al reiniciarse el programa en esa línea, ya puede tener un
disco
‘para que no se repita el error.
End If
En esta ventana podemos presentar otro tipo de datos, por ejemplo el valor de una variable en
un determinado momento:
Debug.Print MiVariable
Si queremos que cuando se produzca un error se nos presente en esa ventana, basta con
insertar esta línea de código en la Rutina de Error:
Hemos visto la forma de detectar un error y tomar las medidas oportunas para que el
programa siga funcionando. Aquí lo hemos hecho solicitándole una operación al usuario. En
otros casos nos interesará que el programa “pase” del error, en otras que repita un
procedimiento... El programador deberá ver en cada caso la respuesta que debe dar el
programa a un determinado error.
Un programa perfecto es aquel que contempla todas las posibilidades de error y les da
solución a todas. Esto quiere decir, que un programa debería tener en cada procedimiento una
llamada a la detección de errores (On error GoTo ... ) y una rutina de corrección. El trabajo es
grande. La recompensa también.
Pero un error muy común entre programadores es autocomprobar sus errores. Realiza un
programa y comienza a ejecutarlo intentando descubrir los errores en los que puede caer. Le
recomiendo que esa labor la realice un compañero. La persona que realizó el programa sabe
perfectamente lo que debe hacer. Y aún queriendo, le cuesta mucho trabajo cometer errores.
Una persona que nunca haya trabajado con el programa, lo que le cuesta trabajo es no
cometerlos.
Pagina: 315
OPTIMIZACION DE PROGRAMAS
Un programa será mejor, cuanto mejor cumpla los requisitos del cliente y los requisitos
generales que debe cumplir una aplicación. Estos requisitos pueden resumirse en:
- Seguridad
- Rapidez
- Mínimos recursos del sistema
- Ergonomía
- Amigabilidad
- Facilidad de programación de parámetros
Para que un programa sea Seguro es necesario que no falle, lo que se consigue mediante una
depurada técnica de control de errores. Cuando el programa hace uso de una Red de Area
Local, es necesario determinar correctamente las exclusiones mutuas entre usuarios,
protecciones de información, etc.
Declare todas las variables, optimizando el tipo de dato a los datos reales que vaya a contener.
No abuse de bucles anidados. No redibuje ni emplee el método Refresh durante un proceso en
el que necesite rapidez.
La ejecución del código es más rápida si está en un único procedimiento que si utiliza
llamadas a otros procedimientos.
Los accesos a bases de datos (ya se verán) emplean mucho tiempo. Ahí sí merece la pena
optimizar en lo posible.
Pero no merece la pena en la mayor parte de los programas pretender optimizar el software
para aquilatar al máximo la rapidez del programa. Sobre todo cuando esa optimización nos
lleva a pensar que debemos evitar los accesos a disco. El disco flexible (A :) sí presenta unos
tiempos de acceso que deben evitarse. La lectura del disco A: debería ser solamente para
aquellos datos que se traen o se llevan de nuestra aplicación, nunca para meter o sacar datos
necesarios para el funcionamiento de la misma. Para esos datos debe emplearse siempre el
disco duro, que tiene tiempos de acceso muy cortos.
Los recursos del sistema es un tema que debe mirarse con sumo cuidado. Sobre todo la
ocupación de nuestro programa en la memoria.
Para que el programa ocupe el menor espacio posible, debemos tener en cuenta estas reglas:
- Declarar todas las variables con el tipo de datos optimizado a los datos que van a
contener. Una variable sin declarar se convierte automáticamente en tipo Variant, que
ocupará 16 bytes de memoria. Use preferentemente el tipo de dato Byte, que es el que
menos ocupa (1 byte, menos que el boolean) cuando le sea suficiente.
- Cuando veamos Bases de datos, verá que se libera memoria cerrando los objetos de
acceso a datos.
- No abuse de los Bitmap. Quedan preciosos como fondo de las aplicaciones, pero le
pueden estar ocupando 300 ó 400 Ks de RAM. Use en su lugar degradados de color, que
también quedan muy bonitos y no ocupan memoria.
Pagina: 316
Ergonomía y Amigabilidad son dos palabras unidas de raíz a las aplicaciones con interface
gráfica.
Ergonomía significa que una persona frente a una aplicación debe sentirse a gusto. Para ello
debe crear una interfaz gráfica sencilla, con las dimensiones de sus componentes adaptadas al
contenido y tamaño del formulario que los contiene. Los componentes deben quedar
dispuestos el la interface de una manera lógica, buscando la armonía de formas.
No se debe emplear a fondo con los colores. Los tonos vivos y “disparatados” que pueden
parecerle bien en un principio, terminan cansando al usuario. Use preferentemente tonos
apagados, grises, azules o verdes, y estos últimos ni muy oscuros ni muy chillones.
Una vez conocido el ancho de la pantalla, reorganice las medidas de cada control:
No tiene necesidad de complicarse la vida con APIs. Puede hallar el ancho de su pantalla
mediante el objeto Screen
La Amigabilidad se definió como la facilidad que tiene un programa para aportar datos o
facilidades de operación al usuario, antes de que este se los pida. Una aplicación es amigable
cuando el usuario, por ejemplo, no tiene que usar el ratón en un proceso de escritura. ¿Se
imagina un programa de captura de datos, donde debe señalar con el ratón una a una las
casillas donde va a escribir? Esa aplicación no sería nada amigable. Imagínese sin embargo
ese mismo programa, que al terminar de insertar un dato, pulsando ENTER se pasa el foco
automáticamente a la siguiente casilla por orden lógico de inserción. Esa es una aplicación
amigable.
Una aplicación amigable debe tener necesariamente una ayuda. Y la ayuda que debe usar es
precisamente la Ayuda de Windows. Las ayudas deben ser breves, exactas y concisas. No
deben liar mas de lo que está al usuario. No deben ser muy extensas. Si necesita explayarse
para explicar su aplicación, haga dos ficheros de ayuda.
En VB5 puede usar la propiedad ToolTipText de sus controles. Esto le permite colocar una
pequeña etiqueta con la operación que se realiza si hace click en ese control. Es muy práctico
y muy bonito, pero no abuse de los ToolTipText porque llega a ser farragoso que cada vez que
detenemos un instante el cursor de ratón aparezca la típica etiqueta amarilla.
Pagina: 317
Imagínese un programa hecho rígidamente. Es posible que cumpla con las todas las
especificaciones pedidas por el cliente. Las cumple hoy. Si mañana el cliente incorpora un
nuevo producto a su línea de negocios, será necesario introducir una reforma en el código de
la aplicación.
Pero imagínese la parte peor de este planteamiento. Lo más probable es que ese programa
solamente le sirva al cliente que se lo encargó.
Los programas deben ser abiertos, permitiendo que la mayor parte de los parámetros puedan
variarse. Para ello es muy práctico emplear ficheros de inicialización.
Un fichero de este tipo debe estar en ASCII puro, de manera que se pueda editar con cualquier
editor (Bloc de notas, p.e.) y ver todos los parámetros que se introducen. Esta forma de
guardarlo nos permite ver cualquier error que pueda contener simplemente editándolo. Podría
tener esta forma:
[TITULO]
Talleres Pepe. Programa de Recepción de Vehículos para Reparar
[BASEDATOS]
C:\Mis Documentos\Bases de Datos\Vehiculos.MDB
[USUARIOS]
María López González
José Suárez Martín
Andrés Ortiz Gómez
Luisa Ortega Cano
[TECNICOS]
Obdulio Pérez Pérez
Ataulfo López Alvarez
Octavio Fernández Alonso
Edelmiro López Arriortúa
[BASECLIENTES]
C:\Mis Documentos\Bases de Datos\Clientes.MDB
[FIN DATOS]
Este es un posible fichero de inicialización. Observe que existen unas líneas donde se
introduce entre brackets [ ] el tipo de información que va a venir a continuación. La línea o
líneas siguientes a estas líneas contienen una o varias informaciones del tipo especificado
entre [ ].
En el ejemplo anterior, la primera línea de información nos aporta el título que va a tener la
aplicación para ese cliente determinado. Para instalar la aplicación a otro cliente, basta
cambiar el contenido de esta línea, sin tocar para nada el programa. Lo mismo ocurre con la
línea siguiente, que le permite al programa conocer la ubicación dentro del disco de la base de
datos.
Pagina: 318
La línea [USUARIOS] nos va a permitir introducir varios nombres, que serán los nombres de
las personas que manejan el programa. Observe que existe una diferencia fundamental entre
las líneas anteriores y esta. En las líneas anteriores, la información no cambia a lo largo del
tiempo, y si hubiera que realizar algún cambio en una de estas informaciones, sería el
programador quien lo realizase. En el apartado [USUARIOS] la información es cambiante a lo
largo del tiempo. No tendría sentido que tuviese que ir el programador a introducir el dato de
un nuevo trabajador cada vez que haya un movimiento en la plantilla de ese taller. Tampoco
será muy práctico que sea el propio cliente el que edite mediante el bloc de notas este fichero.
Probablemente cometa un error involuntario que haga que no funcione la aplicación. La
solución para que el usuario pueda cambiar la información de ciertas partes de este fichero, es
dotar a la aplicación de un asistente para que lo realice. Este asistente le permitirá cambiar
solamente las partes que no afecten al funcionamiento del programa, y se lo permitirá hacer
de una forma cómoda y sistemática, de forma que cualquier usuario, por muy pocos
conocimientos que tenga, pueda realizarlos.
Veamos un procedimiento donde el programa puede interpretar estos datos. Imagine que este
fichero con datos se encuentra situado en el mismo directorio de la aplicación (No obligue
nunca a poner la aplicación en un determinado directorio. No gusta a muchos clientes) Como
no sabemos en que directorio va a estar, obtenga este dato del objeto App. Supongamos que
el fichero anterior se llama MisDatos.Ini. Veamos el Procedimiento. Este procedimiento
deberá estar en el formulario inicial, y lo llamaremos desde el procedimiento Form.Load de
ese formulario para que se ejecute durante la carga del mismo.
Como los datos obtenidos aquí se van a utilizar en otros procedimientos, suponemos que las
variables que los contienen se han declarado en el sitio adecuado para cubrir el ámbito que
deseamos.
General – Declaraciones
Dim BaseDatos1 As String, BaseDatos2 As String
Pagina: 319
'las líneas iniciales y evitar que pase por el Select Case
Loop
Close #1
End Sub
DISTRIBUCION DE APLICACIONES
Esta técnica permite ahorrar espacio en el disco, ya que si tenemos dos aplicaciones
realizadas en VB, lo mas probable es que compartan varios de estos ficheros DLLs u OCX, de
forma que se consigue un ahorro real de disco duro. Pero eso sí, a costa de complicar un poco
la instalación … y el Registro de Windows.
Sería difícil conocer las DLLs y OCX que debemos distribuir con nuestra aplicación. Pero VB
facilita las cosas ya que dispone de un buen asistente (Wizard) para la creación de discos de
distribución. Y me refiero a la versión 4 de VB. El Wizard de la versión 5 da problemas. Ojo.
Este asistente detectará los controles que hemos usado en la aplicación y por lo tanto las DLLs
y OCX necesarios. Primera precaución. El asistente considera que la aplicación usa TODOS
los controles presentes en la caja de herramientas en el momento de realizar el ejecutable. En
la caja de herramientas puede haber muchos controles y nuestro programa utiliza solamente
uno de ellos. El asistente distribuiría las DLL y OCX necesarios para todos los controles
presentes en la caja de herramientas en el momento de la creación del .EXE
Una vez quitado todo lo que no es necesario, se genera el ejecutable de la aplicación, que
debe estar necesariamente, en el mismo directorio donde esté el fichero .VBP.
Salga de VB y vaya al Asistente para instalar Aplicaciones, que está en el mismo grupo de
trabajo que el VB. Para buscar el programa a distribuir, haga click en el botón con tres puntos
al lado del cuadro de texto de Archivo de Proyecto.
Pagina: 320
Ahora le da a elegir entre guardar los ficheros a distribuir en un directorio de su disco duro (o
de su Red de Area Local) o en disquetes. La elección depende de sus necesidades. Es muy
práctico, meterlo en un directorio. No le pedirá discos formateados y la ejecución será mucho
más rápida. Esta solución es práctica cuando la distribución la va a realizar a través de la Red
de Area Local o a través de Internet. Para realizar la instalación en el ordenador destino,
deberá copiar todos los ficheros generados por el asistente en el mismo directorio, y proceder
a la instalación desde ese directorio. Si tiene RAL es comodísimo instalar desde un directorio
de un disco del servidor.
Si lo que quiere es distribuirla en disquetes, es más práctico elegir guardar los ficheros en
disquetes. Le dirá cuantos discos necesita. Le irá pidiendo uno a uno.
En el siguiente paso analiza si ha usado algún servidor OLE. En ese caso se lo incluye en los
discos de distribución.
En el siguiente paso es cuando le indica las DLLs y OCX que va a distribuir con su aplicación:
Ficheros .DLL y .OCX que va a distribuir con su aplicación.
Si hace click en Detalles del archivo, le dirá las propiedades del fichero seleccionado. Esto le
permite conocer la versión y fecha de ese fichero. Recuerde que a la hora de hacer la
instalación, si existe un fichero .DLL con fecha anterior al que lleva su instalación, se lo
cambia. Si el fichero DLL que lleva su instalación tiene fecha anterior al existente, no lo
cambia. Es decir, se queda con el mas moderno.
En el siguiente paso le pide que elija entre instalarlo en el directorio de la aplicación o como
servidor OLE. Elija siempre el primero.
En el paso siguiente le invita a quitar o añadir ficheros a la distribución. Puede quitar ficheros
DLL u OCX, siempre a sabiendas de que la aplicación no se podrá ejecutar si no lo distribuye.
Pero puede ocurrir que el ordenador donde la va a instalar ya lo tenga. Depende de Ud. Quitar
uno de estos ficheros.
En este paso también puede añadir un fichero. Piense por ejemplo, en el fichero de
inicialización que vimos anteriormente. Deberá distribuirlo con su aplicación, aunque luego,
una vez en el ordenador del cliente necesite cambiarle algún parámetro. Para ello haga click
en Agregar Archivos, le aparecerá un cuadro donde puede elegirlo. Verá que se le inserta en el
cuadro donde están el resto de los ficheros. Si ahora lo selecciona y hace click en Detalles del
Archivo le aparecerá un cuadro donde puede ver, entre otras cosas, el directorio de destino.
Por defecto siempre le aparece el directorio de la aplicación $(App.Path), pero puede
cambiarlo al directorio que desee: directorio de Windows $(WinPath), directorio
Windows\System &(WinSysPath), directorio de ficheros comunes $(CommonFiles), directorio
de Archivos de Programas $(ProgramFiles).
Una vez realizado este paso, solamente le queda hacer click sobre Terminar. Si ha elegido
realizar la distribución sobre disquetes se los irá pidiendo uno a uno.
Le creará varios ficheros, casi todos ellos comprimidos (Observe que el nombre del fichero
termina en _). Existirá uno que no está comprimido, el Setup.LST
Este fichero contiene toda la información relativa a la instalación, y puede cambiarla ya que
está editado en ASCII puro. Tiene esta forma:
[BootStrap]
File1=1,,setup132.ex_,setup132.exe,$(WinPath),$(EXESelfRegister),,10/16/1995,174592,4.0.0.2422
File2=1,,stkit432.dl_,stkit432.dll,$(WinSysPath),,$(Shared),10/16/1995,24576,4.0.2422.0
File3=1,,VB40032.DL_,VB40032.DLL,$(WinSysPath),,$(Shared),8/15/1995,721168,4.0.24.22
File4=1,,ven2232.ol_,ven2232.olb,$(WinSysPathSysFile),,,11/17/1997,37376,2.0.0.5924
File5=1,,olepro32.dl_,olepro32.dll,$(WinSysPath),$(DLLSelfRegister),$(Shared),11/17/1997,114960,5.0.4118.1
File6=1,,msvcrt20.dl_,msvcrt20.dll,$(WinSysPathSysFile),,,8/24/1996,253952,2.11.0.0
File7=1,,msvcrt40.dl_,msvcrt40.dll,$(WinSysPath),,$(Shared),11/24/1997,326656,4.10.0.6038
File8=1,,ctl3d32.dl_,ctl3d32.dll,$(WinSysPathSysFile),,,10/16/1995,27136,2.29.0.0
File9=1,,VB4ES32.DL_,VB4ES32.DLL,$(WinSysPath),,$(Shared),10/16/1995,37184,4.0.24.22
[Files]
File1=1,,COMDLG32.OC_,COMDLG32.OCX,$(WinSysPath),$(DLLSelfRegister),$(Shared),11/17/1997,128784,5.0.37.14
Pagina: 321
File2=1,,MFC40.DL_,MFC40.DLL,$(WinSysPath),$(DLLSelfRegister),$(Shared),4/2/1997,924432,4.1.0.6139
File3=1,,MFC40LOC.DL_,MFC40LOC.DLL,$(WinSysPath),,$(Shared),10/16/1995,45056,4.0.0.5208
File4=1,,TABCTL32.OC_,TABCTL32.OCX,$(WinSysPath),$(DLLSelfRegister),$(Shared),11/17/1997,192784,5.1.43.19
File5=1,,RICHTX32.OC_,RICHTX32.OCX,$(WinSysPath),$(DLLSelfRegister),$(Shared),2/20/1997,195856,5.0.37.14
File6=1,,COMCTL32.OC_,COMCTL32.OCX,$(WinSysPath),$(DLLSelfRegister),$(Shared),11/17/1997,604432,5.1.43.19
File7=1,,CCTLES32.DL_,CCTLES32.DLL,$(WinSysPath),,$(Shared),10/16/1995,39936,1.0.23.31
File8=1,,DBLIST32.OC_,DBLIST32.OCX,$(WinSysPath),$(DLLSelfRegister),$(Shared),2/20/1997,202000,5.0.37.14
File9=1,,DBGRID32.OC_,DBGRID32.OCX,$(WinSysPath),$(DLLSelfRegister),$(Shared),2/20/1997,519680,5.0.37.14
File10=1,,GRDKRN32.DL_,GRDKRN32.DLL,$(WinSysPath),,$(Shared),10/16/1995,136704,1.19.0.54
File11=1,,DAO3032.DL_,DAO3032.DLL,$(MSDAOPath),$(DLLSelfRegister),$(Shared),11/17/1997,447760,3.0.0.2627
File12=1,,MSJT3032.DL_,MSJT3032.DLL,$(WinSysPathSysFile),,,11/17/1997,965904,3.0.0.2809
File13=1,,MSJTER32.DL_,MSJTER32.DLL,$(WinSysPathSysFile),,,11/17/1997,98356,3.0.0.2712
File14=1,,MSJINT32.DL_,MSJINT32.DLL,$(WinSysPathSysFile),,,11/17/1997,33552,3.0.0.2712
File15=1,,VBAJET32.DL_,VBAJET32.DLL,$(WinSysPathSysFile),,,2/20/1997,18192,5.0.0.7122
File16=1,,VBDB32.DL_,VBDB32.DLL,$(WinSysPath),,$(Shared),10/16/1995,59504,4.0.24.22
File17=1,,MSRD2X32.DL_,MSRD2X32.DLL,$(WinSysPathSysFile),$(DLLSelfRegister),,10/16/1995,250640,3.0.0.2008
File18=1,,MSWNG300.DL_,MSWNG300.DLL,$(WinSysPathSysFile),,,10/16/1995,302352,3.0.0.2008
File19=1,,ODBCJT32.DL_,ODBCJT32.DLL,$(WinSysPathSysFile),,,2/20/1997,241664,3.50.3602.0
File20=1,,ODBCJI32.DL_,ODBCJI32.DLL,$(WinSysPathSysFile),,,2/20/1997,42854,3.50.3602.0
File21=1,,ODBCTL32.DL_,ODBCTL32.DLL,$(WinSysPathSysFile),,,2/20/1997,77824,3.50.3602.0
File22=1,,VBAR2232.DL_,VBAR2232.DLL,$(WinSysPathSysFile),,,11/17/1997,244496,2.0.0.5924
File23=1,,TPepe.ex_,TPepe.exe,$(AppPath),$(EXESelfRegister),,9/1/1998,10240,1.0.0.0
File24=1,,Datos.In_,Datos.Ini,$(AppPath),,$(Shared),9/1/1998,753
[Setup]
Title=TPepe
DefaultDir=$(ProgramFiles)\TPepe
Setup=setup132.exe
AppExe=TPepe.exe
AppPath=
Las últimas líneas son únicamente de relleno. Cuando realiza la distribución en disquetes, este
fichero va en el primero de ellos. Como no le sobra ni un byte, no podría modificar nada en
este fichero. Cuando tenga que realizar alguna modificación, consiga espacio extra en este
fichero borrando varias líneas de las que contienen xxxx
[Setup]
Title=TPepe
DefaultDir=$(ProgramFiles)\TPepe
Setup=setup132.exe
AppExe=TPepe.exe
AppPath=
Esto le va a fijar el título de la aplicación (Title), que será el que le figure en el icono o en la
barra de programas. Puede poner el nombre que quiera. Toma como nombre por defecto el
que le hayamos dado al proyecto (En nuestro ejemplo Tpepe (Talleres Pepe))
También le fija el directorio donde lo va a instalar (DefaultDir). Por defecto pone el directorio
Archivos de Programas $(ProgramFiles) y en él un subdirectorio con el mismo nombre de la
aplicación. Puede cambiar al directorio que desee. Por ejemplo:
DefaultDir = C:\MiCarpeta
Pagina: 322
App.Path = No ponga nada. Le evitará complicaciones.
La sección [Files] indica los ficheros que debe cargar, cada uno con indicación del directorio
donde debe colocarlo. No toque nada de esta sección.
La sección [BootStrap] contiene información de los ficheros que le van a realizar la instalación.
No los toque.
Nota final
Este capítulo termina la primera parte de esta Guía del Estudiante. Aproximadamente,
corresponde al primer trimestre del curso. La segunda parte habla exclusivamente de bases de
datos. Asegúrese que conoce perfectamente lo explicado hasta aquí. No se volverán a tocar
estos temas en el resto del curso.
Pagina: 323