![]()
·
INDICE
·
Introduccion e historia de VISUALBASIC
·
Visual Basic - Guía del Estudiante Cap. 1:
ARRANQUE Y ENTRADA
·
Visual Basic - Guía del Estudiante Cap. 2:
FORMULARIOS
·
Visual Basic - Guía del Estudiante Cap. 3:
CONTROLES
·
Visual Basic - Guía del Estudiante Cap. 4:
CONTROLES DE IMAGEN
·
Visual Basic - Guía del Estudiante Cap. 5:
CONTROLES DE BUSQUEDA DE FICHEROS
·
Visual Basic - Guía del Estudiante Cap. 6:
DDE
·
Visual Basic - Guía del Estudiante Cap. 7:
METODOS
GRAFICOS
·
Visual Basic - Guía del Estudiante Cap.8:
FICHEROS
·
Visual Basic - Guía del Estudiante Cap.9:
INTERFACE DE DOCUMENTOS MULTIPLES (MDI)
·
Visual Basic - Guía del Estudiante Cap.10:
El
Objeto Printer
·
Visual Basic - Guía del Estudiante Cap. 11:
FUNCIONES
·
Visual Basic - Guía del Estudiante Cap. 12:
EL CONTROL RICH TEXT BOX
·
Visual Basic - Guía del Estudiante Cap. 13:.
LA
AYUDA DE WINDOWS
·
Visual Basic - Guía del Estudiante Cap. 14:
Procedimientos
y funciones en VB
·
Visual Basic - Guía del Estudiante Cap. 15:
OLE
·
Visual Basic - Guía del Estudiante Cap. 16:
MULTIMEDIA. REPRODUCCION DE SONIDOS E IMÁGENES
·
Visual Basic - Guía del Estudiante Cap. 17:
CORRECCION DE ERRORES Y DEPURACION DE PROGRAMAS -
EL OBJETO ERROR. OPTIMIZACION – DISTRIBUCION DE APLICACIONES
·
Visual Basic - Guía del Estudiante Cap. 18:
BASES DE DATOS EN VISUAL BASIC
·
Visual Basic - Guía del Estudiante Cap. 19:
OPERACIONES CON BASES DE DATOS SIN UTILIZAR EL
CONTROL DATA
Introduccion
e historia de VISUALBASIC
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 aparición de los primeros
ordenadores personales, dedicados comercialmente al usuario particular, allá
por la primera mitad de los ochenta, el BASIC resurgió como lenguaje de
programación pensado para principiantes, y muchos de estos pequeños ordenadores
domésticos lo usaban como único sistema operativo (Sinclair, Spectrum, Amstrad)
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.
Las razones para ello eran obvias:
-
No era un lenguaje estructurado.
-
No existían herramientas de compilación fiables.
-
No disponía de herramientas de intercambio de información.
-
No tenía librerías.
-
No se podía acceder al interior de la máquina.
-
Un largo etcétera de desventajas respecto a otros lenguajes de programación.
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 profesional hizo
borrar por fin el "mal nombre" asociado a la palabra BASIC.
Actualmente se está comercializando la versión
5.0 de este producto. Desde su salida al mercado, cada versión supera y mejora
la anterior. Dados los buenos resultados a nivel profesional de este producto,
y el apoyo prestado por el fabricante para la formación de programadores,
Visual-Basic se ha convertido en la primera herramienta de desarrollo de
aplicaciones en entorno Windows.
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.
Características
Generales de Visual-Basic
Visual-Basic es una herramienta de diseño
de aplicaciones para Windows, en la que estas se desarrollan en una gran parte
a partir del diseño de una interface gráfica. En una aplicación Visual - Basic,
el programa está formado por una parte de código puro, y otras partes asociadas
a los objetos que forman la interface gráfica.
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.
La creación de un programa bajo Visual
Basic lleva los siguientes pasos:
- Creación de un interface de usuario.
Este interface será la principal vía de comunicación hombre máquina, tanto para
salida de datos como para entrada. Será necesario partir de una ventana - Formulario - a la que le iremos añadiendo
los controles necesarios.
- Definición de las
propiedades de los controles - Objetos - que hayamos colocado en ese
formulario. Estas propiedades determinarán la forma estática de los controles,
es decir, como son los controles y para qué sirven.
- 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.
- Generación del
código del programa. Un programa puede hacerse solamente con la programación de
los distintos procedimientos que acompañan a cada objeto. Sin embargo, VB
ofrece la posibilidad de establecer un código de programa separado de estos
eventos. Este código puede introducirse en unos bloques llamados Módulos, en
otros bloques llamados Funciones, y otros llamados Procedimientos. Estos
Procedimientos no responden a un evento acaecido a un objeto, sino que
responden a un evento producido durante la ejecución del programa.
No es necesario entender de momento lo
anterior. Visual Basic introduce un concepto nuevo de programación, y es
necesario cambiar hasta el argot del programador. Posiblemente se le habrán
acumulado demasiados términos de una sola vez. Es normal. A poco que siga
leyendo verá las cosas mas claras cuando se explique una por una.
VARIABLES.
DEFINICION Y ENTORNO
Basic, desde siempre, al contrario de
otros sistemas de programación, no exigió la definición 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:
Declare
Nombre As String Le dice que Nombre es una
sucesión de letras
Declare Apellido1
As String
Declare Apellido2 As String
Declare
Dirección As String
Declare
Teléfono As String Le dice que
Teléfono es una sucesión de letras
Declare
DNI As Número Le dice que DNI
es un número
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.
Por ejemplo, si Basic encuentra estas
instrucciones
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
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.)
Booleana (2) Admite los valores 0 y 1, o True
(verdadero) y False (falso)
Byte (1) Números enteros, en el rango de 0 a 255
Integer (2) Números enteros en el rango de -32768 a
32767
Long (4) Números enteros en el rango de -2147483648
a 2147483647
Single (4) Punto flotante, simple precisión
Doble (8) Punto flotante, doble precisión.
Currency (8) Entero, con punto decimal fijo (Típico de monedas)
String (*) Cadenas alfanuméricas de longitud variable
o fija
Date (8) Fechas
Objet (4) Referencia a objetos
Variant (**) Otros tipos de datos
(*) 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
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.
Los caracteres que definen cada tipo de
variable son:
% Integer & Long ! Single
# Double @ Currency $ String
Ejemplos
Prácticos de declaración de variables
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 :
Dim
Var1 as String Var1 puede tener
cualquier número de caracteres
Dim
Var2 as String * 15 Var2
puede tener un máximo de 15 caracteres.
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 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)
Si la aplicación va a tratar moneda,
piense en la forma de expresar los números decimales y el número de ellos
permitidos, así como el redondeo. La
variable correcta para este caso es Currency, pero Currency le añade
automáticamente el tipo de moneda de cada país (Pts. Para España) lo que con
frecuencia es un engorro. Los datos del tipo de moneda los toma del sistema
operativo del ordenador, por lo que no se extrañe si le expresa el número de
pesetas en dólares. Cambie el país en
su S. O.
Ambito
de las variables.
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:
Formulario1 Formulario2 Formulario3 Módulo1 Modulo2
Declaraciones Declaraciones Declaraciones Declaraciones Declaraciones
Proc.
A1 Proc.B1 Proc.C1 Proc.D1 Proc.E1
Proc.
A2 Proc.B2 Proc.C2 Proc.D2 Proc.E2
Proc. A3 Proc.B3 Proc.C3 Proc.D3 FunciónE1
Proc. A4 Proc.B4 Proc.C4 Proc.D4
FunciónE2
Proc. A5 Proc.BB1
Proc.CC1 FunciónE3
Proc. AA1 Proc.BB2 Proc.CC2 FunciónE4
Proc. AA2 Proc.B33 Proc.CC3 FunciónE5
Proc. AA3 Proc.CC4 FunciónE6
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.
Tipos
de declaración de variables.
Sentencia DIM Es la forma
mas común de declarar una variable como
Privada. Puede
emplearse en un Procedimiento, Función, Formulario o Módulo. La sintaxis es de
la siguiente forma:
Dim nombrevariable As
Integer (o el tipo que sea)
Declarando una variable con la sentencia
DIM, en un formulario, Función, procedimiento o
módulo, el entorno de la variable será el explicado anteriormente para
una variable declarada como Privada. Es decir, esa variable no sale del
formulario, procedimiento ó módulo donde se declaró. Cada vez que entremos al
formulario, procedimiento o módulo, esa variable tomará el valor cero (si es
numérica) o nulo (si es string).
Sentencia
PRIVATE Es la forma de declarar una variable como Privada.
Puede
emplearse solamente
en la sección de declaraciones de un Formulario o Módulo. La sintaxis es de la
siguiente forma:
Private nombrevariable As Tipovariable
Declarando una variable mediante la
sentencia PRIVATE en un Formulario o
Módulo, esa variable puede usarse en todo ese Formulario o Módulo (En todos sus
Procedimientos y Funciones), pero NO fuera del Formulario o Módulo donde se
declaró.
La sentencia Private no puede usarse en un procedimiento o función.
Sentencia
PUBLIC Es la forma de declarar una variable como Pública. Puede
emplearse solamente
en la sección de declaraciones de un Formulario o Módulo. La sintaxis es de la
siguiente forma:
Public nombrevariable As Tipovariable
Declarando una variable de esta forma en
la sección de declaraciones de un Módulo,
esa variable puede usarse en cualquier parte del programa citándola simplemente
por su nombre.
Si se declara de esta forma en la sección
de declaraciones de un Formulario, esa variable puede usarse en toda el
programa. Para nombrarla, si estamos en el Formulario donde se declaró basta
con citarla por su nombre. Si no estamos en ese Formulario, habrá que citarla
por el nombre del Formulario, seguido del nombre de la variable, separados por
un punto :
NombreFormulario.Nombrevariable
En un Módulo puede usarse también la
sentencia Global en vez de Public :
Sentencia GLOBAL Declara una variable que es válida en todo el
programa. La sintaxis
es:
Global nombrevariable As tipovariable
La sentencia Global sólo puede usarse en el apartado de declaraciones de un Módulo.
Mediante la sentencia Global la variable puede usarse en todo
el espacio del programa.
Sentencia
STATIC
Como se dijo anteriormente, una variable
declarada en un procedimiento pierde su valor al salir de él. Lo peor es que
una vez que el programa vuelva a entrar en ese procedimiento, la variable
estará puesta a cero. Afortunadamente, esto último tiene solución. Si
declarásemos una variable en un procedimiento o función, como estática, esa
variable, aunque no la podremos utilizar fuera de ese procedimiento o función,
cuando volvamos a él conservará el valor que tenía cuando lo abandonamos. Esta
declaración como estática se realiza mediante la intrucción Static
Static nombrevariable As tipovariable
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 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.
Resumimos la forma de declarar una
variable :
En un Procedimiento (La variable
no puede usarse fuera de esta Procedimiento)
Dim Variable As Tipovariable
En un Procedimiento, como permanente (La variable no puede usarse fuera de este
procedimiento, y dentro de él conserva el valor aunque se salga y se vuelva a
entrar)
Static Variable
As Tipovariable
En un Formulario (En su
sección de declaraciones)
Como Privada (Solamente se puede usar en ese Formulario)
Dim Variable As Tipovariable ó
Private Variable As Tipovariable
Como Pública (Puede usarse en toda la aplicación)
Public Variable As Tipovariable
En un Módulo
Como Privada (Solamente puede usarse en ese Módulo)
Dim Variable As Tipovariable ó
Private Variable As Tipovariable
Como Pública (Puede usarse en toda la aplicación)
Public Variable As Tipovariable ó
Global Variable As Tipovariable
Error
típico de un programador novel de Visual Basic
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 :
Dim Variable1, Variable2, Variable3, Variable4 As String
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 :
Dim Variable1 As
String, Variable2 As String,
Variable3 As String, Variable4 As String.
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.
Llamamos sentencias condicionales a
aquellas que se realizan si se cumple una determinada condición. Son las
sentencias por las que empieza cualquier texto de Basic, y este no va ser
menos.
La sentencia condicional mas usada es:
Si se cumple una condición Entonces
Realiza
estas instrucciones
Si no se cumple
Realiza
estas otras instrucciones
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
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.
Cuando lo que queremos es elegir un
valor, no ejecutar instrucciones como hacíamos anteriormente, disponemos de
otras dos funciones: Choose y Switch.
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)
A = Switch
(B=1, 5, B=2, 7, B=3, 11)
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 )
En estas sentencias, Switch y Choose, si el valor de
B no coincide con ninguno de los valores que se le habían establecido (1, 2 ó 3
en nuestro caso), la sentencia devuelve el valor Nulo ( Null ). Esto puede producir algún error si no se
contempla esa posibilidad.
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
Fin del bucle
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.
Bucle por contador
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
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á.
Bucles por condición
Ejecuta
las instrucciones del bucle mientras se cumple una condición
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.
Si lo que queremos es que el programa se
ejecute mientras no se cumpla una determinada condición, la sentencia será:
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 ....
Para terminar bien el programa anterior
utilizaremos la condición de While (Mientras se cumpla la condición)
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 (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.
Private
Sub Command1_Click() ' Esta línea sale
automáticamente
For N=65 To 90
Label1.caption
= Chr ( N )
Label1.RefreshN ' Refresca la etiqueta
X = 0
Do While X < 1000 ' Bucle de temporización
X = X + 1
Loop
Next N ' Termina el bucle de temporización
End
Sub ' Esta línea
sale automáticamente
Hemos puesto nuestra primera piedra en Visual Basic.
Este ejemplo es muy sencillo. Visual Basic es tan sencillo como este ejemplo.
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:
Curso de Visual Basic
abcdefghijklmnopqrstuvwxyz1234567890
123456789
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.
Para presentar un número en la pantalla,
el ordenador debe convertirlo previamente a una cadena.
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:
Str (número) Convierte
un número a una cadena en numeración decimal.
Val (cadena
numérica) Obtiene el valor (el número) correspondiente a esa cadena.
Ejemplos
Variablenumerica
= Val (TextBox1.Text)
Este
ejemplo convierte la cadena de caracteres (numéricos) que hubiese en la caja de
texto TextBox1 en un número, y asocia este número a la variable Variablenumerica.
Si
el contenido de la caja de textos no fuesen caracteres numérico (abcd, por
ejemplo), Variablenumerica tomaría el valor 0.
Label1.Caption
= Str (Variablenumerica)
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.
Puede también transformar a una cadena de
caracteres el valor de un CheckBox o de un OptionButton. En estos casos
devuelve 0 y 1 para el CheckBox (Desactivado / Activado) y Verdadero ó
Falso para el OptionButton (Activado /
Desactivado)
label1.Caption = CStr(booleana) Label1.Caption = Verdadero si booleana es
true
Label1.Caption
= Falso si booleana es False
Label2 = CStr(Check1.Value) Label2.Caption = 1
si Check1 está activado
Label2.Caption
= 0 si Check1 está desactivado
Label3 = CStr(Option1.Value) Label3.Caption = Verdadero si Check1 está activado
Label3.Caption
= Falso si Check1 está desactivado
Si se aplica Cstr a una variable tipo
Fecha/Hora devuelve la fecha / Hora en formato corto.
Mas funciones de cadena:
Left (cadena,
n)
Extrae los n
primeros caracteres de una cadena, comenzando por la izquierda.
Si
cadena = Curso de Visual Basic (Para
todos los ejemplos)
Resultado
= Left (cadena, 10) ----> Resultado = Curso de V
Right (cadena, n) Extrae lo n últimos caracteres de la cadena
Resultado
= Right (cadena, 10) ----> Resultado = sual Basic
Mid (cadena, m, n) Extrae
n caracteres de la cadena, siendo el primer carácter extraído el que ocupa el lugar m.
(Vea Instrucción
Mid mas abajo)
Resultado
= Mid (cadena, 3, 10) ----> Resultado
= rso de Vis
LCase
(cadena) Devuelve otra cadena igual, pero con todos los
caracteres en
minúsculas. (LCase = Lower Case)
Resultado
= Lcase (cadena) ----> Resultado
= curso de visual basic
UCase (cadena) Devuelve
otra cadena igual, pero con todos los
caracteres en
mayúsculas. (UCase = Upper Case)
Resultado
= UCase (cadena) ----> Resultado
= CURSO DE VISUAL BASIC
Len (cadena) Devuelve
la longitud de la cadena
Resultado
= Len (cadena) ----> Resultado
= 21
LenB (Cadena) Devuelve el número de Bytes empleados para almacenar
la
cadena.
Sorpréndase, es el doble que Len (Cadena)
String (n, carácter) Devuelve una cadena de n caracteres como el
indicado
Resultado
= String (8, "a") ----> Resultado = aaaaaaaa
Resultado
= String (8, Chr(65)) ----> Resultado = AAAAAAAA
Resultado
= String (8, 65) ----> Resultado = AAAAAAAA
Space (n) Devuelve una cadena formada por
n espacios.
Resultado
= "A" + Space (6)+
"B" ----> Resultado = A B
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.
InStr
(cadena, cadena1) Busca la cadena1 dentro de cadena
y devuelve el número de orden dentro de cadena
donde se encuentra la primera letra de cadena1
Resultado
= InStr (cadena, "sua") ----> Resultado = 12
StrConv Convierte
una cadena de caracteres en otra, según las instrucciones
que le sigan. Puede
sustituir a UCase o LCase si la instrucción es
UpperCase o
LowerCase respectivamente, o poner la primera letra de todas las palabras de la cadena en mayúsculas, si la
instrucción es ProperCase.
Resultado
= StrConv (cadena, UpperCase) ----> Resultado = CURSO DE VISUAL
BASIC
Resultado
= StrConv (cadena, LowerCase) ----> Resultado = curso de visual basic
Resultado
= StrConv (cadena, ProperCase) ----> Resultado = Curso De Visual Basic
Instrucción
Mid
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.
La Instrucción Mid reemplaza un número especificado
de caracteres en una variable de cadena con caracteres de otra cadena.
Sintaxis Mid(cadena1,
inicio[, longitud]) = cadena2
Resultado
Mid (cadena, 7,2)=”Sobre” ---- > Resultado = Curso sobre
Visual
Basic
FUNCIONES CON NUMEROS
_________________________
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.
Los
operadores que utiliza para las operaciones básicas son:
+ Suma
- Resta
* Multiplicación
/ División
\ División sin decimales
Mod Resto de una división
^ Eleva a un exponente
Ejemplos
Resultado
= 12 + 15 ----> Resultado = 27
Resultado
= 15 - 12 ----> Resultado = 3
Resultado
= 15 * 12 ----> Resultado = 180
Resultado
= 15 / 12 ----> Resultado = 1.25
Resultado
= 15 \ 12 ----> Resultado = 1
Resultado
= 15 Mod 12 ----> resultado = 3
Resultado
= 12 ^ 2 ----> Resultado = 144
resultado
= ( ( 4 * 3 ) / 2 ) ^ 2 ----> Resultado = 36
Estos operadores se denominan Operadores aritméticos.
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:
= 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.
El operador = puede usarse también para
comparar cadenas o fechas.
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.
Operador Función Devuelve
True si Devuelve False si
And Función
AND A=True y B=True Cualquier otro caso
Or Función
OR A=True o B=True A=False y B=False
Xor Función
XOR A=True y B=False A=True y B=True
A=False
y B=True A=False y B=False
Eqv F. Equivalente A=True
y B=True A=True y B=False
A=False
y B=False A=False y B=True
Imp Implicación A=True
y B=True A=True y B=False
A=False
y B=True
A=False
y B=False
Not Negación A=False A=True
Like Igualdad A=True A=False
Otras Funciones con números
CInt Parte
entera Devuelve la parte entera de un
número con decimales
Abs Valor
Absoluto Devuelve el valor absoluto
de un número
Sgn Signo Devuelve el signo de un número
Sqr Raíz
cuadrada Devuelve la raíz cuadrada
de un número
Exp Exponenciación Devuelve el número elevado al exponente
indicado
Log Logaritmo Devuelve el logaritmo natural de ese número
Trigonométricas
Sin Seno Devuelve el valor del seno de un
ángulo (Expresado
en
radianes)
Cos Coseno Devuelve el coseno de un
ángulo (En radianes)
Tan Tangente Devuelve la tangente de un ángulo
Atn Arco
Tang. Devuelve un arco cuya tangente
sea el número
(Angulo
en radianes)
Una función curiosa
Timer Tiempo
acumulado Devuelve el tiempo (en
segundos) que ha pasado
desde las 12 de la noche.
Generación de números aleatorios
Randomize (Numero) Inicia el generador aleatorio tomando
como dato de partida el Numero.
Devuelve el resultado en una variable llamada Rnd.
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.
La forma de obtener números realmente
aleatorios es introducir como parámetro un número que sea variable con el
tiempo. Ese número no puede ser otro que el número timer visto antes. Y siempre
con la precaución de que medie mas de un segundo entre dos instrucciones
Randomize. La función toma entonces la forma:
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.
Un ejemplo. Generador de números para la Lotería
Primitiva
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:
Private Sub
Command1.click
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.
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.
Time Devuelve
la hora actual.
Now Devuelve
la fecha y hora actual.
WeekDay Devuelve
el día de la semana (En número, 1=Domingo, 2=Lunes,...)
Day Obtiene
el día, a partir de una fecha
Month Obtiene
el mes a partir de una fecha.
Year Obtiene
el año a partir de una fecha.
Hour Obtiene
la hora a partir de una hora
Minute Obtiene
el minuto a partir de una hora.
Second Obtiene
el segundo a partir de una hora.
DateAdd Añade
un intervalo de tiempo a una fecha
DateDiff Obtiene el intervalo de tiempo entre dos fechas
DatePart Devuelve una parte de una fecha (semana, trimestre, etc.)
DateSerial Compone una fecha a partir de parámetros relativos
TimeSerial Compone una hora a partir de parámetros relativos.
DateValue Devuelve una fecha a partir de un dato que se le parezca y VB
pueda
obtener
de él una fecha válida
Mediante estas instrucciones podemos
obtener el dato necesario de una fecha u hora. Por ejemplo, para obtener el día
de hoy solamente:
Día = Day (Now) Día
será un número
El día de la semana lo obtendríamos
Diasemana
= WeekDay (Now) Diasemana será
un número
DateValue, una instrucción que le sacará mucho
provecho
Fecha = DateValue (120796)
Fecha = DateValue (12 07 96) Fecha =12/07/96
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 :
Format(expresión[, formato[,
primerdíadesemana[, primerasemanadelaño]]])
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 :
FechadeHoy = Format (Now, “yyyy-mm-dd”)
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
Variable =
Format(123456, "Currency")
Variable = 123.456 Pts
Variable =
Format(123456, "Standard")
Variable = 123.456,00
Veamos ahora con un poco mas de
conocimiento la sintaxis de Format
Variable = Format (expresión[,
formato[, firstdayofweek[, firstweekofyear]]])
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 :
Constante Valor Descripción
vbUseSystem 0 El
especificado en el sistema operativo.
VbSunday 1 Domingo (valor por defecto)
vbMonday 2 Lunes
vbTuesday 3 Martes
vbWednesday 4 Miércoles
vbThursday 5 Jueves
vbFriday 6 Viernes
vbSaturday 7 Sábado
firstweekofyear Especifica cual es la primera semana del año. Puede tomar uno
de los siguientes valores o constantes :
Constante Valor Descripción
vbUseSystem 0 Usa
el valor del sistema operativo
vbFirstJan1 1 La primera
semana es la que contiene al día 1 de Enero(Valor
por
defecto
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.
Para poner los números separados por
millares :
Variable
= Format(1234567,
"##,###,###") Variable =
1.234.567
(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 :
General Number Muestra el número tal como lo tecleó
Currency En
formato de la moneda de su sistema operativo
Fixed Sin
separador de millar y dos decimales
(1234567,00)
Standard Con
separador de millares y dos decimales (1.234.567,00)
Percent Multiplica
el número por cien y lo presenta cono
porcentaje(123456700,00%)
Scientific Usa notación científica (1,23E+06)
.
Para fechas (Observe que usamos el ejemplo Format(Now, “Formato”) y Now =
21/07/98
a
las 22:16:00 y pico)
General Date 21/07/98 22:16:00
Long Date martes
21 de julio de 1998
Medium
Date 21-jul-98
Short
Date 21/07/98
yyyy-mm-dd 1998-05-21
yy-mm-dd 98-07-21
Long
Time 22:19:53
Medium
Time 10:20 PM
Short
Time 22:20
hh :mm :ss 22 :21 :29
hh :mm 22 :21
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.
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:
Alumno
(n) Donde n es el número por orden de
lista de ese alumno.
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:
Dim Alumno (25) as String
Hemos declarado que la variable alumno es
una cadena, y que hay 25 elementos en esa matriz.
Una matriz también se puede declarar de
la siguiente forma :
Dim Alumno(1 To 25) as String
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:
Dim Alumno (1 To 25, 1 To 3) As String
De esta forma, el primer apellido del
alumno que ocupa el puesto número 15 de la clase, será el elemento:
Alumno (15, 2)
Podemos definir matrices de dimensión
superior a dos. Podemos llegar a un máximo de 60 dimensiones. Una matriz de 5
dimensiones se declararía:
Dim Variable (
1 To N, 1 To M, 1 To P, 1 To Q, 1 To R)
entendiendo que hay N, M, P, Q y R
elementos en cada una de las dimensiones respectivamente.
Una variable ya declarada como una matriz
puede redimensionarse a lo largo del programa mediante la instrucción ReDim
ReDim Alumno (1To 25)
Mediante esta instrucción, estamos ReDimensionando una matriz ya
declarada. No se puede redimensionar una matriz inexistente.
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.
Si usa la palabra clave Preserve en matrices de dimensión
superior a 1, va a encontrarse con comportamientos no esperados. Como podrá ver
en la Ayuda de VB, usando ReDim Preserve
sólo puede cambiar el tamaño de la última dimensión de matriz y no puede
modificar en ningún momento el número de dimensiones. NO es cierto del todo. SÍ
lo podrá hacer una sola vez.
Respecto a cambiar el número de
dimensiones, si ha declarado la matriz con unas dimensiones determinadas, ya no
podrá cambiar las dimensiones ni con ReDim
ni con ReDim Preserve. Le saldrá un
error que dice que las dimensiones de la matriz ya han sido declaradas.
Pero si ha declarado la matriz sin
dimensiones :
Dim
MiMatriz()
puede cambiar las dimensiones Dim
MiMatriz (1 To 5, 1 To 9)
y volver a cambiarlas Dim
MiMatriz (1 To 8, 1 To 15, 1 To 6)
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 :
ReDim Preserve
MiMatriz (1 To 5, 1 To 9)
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)
a partir de ahora, solamente podemos
cambiar los elementos de la última dimensión :
ReDim Preserve (1
To 5, 1 To 20)
ReDim Preserve (1 To 5, 1 To 30)
es decir, no podremos hacer esto :
ReDim
Preserve (1 To 10, 1 To 30) donde se señala en negrita el error.
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.
Cuando a lo largo de la aplicación se va
redimensionando una matriz, podemos llegar la circunstancia de que, en un
momento determinado, no sepamos las dimensiones de esa matriz.
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.
Sintaxis UBound(nombredelamatriz[, dimensión])
LBound devuelve el mayor subíndice disponible para la
dimensión indicada de una matriz.
Sintaxis LBound(nombredelamatriz[, dimensión])
Ejemplo
Tengamos una matriz llamada Mimatriz, de tres dimensiones. En un momento
de la aplicación se ejecutó la siguiente instrucción válida :
ReDim Mimatriz (1 To 100, 0
To 3, 5 To 20)
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. )
IID 1= LBound (Mimatriz, 1) IID1 = 1
ISD1 = UBound (Mimatriz, 1) ISD1
= 100
IID 2= LBound (Mimatriz, 2) IID1 = 0
ISD2 = UBound (Mimatriz, 2) ISD1
= 3
IID 1= LBound (Mimatriz, 3) IID1 = 5
ISD1 = UBound (Mimatriz, 3) ISD1
= 20
VISUAL
BASIC Guía del Estudiante
Cap. 1
Tras esta pequeña introdución al lenguaje
Basic ya estamos en disposición de encender el ordenador y comenzar a trabajar
con Visual-Basic. Se supone que su PC tiene instalado el programa Visual basic,
bien en su versión de 16 bits si dispone de Windows 3.xx o la de 32 bits si
dispone ce Win95 ó Windows NT.
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 :
Proyect1 - Microsoft Visual Basic
(Diseño)
Por debajo de esta barra de Título del
VB, encontramos la barra de menú de
VB, con las leyendas :
Archivo Edición Ver Insertar Ejecutar
Herramientas Complementos Ayuda
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)
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.
En el centro, y ocupando casi toda la
pantalla, tenemos el Formulario.
Este Formulario es la interface gráfica de su aplicación, sobre el que podrá
añadir los controles que necesite. Lo veremos mas adelante con todo detalle.
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 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 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
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.
¿Cual es el nombre de un procedimiento
existente dentro de un módulo ?
Depende. Si estamos ejecutando código escrito en otro procedimiento
dentro del mismo módulo, es decir, si estamos dentro de ese mismo módulo, basta
con citarlo por su nombre : p.e., si en el MóduloA tenemos un
procedimiento llamado Procedimiento1, y queremos llamarle desde una línea de
código dentro de ese mismo módulo, basta con referirse a él con :
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
Lo mismo podemos decir para cualquier
procedimiento insertado en un formulario. Desde dentro del formulario basta con
referirse a él citándolo por su nombre. Desde fuera de ese formulario deberemos
citarle como :
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
Al igual que introducimos Procedimientos,
podemos introducir Funciones en nuestra aplicación. Una Función es un Procedimiento
al que le pasamos uno o varios parámetros.
(O Ninguno) Verá los Procedimientos y funciones mas adelante (Cap. 15). Al igual que los Procedimientos,
pueden ser públicas (se verán en toda la aplicación) o privadas (se verán
solamente en el formulario donde estén.
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
formulario dispondremos el código necesario para que la aplicación se ejecute
en el orden deseado.
Si hacemos click en la Barra de Menú de
Visual Basic, en Herramientas | Opciones
obtendremos el siguiente cuadro de
diálogo :

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.
En otra pestaña podemos configurar varias
prestaciones del entorno de trabajo :
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.
Si tenemos la activada la casilla Declaración de variables requerida nos
pondrá automáticamente Option Explicit
en el encabezamiento de todas las secciones de declaraciones de la aplicación.
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.

La pestaña de Editor nos permite
fundamentalmente 2 cosas :
Ver solamente el código correspondiente
al procedimiento que estamos escribiendo ó Ver el código del Módulo (o
Formulario) completo. En este último caso es un poco mas difícil de manejar la
ventana de código, sobre todo si el programador no está muy habituado a ello.
Le presenta procedimiento tras procedimiento, separados por una línea. Para seleccionar una u otra opción hay que
seleccionar o deseleccionar la casilla Ver módulo completo.
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.
Visual Basic - Guía del
Estudiante Cap. 2
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
El Formulario es un objeto, que sirve de soporte de otros objetos.
El nombre de FORMULARIO lo toma precisamente porque, al igual que un
formulario de papel contiene textos escritos, lugares donde podemos escribir,
figuras, cajas donde podemos elegir una u otra opción, etc., en este cuadro
gráfico que llamamos formulario, podemos introducir textos escritos, lugares
donde podemos escribir, figuras, cajas donde podemos elegir una u otra opción
....
En realidad un formulario
es lo que normalmente conocemos por VENTANA. El nombre de formulario le viene
muy bien cuando ese formulario es una ventana donde vamos a introducir datos
alfanuméricos. Cuando en vez de introducir datos, lo que tenemos es, por ejemplo,
una ventana donde se reproducen exactamente los controles de operación de una
máquina, parece en principio que sería mas correcto el nombre de
"ventana". De alguna forma lo
hay que llamar, y esa forma es FORMULARIO. Posiblemente a lo largo de estos
apuntes nos referiremos al formulario con el nombre de ventana, o incluso,
pantalla. Procuraremos usar el nombre apropiado: FORMULARIO.

Forma inicial del formulario.

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.
Como cualquier objeto
Visual Basic, un formulario tiene propiedades y procedimientos:
PROPIEDADES.
Name Nombre
Define al
objeto durante la ejecución del programa. Se introduce en tiempo de diseño y no
se puede variar durante la ejecución. Nombre por defecto: Form1 (Form2
y sucesivos) Este nombre por
defecto debe cambiarse, (debería cambiarse por norma en el momento de
introducir el formulario), ya que de no hacerlo corremos el riesgo de borrar el
código existente de otro formulario del mismo nombre en el momento de guardar
la aplicación.
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.
NOTA.-
No confundir Nombre (Name) con Título (Caption)
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ú.
MinButton
MaxButton Valor por defecto: True
Botones
(flechas) de minimizar y maximizar este formulario. Son igualmente propiedades
booleanas, que admiten el valor True o False. Si están en true, aparecerá la
flecha correspondiente. Si están en False, no aparecerá dicha flecha. Deben
configurarse de una u otra forma, dependiendo si se quiere minimizar /
maximizar este formulario durante la ejecución.
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.
BorderStyle Tipo de borde
Define el tipo
de borde que tendrá el formulario durante la ejecución. No se puede cambiar en
tiempo de ejecución,
Admite los
siguientes valores:
0 - None El formulario no tiene borde alrededor
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.
Valor por defecto: 2 . Sizable
Nota: Al
cambiar a determinados valores, las propiedades MaxButton y MinButton se ponen
a False. Pueden cambiarse a True posteriormente.
Appearance Apariencia Valor por defecto: 3D
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 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
Autoredraw Valor por defecto: False
Propiedad
booleana. Esta propiedad, estando en True, permite actualizar el contenido del
formulario y de sus controles incluso cuando no están visibles. Imaginemos que
en este formulario existe un texto, una etiqueta (Label) o caja de texto (Text
Box) cuyo texto se haya cambiado, bien por programa, bien por una entrada,
mientras este formulario no estaba visible. Lo mismo podemos decir de las
propiedades de cualquier otro control. Si esta propiedad Autoredraw está en False, al hacer visible este formulario,
aparecerá igual que cuando se ocultó. Si esta propiedad está en True, aparecerá
actualizado.
Backcolor Color del fondo
Establece el
color del fondo del formulario. Puede cambiarse en tiempo de ejecución.
Valor por defecto: El establecido en el Panel de Control de Windows.
ClipControls Valor por defecto:
False
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
Establece un valor que
determina el aspecto de la salida de un método gráfico o el aspecto de un
control Shape o Line. Verá mas adelante los efectos de esta propiedad.
DrawStile Valor por defecto : 0
Establece el estilo de
línea de la salida de métodos gráficos:
Valores: 0 - Línea continua
1
- Rayas
2
- Puntos
3
- Raya-Punto
4
- Raya - Punto - Punto
5
- Transparente
6
- Continuo interior.
DrawWidth Valor por defecto: 1
Establece el
ancho de una línea dibujada. El valor debe expresarse en pixeles.
Enabled Activado Valor por defecto: True
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.
ForeColor Valor por
defecto: Negro
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,.
FillStyle Tipo de relleno Valor
por defecto: 2
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
FillColor Color de
relleno
Especifica el
color del relleno contemplado en FillStyle.
Font Tipo de letra Valor por defecto: El determinado en la
personalización.
Especifica el
tipo y tamaño de la letra que se usará en el formulario. Al seleccionar esta
propiedad en la ventana de propiedades, aparece un cuadro de dialogo donde se
eligen ambos parámetros.
Cuando
introduzca nuevos controles en el Formulario, la propiedad Font de estos
controles tomará el valor que tenga esta propiedad en el Formulario. Puede servirle este pequeño truco para
utilizar en todos los controles una determinada fuente sin tener que teclearla
para cada control.
FontTranparent Texto Transparente Valor
por defecto: True
Establece si
el texto o gráfico de fondo del formulario se muestra (True) o no se muestra
entre los caracteres de texto escritos en el propio formulario.
FontSize Tamaño de letra
Establece el
tamaño de la letra. Esta propiedad, que puede variarse en tiempo de ejecución,
varía solamente el tamaño, y no el tipo de letra. El tamaño debe expresarse en
puntos. Máximo, 2160 puntos.
FontBold, FontItalic,
FontStrikethru, FontUnderline
Permiten, en
tiempo de ejecución, cambiar un texto a negrita, cursiva, tachado y subrayado.
Son propiedades booleanas True / False
Height Altura Valor
por defecto: No existe
Define la
altura del formulario. El valor de esta propiedad no se introduce normalmente
como un dato numérico, sino que toma el valor automáticamente, dependiendo de
las dimensiones del formulario durante el tiempo de diseño. Puede cambiarse
durante el tiempo de ejecución.
HelpContextID Valor por defecto: 0
Establece un
número de contexto asociado para este formulario. Este número se aplica para
determinar la ayuda interactiva asociada a este formulario. Vea mas adelante,
el tema Ayuda de Windows.
Puede tomar
los siguientes valores : 0 - No
se especifica número de contexto
>0 Un entero que
especifique un contexto válido.
Icon Icono
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.
Valor por defecto: el icono que se le haya programado en la
personalización.
KeyPreview Valor por defecto: False
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.
Left Borde Izquierdo Valor por defecto: No existe
Indica la
posición del borde izquierdo del formulario. Normalmente no se introduce como
valor numérico, sino que lo toma automáticamente de la posición que tenga el
formulario en el tiempo de diseño.
Puede cambiarse en tiempo de ejecución, para mover el formulario.
LinkMode Valor por defecto: 0
Permite que
una aplicación destino inicie una conversación DDE con el formulario (origen de
datos). Puede tomar los siguiente valores:
0 - No hay interacción DDE
1 - Source.
Indica que este Formulario es origen de una comunicación DDE. El dato que se va
a traspasar en esa comunicación DDE estará en un TextBox, en un Label o en un
PictureBox de este Formulario.
LinkTopic
Establece el
tema al que este formulario va a responder a una conversación DDE, cuando
funciona como origen. Es por este tema por el que se debe llamar a este formulario
cuando actúa de origen en una conversación DDE
MDIChild Valor por defecto:
False
Establece que
este formulario es un formulario Hijo dentro de un formulario MDI. No se puede
cambiar en tiempo de ejecución. Es una propiedad booleana
True
= es formulario hijo False =No
lo es
MouseIcon Valor por defecto: ninguno
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.
MousePointer Valor por defecto:
flecha
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
visto en la propiedad anterior. Para elegir ese icono personalizado, debemos
poner en esta propiedad el valor 99.
Picture Gráfico Valor por
defecto: No existe
Mediante esta
propiedad podemos poner un gráfico como fondo del formulario. El gráfico puede
ser un bit-map o un fichero .ICO
ScaleHeight, ScaleWidth,
ScaleMode,
Indican la
unidad de medida de dimensión de altura y anchura del Formulario. ScaleMode indica en qué unidades de
medida se van a medir esas dimensiones.
Acepta Twips (1), Point(2), Pixel (3),
Character (4), Pulgadas (Inch) (5), Milímetros (6), Centímetros (7). Si colocamos la propiedad ScaleMode en cualquiera de estos valores, las propiedades ScaleHeight y ScaleWidth nos vendrán dadas automáticamente dependiendo del ancho
del Formulario, y no se extrañe si encuentra para estas propiedades valores tan
peregrinos como 4815 y 7423. Al haber elegido la unidad de medida, los
valores de ancho (ScaleWidth) y alto
(ScaleHeight) serán los que tengan
que ser, medidos en la unidad que hemos elegido. Podemos elegir una cifra para
el ancho y el alto del Formulario de forma que podamos controlar mejor las
distintas posiciones que van a ocupar en él los controles, los textos o los
dibujos. Podemos poner, por ejemplo, que el Formulario mida 400 de ancho (ScaleWidth = 400) y 300 de alto (ScaleHeight = 300) forzándole estas propiedades,
bien en tiempo de diseño en la caja de propiedades, o en tiempo de ejecución
mediante código. Entonces sabemos que el formulario, independientemente de las
dimensiones físicas que tenga sobre la pantalla, medirá 400 de ancho y 300 de
alto, y si en estas condiciones queremos colocar un control o un dibujo justo
en el medio del Formulario, sabemos que tenemos que colocarle en las
coordenadas 200, 150. ¿Que unidad de medida estaremos utilizando entonces en el
Formulario ? Unas definidas por
el usuario (distintas para el ancho y el alto) que serán las necesarias para
que el Formulario mida de ancho lo que le hayamos puesto en la propiedad ScaleWidth y de alto lo que le hayamos
puesto en la propiedad ScaleHeight.
Observe que la propiedad ScaleMode se
ha cambiado automáticamente a User (0)
al introducir las dimensiones de ancho y alto que nosotros queremos.
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
Estas
propiedades, medidas en la unidad de medida elegida para el ancho y alto
mediante las propiedades ScaleMode, ScaleWidth y ScaleHeight anteriores, expresan las coordenadas iniciales de la
parte izquierda y de la parte superior respectivamente del Formulario. Estas
propiedades no afectan a la posición del Formulario en la pantalla (Si está
maximizado seguirá ocupando toda la pantalla, si está en “Normal” ocupará el
mismo sitio que se dio en tiempo de diseño).
Supongamos que se le asigna a un Formulario, las propiedades ScaleWidth = 400, y ScaleHeight = 300. Si colocamos un
control justamente en el centro del Formulario tendrá sus propiedades Top =150 y Left=200. Si ponemos ahora las propiedades del Formulario ScaleLeft a 30 y ScaleTop a 10, ese control, para seguir en el centro del Formulario
deberá tener sus propiedades Top a
160 (150 + 10) y Left a 230 (200 + 30).
Recuerde que
las medidas de un formulario crecen, desde la esquina superior izquierda, según
avanzamos hacia abajo y hacia la derecha.
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.
1 Point=20 Twips ; 1Pixel=15 Twips : 1 Charecter=240 Twips ; 1 Inch
(pulgada) =1440 Twips 1mm=56,52
Twips 1 cm=566 Twips
Tag Valor por defecto: No existe
Esta propiedad
no la usa directamente Visual-Basic. Sirve para asociar al formulario
información adicional para fines externos a la programación. Pero también le
puede servir para almacenar en ella una variable para que la use un código
ajeno al formulario. El autor de estos apuntes tiene por costumbre utilizar la
propiedad Tag del formulario inicial
para guardar el parámetro que se le pasa a algunos programas para acceder a
ellos con unos determinados privilegios.
Resumiendo, está ahí para lo que el programador quiere.
Top Posición del borde superior Valor por defecto: No
existe
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.
Visible Valor
por defecto: True
Propiedad
Booleana. Asignándole el valor True la
pantalla es visible, y asignándole el valor False, no se ve. Este valor puede cambiarse durante el tiempo
de ejecución para ocultar y hacer visible el formulario.
Width Ancho Valor por defecto: No existe
Define la
anchura del formulario. Normalmente no se introduce como valor numérico sino
que lo toma automáticamente del tamaño que tenga el formulario durante el
tiempo de diseño. Juntamente con Height
define el tamaño del formulario. Puede cambiarse durante el tiempo de
ejecución.
WindowState
Establece el
estado en el que aparecerá el formulario cuando se activa y presenta en
pantalla. Admite tres opciones:
0 - Normal El formulario recupera la posición y
tamaño que tenía en el tiempo de diseño.
1 - Minimizado
El formulario aparece minimizado, representado por su icono.
2 - Maximizado
El formulario aparece maximizado, ocupando toda la pantalla.
PROCEDIMIENTOS
Activate Activación Click Click
DblClick Doble click Deactivate Desactivación
DragDrop Arrastrar y
soltar DragOver Arrastrar por encima
GotFocus Obtener el foco KeyDown Mantener pulsada
una tecla
KeyPress Pulsar una tecla KeyUp Soltar
una tecla
LinkError Error de enlace LinkExecute Ejecución de un
enlace de datos
LinkOpen Romper el enlace Load Cargar el
formulario
LostFocus Perder el foco MouseDown Pulsar una tecla del
ratón
MouseMove Mover el ratón (Detecta la posición del ratón
sobre el formulario)
MouseUp Soltar una tecla del ratón Paint Pintar
QueryUnload Confirmación de descarga Resize Cambio de tamaño
Unload Descargar el
formulario
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.
Un Formulario puede servir también como soporte de textos o dibujos.
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.
Los controles, lo mismo que el Formulario, tienen Propiedades y Procedimientos.
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.
Para colocar un control en
un Formulario, basta con “tomarlo” de la caja de herramientas existente en la
parte izquierda de la pantalla de VB y llevarlo al Formulario. Si no existiese
el control deseado en la caja de herramientas, deberemos ir a “cogerlo” a Controles
personalizados que está en el menú desplegable Herramientas de la barra
de Menú de VB. Se elige el nuevo control, marcando la caja de opción a la
izquierda de su nombre, y haciendo click en ACEPTAR. Este control ya pasa a la
caja de herramientas.
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.
NOTA.-
No confundir Nombre (Name) con Título (Caption)
Appearance Apariencia
Determina la forma
del botón. Admite los valores de Flat (Plano) y 3D. No se aprecia en gran medida la diferencia.
Backcolor Color
de fondo
Es el color de un
pequeño cuadrado que aparece rodeando el título, NO el color del botón, que es
invariable. Puede cambiarse en tiempo de ejecución.
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 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.
Puede tener los siguientes valores:
0 = No se especifica número de contexto
>0
Un entero que especifica un contexto válido.
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 diseño. Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de
ejecución.
MouseIcon Icono
para el puntero del ratón
Determina el icono
que presenta al puntero del ratón cuando pasa por encima del botón, cuando se
especifica en la propiedad MousePointer
que el puntero del ratón es el definido por el usuario. (Custom)
MousePointer Puntero ratón
Determina la forma
del puntero del ratón cuando éste pasa por encima del botón. Puede elegirse uno
de los punteros preestablecidos (15) o incluso uno diseñado especialmente. Para
especificar que el puntero es uno diseñado especialmente, hay que poner a esta
propiedad el valor 99 (Custom), y en este caso aparecerá el icono determinado
por la propiedad MouseIcon
TabIndex Nº de orden
para tabulador
Cuando disponemos
de varios controles en un mismo formulario, solamente uno de ellos tiene el
foco. Esta expresión de tener el foco significa que ese control está remarcado
y en esa condición, si pulsamos la tecla ENTER haría el mismo efecto que hacer
click con el ratón en ese control. Esto es necesario, ya que existen
ordenadores que no disponen de ratón (típico de algunos portátiles). En estos
casos, para elegir uno u otro control debemos pulsar repetidas veces la tecla
TABulador. El foco irá cambiando de uno a otro control (pueden ser controles de
distinto tipo) cada vez que pulsemos la tecla TABulador. Esta propiedad TabIndex marca el orden que seguirá el
foco a través de cada control.
TabStop Sale
del control de la tecla TAB
Propiedad booleana.
Cuando esta propiedad está a False, el
botón no tomará el foco cuando se pulse la tecla del Tabulador. Sin
embargo sigue manteniendo el índice de la propiedad TabIndex descrita anteriormente. Puede cambiarse en tiempo de
ejecución. Esto nos permite descartar algún botón de tomar el foco, cuando por
facilidad para el usuario, sea conveniente en determinados puntos del programa.
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 objetos (controles) necesarios.
WhatThisHelpID (Propiedad,
Windows 95)
Devuelve o
establece un número de contexto asociado a un objeto. Se utiliza para dotar a
las aplicaciones de Ayuda interactiva con el menú emergente ¿Qué es esto? de la
Ayuda de Windows 95.
Width Ancho
Define el ancho del
botón. Con Height determina la
dimensión del botón.
PROCEDIMIENTOS
DEL BOTON DE COMANDO
Click DragDrop DragOver GotFocus
KeyDown KeyPress KeyUp LostFocus
MouseDown MouseMove MouseUp
¡ El botón de Comando no tiene el
procedimiento DbClick !
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.
Appearance Apariencia Plana o tridimensional.
Autosize Tamaño
Propiedad booleana.
Si se pone a True, el tamaño de la etiqueta se ajusta al texto que contiene.
Backcolor Color
de fondo
Es el color de
fondo de la etiqueta. Puede cambiarse en tiempo de ejecución.
BackStyle Tipo de
fondo
Opaco o
transparente. Cuando se selecciona transparente, se ve solamente el texto de la
etiqueta. Cuando se selecciona opaco, este texto se vé sobre un fondo gris.
BorderStyle Tipo
de borde
Sin borde o con
borde. En caso de haber elegido en la propiedad Appearance el modo tridimensional, y eligiendo con borde en esta
propiedad, el aspecto adopta una forma como incrustada en el formulario.
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
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.
Left Posición de
su parte izquierda
Indica la posición
de la etiqueta, concretamente de su parte izquierda. Normalmente esta propiedad
no se introduce numéricamente, sino que la toma automáticamente de la posición
que ocupaba en tiempo de diseño. Puede cambiarse, cambiando el valor a esta
propiedad, en tiempo de ejecución.
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
MouseIcon Icono
del puntero del ratón
MousePointer Puntero
ratón
Para estas
propiedades es aplicable todo lo dicho para las mismas en el Botón de Comando
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.
Los valores que
puede tomar son True o False.
True (Predeterminado) Los caracteres (&) que
aparezcan en el texto de la propiedad Caption definen al carácter siguiente
como tecla de acceso. El signo (&) no aparece en la interfaz del control
Label.
False Los caracteres (&) que aparezcan en el
texto de la propiedad Caption aparecen como tales en la interfaz del control
Label.
En tiempo de
ejecución, al presionar ALT+ la tecla de acceso definida en la propiedad
Caption del control Label, el enfoque se desplaza al control siguiente al control
Label en el orden de tabulación.
Visible Visible
Propiedad Booleana.
Si es true, la etiqueta se ve, si es False no se ve. Puede cambiarse en tiempo
de ejecución.
WhatThisHelpID (Propiedad,
Windows 95)
Devuelve o
establece un número de contexto asociado a un objeto. Se utiliza para dotar a
las aplicaciones de Ayuda interactiva con el menú emergente ¿Qué es esto? de la
Ayuda de Windows 95.
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.
Esta propiedad
puede cambiarse en tiempo de ejecución
True El control Label se expande o contrae
horizontal y verticalmente para adaptarse al texto y al tamaño de la fuente.
Contempla para la expansión horizontal la colocación de los espacios del texto.
False (Predeterminado) El texto no se ajusta a la
siguiente línea; el control Label se expande o contrae horizontalmente para
adaptarse a la longitud del texto y verticalmente para adaptarse al tamaño de
la fuente y al número de líneas.
Nota Si se establece False en AutoSize, el texto
siempre se ajustará a la línea siguiente, independientemente del tamaño del
control Label y del valor de la propiedad WordWrap. Esto puede ocultar parte
del texto, ya que el control Label no se expande en ninguna dirección.
PROCEDIMIENTOS
DEL LABEL
Click Change DbClick DragDrop
DragOver LinkClose LinkError LinkNotify
TEXT BOX CAJAS
DE TEXTO
_____________________________
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.
La forma de una caja de texto es la
siguiente, dependiendo de las propiedades BorderStyle y Appearance:

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.
Backcolor Color
de fondo
Es el color de
fondo de la caja de texto. Puede cambiarse en tiempo de ejecución.
BorderStyle Tipo
de borde
Sin borde o con
borde. En caso de haber elegido en la propiedad Appearance el modo tridimensional, y eligiendo con borde en esta
propiedad, el aspecto adopta una forma como incrustada en el formulario.
DataField
DataSource Fuente
de Datos
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.
ForeColor Color
de la letra
Determina el color
de las letras del texto.
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.
Puede tener los siguientes valores:
0 = No se especifica número de contexto
>0 Un entero que especifica un contexto válido.
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.
Left Posición de
su parte izquierda.
Indica la posición
de la caja de texto, concretamente de su parte izquierda. Normalmente esta
propiedad no se introduce numéricamente, sino que la toma automáticamente de la
posición que ocupaba en tiempo de diseño. Puede cambiarse, cambiando el valor a
esta propiedad, en tiempo de ejecución.
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.
MouseIcon Puntero
del ratón personalizado
MousePointer Puntero
ratón
Determina la forma
del puntero del ratón cuando éste pasa por encima de la caja de texto. Puede
elegirse uno de los punteros preestablecidos en esta propiedad, (15 en total) e
incluso un puntero personalizado en la propiedad MouseIcon. Para que aparezca este puntero personalizado, MousePointer debe ponerse al valor
99. Lo típico para esta propiedad es el
I-Beam (barra vertical)
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 = “”
Esta propiedad se
ignora cuando la propiedad Multiline
está a True.
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.
TabIndex Nº de orden
para obtener el foco
Al igual que para
los botones de comando, esta propiedad para 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.
WhatThisHelpID (Propiedad,
Windows 95)
Devuelve o
establece un número de contexto asociado a un objeto. Se utiliza para dotar a
las aplicaciones de Ayuda interactiva con el menú emergente ¿Qué es esto? de la
Ayuda de Windows 95.
Width Ancho
Define el ancho de
la caja de texto. Con Height
determina la dimensión de la misma.
PROCEDIMIENTOS
DE LA CAJA DE TEXTO
Click Change DblClick DragDrop DragOver GotFocus
KeyDown KeyPress KeyUp LinkClose
FRAME RECUADRO
Se obtiene directamente de la caja de herramientas

Tiene la siguiente forma :
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 (*)
Caption Es el título que aparece en el borde del Frame.
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 (*)
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 (*)
PROCEDIMIENTOS DEL FRAME
Click DblClick DragDrop DragOver MouseDown
MouseMove MouseUp
CHECK BUTTON
Y OPTION BUTTON (BOTONES DE ELECCION Y OPCION)
Se obtienen directamente de la caja de
herramientas.

Dada la similitud de ambos controles, se
comentan conjuntamente.
El control CheckBox, o casilla de verificación, permite elegir una opción
(activada/desactivada, True/False) que el usuario puede establecer o anular
haciendo click. Una X en una casilla de
verificación indica que está seleccionada, activada, o con valor True. Cada
casilla de verificación es independiente de las demás que puedan existir en el
formulario, pudiendo tomar cada una de ellas el valor True o False, a voluntad
del operador.
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.
Generalmente, los controles OptionButton se utilizan en un grupo de
opciones para mostrar opciones de las cuales el usuario sólo puede seleccionar
una. Los controles OptionButton se
agrupan dibujándolos dentro de un contenedor como un control Frame, un control PictureBox o un formulario. Para agrupar controles OptionButton en un Frame o PictureBox,
dibuje en primer lugar el Frame o PictureBox y, a continuación, dibuje
dentro los controles OptionButton.
Todos los controles OptionButton que
están dentro del mismo contenedor
actúan como un solo grupo, e independientes de los controles OptionButton de otros grupos distintos.
Aunque puede parecer que los controles OptionButton y CheckBox funcionan de forma similar, hay una diferencia
importante: Cuando un usuario
selecciona un OptionButton, los
otros controles del mismo grupo OptionButton
dejan de estas disponibles automáticamente. Por contraste, se puede seleccionar
cualquier número de controles CheckBox.

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
Las señaladas con
(*) son comunes a ambos controles y no presentan novedades respecto a las ya
comentadas para los controles precedentes.
Alignment Común a ambos controles.
Admite los
siguientes valores :
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 (*).
DataField DataSource Propiedades del CheckBox solamente.
Establecen la base
de datos y el campo donde están los datos (True / False) que se llevarán a la
propiedad Value . Al igual que en
los controles Label y TextBox esta propiedad nos permite
visualizar datos de una base de datos de una forma muy sencilla. En este caso, el CheckBox solamente permite presentar (logicamente) datos de tipo
Booleano.
DragIcon (*)
DragMode (*)
Enabled (*)
Font (*)
ForeColor (*)
Height Común a ambos controles.
La altura del
control solamente afecta a la colocación del Titulo (Puede ponerse un título
largo en varias líneas), no al tamaño del botón, que es invariable.
HelpContextID (*)
Index (*)
Left (*)
MouseIcon (*)
MousePointer (*)
Name (*)
TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Value Común
a ambos controles
El valor de esta
propiedad indica si el control está seleccionado (Value = 1) o no seleccionado
(Value = 0 ó Value = False). Esta propiedad puede cambiarse en tiempo de
ejecución. Mediante esta propiedad,
podemos tanto forzar el valor como leerlo.
Atención.
Presenta una diferencia entre uno y otro control respecto a la forma de
expresarse respecto a su valor cuando está seleccionado. Para forzar que el
control NO esté seleccionado, o para leer el Value cuando no está seleccionado, podemos utilizar tanto Value = 0 como Value = False. Sin embargo,
cuando lo que se quiere es poner la propiedad a True hay una diferencia entre ambos controles.
Para el OptionButton podemos utilizar
indistintamente las siguiente formas :
Option1.Value = True Option1.Value = 1
Con cualquiera de
ellas seleccionaremos ese control por programa.
Para el CheckBox solamente se podrá usar para
este propósito la instrucción :
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.
Para leer el dato
existente en un CheckBox es
necesario utilizar la forma :
variable =
Check1.Value donde variable tomará el valor 1 (no True)
Para el control OptionButton emplearemos una instrucción igual :
variable =
Option1.Value donde variable tomará
el valor True (no 1)
Visible (*)
WhatsThisHelpID (*)
Width (*)
PROCEDIMIENTOS
Click DblClick
(Solo
OptionButton) DragDrop DragOver GotFocus
KeyDown KeyPress
KeyUp LostFocus
LIST
BOX Y COMBO BOX
Estos dos controles, debido a su
similitud, se estudian conjuntamente.
Se obtienen directamente de la caja de
herramientas :

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.
Un control ComboBox combina las características de un control TextBox y un control ListBox. Los usuarios pueden introducir
información en la parte del cuadro de texto y seleccionar un elemento en la
parte de cuadro de lista del control. En resumen, un ComboBox es la combinación
de un ListBox, que se comporta como
si de un ListBox se tratase, y de un
TextBox, con comportamiento análogo
a un TextBox sencillo, con la
particularidad aquí de que el texto se le puede introducir por teclado, o
elegir uno de los que figuran en la parte ListBox
del Combo.
Estos controles toman la siguiente
forma :

Puede verse en la figura un ejemplo de
presentación de un ListBox
(izquierda), un ComboBox con la
lista desplegada (Centro) y un ComboBox
con la lista sin desplegar (Combo2 a la derecha).
La lista tiene varios elementos. Cada
línea de esta lísta es un elemento de la lista. Como el 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 :
ListCount - Indica el número de
elementos que tiene la lista
ListIndex - Indica el número de orden del elemento seleccionado dentro de la
lista.
AddItem -
Añade un elemento a la lista.
RemoveItem
- Elimina un elemento de la lista.
Text -
Obtiene el elemento seleccionado.
List (n) -
Obtiene el elemento cuyo orden dentro de la lista es n.
ListCount
valdrá 0 si la lista no tiene ningún elemento, y n si tiene n elementos.
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
Supongamos que tenemos un ListBox llamado List1, y un ComboBox llamado Combo1. Se enumeran
distintas formas de obtener información de ellos.
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.
List1.AddItem “ELEMENTO NUEVO”
Añade un elemento a
List1. En este caso, el elemento añadido es la palabra ELEMENTO NUEVO.
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)
Variable = List1.List (n)
Variable
contendrá el elemento que ocupa el número de orden n dentro de la lista.
Variable = List1.List
(List1.ListIndex)
Variable
contendrá el elemento que estaba seleccionado en List1. Se ha utilizado la
propiedad List para obtener el elemento, y en vez de introducir un número para
definir el elemento que se desea, se introdujo el valor ListIndex de List1, que
es concretamente, el número de orden del elemento seleccionado en ese momento.
Observe que poner List1.List (List1.ListIndex)
es idéntico a poner List1.Text.
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)
PROPIEDADES
DE ListBox y de ComboBox
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.
Determina si los elementos se presentan
en una sola columna o en varias columnas, y la forma de presentar los elementos
en el ListBox. Si esta propiedad se pone a 0 la lista tendrá solamente una
columna, y presentará los elementos uno debajo de otro. Cuando los elementos
sean mas que los que se pueden presentar en la lista, aparecen automáticamente unas barras de desplazamiento vertical.
Si la propiedad se pone a un número
distinto a 0, el ListBox es de tipo
multicolumna, presentará en cada columna los elementos que le quepan
dependiendo de su dimensión vertical, y tendrá tantas columnas como sea
necesario para albergar el número de elementos que tenga. Presentará en su cuadro tantas columnas como
se le indique en el valor de esta propiedad, y si no puede presentar todos los
elementos en las columnas que muestra, le aparecerán barras de desplazamiento
horizontales para poder movernos por todas las columnas que tenga.
Recuerde : El número que se le asigna a la propiedad Columns no indica el número de columnas que
tendrá el ListBox sino el número de
columnas que presenta.
Esta propiedad puede asignarse en diseño,
mediante la caja de propiedades, o en tiempo de ejecución mediante una
instrucción como esta :
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.
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.
Devuelve o establece un número específico
para cada elemento de un control ComboBox o ListBox.
Sintaxis
objeto.ItemData(índice) [= número]
La sintaxis de la propiedad ItemData tiene las siguientes partes:
objeto Nombre
del ListBox o ComboBox.
índice El
número de un elemento concreto del objeto.
número El
número que se asocia con el elemento especificado.
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 (*)
List Es
el contenido de la lista.
Si la lista de elementos es corta e
invariable, pueden introducirse los elementos en el cuadro de propiedades
durante el diseño.
MouseIcon (*)
MousePointer (*)
Name (*)
Sorted
Establece o
devuelve un valor que indica si los elementos de un ListBox o ComboBox se colocan automáticamente en orden alfabético. Los valores que puede
adoptar son True o False.
True Los elementos de la lista se ordenan alfabéticamente
(sin distinguir entre mayúsculas y minúsculas).
False (Predeterminado) Los elementos de la lista no se
ordenan alfabéticamente.
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
Click Change
(Solo ComboBox) DblClick DragDrop DragOver
DropDown (Solo ComboBox) GotFocus KeyDown KeyPress
KeyUp LostFocus MouseDown (Solo ListBox) MouseMove
(Solo ListBox)
MouseUp (Solo ListBox)
NOTA MUY IMPORTANTE
El procedimiento Change del ComboBox
solamente se efectúa cuando el cambio se produce mediante la entrada de un
texto DESDE EL TECLADO, no por un
cambio en la parte Text de este control, producido al llevar un elemento desde
la parte List a la parte Text.
CONTROLES
HScrollBar y VScrollBar
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.

Mediante estos controles se pueden
introducir datos variando la posición del cursor.
PROPIEDADES
de HScrollBar y VScrollBar
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 (*)
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 (*)
PROCEDIMIENTOS
DE HScrollBar y VScrollBar
Change DragDrop DragOver GotFocus KeyDown KeyPress
KeyUp LostFocus Scroll
Comentario El
Procedimiento Change se produce
cuando, tras mover el cursor, se suelta el botón del ratón. Esto produce el
efecto de que el cambio que se tenga que producir con el movimiento del cursor
no se realiza de una manera continua.
El procedimiento Scroll se
realiza en el instante que se está moviendo el cursor. Por lo tanto, es este
procedimiento el que se debe usar para conseguir el efecto de un cambio
continuo mientras se está moviendo el cursor.
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.
La temporización producida por el Timer es independiente de la velocidad
de trabajo del ordenador. (Casi
independiente. El timer no es un reloj exacto, pero se le parece)
Se toma directamente de la caja de
herramientas, y tiene el aspecto siguiente :

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
Timer
Se produce cada vez que se cumple un
intervalo completo.
SHAPE
Se toma directamente de la caja de
herramientas :

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.
Este control no tiene Procedimientos. En
realidad, solamente sirve para mostrar un determinado gráfico, envolver
gráficamente a otros controles, pero no tiene ninguna aplicación en cuanto a
programa. Es un “adorno” para sus aplicaciones.
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)
El efecto de
establecer la propiedad BorderStyle depende del valor de la propiedad
BorderWidth. Si BorderWidth no es 1 y BorderStyle no es 0 o 6, BorderStyle se
establece como 1.
BorderWidth
Establece el ancho
de la línea.
DrawMode (*)
FillColor (*)
FillStyle (*)
Height (*)
Index (*)
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
Se toma directamente de la caja de
herramientas

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
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.
Presenta las dos formas siguientes :

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
Autosize, Backcolor, DragIcon, DragMode,
Enabled, ForeColor, Height, HelpContextID,
Index, InnerBottom, InnerLeft, InnerRight, InnerTop, Left, Max, Min, MouseIcon,
MousePointer, Name, NeedleWidth, Picture, Style, TabIndex, Tabstop, Tag, Top, Value, Visible, WhatsThisHelpID,
Width.
Son destacables por nuevas o
particulares, las siguientes propiedades :
ForeColor Color de la
barra
InnerBottom Distancia
entre la parte baja del control y el comienzo de la barra o aguja.
InnerLeft, InnerRight, InnerTop. Idéntico al anterior, respecto a otros lados.
Max Valor
de la propiedad Value a fondo de escala
Min Valor
de la propiedad Value para indicación cero.
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
Change DblClick DragDrop DragOver GotFocus KeyDown
KeyPress KeyUp LostFocus MouseDown MouseMove MouseUp
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.
CUADRO DE DIALOGO CommonDialog
Normalmente se encuentra en la caja de
herramientas

Este control no se presenta en tiempo de
diseño mas que con un simple icono :

El cuadro de diálogo, CommonDialog se utiliza para varias
funciones :
· 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.
El control CommonDialog es un control personalizado (Microsoft CommonDialog
Control COMDLG16.OCX / COMDLG32.OCX), y
como casi todos los controles personalizados presenta un asistente de propiedades
propio. Puede accederse a las propiedades mediante el cuadro de propiedades
típico de otros controles, o mediante el asistente, pulsando el botón derecho
del ratón con el puntero colocado encima del icono del cuadro de diálogo.
Analizando las propiedades, vemos que
tiene gran cantidad de ellas. Esto es porque agrupa 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
y haber puesto, en la propiedad Flags del cuadro de diálogo, el valor
de 1, 2 ó 3, correspondiente respectivamente a los tipos de letra de la
pantalla, de la impresora o ambos. (Véase la propiedad Flags mas adelante) Si no pone uno de estos valores, le dirá que no
tiene fuentes instaladas.
El cuadro de diálogo que se presenta es el siguiente:

Los valores que se pueden obtener de este cuadro de
dialogo son:
CD1.FontName Indica el nombre de la fuente
CD1.FontSize Indica el tamaño de la fuente
CD1.Color Indica el color de la fuente
(Abrir con Flags=256+1, 2 ó 3)
CD1.FontBold
= (True / False) Si es True, se ha
elegido "Negrita"
CD1.FontItalic
= (True / False) Si es True, se ha
elegido "Cursiva"
CD1.FontStrikethru
= (True / False) Si es True, se ha
elegido "Tachada "
CD1.FontUnderline
= (True / False) Si es True, se ha
elegido "Subrayada"
Si se elige una versión Negrita Cursiva serían True las
opciones FontBold y FontItalic
El objeto Font no puede aplicarse al
CommonDialog. Es decir, no podemos poner :
Variable
= CD1.Font.Size sino Variable = CD1.Fontsize
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.
COLOR
Para mostrar el cuadro de diálogo
correspondiente al color, se deberá ejecutar la instrucción:
CD1.ShowColor
El cuadro de diálogo presentado tiene esta forma:

(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)
El número correspondiente al color
elegido se puede conocer analizando la propiedad color de cuadro de diálogo. En
nuestro ejemplo, lo obtendríamos con
Variablecolor = CD1.Color
donde Variablecolor
contendrá un número correspondiente al color elegido.
Nota acerca
del número del 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.
Colores
en Visual Basic.
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.
Por ejemplo: el rojo puro sería: Hex(0000FF)
= 255
el
verde puro sería: Hex(00FF00) = 652280
el
azul puro sería: Hex(FF0000) = 16711680
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
El número de color puede estar
comprendido entre 0 (correspondiente al
negro) y el 16777215 (correspondiente al blanco. Observe que esa cantidad,
16.777.215 (FFFFFF en hexadecimal) corresponde a los famosos 16 millones de
colores de las tarjetas gráficas.
Si queremos poner el color de fondo a un
control Label, usaremos la propiedad Backcolor. Si el Label se llama Label1,
pondríamos la instrucción
Label1.Backcolor
= 12345678
Por
la sentencia RGB
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.
Si queremos poner al Label anterior un
color mediante la sentencia RGB, ejecutaríamos la sentencia :
Label1.Backcolor
= RGB (128, 30, 100)
Mediante
la Función QBColor
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)
El argumento color es un número entero
entre 0 a 15, según la siguiente lista:
Número Color Número 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
Para el mismo Label anterior, usaríamos
la sentencia :
Label1.Backcolor
= QBColor (12)
Fin de la
nota acerca del número del color
IMPRESORAS
Nota: Si utiliza
un CommonDialog para impresoras y otras aplicaciones, puede tener problemas. Utilice un CommonDialog exclusivamente para
impresoras.
Para presentar el cuadro de elección de
impresora, ejecute la instrucción:
CD2.ShowPrinter
(A este cuadro de dialogo le hemos
llamado CD2 para evitar los problemas referidos en la nota).
Aparecerá el siguiente cuadro de diálogo:

La impresora elegida puede conocerla
llamando a la propiedad DeviceName
de un objeto que aún no hemos visto: el objeto Printer. Este objeto es el encargado de pasar al Administrador de
Impresión todos los trabajos de impresión que generen las aplicaciones Visual
Basic:
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.
ABRIR Y
GUARDAR ARCHIVOS
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:
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:
CD1.Filter = "Descripción del
fichero|nombre.extensión"
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
CD1.Filter = "Ficheros ejecutables
|*.exe"
Observe el carácter separador entre la
descripción de los ficheros (Ficheros ejecutables) y el parámetro de busca (*.EXE).
No ponga ningún espacio entre el separador y los caracteres de busca. El
separador es el carácter ASCII 124.
Puede buscar varios tipos de ficheros,
separando los caracteres de busca por medio del carácter punto y coma (;)
CD1.Filter = "Ficheros ejecutables
|*.EXE;*.COM;*.BAT"
Puede también introducir dos filtros,
separados por el separador | (En una línea solamente).
CD1.Filter=”Ficheros
de un tipo |*.EXE |Ficheros de otro |*.COM |Otros ficheros |*.BAT”
Por ejemplo : CD1.Filter =
"Ficheros Word |*.DOC|Ficheros Write |*.WRI"
¡ 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.
Para conocer el nombre del fichero
elegido, se emplea la propiedad FileName :
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.
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 :

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)
Pese a que se pueden presentar estos
ficheros basándonos en el CommonDialog, es preferible usar directamente el
programa WinHelp.Exe, que puede ejecutarlo mediante la función Shell :
VariableID = Shell
(“WinHelp.Exe FicheroAyuda.hlp”,1)
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.
CD1.HelpCommand
=Valor
Las opciones para
valor son:
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.
Si queremos que se muestre el índice de
la ayuda, pondríamos esta propiedad de la forma :
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
Para mostrar la Ayuda de la Ayuda de
Windows :
CD1.HelpCommand
= cdlHelpHelpOnHelp
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
PROPIEDADES
DEL CommonDialog
La
Propiedad Action
La propiedad Action se incluye en la
versión 4 de VB solamente por motivos de compatibilidad con anteriores
versiones. Realiza las mismas funciones que ShowFont, ShowColor, ShowPrinter, ShowOpen y ShowSave. No debe usarse esta
propiedad, sino los equivalentes citados, en previsión de que pueda ser
eliminada en futuras versiones.
La sintaxis de Action es : Nombre.Action
[= valor]
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.
NO
utilice la propiedad Action. Utilice en su
lugar ShowFont, ShowPrinter, ShowSave, ShowOpen , ShowColor y ShowHelp
CancelError
Devuelve o
establece un valor que indica si se genera un error cuando el usuario elige el
botón Cancelar.
Sintaxis : objeto.CancelError = (True / False)
True Se genera un error.
False (Predeterminado) No se genera ningún error.
Cuando se establece
True en esta propiedad, se producirá el error número 32755 (cdlCancel) cada vez que el usuario
elija 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.
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.
Sintaxis objeto.DefaultExt [= cadena]
Puede utilizar esta
propiedad para especificar una extensión de archivo predeterminada, como por
ejemplo .TXT o .DOC.
Importante
para el CommonDialog de Guardar: Cuando se guarde un archivo sin
extensión, se le agregará automáticamente la especificada en esta propiedad.
DialogTitle
Devuelve o
establece la cadena mostrada en la barra de título del cuadro de diálogo.
Sintaxis Nombre.DialogTitle [= título]
Esta propiedad
puede introducirse en la ventana de propiedades, o por programa. Puede utilizar
esa propiedad para mostrar el nombre del cuadro de diálogo en la barra de
título.
Nota El control CommonDialog ignora el valor de
la propiedad DialogTitle cuando muestra los cuadros de diálogo Color o Fuente.
El título
predeterminado para un cuadro de diálogo Abrir es Abrir, y para un cuadro de diálogo Guardar como es Guardar como.
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.
Sintaxis CD1.Filter [= descripción1
|filtro1 |descripción2 |filtro2...]
Utilice el símbolo
de canalización ( | , (ASCII 124) ) para separar los valores de descripción y
de filtro. No incluya espacios antes ni después del símbolo de canalización,
pues aparecerían en los valores de descripción y valor.
Al especificar más
de un filtro en un cuadro de diálogo, utilice la propiedad FilterIndex para especificar el filtro predeterminado.
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.
Sintaxis CD1.FilterIndex [= número]
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.
Sintaxis CD1.Flags [= valor]
El
parámetro valor establece distintas alternativas, dependiendo de cada cuadro.
Para el cuadro de diálogo Color
Las opciones para valor son:
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.
Para los
cuadros Abrir y Guardar
Las opciones para
valor son:
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.
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.
32768 &H8000& cdlNoReadOnlyReturn
Especifica que el
archivo devuelto no tenga el atributo de Sólo lectura ni esté en un directorio
protegido contra escritura. Presenta un aviso (tanto en el cuadro de abrir como
en el cerrar) que impide elegir un fichero de estas características.
Se
pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los valores de cada
una de las condiciones a poner.
Para el
cuadro Mostrar Fuentes:
Las opciones para valor son:
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 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.
4096 &H1000& cdlNoSimulations
Especifica que el
cuadro de diálogo no permita simulaciones de fuente de interfaz de dispositivo
gráfico (GDI).
8192 &H2000& cdlLimitSize
Especifica que el
cuadro de diálogo seleccione sólo los tamaños de fuente comprendidos en el rango especificado por
las propiedades Min y Max.
16384 &H4000& cdlFixedPitchOnly
Especifica que el
cuadro de diálogo seleccione sólo fuentes de espaciado fijo.
32768 &H8000& cdlWYSIWYG
Especifica que el
cuadro de diálogo permita seleccionar solamente fuentes disponibles al la vez
en la pantalla y en la impresora. Si se establece este indicador, también deben
establecerse cdlBoth (sume 3 a este
número) y cdlScalableOnly (sume 131072
a este número)
65536 &H10000& cdlForceFontExist
Especifica que
aparezca un cuadro de mensaje cuando el usuario intente seleccionar una fuente
o un estilo que no existan.
131072 &H20000& cdlScalableOnly
Especifica que el
cuadro de diálogo permita seleccionar solamente fuentes escalables.
262144 &H40000& cdlTTOnly
Especifica que el
cuadro de diálogo permita seleccionar solamente fuentes TrueType.
Nota Antes
de mostrar el cuadro de diálogo Fuentes, debe establecer cdlScreenFonts,
cdlPrinterFonts o cdlBoth en la propiedad Flags. En
caso contrario, se producirá el error No hay fuentes. (O dicho de otra forma,
Flags=1, 2 ó 3)
Se
pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los valores de cada
una de las condiciones a poner.
Para el
Cuadro de Diálogo Imprimir
(Observará seguramente que lo que se
describe a continuación no se cumple siempre. Depende de las impresoras que
tenga Vd. instaladas)
Las opciones para valor son:
0 &H0& cdlAllPages
Devuelve
o establece el estado del botón de opción Todas las páginas.
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.
256 &H100& cdlReturnDC
Devuelve un
contexto de dispositivo para la impresora seleccionada en el cuadro de diálogo.
El contexto se devuelve en la propiedad hDC del cuadro de diálogo.
512 &H200& cdlReturnIC
Devuelve un
contexto de información para la impresora seleccionada en el cuadro de diálogo.
Un contexto de información proporciona un método rápido de obtener información
sobre el dispositivo sin crear un contexto de dispositivo. El contexto de
información se devuelve en la propiedad hDC del cuadro de diálogo.
2048 &H800& cdlShowHelp
Hace que el cuadro
de diálogo muestre el botón Ayuda
262144 &H40000& cdlUseDevModeCopies
Si un controlador de
impresora no admite copias múltiples, al establecer este indicador se desactiva
el control de edición de número de copias. Si el controlador sí admite
múltiples copias, al establecer este indicador el cuadro de diálogo almacenará
el número de copias solicitado en la propiedad Copies.
524288 &H80000& cdlDisablePrintToFile
Desactiva la
casilla de verificación Imprimir a un archivo.
1048576 &H100000& cdlHidePrintToFile
Oculta la casilla
de verificación Imprimir a un archivo.
Propiedades
que afectan al tipo de letra.
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.
Sintaxis Variable = CD1.FontBold
Los valores de Variable son:
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.
Sintaxis Variable = CD1. FontItalic
Los valores de Variable son:
True si se
ha elegido cursiva, False (Predeterminado) en caso
contrario.
FontStrikethru
Propiedad Booleana
que establece o devuelve que el tipo de letra usado es Tachada.
Sintaxis Variable = CD1.
FontStrikethru
Los valores de Variable son:
True si se
ha elegido tachado, False
(Predeterminado) en caso contrario.
FontUnderline
Propiedad Booleana
que establece o devuelve que el tipo de letra usado es Subrayado.
Sintaxis Variable = CD1.FontUnderline
Los valores de Variable son:
True, si
se ha elegido subrayado, False (Predeterminado) en caso contrario
FontName
Devuelve el nombre
de la fuente elegida. Es una variable tipo String
Sintaxis Variable = CD1.FontName
(Variable
toma el valor del nombre de la fuente. Por ejemplo, Variable = “Arial”
En general, deberá
modificar FontName antes de establecer
los atributos de tamaño y estilo con las propiedades FontSize, FontBold, FontItalic, FontStrikethru y FontUnderline.
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
Sintaxis Variable = CD1.FontSize
donde Variable será
una expresión numérica que especifica el tamaño de fuente a utilizar, en
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.
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
Igual que el ya estudiado para otros controles.
InitDir
Devuelve o
establece el directorio de archivos inicial.
Sintaxis objeto.InitDir [= cadena]
La sintaxis de la
propiedad InitDir consta de las siguientes partes:
objeto Nombre que define al CommonDialog
cadena Expresión de cadena que especifica el
directorio de archivos inicial.
Si no se especifica esta propiedad, se
utilizará el directorio actual.
Left y
Top
Estas propiedades
solamente afectan a la colocación del
icono en el formulario. No afectan a la colocación del CommonDialog durante la ejecución. La posición del CommonDialog en
tiempo de ejecución no puede controlarse.
Esta afirmación de
que la posición del CommonDialog no
es controlable es válida para sistemas a 32 bytes. En VB 4 de 16 bits, el
CommonDialog aparece aproximadamente en la parte superior izquierda del
formulario que lo contiene. Algunos programadores han optado por poner un
formulario para contener solamente al CommonDialog, y así, controlando la
posición de ese formulario, poder controlar la posición (aproximada) en la que
aparece el CD.
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.
Sintaxis objeto.MaxFileSize [= valor]
La sintaxis de la
propiedad MaxFileSize consta de las siguientes partes:
objeto = Nombre que
define al CommonDialog
valor = Número
entero que especifica el tamaño máximo del nombre de archivo en bytes. El rango
de esta propiedad es 132KB. El valor predeterminado es 256.
Name
Nombre que define al CommonDialog
PrinterDefault
Devuelve o
establece una opción que determina si la configuración elegida por el usuario
en el cuadro de diálogo Imprimir se utiliza para modificar la configuración
predeterminada de impresora del sistema.
Sintaxis objeto.PrinterDefault [= valor]
objeto = Nombre que
define al CommonDialog
valor = Expresión
booleana que especifica si lo seleccionado por el usuario se utiliza para
modificar la configuración de impresora predeterminada del sistema, según se
indica en Configuración.
Las opciones para
valor son:
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
Lo mismo que se ha explicado para otros controles.
Visual Basic - Guía del
Estudiante Cap. 4
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.
Para mostrar
una imagen en cualquiera de estos objetos, es necesario especificarlo en su
propiedad Picture. La forma de especificarle al objeto la
imagen que debe presentar puede hacerse de dos formas:
En la caja de propiedades, si no se va a
variar la imagen durante la aplicación.
Mediante una instrucción para cambiar esta
propiedad. La instrucción es la siguiente:
Nombreobjeto.Picture = LoadPicture (Path, Fichero)
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:
Form1.Picture = LoadPicture
(“C:\VB\METAFILE\BUSINESS\DOLLAR.WMF”)
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.
CONTROL
PICTURE BOX
Este objeto se encuentra en
la caja de herramientas estándar:

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)
Las
propiedades de un PictureBox son:
Align Appearance Autoredraw Autosize Backcolor BorderStyle
ClipControls DataField DataSource DragIcon DragMode DrawStile
DrawWidth Enabled FillColor FiilStyle Font Fontransparent
ForeColor Height HelpContextID Index Left LinkItem
LinkMode LinkTimeout LinkTopic MouseIcon MousePointer Name
Negotiate Picture ScaleHeight ScaleLeft ScaleMode ScaleTop
ScaleWidth TabIndex TabStop Tag Top Visible
WhatThisHelp Width
Un PictureBox puede disponer de los
siguientes procedimientos :
Click Change DblClick DragDrop DragOver GotFocus
KeyDown KeyPress
CONTROL IMAGE
Este control
se encuentra en la caja de herramientas estándar:

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 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.
Las
propiedades de un Image son:
Appearance BorderStyle Datafield DataSource DragIcon DragMode
Enabled Height Index Left MouseIcon MousePointer Name Picture Stretch Tag Top Visible
WhatThisHelp Width
Un Image puede disponer de los siguientes
procedimientos :
Click DblClick DragDrop DragOver GotFocus MouseDown
MouseMove MouseUp
PROPIEDADES DE
LOS CONTROLES PictureBox e Image
Align (PictureBox solamente)
Permite
colocar el control en el borde superior (Align
Top), en el inferior (Align Bottom),
en el izquierdo (Align Left) o en el
derecho (Align Right) del formulario
que lo contiene. Para no alinearlo con ningún borde basta con poner la
propiedad Align a 0-None.
Cuando se
adosa a uno de los bordes, el tamaño del control se ajusta automáticamente a la
anchura o altura del formulario.
Sintaxis
NombrePictureBox.Align [= número]
número Un entero que especifica cómo se presenta el control. Puede tomar
los siguientes
valores :
0-None (Predeterminado cuando el control se coloca en un formulario no
MDI). Con
este valor, el control mantiene el tamaño y la posición asignada en tiempo de diseño.
1-Top (Predeterminado cuando el control se coloca en formularios MDI)
El control se coloca en la
parte superior del formulario y su anchura es igual a la anchura del
formulario.
2-Bottom El control se coloca en la parte inferior del formulario y
su anchura es igual a
la anchura del formulario.
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.
De la misma
forma se puede crear barras de herramientas a los lados izquierdo o derecho de
un formulario. Si en un formulario hay dos barras de herramientas, una en la
parte superior (o inferior) y otra en un lateral, la de la parte superior o
inferior es la que se extiende hasta la esquina, teniendo preferencia sobre las
colocadas verticalmente a la izquierda o a la derecha.
Al ser el PictureBox un contenedor, puede poner
un PictureBox en la parte superior
de un Formulario, y colocar en este PictureBox
varios controles Image, a los que se
les puede poner un icono. De esta forma realizamos una barra de herramientas.
Negotiate (PictureBox solamente)
Establece un
valor que determina si se muestra un control que puede alinearse cuando un
objeto activo del formulario muestra una o más barras de herramientas. No está
disponible en tiempo de ejecución.
La propiedad
Negotiate puede tener los valores True o False:
True Si el control se alinea en el formulario
(la propiedad Align se establece como un valor no cero), el control permanecerá
visible cuando un objeto activo del formulario muestre una barra de
herramientas.
False (Predeterminado) El control no se muestra
cuando un objeto activo del formulario muestra una barra de herramientas. La
barra de herramientas del objeto activo se muestra en lugar del control.
Appearance (PictureBox
e Image) 3D o Flat, como en
otros controles
Autoredraw (PictureBox
solamente)
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.
Sintaxis objeto.AutoRedraw
[= valor]
Los valores
posibles de valor son:
True Activa
el redibujado automático de un control PictureBox. Los gráficos y el texto se
escriben en la pantalla y en una imagen almacenada en memoria. El control no
recibe eventos Paint; se vuelve a dibujar cuando es necesario, usando la imagen
almacenada en memoria.
False (Predeterminado)
Desactiva el redibujado automático de un control y escribe los gráficos y el
texto solamente en la pantalla. Visual Basic invoca el evento Paint del control
cuando se necesita volver a dibujar dicho control.
Autosize (PictureBox solamente)
Devuelve o
establece un valor que determina si el tamaño de un control se cambia
automáticamente para presentar su contenido completo.
Sintaxis objeto.AutoSize
[= valor]
Los valores
posibles de valor son:
True El
tamaño se cambia automáticamente para presentar el contenido completo.
False (Predeterminado) Mantiene constante el tamaño del control. El
contenido se recorta cuando excede el área del control.
BackColor (PictureBox solamente)
Color de fondo. Igual que
otros controles
BorderStyle (PictureBox
e Image)
Tipo de borde. Ninguno o
fijo. Igual que otros controles.
ClipControls (PictureBox
solamente)
Devuelve o
establece un valor que determina si los métodos gráficos en eventos Paint
vuelven a dibujar el objeto entero o solamente las áreas últimamente expuestas.
También determina si el entorno operativo Microsoft Windows crea una zona de
recorte que excluya los controles no gráficos contenidos en el objeto. En
tiempo de ejecución es de sólo lectura.
Sintaxis objeto.ClipControls
[= booleano]
Los valores
posibles de booleano son:
True (Predeterminado)
Los métodos gráficos de los eventos Paint vuelven a dibujar completamente el
objeto. Antes del evento Paint se crea una zona de recorte alrededor de los
controles no gráficos del formulario.
False Los
métodos gráficos de los eventos Paint solamente vuelven a dibujar las partes
recién expuestas. Antes del evento Paint no se crea una zona de recorte
alrededor de los controles no gráficos. Los formularios complejos se cargan
normalmente más rápido cuando ClipControls está establecido a False.
DataField (PictureBox e Image)
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)
Sintaxis objeto.DataField
=NombredelCampo
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.
DataSource (PictureBox e Image)
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.
Verá esto con
mas detalles cuando estudie los Objetos enlazados a Datos.
DragIcon
DragMode (PictureBox e Image) Igual que otros controles
DrawMode (PictureBox solamente)
Devuelve o
establece un valor que determina el aspecto de la salida de un método gráfico.
DrawStyle (PictureBox solamente)
Devuelve o
establece un valor que determina el estilo de línea de la salida de métodos
gráficos.
Sintaxis objeto.DrawStyle [= número]
Los valores
posibles de número son: 0 (Predeterminado)
Continuo.
1 Rayas.
2 Puntos.
3 Raya-punto.
4 Raya-punto-punto.
5 Transparente.
6 Continuo interior.
DrawWidth (PictureBox solamente)
Devuelve o
establece la anchura de línea de lo dibujado con los métodos gráficos.
Sintaxis NombredelPictureBox.DrawWidth [= tamaño]
tamaño 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.
Enabled (PictureBox e Image)
Habilitado. Igual que otros
controles.
FillColor, FillStyle, Font,
Fontransparent, ForeColor (PictureBox solamente)
Igual que otros controles.
Height, Width , Left, Top (PictureBox e Image)
Definen el
tamaño y la posición del control. En el control Image el tamaño puede depender del gráfico que se introduzca y del
valor de la propiedad Stretch.
HelpContextID (PictureBox solamente) Igual
que otros controles
Index (PictureBox e Image) Igual que otros controles
LinkItem, LinkMode, LinkTimeout, LinkTopic (PictureBox solamente)
Propiedades
que afectan al comportamiento de este control como DESTINO de una conversación
DDE. Se estudiará con mas detalles al estudiar el Intercambio Dinámico de
Datos.
MouseIcon, MousePointer (PictureBox e Image)
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")
imagen Propiedad Picture de un objeto Form, de un
control PictureBox o de un control Image, o nombre de una variable tipo
Picture. De esta forma podemos cargar como un icono el gráfico que tengamos en
otro objeto o en una variable tipo Picture.
Ej. Image1.MouseIcon = Picture1.picture
La propiedad
MouseIcon proporciona un icono de mouse personalizado que se utiliza cuando el
valor de la propiedad MousePointer
es 99.
MousePointer devuelve o establece un
valor que indica el tipo de puntero de mouse que aparece cuando se pasa el
puntero del ratón por encima de un
objeto en tiempo de ejecución.
Sintaxis objeto.MousePointer
[= valor]
objeto Nombre del objeto PictureBox o Image
valor Número entero que especifica el tipo de
puntero de mouse que aparece, según se describe mas adelante.
Las opciones
para valor son:
0 (Predeterminado) Forma que determine el
objeto.
1 Flecha.
2 Cruz (puntero en forma de cruz).
3 Forma de I.
4 Icono (pequeño cuadrado dentro de otro
cuadrado).
5 Tamaño (flecha de cuatro puntas: norte, sur,
este y oeste).
6 Tamaño NE SO (flecha doble apuntando al
nordeste y al sudoeste).
7 Tamaño N S (flecha doble apuntando al norte y
al sur).
8 Tamaño NO SE (flecha doble apuntando al
noroeste y al sudeste).
9 Tamaño O E (flecha doble apuntando al oeste y
al este).
10 Flecha hacia arriba.
11 Reloj de arena (espera).
12 No soltar.
13 Flecha y reloj de arena.
14 Flecha e interrogación.
15 Tamaño de todo (personalizable en
Microsoft Windows NT 3.51)
99 Icono personalizado especificado en la
propiedad MouseIcon explicada anteriormente.
Name (PictureBox
e Image) Nombre del control
Picture (PictureBox e Image)
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
Propiedades
del PictureBox solamente.
¡Todas las propiedades Scale ? ? ? ? afectan a
las coordenadas, no a la escala !
ScaleHeight, ScaleWidth
Devuelven o
establecen el número de unidades de medida horizontal (ScaleWidth) y vertical
(ScaleHeight) del interior de un objeto al utilizar métodos gráficos o al
colocar controles.
Sintaxis objeto.ScaleHeight [= valor]
objeto.ScaleWidth
[= valor]
objeto Nombre del Control
valor Expresión numérica que especifica la
medida horizontal o vertical.
Nota Las propiedades ScaleHeight y ScaleWidth
son distintas de las propiedades Height y Width.
ScaleLeft, ScaleTop
Devuelven o
establecen las coordenadas horizontal (ScaleLeft) y vertical (ScaleTop) de los
bordes izquierdo y superior de un objeto al utilizar métodos gráficos o al
situar controles. Estas coordenadas están medidas de acuerdo con la unidad de
medida establecida en las propiedades ScaleHeight y ScaleWidth
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.
Sintaxis objeto.ScaleMode [= valor]
Nombre del
Control
objeto Nombre del Control
valor Número entero que especifica la unidad de
medida, según se describe a continuación.
0 Indica
que una o más de las propiedades ScaleHeight, ScaleWidth, ScaleLeft y ScaleTop
tienen valores personalizados. Se usa entonces una unidad de medida definida
por el usuario (User)
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.
Utilizando las
propiedades relacionadas ScaleHeight, ScaleWidth, ScaleLeft y ScaleTop, puede
configurar un sistema de coordenadas completo, con coordenadas positivas y
negativas. Estas cuatro propiedades de escala se relacionan con la propiedad
ScaleMode de la siguiente forma:
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.
Stretch (Solo control Image)
Devuelve o
establece un valor que indica si un gráfico cambia su tamaño para ajustarlo al
de un control Image.
Sintaxis objeto.Stretch
[= lógico]
objeto Nombre del control Image
lógico Expresión booleana que especifica si el
gráfico adapta su tamaño, según se describe a continuación.
True El gráfico cambia su tamaño para
ajustarlo al del control.
False (Predeterminado) El control cambia su
tamaño para ajustarlo al del gráfico.
Si Stretch
tiene el valor True, al cambiar el tamaño del control también se cambiará el
del gráfico que contenga. Cuando aumenta el tamaño del control, mantiene las
nuevas medidas aunque se le introduzca un gráfico de menor tamaño. Debe
controlarse por programa el tamaño del mismo.
TabIndex, TabStop (Solo control PictureBox)
Igual que otros controles
Tag
Top
Visible
WhatsThisHelpID
Width Comunes a
ambos. Igual que resto de controles.
Otros controles que pueden
manejar imágenes
IMAGE
LIST
Este control
no está normalmente en la caja de herramientas. Solamente está disponible en la
versión de 32 bits. Hay que introducirlo mediante los Herramientas | Controles Personalizados y pertenece al grupo Microsoft Windows Common Controls (COMCTL32.OCX) (Vea Nota 1)

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.
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.

Nota
1. El grupo de controles Microsoft Windows Common Controls (COMCTL32.OCX) incluye además de este los
controles TabStrip, Toolbar, StatusBar, ProgressBar, TreeView, ListView y
Slider.
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

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)
Si
tenemos un control Picture llamado Picture1 y queremos poner en su propiedad
Picture la imagen cargada en el ImageList1, en su posición 3, usaríamos la
expresión :
Set Picture1.Picture =
ImageList1.ListImages (3) . Picture
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.
Numerodeimágenes =
ImageList1. ListImages.Count
Dado
que al guardar imágenes en un ImageList,
estas imágenes están guardadas en la memoria RAM, es fácil realizar una animación. Para ello necesitamos varias
imágenes que poniendo una tras otra, dé la sensación de movimiento. Imaginemos
un número indeterminado de imágenes dentro de un ImageList, y un control
Picture llamado Picture1 donde queremos presentar la animación. En el procedimiento Timer de un Timer
pondríamos
Static pepe As
Integer
pepe = pepe + 1
If pepe >
ImageList1.ListImages.Count Then pepe = 1
Set
Picture1.Picture = ImageList1.ListImages(pepe).Picture
Una
de las mayores aplicaciones del ImageList es proporcionar imágenes para otros
controles. Entre ellos el TOOLBAR
Barra de Herramientas. Control 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.
Todo ello lo puede hacer el
control Toolbar.
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
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.

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.
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).
La propiedad Style define
el tipo de botón :
0 - Default Botón
monostable. (Se pulsa, pero no se
mantiene pulsado)
1 - Check Botón
Biestable. (Se mantiene pulsado y se levanta con otro click)
2 - Button Group Solo
uno de los botones del grupo puede estar pulsado. Esta
propiedad
lleva implícito que los botones que forman un grupo son biestables. Pueden
hacerse varios grupos independientes introduciendo un botón que no pertenezca a
un grupo (tipos 0, 1, 3 ó 4) entre los dos grupos que se independientes que se
pretenden formar
3 - Separator El
botón se convierte en un separador de anchura fija.
4 - PlaceHolder El
botón se convierte en un separador de anchura variable.
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.
Image es el número de la
imagen en el ImageList.
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 :
Set NombreBotón =
NombreToolbar.Buttons.add ( [Indice], [Key], [Caption],
[Style], [Imagen])
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
Para saber que botón se ha
pulsado, puede leerse la propiedad Key :
Text1.Text = Button.Key
presenta en Text1 el texto introducido
en la propiedad
Key del último
botón pulsado.
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.
El control Toolbar tiene
los siguientes eventos :
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 :
Private Sub
Toolbar1_ButtonClick(ByVal Button As Button)
If Button.Index = 1 Then . . . .
If Button.Index =
2 Then . . . .
También podríamos usar la
propiedad Key como se dijo mas
atrás.
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 cualquier
control.
MouseMove,
MouseUp, MouseDown
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.
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.
¡
El control Toolbar NO sirve de contenedor de otros controles, a excepción de
sus botones ! ! !
LA BARRA DE ESTADO
Este control es muy
parecido a la barra de herramientas, y suele usarse, colocándolo en la parte
inferior de la ventana, para indicar el proceso que está en curso en la
aplicación. La barra de estado, control StatusBar
se introduce en la caja de herramientas al mismo tiempo que el control Toolbar,
mediante el control personalizado múltiple Microsoft Windows Common Controls (COMCTL32.OCX).
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
La barra de estado puede
configurarse como de un solo panel o de múltiples paneles. (Propiedad Style. 0=múltiples paneles, 1= panel
único)
Las dimensiones de cada
panel pueden configurarse como fijas o ajustadas al tamaño del texto o imagen
que presentan.
Las propiedades pueden
establecerse en tiempo de diseño, mediante el siguiente cuadro.

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.
La barra de estado puede
realizarse en tiempo de diseño o en tiempo de ejecución. Para realizarla en
tiempo de ejecución basta con visualizar la ventana de propiedades, muy similar
a la del control Toolbar.
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 :
Set PanelNuevo = Nombrebarraestado.Panels.Add.( [índice],[key],[Text],[estilo],[gráfico]
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)
Los
términos [índice],[key],[Text],[estilo],[gráfico] que entran a formar parte en la sintaxis de
creación del panel se explican a continuación.
Indice - Necesario.
Es el índice que define al panel dentro del StatusBar.
Key -
Opcional. Es la propiedad Key de ese
panel (El contenido de esta propiedad
lo podemos
leer desde cada panel
Variable =
statusbar1.Panels(Panel.Index).Key
Text - El texto
que queremos figure en el panel (Solo
si la propiedad Estilo está en sbrText
Estilo - Propiedad
estilo del panel.
0 - sbrText El panel mostrará el Texto de
la propiedad Text de ese panel
1 - sbrCaps El panel muestra el estado de la tecla
Bloqueo Mayúsculas
2 - sbrNum El panel muestra el estado de
la tecla Bloq. Números
3 - sbrIns El panel muestra el estado de
la tecla Insert
4 - sbrScrl El panel muestra el estado de
la tecla Scroll / Lock
5 - sbrTime El panel muestra la hora
6 - sbrDate El panel muestra la fecha
Gráfico
- Es el gráfico que va a tener el panel. Este gráfico puede obtenerse desde un
ImageList,
ImageList1.ListImages(n).Picture
- o directamente desde el disco duro,
mediante el
método LoadPicture -
LoadPicture("C:\vb\icons\comm\net09a.ico") -
Si
no se pone alguna de las propiedades opcionales intermedias, deben mantenerse
las comas separadoras.
Como
ejemplo, podemos añadir varios paneles de la siguiente forma :
Dim PanelNuevo As Panel ‘Donde deba declararse a efectos del ámbito
Dim pepe As Integer
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.
Visual Basic - Guía del
Estudiante Cap. 5
CONTROLES
DE BUSQUEDA DE FICHEROS - PORTAPAPELES
MENÚS
- MENUS EMERGENTES
CONTROLES DE BUSQUEDA DE FICHEROS Y
DIRECTORIOS
DriveListBox, DirListBox Y FileListBox.
Se obtienen directamente de
la Caja de Herramientas, en los iconos siguientes:

DriveListBox permite elegir una unidad de
disco.
DirListBox muestra los directorios existentes
en un árbol.
FileListBox muestra los ficheros existentes en
un determinado directorio.
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.
DriveListBox
desplegado y sin desplegar Name
(nombre) por defecto List1
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
Drive devuelve el
nombre de la unidad de disco seleccionada :
Variable = List1.Drive
Variable = a : (ó c :[MS-DOS_6] ó
D )
Este control
se trata de una lista como su nombre indica, y posee las propiedades List, ListCount y ListIndex
para permitir al usuario tener acceso a elementos de la lista.
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)
Utilizando el
control DriveListBox en combinación
con DirListBox y FileListBox, podrá realizar un
explorador de ficheros en cualquier disco de su ordenador.
DirListBox.
Presenta un
cuadro de la siguiente forma:

donde puede
verse el árbol completo de un directorio. El DirListBox solamente presenta directorios. No presenta ficheros.
Aparte de las
propiedades geométricas de todos los controles, el DirListBox presentas las siguientes propiedades particulares :
Path
Devuelve o establece la
ruta de acceso actual. No está disponible en tiempo de diseño.
Sintaxis Nombre.Path
[= pathname]
donde
Nombre es el nombre del DirListBox
pathname Una expresión de cadena que evalúa en el
nombre de vía de acceso del directorio por defecto del DirListBox..
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
Cuando se cambia la
propiedad Path en tiempo de ejecución se genera un evento Change.
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.
List,
ListCount y ListIndex
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.
ListCount devuelve un
valor numérico igual al número de directorios existentes en el último nivel,
independientemente de los directorios que tuviesen por arriba.
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
Esta lista nos presenta los
ficheros existentes en un directorio.

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.
Esta lista de ficheros
tiene las siguientes propiedades destacables :
Path
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)
Si le ponemos el nombre por
defecto, List1, para todos los ejemplos :
variable = List1.Path Variable = C:\Archivos de
programa\Microsoft Visual Basic32 (p. e.)
ListCount
Devuelve el número total de
ficheros que hay en ese directorio.
Variable = List1.ListCount Variable = 19 (p. e.)
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
Devuelve el nombre del
fichero seleccionado.
List
(n)
Devuelve el nombre del
fichero que ocupa el lugar n en la lista.
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 :
variable = List1.List (List1.ListIndex) obtendremos el nombre del fichero
seleccionado.
Observe que en este último
caso, el resultado es el mismo que el de
List1.Filename
Veamos otras propiedades del FileListBox
Pattern
Devuelve o
establece un valor que indica los nombres de archivo mostrados en un control FileListBox en tiempo de ejecución.
Sintaxis objeto.Pattern [=
valor]
La sintaxis de la propiedad
Pattern consta de las siguientes partes:
objeto : Nombre del Control FileListBox
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
La propiedad Pattern juega un papel clave en el
diseño de las funciones de examen y tratamiento de archivos de una aplicación.
Puede utilizar Pattern en combinación con otras propiedades de control de
archivos para proporcionar al usuario formas de explorar archivos o grupos de
archivos similares. Por ejemplo, en una aplicación dedicada a iniciar otros
programas, podría hacer que sólo apareciesen los archivos .EXE en el cuadro de
lista de archivos (*.EXE).
Al modificar el valor de la
propiedad Pattern se genera un evento PatternChange.
Archive,
Hidden, Normal, System
Devuelven o
establecen un valor que determina si un control FileListBox presenta los archivos con los atributos Archive,
Hidden, Normal o System.
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 valor booleano puede
presentar los siguientes valores :
True :(Predeterminado para Archive y Normal)
Presenta archivos con el atributo de la propiedad en el control FileListBox.
False : (Predeterminado para Hidden y System)
Presenta archivos sin el atributo de la propiedad en el control FileListBox.
Use estas
propiedades para especificar el tipo de archivos a presentar en un control
FileListBox, basándose en los atributos de archivos estándar usados en el
entorno operativo. La definición de estas propiedades en el código en tiempo de
ejecución hace que el control FileListBox presente sólo aquellos archivos con
los atributos especificados.
Por ejemplo,
en una operación de buscar y reemplazar se podrían presentar solamente archivos
del sistema estableciendo la propiedad System a True y las demás propiedades a
False. También, como parte del procedimiento de copia de seguridad, se podría
establecer la propiedad Archive a True para relacionar solamente aquellos
archivos modificados a partir de la última copia de seguridad.
PROCEDIMIENTOS
del FileListBox
Click Change DragDrop DragOver GotFocus
KeyDown KeyPress KeyUp
SENTENCIAS DE
MANEJO DE DIRECTORIOS Y FICHEROS
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 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.
Ejemplo : Introduzca una línea de código con la
siguiente sentencia
Variable = CurDir Al ejecutarla la variable Variable
contendrá la información :
Variable = C:\Archivos de
programa\Microsoft Visual Basic32 (p. e.)
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 :
Variable = CurDir
(“A”) Variable tomará entonces el
valor Variable = “A :\ApVB\Tema1”
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)
Ejemplo ChDrive
“A” cambia la unidad actual
a la unidad A. Observe que el
parámetro A no tiene que
llevar los dos puntos ( : ),
aunque si lo
desea, puede ponerlos. También
es indiferente que la letra sea
mayúscula o minúscula.
También
podemos forzar a que un directorio sea el directorio por defecto. La sentencia
que tendremos que usar en ChDir.
Ejemplo : ChDir
“C :\Windows\System” cambiaría el
directorio actual al especificado.
Podemos
incluso crear un directorio. Usaremos para ello la sentencia MkDir. Esta sentencia crea el
directorio con el nombre indicado, sobre el directorio actual.
Si el directorio actual es
el C:\VB\Icons y ejecutamos la
sentencia :
MkDir
“Varios” crearíamos el directorio C:\VB\Icons\Varios
Podemos incluso eliminar un
directorio. La sentencia para eliminar un directorio es RmDir
¡ 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.
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)
fichero =
Dir("*.*") ‘Le
decimos que imprima todos (*.*)
Do Until
fichero = "" ‘Hasta que fichero
sea una cadena de longitud cero..
Printer.Print fichero ‘Imprime
la variable fichero en la impresora
fichero = Dir ‘Toma el nombre de otro
fichero
Loop ‘Vuelve a Do Until
.....
Printer.EndDoc ‘Termina la impresión y saca la hoja
de la impresora
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”
borra el
fichero Ejemplo1.txt, que se encuentra en el disco C, directorio \
CursoVB\Ejemplos
Función FileCopy. Copia un fichero. La sintaxis
de esta función es la siguiente :
FileCopy Origen, Destino
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 :
FileCopy Text1.Text,
Text2.Text
Si queremos
copiar un fichero del disco A, en el directorio CursoVB y de nombre Ejemplo1 al disco y directorio
C:\CursoVB\Ejemplos y con el mismo nombre que tenía en el disco A, es decir,
Ejemplo1, ejecutaremos la sentencia :
FileCopy “A :\CursoVB\Ejemplo1” ,
“C:\CursoVB\Ejemplos\Ejemplo1”
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.
La instrucción
Name cambia el nombre de un fichero.
No solamente puede cambiar un nombre, puede incluso moverlo de sitio, pero
siempre en la misma unidad de disco.
La sintaxis de
Name es la siguiente :
Name nombrerutaantiguo As
nombrerutanuevo
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.
Tanto nombrerutanuevo
como nombrerutaantiguo
deben encontrarse en la misma unidad de disco. Si la ruta de acceso
especificada en nombrerutanuevo existe y es distinta de la ruta de acceso
especificada en nombrerutaantiguo, la instrucción Name coloca el archivo en el
nuevo directorio o carpeta y cambia el nombre del archivo, de ser necesario. Si
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.
En el ejemplo,
vamos a cambiar el nombre del fichero C:\CursoVB\Ejemplos\Ejemplo1 por el de
C :\CursoVB\Ejemplos\Prueba1
Name “C:\CursoVB\Ejemplos\Ejemplo1” As “C :\CursoVB\Ejemplos\Prueba1”
En el
siguiente, aparte de cambiarlo de nombre, le cambiamos de directorio.
Name “C:\CursoVB\Ejemplos\Ejemplo1” As “C :\CursoVB\Ejercic\Prueba1”
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")
Variable
tomará un valor numérico igual al número de bytes del fichero.
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.
La sintaxis
es, para el caso del ejemplo :
Variable = FileDateTime ("C:\CursoVB\Ejemplos\Ejemplo1")
Variable puede
tomar un valor como el siguiente :
Variable = 13/02/97 14:59:20
(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.
Sintaxis Variable = GetAttr (nombreruta)
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:
Valor Constante Descripción
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.
Si la
expresión nombreruta representa un directorio, se lo indicará devolviendo el
valor 16.
Para cambiar
un atributo utilizaremos la función SetAttr.
La sintaxis de esta función es la siguiente
Sintaxis SetAttr
nombreruta , atributos
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.
Dado que el
valor 16 indica que lo expresado en nombreruta es un directorio, no puede
pretenderse darle a ese directorio atributos que solamente se pueden aplicar a
un fichero, ni puede pretender darle a un fichero un valor en el que entre el
16 como sumando. Estos casos le producirán un error en tiempo de ejecución.
Si pretende
establecer los atributos de un archivo abierto, se producirá un error en tiempo
de ejecución.
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
Devuelve el
modo de apertura de un archivo. Logicamente debe referirse a un archivo abierto
en el momento de ejecutar esta función. Vea para mas detalles la sentencia
Open.
Sintaxis variable = FileAttr (numerocanal , tipoinformación)
Donde
numerocanal es el número del canal de apertura de ese archivo, y
tipoinformación es el tipo de información que deseamos de ese fichero. Si
tipoinformación = 1 nos devuelve el modo de apertura del fichero, según la
siguiente lista
Valor Modo del archivo
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.
Visual Basic - Guía del Estudiante Cap. 5 Cont.
EL PORTAPAPELES. EL OBJETO CLIPBOARD
OBJETO CLIPBOARD
Proporciona acceso al
Portapapeles del sistema.
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
Clipboard.SetText
datos, formato
datos Requerido.
Cadena de datos que se va a colocar en el Portapapeles.
formato Opcional.
Una constante o valor que especifica uno de los formatos del Portapapeles
reconocidos por Visual Basic, como se describe a continuación :
Los valores de formato son:
Constante Valor Descripción
vbCFLink &HBF00 Información de conversación DDE
vbCFRTF &HBF01 Formato de texto enriquecido
vbCFText 1 (Predeterminado) Texto
Estas constantes se enumeran en la biblioteca de
objetos de Visual Basic (VB) del Examinador de objetos.
SetData
Pone una imagen en el objeto Clipboard usando el
formato gráfico especificado. No acepta argumentos con nombre.
Sintaxis Clipboard.SetData datos, formato
datos Requerido.
El gráfico que se va colocar en el objeto Clipboard.
Importante.
Ver NOTA1 mas adelante
formato Opcional.
Una constante o valor que especifica uno de los formatos del
objeto Clipboard reconocidos por Visual Basic, como se describe mas adelante.
Si formato se omite, SetData determina el formato gráfico automáticamente.
Los valores de formato son:
Constante Valor Descripción
vbCFBitmap 2 Mapa de bits (archivos .BMP)
vbCFMetafile 3 Metarchivo (archivos .WMF)
vbCFDIB 8 Mapa de bits independiente del
dispositivo (DIB)
vbCFPalette 9 Paleta de colores
Estas constantes se enumeran en la biblioteca de
objetos de Visual Basic (VB) del Examinador de objetos.
El gráfico que se va colocar en el objeto Clipboard
se define mediante la función LoadPicture o la propiedad Picture de los objetos
Form, Image o PictureBox.
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.
NO pretenda hacer esto Clipboard.SetData
Picture1.Picture
sino ESTO Clipboard.SetData Picture1.Image
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.
(Observe
que esto NO coincide con lo que aporta la información de VB.)
GetData
Devuelve un gráfico del objeto Clipboard. No acepta
argumentos con nombre.
Sintaxis Clipboard.GetData (formato)
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.
Los valores de formato son:
Constante Valor Descripción
vbCFBitmap 2 Mapa de bits (archivos .BMP)
vbCFMetafile 3 Metarchivo (archivos .WMF)
vbCFDIB 8 Mapa de bits independiente del
dispositivo (DIB)
vbCFPalette 9 Paleta de colores
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.
Sintaxis Clipboard.GetText (formato)
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.
Los valores de formato son:
Constante Valor Descripción
vbCFLink &HBF00 Información de conversación DDE
vbCFText 1 (Predeterminado) Texto
Si en el objeto Clipboard no hay ninguna cadena de
texto que coincida con el formato esperado, se devuelve una cadena vacía
("").
Paste
Copia datos desde el Portapapeles del sistema en un
control contenedor OLE.
Sintaxis objeto.Paste
Objeto es el nombre del Panel Contenedor OLE donde se
quiere depositar el contenido del Portapapeles.
Comentario
Para usar este método, defina la propiedad
OLETypeAllowed y después verifique el valor de la propiedad PasteOK. No se
puede pegar con éxito a menos que PasteOK devuelva True.
Si se ha ejecutado el método Paste, la propiedad
OLEType es vbOLELinked (0) o vbOLEEmbedded (1). Si no se ha ejecutado el método
Paste, la propiedad OLEType es vbOLENone (3).
Este método puede usarse para implementar un comando
Edición Pegar en un menú.
Si el valor de la propiedad PasteOK es True y Visual
Basic no puede pegar el objeto, el control contenedor OLE elimina cualquier
objeto existente en el control.
PasteOK
Devuelve un valor que determina si el contenido del
Portapapeles del sistema se puede pegar en el control contenedor OLE.
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.
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.
Los objetos se pegan en el control contenedor OLE con
el método Paste.
Para ofrecer mayor flexibilidad al usuario, presente
un cuadro de diálogo Pegado especial cuando el usuario elija el comando Edición
Pegar
. (Establezca OLETypeAllowed = 2 y después use el
método PasteSpecialDlg). Cuando se presenta este cuadro de diálogo, el objeto
del Portapapeles del sistema se pega basándose en las selecciones del usuario
en el cuadro de diálogo.
GetFormat
Devuelve un entero que indica si un elemento del
objeto Clipboard coincide con un formato especificado. No acepta argumentos con
nombre.
Sintaxis Clipboard.GetFormat (formato)
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.
Los valores de formato son:
Constante Valor Descripción
vbCFLink HBF00 Información de conversación DDE
vbCFText 1 Texto
vbCFBitmap 2 Mapa de bits (archivos .BMP)
vbCFMetafile 3 Metarchivo (archivos .WMF)
vbCFDIB 8 Mapa de bits independiente del
dispositivo (DIB)
vbCFPalette 9 Paleta de colores
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
Borra el contenido del Portapapeles del sistema.
Sintaxis Clipboard.Clear
Con Clear se borra todo el contenido
del portapapeles, texto y gráficos.
Copy
Copia el objeto de un control contenedor OLE al
Portapapeles del sistema.
Sintaxis objeto.Copy
Objeto
es el nombre del contenedor OLE cuyo contenido queremos copiar
Comentario
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.
Cree
un formulario de la siguiente forma :

El
gráfico que tiene el Picture de la izquierda puede ser cualquiera.
El
código de este formulario es el siguiente :
Option Explicit
Private Sub Check1_Click()
End Sub
Private Sub Command1_Click()
Clipboard.SetData
Picture1.Image
End Sub
Private Sub Command2_Click()
Dim ClpFmt As Integer
Dim Msg As String
On
Error Resume Next ' Configura el
controlador de errores.
If Clipboard.GetFormat(vbCFText) Then ClpFmt =
ClpFmt + 1
If Clipboard.GetFormat(vbCFBitmap) Then ClpFmt = ClpFmt + 2
If Clipboard.GetFormat(vbCFDIB) Then ClpFmt = ClpFmt + 4
If Clipboard.GetFormat(vbCFMetafile) Then ClpFmt = ClpFmt + 8
Select Case ClpFmt
Case 1
Msg = "El
Portapapeles sólo contiene texto."
Case 2
Msg = " El Portapapeles sólo
contiene un archivo de mapa de bits."
Case 3
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
Private Sub Command3_Click()
Clipboard.Clear
End Sub
Private Sub Command4_Click()
Clipboard.SetText
Label2.Caption
End Sub
Private Sub Command5_Click()
Label3.Caption =
Clipboard.GetText
End Sub
Private Sub Command6_Click()
Picture2.Picture =
Clipboard.GetData()
End Sub
Private Sub Command7_Click()
Picture2.Picture =
LoadPicture
End Sub
Private Sub Command8_Click()
Text1.Text = Trim(Text1.Text)
If UCase(Right(Text1.Text,
3)) = "BMP" Then
Check1.Value = 1
Else
Check1.Value = 0
End If
If Check1.Value = 1 Then
Clipboard.SetData
LoadPicture(Text1.Text), 8
Else
Clipboard.SetData
LoadPicture(Text1.Text)
End If
End Sub
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)

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 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)
NegotiatePosition. Establece un
valor que determina si los controles Menu de nivel superior se muestran en la
barra de menús mientras un objeto vinculado o incrustado de un formulario está
activo y mostrando sus menús. No está disponible en tiempo de ejecución. Puede
tener los valores 0 (Predeterminado) Ninguno. El menú no se muestra en la barra
de menús cuando el objeto está activo.
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.
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.
Los
botones con flecha hacia arriba o abajo nos permiten variar el orden de las
líneas ya editadas.
Podemos
hacer varios niveles de submenús a base de introducir varias tabulaciones. Al
comienzo de este capítulo puede ver un ejemplo de ello.
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ú.
El
carácter & no tiene porqué ir precisamente al comienzo de la palabra. Puede ir en el medio de la
palabra. De esta forma se subrayará una letra intermedia.
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.
NOTA MUY IMPORTANTE
Siempre se recomienda poner la orden de
SALIR en la primera palabra de la barra de Menú. Bien que esa primera palabra
sea Salir o que esté en el menú desplegable de la primera palabra de la Barra
de Menú, en este último caso, separada mediante una línea separadora. (Vea The Windows Interface Guidelines for Software
Design, pág.124)
POPUP
MENÚS
Un
PopUpMenú o Menú Emergente es un menú que despliega en cualquier punto de un
Formulario (MDI o normal) con varias opciones. Es normal en los procesadores de
texto que se obtenga un menú emergente pulsando el botón derecho del ratón,
donde aparecen las tres palabras mágicas de Copiar, Cortar y Pegar.
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 :
Caption Name Tabulada
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.
La sintaxis de
este método es la siguiente :
NombreFormulario.PopupMenu nombremenú, indics, x, y,
negrita
Donde NombreFormulario
es el nombre del formulario donde presentamos el PopUpMenu. Puede omitirse.
Nombremenú. Este
parámetro es requerido. Es el Name de la palabra del menú de donde cuelga el
menú desplegable. La palabra del menú a que se refiere Nombremenú debe tener al
menos un submenú.
Indics. Parámetro
opcional. Un valor o constante que especifica la posición y el comportamiento
del menú emergente, como se describe a continuación :
Constante (posición) Valor Descripción
vbPopupMenuLeftAlign 0 (Predeterminado)
El lado izquierdo del menú se
sitúa
en x.
vbPopupMenuCenterAlign 4 El
menú emergente se centra en x.
vbPopupMenuRightAlign 8 El
lado derecho del menú se sitúa en x.
Constante (comportamiento) Valor Descripción
vbPopupMenuLeftButton 0 (Predeterminado) Los elementos del
menú
emergente sólo reaccionan a los
clic
del mouse cuando se use el botón
primario
del mouse.
vbPopupMenuRightButton 2 Los elementos del menú emergente
reaccionan
a los clic del mouse cuando se
usen
los botones primario o secundario.
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.
X, y Parámetro(s) opcionales que especifican las
coordenadas x e y donde va a aparecer el menú emergente. Si no se especifican,
aparecerá donde esté el puntero del mouse. Las unidades de medida de las
coordenadas x e y se definen mediante la propiedad ScaleMode.
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 :
Private Sub
Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
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.
Cuando se
presenta un menú emergente, el código que sigue a la llamada al método
PopupMenu no se ejecuta hasta que el usuario elige un comando del menú (en cuyo
caso se ejecuta antes el código del procedimiento de evento Click) o cancela el
menú. Además, sólo puede presentarse un menú emergente al mismo tiempo; por lo
tanto, las llamadas a este método se ignoran si el menú emergente está
presentado actualmente o si un menú desplegable está abierto.
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.
Visual Basic - Guía del
Estudiante Cap. 6
INTERCAMBO DINAMICO DE DATOS
EL
CONTROL PERSONALIZADO MICROSOFT COMM
INTERCAMBO DINAMICO DE DATOS (Dinamic Data Exchange) DDE
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.
A
la aplicación que envía la información se le llama aplicación servidor, y a la que la recibe, aplicación cliente.
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.
Los
datos a traspasar de una aplicación a otra pueden ser :
Textos,
de un Label o un TextBox.
Imágenes,
de un PictureBox.
El
origen de un intercambio DDE siempre es
un formulario. Dentro de este
formulario origen estará el Label, TextBox o PictureBox que contiene la
información a enviar.
Para
indicar que un formulario es origen de información para un intercambio DDE
debemos decírselo en sus propiedades LinkMode
y LinkTopic.
El
destino de un texto ha de ser necesariamente un Label, un TextBox, y el
destino de un gráfico debe ser un PictureBox.
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
Tiene
distinta forma si se trata de un control
(Label, TextBox y PictureBox) ó un formulario.
Para un formulario tiene dos valores posibles :
0 = None No puede existir
comunicación DDE con ese formulario
1= Source El
formulario permite que exista una comunicación DLL entre uno de
sus controles y otra aplicación.
Si
se establece el valor de esta propiedad a 0 en tiempo de diseño, no podrá
cambiarse en tiempo de ejecución. Si se establece a 1 en tiempo de diseño, se
podrá cambiar a 0 y volver a ponerla a 1 en tiempo de ejecución.
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 :
0=None. No
existe comunicación DDE con ese control
1=Automático Los datos se traspasarán desde la
aplicación servidor a este control de
la aplicación
cliente cada vez que cambie el dato en la aplicación
servidor (origen)
2=Manual Los datos se traspasarán cuando lo pida la
aplicación cliente (destino),
mediante la orden LinkRequest.
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)
En
tiempo de ejecución, para un control, esta propiedad es de lectura y escritura,
es decir, se puede usar para saber que valor tiene esta propiedad en un
determinado control, o para forzar esa propiedad a un determinado valor.
La sintaxis de esta propiedad
es :
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.
La propiedad LinkTopic, para un formulario de
origen, devuelve o establece el tema al
que el formulario “responde” en una conversación DDE.
Sintaxis nombredelformulario.LinkTopic [= tema]
Para un control destino, La
propiedad LinkTopic contiene el nombre de la aplicación y el tema, ambos
separados mediante el carácter |
(carácter 124)
Sintaxis nombredelcontrol.LinkTopic [= aplicacionorigen|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
La
propiedad LinkItem solamente la tiene el control destino de la información. No
la tiene el formulario origen. En esta propiedad deberá expresarse el nombre
del control
origen de la información.
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.
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.
Sintaxis objeto.LinkTimeout [= número]
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).
Private Sub objeto_LinkNotify([índice As Integer])
End Sub
En
este procedimiento se puede escribir el código necesario para nuestra
aplicación, a sabiendas de que este evento se produce cuando cambia la
información en origen. Posiblemente no quiera depositarlo de inmediato en el
control destino, puesto que si fuese así habría puesto la propiedad LinkMode a
1. Cuando quiera colocar el dato en el control destino, puede utilizar el
método LinkRequest para obtener el nuevo dato de la fuente.
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
Siendo
objeto el nombre del control destino
de la aplicación.
Objeto
es el nombre de un control Label, PictureBox o TextBox involucrado en una
conversación DDE como destino. LinkRequest provoca que la aplicación origen
envíe los datos actuales al objeto, actualizando la propiedad Caption si objeto
es un control Label, la propiedad Picture si objeto es un control PictureBox o
la propiedad Text si objeto es un control TextBox.
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.
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
Transfiere
el contenido de un control PictureBox a la aplicación destino de una
conversación DDE.
Sintaxis objeto.LinkSend
Objeto debe ser un control PictureBox de un objeto Form que
sea origen de una conversación DDE.
Cuando
otras aplicaciones establecen vínculos automáticos con un objeto Form de su
aplicación, Visual Basic las notifica cuando el contenido de un control TextBox
o Label origen cambia. Sin embargo, Visual Basic no notifica automáticamente a
una aplicación destino DDE cuando el valor de la propiedad Picture de un
control PictureBox origen cambia. Como la cantidad de datos de un gráfico
pueden ser muy grande y como no tiene sentido actualizar la aplicación destino
por cada cambio de píxel de la imagen, Visual Basic requiere el uso del método LinkSend para notificar explícitamente
a las aplicaciones destino DDE cuándo cambia el contenido de un control
PictureBox.
Método LinkPoke
Transfiere
el contenido de un control Label, PictureBox o TextBox a la aplicación origen
de una conversación DDE.
Sintaxis objeto.LinkPoke
Objeto es el nombre del control Label, PictureBox o TextBox
involucrado en la conversación DDE como destino. Si objeto es un control Label, LinkPoke
transfiere el contenido de la propiedad Caption al origen. Si objeto es un control PictureBox,
LinkPoke transfiere el contenido de la propiedad Picture al origen. Si objeto
es un control TextBox, LinkPoke transfiere el contenido de la propiedad Text al
origen.
Normalmente,
en una conversación DDE la información fluye de origen a destino. Sin embargo,
LinkPoke permite que un objeto destino suministre datos al origen. No todas las
aplicaciones origen aceptan información de esta forma; si la aplicación origen
no acepta los datos, se produce un error.
EL
CONTROL PERSONALIZADO MICROSOFT COMM
Este control permite la comunicación de
una aplicación VB con el puerto serie.
El control MSComm no está normalmente en
la caja de herramientas, por lo que será necesario introducirlo mediante Herramientas | Controles Personalizados.
En el formulario solamente se le ve en
tiempo de diseño. El icono que lo representa en la caja de herramientas
coincide con el que presenta en el formulario :
![]()
Al tratarse de un control personalizado,
presenta dos formas de ver las propiedades. Si hacemos click con el botón
derecho del ratón sobre el control y vamos a propiedades, nos presenta tres
cuadros de configuración de los típicos de los controles personalizados.
Si seleccionamos el control MSComm y
pulsamos F4 , aparecerá la caja de propiedades típica de los controles VB.
PRPIEDADES
Existen propiedades que pueden
establecerse en tiempo de diseño o en tiempo de ejecución, y otras que
solamente se pueden ejecutar o consultar en solamente en tiempo de ejecución.
Se detallan a continuación las primeras. Las segundas se enumerarán tras estas,
aunque se nombran algunas de estas últimas al explicar cada una de las
propiedades del primer tipo.
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.
Settings Sintaxis Velocidad, Paridad, Bits de
información, Bits parada
Indica la velocidad, paridad, número de
bits y bits de stop (parada) que se van a usar en la comunicación.
Los valores posibles para velocidad son : Indica la
velocidad en baudios.
50 100
110 300 600
1200 2400 4800
9600 14400 19200
y 28800
Los valores posibles para paridad son :
N
- No envía bit de paridad ni hace comprobación de paridad en la
recepción.
O -
Envía y comprueba paridad, con el criterio de paridad IMPAR
E -
Envía y comprueba paridad, con criterio de paridad PAR
Los valores para el parámetro Bits de Información pueden ser :
7 - Se
envían / reciben 7 bits por trama de información.
8 - Se
envían / reciben 8 bits por trama de información
5
- Se envían / reciben 5 bits por trama de información. Este valor de 5 bits es
el típico
del sistema Baudot
para transmisión telegráfica (Teletipos) que se ha conservado en las comunicaciones informáticas por pura tradición. Si se
eligen 5 bits, los bits de parada se ponen automáticamente a 1,5 (Típico
también del sistema Baudot.)
Los valores para el parámetro Bits de parada pueden ser :
1 - Se
envía un bit de parada
2 - Se
envían 2 bits de parada
(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
Especifica el método de control sobre el
flujo de información. En una comunicación serie se necesita conocer si el
puerto puede enviar información (necesita saber si el módem está preparado para
recibirla) y necesita indicarle al módem que él está preparado para recibir
información. A este proceso se le
denomina Handshaking. (Handshaking
= Control de Flujo)
(Como sabrá por sus conocimientos de
inglés, Handshaking significa apretón de manos, ponerse de acuerdo. Y ponerse
de acuerdo entre dos terminales que van a comunicarse es establecer las
condiciones de control que uno va a tener sobre otro.)
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 :
0
- No existe Control de Flujo
1
- Control de Flujo mediante XON - XOFF
2 - Control de
Flujo mediante Request To Send (RTS) y Clear To Send (CTS)
3
- Control de Flujo mediante XON - XOFF y RTS - CTS
Los tres tipos de Control de Flujo tiene
cada uno su aplicación.
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.
Puede conocerse el número de caracteres
presentes en el Buffer de entrada consultando el valor de la propiedad InBufferCount.
OutBufferSize
Mediante esta propiedad controlamos el tamaño del
Buffer de salida.
El tamaño de los Buffers dependerá de la
aplicación y de la velocidad de comunicación. Si la aplicación tiene muchas
cosas que hacer, aparte de controlar el puerto de comunicaciones, se 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
Si la comunicación se realiza con bit de
paridad (Par o Impar), en recepción se comprueba byte a byte la recepción de la
paridad correcta. Si se recibe un Byte que no tiene paridad correcta, lo mas
probable es que ese Byte (carácter) se haya recibido defectuoso. Esta propiedad
nos permite sustituir un carácter que ha llegado con bit de paridad incorrecto
por otro carácter. ( ? predeterminado). Se puede sustituir por una cadena de
caracteres (Error, por ejemplo).
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 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.
Las siguientes propiedades no difieren en nada respecto
a otros controles :
Left, Name,
Index, Top, Tag
Propiedades propias del tiempo de ejecución
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
Para cerrarlo, ejecutaremos :
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 = “Curso de Visual Basic”
Si deseamos enviar el contenido de una
variable
MSComm1.Output = variable
Input
Lee el Buffer de recepción. El número de
caracteres leídos dependerá del valor de la propiedad InputLen. Cuando la propiedad InputLen
tiene el valor 0, el Buffer se lee completo. Si InputLen tiene un valor distinto de 0, se leerá un número de
caracteres igual al valor de esta propiedad.
CommEvent
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
Break
Devuelve un valor (True / False) que
indica que se ha recibido la señal Break.
variable = MSComm1.Break
CDHolding
Devuelve el estado de la línea de control
CD (Detección de Portadora) Si es True, esa entrada está activada, si es False, la entrada está desactivada.
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
EVENTOS DEL MSComm
El MSComm
tiene varios eventos, pero un solo Procedimiento : el Procedimiento OnComm. Este procedimiento se ejecuta
cada vez que se produce alguno de los eventos del MSComm.
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.
Para averiguar qué evento se ha producido
puede hacerse consultando el valor de la propiedad CommEvent.
If CommEvent = ComEvRing Then
'Se
ha consultado si el evento particular que ha producido el evento general OnComm
'ha
sido el ComEvRing (Se está
recibiendo la llamada del teléfono). En esta sentencia
‘If Then deberemos colocar el código necesario
para que la aplicación se prepare para
‘recibir una
comunicación a través del módem.
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.
Se ejecutará el Procedimiento OnComm cuando ocurra alguno de los
siguientes eventos :
ComEvCD ( 5 ) Cambio
en la línea CD. Para conocer el estado actual de esa línea
(Activado/Desactivado)
deberemos invocar la propiedad CDHolding
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.
ComEvRing ( 6 ) Cambio en la línea de detección de llamada
(Ring). Este evento se
produce
cuando hay un cambio en la línea Ring
(Detección de
llamada
en el módem)
No existe una propiedad para
averiguar el estado de la línea Ring
pues
no es necesario. Lo importante de esta línea es que está
cambiando,
es decir, el teléfono está sonando y poco importa que
analicemos
si la línea Ring está a 1 o a 0,
pues toda llamada
telefónica es
intermitente. Dependiendo de la UART de
su PC, puede que este evento no lo soporte.
ComEvReceive(
2 ) Cuando
se recibe un número igual o mayor de caracteres que el
indicado
en la Propiedad RThreshold
ComEvSend ( 1 ) Cuando quedan en el búfer de transmisión menos
caracteres que los
indicados en la
Propiedad SThreshold
ComEvEOF ( 7 ) Recibido un carácter de fin de archivo
(carácter ASCII 26) .
comEventBreak
(1001) Se ha recibido una señal de interrupción. (Break)
ComEventCDTO
(1007) Tiempo de espera de Detección de portadora. La línea
Detección
de portadora (CD) estuvo baja durante el periodo de tiempo
especificado en la
Propiedad CDTimeout, mientras se
intentaba transmitir un carácter.
ComEventCTSTO 1002 Tiempo
de espera de Preparado para enviar. La línea
Preparado
para enviar (CTS) estuvo baja durante el periodo de tiempo
especificado en la
propiedad CTSTimeout mientras se
intentaba
transmitir un
carácter.
ComEventDSRTO 1003 Tiempo
de espera de Equipo de datos preparado. La línea
Equipo
de datos preparado (DSR) estuvo baja durante el periodo de
tiempo especificado
en la Propiedad DSRTimeout mientras se
intentaba
transmitir un carácter.
ComEventOverrun 1006 Se
sobrepasó la capacidad del Buffer de entrada sin haber
leído todos los
caracteres. Los caracteres no leídos se
han perdido.
Debemos aprovechar
este evento para solicitar al colateral una
repetición de los
datos perdidos.
ComEventRxOver 1008 Desbordamiento del búfer de recepción. No hay
espacio para
más datos en el búfer de recepción.
ComEventRxParity 1009 Error de paridad. El hardware ha
detectado un error de
paridad.
ComEventTxFull 1010 Búfer de transmisión lleno. El
búfer de transmisión estaba
lleno
cuando se ha intentado agregar un carácter a la cola de
transmisión. Este
error es fácil de evitar, analizando el valor
de la propiedad OutBufferCount antes de enviar mas
datos al buffer
de salida.
ComEventDCB 1011 Error
inesperado al recuperar el Bloque de control de
dispositivos (DCB)
para el puerto.
ComEventFrame 1004 Error de trama. El hardware ha
detectado un error de trama.
NOTA ADICIONAL
El puerto
de comunicaciones.
El puerto de comunicaciones de un PC está
formado por varias entradas / salidas. El soporte físico es un conector tipo
Sub-D de 9 ó 25 contactos, macho en ambas versiones. Se necesita por tanto un
cable con conector Sub-D hembra de 9 o 25 pines para acceder a él.
La distribución de las señales en cada
uno de sus pines es la siguiente :
GND (Potencial de
0 V.).
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.
DCD o CD Carrier
Detect. Detección de portadora. Es una
entrada del ordenador. Le
indica
al ordenador que el módem está detectado señal de audio (tonos) válida.
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.
Disposición de los pines en el ordenador
Dependiendo de si tiene conector de 9
pines o de 25, la distribución de estas señales físicamente en el conector es :
Conector
de 9 pines Conector
de 25 pines
Pin Señal Pin
3 TxD 2
2 RxD 3
7 RTS 4
8 CTS 5
6 DSR 6
5 GND 7
1 CD 8
4 DTR 20
RING 22
Tierra
de protección 1
Visual Basic - Guía del
Estudiante Cap. 7
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 :
Circle, Cls, Line, PaintPicture, Point, Print, y PSet.
METODO Line
Dibuja
líneas y rectángulos en un objeto. El
objeto puede ser un Formulario, un
control PictureBox o el objeto Printer.
Sintaxis 1 objeto.Line (x1, y1) - (x2, y2), color, BF
(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.
Sintaxis 2 objeto.Line (x1,y1) - Step
(x2,y2), color, BF
(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 :
objeto.Line (x1,y1) - (x1+x2, y1+y2), color, BF
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 :
Sintaxis 3 objeto.Line Step (x1,y1) - Step
(x2,y2), color, BF
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.
En
estas expresiones, las coordenadas estarán especificadas en las unidades de
medida determinadas por las propiedades ScaleMode o ScaleWidth / ScaleHeight
del objeto.
En
las expresiones anteriores objeto es
el nombre del Formulario, PictureBox u objeto Printer sobre el que queremos
dibujar. Si no se especifica objeto se entiende por defecto que el
objeto sobre el que queremos dibujar es el formulario que tiene el enfoque en
ese momento.
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 :
Form1.Line (x1,y1) - (x2,y2) , RGB(255,0,0), B
dibuja un rectángulo entre
los puntos (x1,y1) y (x2,y2).
La expresión :
Picture1.Line (x1,y1)
- (x2,y2), RGB (0,255,0), BF
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)
De
lo explicado se deduce que si el parámetro opcional BF es solamente B dibuja
un cuadrado con esquinas en las coordenadas indicadas (pueden ser absolutas o
relativas), y si es BF pinta ese
rectángulo y además lo rellena con el mismo color elegido en el parámetro color.
No puede usarse solamente la F pues
no tiene sentido “rellenar” de color una figura abierta.
Para
dibujar líneas unidas, comience la línea siguiente en el punto final de la
línea anterior.
La
anchura de la línea dibujadas depende de la configuración de la propiedad
DrawWidth.
Cuando
se ejecuta Line, las propiedades CurrentX y CurrentY toman el valor del punto
final de la línea.
METODO Circle
Dibuja una circunferencia,
círculo, elipse o arco sobre un objeto.
Sintaxis objeto.Circle (x, y), Radio, Color, Inicio,
Final,
Aspecto
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.
Nota para los que no aprobaron Matemáticas
Un circulo completo tiene 2 x pi radianes. Es decir,
2 x 3,1416 radianes equivalen a 360 º.
Como los datos de ángulos hay que introducirlos en radianes y nosotros
normalmente pensamos en grados, emplee esta fórmula para convertir grados a
radianes :
Radianes = Grados
x 2 x 3,1416 / 360
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.
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 !!!
Lo
expuesto anteriormente NO FUNCIONA
para valores de Inicio o Final iguales a 0.
Por lo tanto, si queremos hacer un radio en 0 radianes (línea recta desde el
centro a la derecha) deberemos poner una cantidad muy cercana a 0 (0.00000001, p. e.) para que ponga el radio.
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
Donde
objeto representa un formulario, control Image o PictureBox. Si objeto se
omite, se asume que el objeto es el control Form que tenga el enfoque.
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
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.
Imagen Este
parámetro es requerido. Es el origen del gráfico que se va a presentar en el
objeto. Debe ser la propiedad Picture de un objeto Form, control PictureBox o
control Image. También puede ser el contenido de una variable tipo Picture. Es
decir, la imagen debe existir en un PictureBox, en un Formulario, en un control
Image o en una variable. Si es un control, el que contiene la imagen, puede
ponerse invisible (Su propiedad Visible
= False) con lo que podemos hacer un “almacenillo” de imágenes en un
formulario sin que molesten a la hora de trabajar
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.
anchura1 Opcional. Indica la anchura destino de la imagen. La
propiedad ScaleMode del objeto determina las unidades de medida que se usan. Si
anchura destino es mayor o menor que la anchura origen (anchura2), imagen se
amplía o se comprime respecto al original. Si se omite, se usa la anchura
origen.
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.
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
Asigna
a un punto de un objeto un color especificado. El objeto puede ser un Formulario, un PictureBox o el objeto Printer.
Sintaxis objeto.PSet (x, y), Color
ó objeto.PSet Step (x, y), Color
La
sintaxis del método PSet tiene las partes siguientes:
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.
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.
Por ejemplo: el rojo puro sería: Hex(0000FF)
= 255
el
verde puro sería: Hex(00FF00) = 652280
el
azul puro sería: Hex(FF0000) = 16711680
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
Por
la sentencia RGB
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.
Mediante
la Función QBColor
Devuelve o establece el código de color
RGB correspondiente a un número de color.
Sintaxis Objeto.QBColor(color)
El argumento color es un número entero
entre 0 a 15, según la siguiente lista:
Número Color Número 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
Ejemplo. Tengamos un Label llamado Label1
y un botón de comando, en cuyo procedimiento click le introducimos el código:
Static i As
Integer
i = i + 1
If i = 16 Then i = 0
Label1.caption = i
Label1.BackColor = QBColor(i)
En el Label podremos ver el color y su
número de color.
FIN
DE LA NOTA ADICIONAL SOBRE COLORES EN VB
SavePicture
(Instrucción)
Guarda un gráfico de un objeto Form, de
un control PictureBox o de un control Image en un archivo.
Sintaxis SavePicture imagen, expcadena
La sintaxis de la instrucción SavePicture
tiene las siguientes partes:
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.
Ejemplo: SavePicture
Picture1.Picture, "c:\suarez\luis.bmp"
En este ejemplo, guardamos en el fichero
LUIS.BPM que está en el directorio C:\SUAREZ el gráfico que contiene el
PictureBox denominado Picture1
Si un gráfico ha sido cargado en la
propiedad Picture desde un archivo, en tiempo de diseño o en tiempo de
ejecución, se guarda usando el mismo formato del archivo original. Los gráficos
de la propiedad Image siempre se guardan como archivos de mapas de bits (.BMP).
LoadPicture
(Función)
Carga un gráfico en un objeto Form, un
control PictureBox o un control Image.
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:
Form1.Picture
= LoadPicture ("FIESTA.BMP")
Imagen1.Picture
= LoadPicture ("FIESTA.BMP")
Picture1.Picture
= LoadPicture (FIESTA.BMP")
Para asignar un icono a un formulario, se
asigna el valor devuelto por la función LoadPicture a la propiedad Icon del
objeto Form:
Form1.Icon
= LoadPicture ("UNICONO.ICO")
Los iconos también pueden ser asignados a
las propiedades DragIcon de todos los controles
excepto los controles Timer y Menú. Por
ejemplo:
Comando1.DragIcon = LoadPicture ("UNICONO.ICO")
Para cargar gráficos en el Portapapeles
del sistema se usa LoadPicture de la forma siguiente:
Clipboard.SetData LoadPicture ("FIESTA.BMP") (Vea Capítulo del
Portapapeles)
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.
Para
ello hay que declarar las variables como Picture
Option Explicit
Dim MiVariable1 As Picture, MiVariable2 As
Picture
Private Sub Form_Load()
Set MiVariable1 = LoadPicture("c:\pruebavb\ athena.bmp ")
Set MiVariable2 = LoadPicture("c:\list_tel\rr1.bmp")
End Sub
Private Sub Command1_Click()
Picture1.Picture = MiVariable1
End Sub
Private Sub Command2_Click()
Picture1.Picture = MiVariable2
End Sub
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)
Devuelve o establece un valor que
determina el aspecto de la salida de un método gráfico o el aspecto de un
control Shape o Line.
Sintaxis objeto.DrawMode [= número]
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)
Devuelve o establece un valor que
determina el estilo de línea de la salida de métodos gráficos.
Sintaxis objeto.DrawStyle [= número]
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.
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)
Devuelve o establece la anchura de línea
de lo dibujado con los métodos gráficos.
Sintaxis objeto.DrawWidth [= tamaño]
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.
Sintaxis objeto.FillColor [ = valor]
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
Excepto en el objeto Form, cuando la propiedad FillStyle
se define con su valor predeterminado, 1 (Transparente), el valor de FillColor se ignora.
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.
Sintaxis objeto.FillStyle [= número]
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.
5 Diagonal
hacia abajo.
6 Cruzado.
7 Diagonal
Cruzada.
Cuando la propiedad FillStyle se define
con su valor predeterminado, 1 (Transparente), el valor de FillColor se ignora,
excepto en el objeto Form.
AutoRedraw
(Propiedad)
Devuelve o establece la salida de un
método gráfico como gráfico persistente.
Sintaxis objeto.AutoRedraw [= booleano]
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.
False (Predeterminado)
Desactiva el redibujado automático de un objeto y escribe los gráficos y el
texto solamente en la pantalla. Visual Basic invoca el evento Paint del objeto
cuando se necesita volver a dibujar dicho objeto.
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.
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.
Barra de Herramientas. Control 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.
Todo
ello lo puede hacer el control Toolbar.
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 :

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.
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).
La
propiedad Style define el tipo de botón :
0 - Default Botón monostable.
1 - Check Botón Biestable.
2 - Button Group Solo uno de los botones del grupo puede
estar pulsado. Esta
propiedad lleva implícito que los botones que forman
un grupo son biestables. Pueden hacerse varios grupos independientes
introduciendo un botón que no pertenezca a un grupo (tipos 0, 1, 3 ó 4) entre
los dos grupos que se independientes que se pretenden formar
3 - Separator El botón se convierte en un separador de anchura
fija.
4 - PlaceHolder El botón se convierte en un separador de anchura
variable.
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.
Image
es el número de la imagen en el ImageList.
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 :
Set NombreBotón =
NombreToolbar.Buttons.add ( [Indice], [Key], [Caption],
[Style], [Imagen])
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
Para
saber que botón se ha pulsado, puede leerse la propiedad Key :
Text1.Text = Button.Key presenta en Text1 el texto introducido en la
propiedad
Key del último botón pulsado.
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.
El
control Toolbar tiene los siguientes eventos :
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 :
Private Sub
Toolbar1_ButtonClick(ByVal Button As Button)
If Button.Index = 1 Then . . . .
If Button.Index =
2 Then . . . .
También
podríamos usar la propiedad Key como se dijo mas atrás.
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 cualquier control.
MouseMove, MouseUp, MouseDown
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.
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.
¡ El control Toolbar NO sirve de
contenedor de otros controles, a excepción de sus botones ! ! !
LA
BARRA DE ESTADO
Este
control es muy parecido a la barra de herramientas, y suele usarse, colocándolo
en la parte inferior de la ventana, para indicar el proceso que está en curso
en la aplicación. La barra de estado, control StatusBar se introduce en la caja de herramientas al mismo tiempo
que el control Toolbar, con el control personalizado Microsoft Windows Common Controls (COMCTL32.OCX).
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
La
barra de estado puede configurarse como de un solo panel o de múltiples
paneles. (Propiedad Style. 0=múltiples paneles, 1= panel único)
Las
dimensiones de cada panel pueden configurarse como fijas o ajustadas al tamaño
del texto o imagen que presentan.
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 (.BMP)
o .ICO. Los paneles pueden
combinar una gráfico y un texto.
La
barra de estado puede realizarse en tiempo de diseño o en tiempo de ejecución.
Para realizarla en tiempo de diseño basta con visualizar la ventana de
propiedades, muy similar a la del control Toolbar.
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 :
Set
nombobjeto = Nombrebarraestado.Panels.Add.(
[índice],[key],[Text],[estilo],[gráfico])
Un panel puede eliminarse en tiempo de
ejecución mediante la sentencia :
StatusBar1.Panels.Remove
(n)
O simplemente puede hacerlo invisible
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 :
If Panel =
StatusBar1.Panels(1) Then label1.Caption = "Salir"
If Panel = StatusBar1.Panels(2) Then label1.Caption =
"información"
If Panel = StatusBar1.Panels(3) Then label1.Caption =
"En Ejecución"
If Panel = StatusBar1.Panels(4) Then label1.Caption =
"Imprimiendo"
If Panel = StatusBar1.Panels(5) Then label1.Caption =
"Esperando"
La Barra de estado tiene muchas
aplicaciones y propiedades. Avanzar en ellas se deja a la necesidad del alumno.
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.

Para
introducir el ProgressBar en la caja de herramientas debe seleccionarse en Herramientas | Controles Personalizados
el conjunto Microsoft Windows Common Controls 5.0 (Este conjunto incorpora también los controles TabStrip, Toolbar, StatusBar, TreeView, ListView, ImageList y Slider.
Las
propiedades mas destacables del ProgressBar son :
Max Para indicar el valor a fondo de escala
Min Para indicar el valor a mínimo
Value El valor de esta propiedad es el que se
indicará gráficamente en el ProgressBar.
Visual Basic - Guía del
Estudiante Cap. 8
FICHEROS EN VISUAL BASIC
Existen tres tipos de ficheros donde podremos
almacenar y leer datos:
-
Secuenciales
-
Aleatorios (Random)
-
Binarios
Cada uno de ellos tiene sus aplicaciones y
particularidades.
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:
Open Nombrefichero For Output As # Numerocanal
De esta forma, si ya existía un fichero
llamado Nombrefichero,
sobreescribiremos dicho fichero perdiendo la información que contuviese. Es la
forma típica de hacerlo cuando modificamos un texto. Para añadir la nueva
información tras la ya existente, deberemos abrirlo con la siguiente
instrucción:
Open Nombrefichero For Append As # Numerocanal
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.
Para cerrar un fichero secuencial, basta con ejecutar
la instrucción:
Close # Numerocanal
Si no se especifica Numerocanal (la instrucción
Close a secas) se cerrarán todos los
ficheros abiertos actualmente.
Para introducir la información, pueden
emplearse dos métodos: Print y Write
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:
Print #1, Text1.Text
El texto queda en
el fichero en caracteres ASCII, que se pueden leer con el Type de MS-DOS o
mediante el Bloc de Notas de Windows.
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:
Se
abre el archivo con la instrucción Open
Open
Nombrefichero
For Input As # Numerodecanal
Se
utiliza la instrucción Input o Line Input para sacar los datos del
fichero.
La instrucción Input tiene en
este caso la siguiente sintaxis:
Input (Numero de caracteres, # Numero de canal)
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 :
Input (LOF(1),
#1) LOF(1)=longitud del fichero #1
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.
INSTRUCCION
LINE INPUT
La
instrucción Line Input se utiliza
para extraer una línea completa. Tiene la siguiente sintaxis:
Line Input # Número de canal,
Variable
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
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 :
Private
Sub BAbrir1_Click()
Dim
VarTexto As String
CD1.Filter = "Ficheros de Texto
|*.txt"
CD1.ShowOpen
Open
CD1.filename For Input As #1
VarTexto = Input(LOF(1), #1)
'leemos todo el fichero de un golpe
Close
#1
TBTexto
= VarTexto
End
Sub
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.
Para leer carácter a carácter :
Private
Sub BAbrir_Click()
Dim
VarTexto As String
CD1.Filter = "Ficheros de Texto
|*.txt"
CD1.ShowOpen
Open
CD1.filename For Input As #1
Do Until EOF(1) ‘Hacemos un bucle de lectura hasta que
encontremos EOF(1)
‘ Vea mas adelante la Propiedad EOF en Propiedades de los ficheros Secuenciales
VarTexto = Input(1, #1) 'leemos
el fichero carácter a carácter
TBTexto = TBTexto & VarTexto 'vamos
añadiendo los caracteres leídos a TBTexto
Loop
Close
#1
End
Sub
(NOTA.- Lo expuesto funciona perfectamente,
pero el hecho de meter en un TextBox carácter a carácter eterniza la
aplicación. - Meter un texto en un TextBox o en un Label es una operación que
tarda cierto tiempo. Si esa operación hay que hacerla una vez por carácter,
puede tardar mucho tiempo. Para evitar esto, cuando vaya a leer un fichero
carácter a carácter, métalo primero en una variable y luego realice un volcado
único de esa variable al TextBox o Label)
Y podemos hacerlo también leyendo línea a
línea con Line Input
Dim
VarTexto As String
CD1.Filter = "Ficheros de Texto
|*.txt"
CD1.ShowOpen
Open
CD1.filename For Input As #1
Do
Until EOF(1)
Line Input #1, VarTexto 'leemos el fichero Línea a Línea
TBTexto = TBTexto & VarTexto &
vbCrLf 'vamos añadiendo las líneas
leídas a TBTexto
'(Hay que introducir un retorno + avance
de línea con cada línea (vbCrLf), ya que VarTexto no
‘contiene los retornos ni avances de
línea.
Loop
Close #1
Los Botones de Guardar tienen el
código :
Private
Sub BGuardar_Click()
Dim
VarTexto As String
CD1.Filter = "Ficheros de Texto
|*.txt"
CD1.ShowSave
Open
CD1.filename For Output As #1
Print
#1, TBTexto.Text
Close
#1
End Sub
O para el caso de abrir con For Append
Private
Sub BGuardar2_Click()
Dim
VarTexto As String
CD1.Filter = "Ficheros de Texto |*.txt"
CD1.ShowSave
Open
CD1.filename For Append As #1
Print
#1, TBTexto.Text
Close
#1
End Sub
Ya hemos visto como se guardan y se leen
datos de texto en un fichero secuencial.
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 :
“Luis Suárez”,” VisualBasic - Guía del
estudiante”,”Editorial XX”,”3200”,”51”
“Miguel de Cervantes”,”El
Qijote”,”Editorial YY”,”5000”,”27”
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:
Private Sub
Command1_Click()
TITULO = LIBRETBTITULO.Text
AUTOR = LIBRETBAUTOR.Text
EDITORIAL = LIBRETBEDITORIAL.Text
PRECIO = LIBRETBPREC.Text
EXISTENCIAS = LIBRETBEX.Text
‘Donde LIBRETBTITULO, LIBRETBAUTOR, Etc.
son los nombres de los TextBox
‘Ha leído los datos de los TextBox. Ya
están el las variables TITULO, AUTOR, Etc.
‘Ahora los metemos en el fichero con la
instrucción Write. El nombre del
fichero será el
‘que hayamos puesto en el TextBox
LIBRETBFICHERO, y lo guardará en el directorio
‘C :\cursoVB
Open TBNombreFichero.Text For Append As #1
Write #1, TITULO, AUTOR, EDITORIAL, PRECIO, EXISTENCIAS
Close #1
End Sub
Si introduce los datos del ejemplo
anterior, se creará un fichero que tiene esta apariencia:
“Luis Suárez”,” VisualBasic - Guía del
estudiante”,”Editorial XX”,”3200”,”51”
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:
“Luis Suárez”,” VisualBasic - Guía del
estudiante”,”Editorial XX”,”3200”,”51”
“Miguel de Cervantes”,”El
Qijote”,”Editorial YY”,”5000”,”27”
¿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:
Private Sub
Command2_Click()
' Limpiamos los TextBox
LIBRETBTITULO.Text = "" : LIBRETBAUTOR.Text
= "" : LIBRETBEDITORIAL.Text = ""
LIBRETBPREC.Text = "" : LIBRETBEX.Text =
""
'Abrimos el
fichero
Open TBNombreFichero.Text For Input As #1
Do Until EOF(1)
' Introducimos una parada para poder leer datos
DETENERSE = True
Input #1, TIT,
AUT, NED, PRE, EXS
LIBRETBTITULO.Text
= TIT
LIBRETBAUTOR.Text
= AUT
LIBRETBEDITORIAL.Text
= NED
LIBRETBPREC.Text =
PRE
LIBRETBEX.Text = EXS
' Refrescamos los TextBox
Refresh
' 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 :
"EL RODABALLO","GUNTER
GRASS","PLANETA",”1995”,2000,12
" VisualBasic - Guía del Estudiante
","LUIS SUAREZ","CEU",”PRIMERA”,1000,21
"EL NOMBRE DE LA
ROSA","UMBERTO ECO","AGUILAR",”28”,1000,21
"ENCICLOPEDIA DEL
VB","CEBALLOS","RAMA",”CUARTA”,1200,23
"LA GRANJA
ANIMAL","ORWELL","DESTINO",”45”,12000,78
"LA PASION TURCA","ANTONIO
GALA","PLANETA",”SEGUNDA”,2500,25
"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.
La interfaz gráfica quedó de la siguiente
forma :

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
El fichero anterior podemos leerlo tal y
como indicábamos antes :
Open TBNombreFichero.Text For Input As #1
Do Until EOF(1)
Input #1, TITULO, AUTOR, EDITORIAL, EDICION, PRECIO,
EXISTENCIAS
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 :
" VisualBasic - Guía del Estudiante
","LUIS SUAREZ","CEU",”PRIMERA”,1000,21
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, 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
Observe que al usar paréntesis al declarar la variable REGISTROLIBROS le estamos
diciendo a VB que esa variable será un Array, y además que es una variable del
tipo REGISTROLIBRO, tipo de variable que ya conoce, puesto que se la hemos
definido en un módulo.
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 :
Private Sub BIntroducir1_Click()
TITULO = LIBRETBTITULO.Text ‘TextBox
para introducir el título
AUTOR = LIBRETBAUTOR.Text ‘ autor
EDITORIAL = LIBRETBEDITORIAL.Text ‘ editorial
EDICION = LIBRETBEDICION.Text ‘ edición
PRECIO = Val(LIBRETBPREC.Text) ‘ precio
EXISTENCIAS = Val(LIBRETBEX.Text) ‘ existencias
‘(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.)
Open
"C:\cursoVB\" + LIBRETBFICHERO.Text For Append As #1
Write #1, TITULO, AUTOR, EDITORIAL,
EDICION, PRECIO, EXISTENCIAS
Close #1
End Sub
Tras reiteradas entradas, el fichero de
la BD quedó como se vio anteriormente.
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 :
Private
Sub Command2_Click()
LIBRETBTITULO.Text = "" ‘Pone todos los TextBox en blanco
LIBRETBAUTOR.Text = ""
LIBRETBEDITORIAL.Text = ""
LIBRETBEDICION.Text = ""
LIBRETBPREC.Text = ""
LIBRETBEX.Text = ""
NR = 0 ‘
NR=número de registros
‘ 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.
Open
TBNombreFichero.Text For Input As #1
Do
Until EOF(1)
A =
Input(1, #1)
If A =
Chr(13) Then NR = NR + 1
Loop
Close #1
‘ Presenta en LNumFich el número de
registros
LNumFich.Caption
= Str(NR) + " Registros)"
'Redimensionamos la matriz de
REGISTROLIBROS a NR elementos..
ReDim REGISTROLIBROS(1 To NR)
‘Volvemos a abrir el fichero
Open
TBNombreFichero.Text For Input As #1
‘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
NOTA.-
Estas líneas podríamos heberlas puesto en una línea única :
Input#1,REGISTROLIBROS(I).TITULO,REGISTROLIBROS(I).AUTOR,_
REGISTROLIBROS(I).EDITORIAL,REGISTROLIBROS(I).EDICION,_
REGISTROLIBROS(I).PRECIO, REGISTROLIBROS(I).EXISTENCIAS
‘NRP = Número del Registro Presentado. Lo
hacemos igual a 1 para presentar, de momento, el ‘número 1
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
Copiamos este código de presentación de
datos y lo llevamos a las flechas de incrementar o disminuir el número del
registro a presentar.
Private
Sub BMas1_Click()
NRP = NRP + 1
If NRP > NR Then ‘protegemos que salga error de NRP fuera de
intervalo
MsgBox "No existen mas registros en
esta dirección"
NRP = NR
Else
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 If
End
Sub
Esta es la de incrementar. La de
disminuir es igual, pero restando 1 a NRP
Las flechas dobles llevan al registro 1 y
al último. Tienen este código
Private Sub BMas2_Click()
NRP = NR
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.
Propiedades
de los ficheros Secuenciales:
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:
Do until EOF(1) (Hazlo hasta que encuentres el EOF del canal 1)
Do While Not EOF(1) (Hazlo mientras EOF del canal
1 sea False)
Estas expresiones
se usan en un bucle, para ir extrayendo con la instrucción Input o Line Input
los caracteres de un fichero hasta que se encuentre la marca de final de
fichero (EOF)
LOC
Devuelve la
posición de lectura/escritura actual en un archivo abierto.
La sintaxis de esta
propiedad es: LOC (Numero de canal)
la información
devuelta para un archivo secuencial es la posición de byte actual en el
archivo, dividida por 128.
LOF
Devuelve la
longitud de un fichero (Lenght Of File) abierto mediante Open.
Sintaxis LOF(numeroarchivo)
Ejemplo Long
= LOF (1)
Observaciones Para obtener la longitud de
un archivo que no está abierto utilice la función FileLen.
(Véala mas abajo)
SEEK
Devuelve la posición actual de lectura/escritura
de un archivo abierto con la instrucción Open.
Sintaxis Seek(númeroArchivo)
Observaciones
Seek devuelve un valor entre 1 y
2,147,483,647 (equivalente a 2^31-1) inclusive. Para archivos abiertos en modo
Output, Append o Input, Seek devuelve la posición de byte en la que se va a ejecutar la siguiente operación. El primer
byte de un archivo está en la posición 1, el segundo en la posición 2 y así
sucesivamente.
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"
Si deseábamos guardar la información de
muchos libros, no había mucho problema para guardarla, pero sí para almacenarla
en memoria para poder usarla luego. Teníamos que leer todo el fichero, y
extraer de él la colección de informaciones y guardarlas en una matriz. Cambiar
una información dentro del fichero secuencial también implica una complicación
adicional, ya que debemos rehacer el fichero completo, pues un fichero
secuencial no permite “remendar” el trozo que queremos cambiar.
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.
Para abrir un fichero aleatorio debemos
emplear la expresión:
Open Nombrefichero For Random As
# Numerocanal Len
= LongitudRegistro
Nombrefichero
es el nombre que queremos dar al fichero
Numerocanal es el número del canal (número de fichero) que puede
ser de 1 a 255
LogitudRegistro es la longitud total del registro.
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.
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 :
Dim
MiVariable as Registro
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 :
Titulo : Guía del Estudiante
Autor :
Luis Suárez Bernaldo
Editorial : Ediciones XX
Edición : 2ª
Precio : 3500
Existencias : 25
el registro correspondiente a este libro
tendrá una forma mas o menos así :
Guía del
Estudiante///////////Luís Suárez Bernaldo//////////Ediciones XX///2ª////350025/
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 :
Open Nombrefichero For Random As
# Numerocanal Len
= LongitudRegistro
(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
¿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.
Tipo de Dato Ocupa
Byte 1
byte
Boolean 2
bytes
Integer 2
bytes
Long(entero largo) 4 bytes
Single(coma flotante Simple precisión) 4 bytes
Double(coma flotante Doble Precisión) 8 bytes
Currency 8
bytes
Date 8
bytes
Object 4
bytes
String (longitud variable) 10 bytes + longitud de
cadena
String (longitud fija) longitud
declarada de la cadena
Variant (con números) 16 bytes
Variant (con caracteres) 22 bytes +
longitud de cadena
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
LongitudRegistro = Len (MiVariable)
Pero si quiere reducir mas la cosa, abra
el fichero de esta forma :
Open Nombrefichero For Random As # Numerocanal Len = Len (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.
La declaración del registro mediante la
instrucción Type debe hacerse en la sección de declaraciones de un Módulo. Esta instrucción Type en realidad lo que
está haciendo es definir un nuevo tipo de variable, (una variable definida por
el usuario) que servirá de “muestra” para que en otra parte del programa le
digamos, mediante una instrucción Dim, que tal variable es del tipo definido
anteriormente mediante la instrucción Type. Por lo tanto, debemos declarar 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.
Usando la declaración de Registro del
ejemplo anterior, vamos a retomar el ejemplo de la biblioteca. Declararemos
(posiblemente en la sección de declaraciones del formulario) una variable que
llamaremos p.e. REGLIBROS de la siguiente forma :
Dim
REGLIBROS as Registro
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.
Escribir datos en un fichero
Random. Instrucción Put
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:
Put
# Numerocanal , NumeroRegistro, Variable
Puede omitirse NumeroRegistro. En este caso, el número de registro que se
escribirá será el siguiente al último registro escrito.
NumeroRegistro es el número del registro que queremos escribir, y Variable
es el contenido de ese registro. Siguiendo con nuestro ejemplo de
biblioteca, Variable tiene en este
caso el nombre REGLIBROS, que no es un String ni un Integer, sino una variable
definida por el usuario ya que la declaramos con Dim REGLIBROS as Registro.
Por lo tanto, la variable REGLIBROS contendrá los mismos campos que habíamos
declarado para Registro en la
instrucción Type. Recuerde :
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 :
Campo Título : TBTITULO
Campo Autor : TBAUTOR Campo Editorial : TBEDITORIAL
Campo Edición :TBEDICION Campo Precio : TBPRECIO Campo Existencias : TBEXISTENCIAS
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
(Si se hubiese omitido alguna de estas
igualdades, el campo correspondiente contendría el valor nulo)
De esta forma, REGLIBROS ya tiene un
valor que se puede escribir en el fichero mediante la instrucción Put.
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 :
Private Sub BEXAMINAR_Click()
Close ‘Cierra
cualquier fichero abierto
Open TBNOMBREFICHERO For Random As #1 Len
= 88 ‘Abre el fichero deseado
LONGITUDFICH = LOF(1) ‘Obtiene
su longitud
NUMREGS = LONGITUDFICH / 88 ‘Calcula el Nº. de registros
LNUMFICH.Caption = NUMREGS ‘Pone ese
Nº. en el Label
End Sub
Veamos como se escribe un registro.
Analicemos el código del procedimiento click del botón ESCRIBIR
Private Sub BESCRIBIR_Click()
REGISTROLIBRO.Titulo = TBTITULO.Text ‘Se asignan los valores
de cada
REGISTROLIBRO.Autor = TBAUTOR.Text ‘uno de los campos de
la variable
REGISTROLIBRO.Editorial =
TBEDITORIAL.Text ‘REGISTROLIBROS
REGISTROLIBRO.Edición = TBEDICION.Text
REGISTROLIBRO.Precio = TBPRECIO.Text
REGISTROLIBRO.Existencias =
TBEXISTENCIAS.Text
Put #1, Val(TBLEERESCR), REGISTROLIBRO ‘Se escribe el
registro
End Sub
Observe que el Nº. de registro es el
valor que figure en el TextBox TBLEERESCR
Leer datos en un fichero Random. Instrucción Get
Para leer los datos de un fichero Random
utilizaremos la instrucción Get. Su sintaxis es la siguiente :
Get # Numerocanal , NumeroRegistro, Variable
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
Private
Sub BLEER_Click()
Get #1, Val(TBLEERESCR), REGISTROLIBRO ‘Lee el registro completo
TBTITULO.Text = REGISTROLIBRO.Titulo ‘Obtiene el valor del campo
Titulo
TBAUTOR.Text = REGISTROLIBRO.Autor ‘Autor, Editorial, Edición,
Precio
TBEDITORIAL.Text = REGISTROLIBRO.Editorial ‘y Existencias y los pone en los
TBEDICION.Text = REGISTROLIBRO.Edición ‘TextBox correspondientes a cada
TBPRECIO.Text = REGISTROLIBRO.Precio ‘dato
TBEXISTENCIAS.Text =
REGISTROLIBRO.Existencias
End Sub
Funciones
e instrucciones aplicables a los ficheros Random.
Funciones
Seek y Loc.
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.
La sintaxis de la función Loc es :
Variable = Loc (Numerocanal)
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.
La sintaxis de la función Seek es :
Variable = Seek (Numerocanal)
ATENCION
¡¡¡ Seek puede ser una función (lee un
Dato) o una instrucción (fuerza un dato) ! ! !
Instrucción
Seek
La instrucción Seek establece el próximo registro a leer o escribir en un fichero
Random.
Sintaxis
Seek (Numerocanal), posición
posición
es el número de registro que se va a
leer o escribir en la siguiente operación. No acepta el 0 como número de
registro, el mas bajo debe ser el 1. Si se intenta forzar a la posición 0 dará
un error.
Funciones
de los ficheros Random:
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
LOF ( Lenght Of File )
Devuelve la
longitud de un fichero .
Sintaxis Variable
= LOF(Numerocanal)
Mediante la función LOF podemos conocer el número de
registros existentes en un fichero Random, dividiendo el valor devuelto por LOF
por la longitud del registro declarada en la instrucción Open (LEN = longitud)
Nº.
Registros = LOF / longitud
Recuerde Para
obtener la longitud de un archivo que no está abierto utilíce la función FileLen.
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) .
Para abrir un fichero secuencial se abre
utilizando la instrucción :
Open Nombrefichero
For Binary As # Numerocanal
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.
Nombrefichero
es el nombre completo del fichero, con su Path.
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.
Put # Numerocanal, Posición, Variable
Donde Posición
es el Byte donde comenzará la escritura, y Variable
es el nombre de la variable que contiene el dato a escribir. Este dato puede
ser un byte o varios bytes.
Para escribir varios bytes podemos
hacerlo de dos formas :
- Si se puede conocer de antemano el
número de bytes a escribir, puede declararse Variable como un string de ese número de caracteres mediante la
instrucción Dim, por ejemplo :
Dim
Variable As String * numero de bytes
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 ).
- Si no se conoce de antemano el número
de bytes a escribir, podemos declarar la variable sin especificar el número de
bytes que tiene, y de esta forma se escribirán todos los bytes que componen la
variable :
Dim Variable
As String
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.
Si se omite el dato Posición, se tomará como byte de inicio de la escritura el siguiente al último usado por la
instrucción Put. Si quiere omitir este dato, debe conservar
las comas que lo separan :
Put # Numerocanal, , Variable
¿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.
Para leer datos de un fichero binario,
utilizaremos la instrucción Get.
Get # Numerocanal, Posición, Variable
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 :
Dim Variable
As String * 10
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.
Podemos leer caracteres de un fichero
secuencial mediante la instrucción Input
:
Variable = Input (Numero de bytes, # Numerocanal)
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 :
Seek (Numerocanal), Número del primer
Byte a 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)
Variable
contendrá ahora los 35 bytes
deseados.
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.
El formulario del ejemplo tiene esta forma :

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
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
BOTON
LEER (GET)
Private
Sub BLEER_Click()
TBVAR2.BackColor = RGB(255, 0, 0) ‘Pone en rojo el TB TBVAR2 (long. de la
variable)
TBVAR2.Text = "1" ‘e indica que la longitud
leída es 1
If Seek(1) >= LOF(1) Then ‘Si está al final del
archivo
Seek #1, 1 ‘pone el puntero en la posición 1
End If ‘
Dim TEXTO As String * 1 ‘Declara la variable TEXTO de un
byte
If TBVAR3.Text <> "" Then ‘Si se le ha indicado donde
tiene que comenzar
COMIENZA = Val(TBVAR3.Text) ‘le dice que comience en la posición indicada
en TBVAR3
ElseIf Lvar5.Caption <>
"" Then ‘si no, si
existe posición por defecto
COMIENZA = Val(Lvar5.Caption) ‘le indica que comience en la posición por
defecto
Else ‘
si no
COMIENZA = Seek(1) ‘pone el puntero en la posición 1 (byte 1)
End If
Get #1, COMIENZA, TEXTO ‘lee un byte
TBVAR1.Text = TEXTO ‘y lo presenta en TBVAR1
pospordef = Seek(1) ‘busca la nueva posición por defecto
Lvar5 = Str(pospordef) ‘y pone ese valor en
Lvar5
End
Sub
BOTON
LEER (INPUT)
Private
Sub BLLERINPUT_Click()
TBVAR2.BackColor = RGB(255, 255, 255) ‘Pone TBVAR2 en blanco
LONGVAR = Val(TBVAR2.Text) ‘pasa el valor para long. de variable a
LONGVAR
If TBVAR3.Text <> "" Then ‘si ese valor existe (TBVAR3
es distinto de nada)
COMIENZA = Val(TBVAR3.Text) ‘la variable COMIENZA toma ese valor
Seek (1), COMIENZA ‘coloca el puntero en ese valor
End If ‘
Dim TEXTO As String ‘Declara la variable
TEXTO sin limitación
TEXTO = Input(LONGVAR, #1) ‘Lee LONGVAR bytes del canal 1 y
los pasa a TEXTO
TBVAR1.Text = TEXTO ‘y lo presenta en el TB
TBVAR1
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
Private
Sub TBVAR2_Change()
TBVAR2.BackColor = RGB(255, 255, 255) ‘Vuelve a color blanco si introducimos un
dato en
End
Sub ‘este
Text Box
FIN DE LA APLICACIÓN PARA MANEJO DE
FICHEROS BINARIOS
Funciones
y propiedades aplicables a todos los ficheros
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.
Sintaxis Dir[(nombreruta[, atributos])]
nombreruta Expresión de
cadena que especifica un nombre de archivo. Puede incluir el directorio o
carpeta y la unidad de disco. Si no se encuentra nombreruta, devuelve Null.
atributos Constante
o expresión numérica, cuya suma especifica atributos de archivo. Si se omite,
devuelve todos los archivos normales que satisfacen el nombreruta.
El argumento atributos tiene estas constantes y
valores:
Constante Valor Descripción
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.
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.
Si intenta utilizar la instrucción FileCopy en un archivo abierto
actualmente, se produce un error.
FILEDATATIME
Devuelve una fecha que indica la fecha y hora en que
un archivo fue creado o modificado por última vez.
Sintaxis Variable
= FileDateTime(nombreRuta)
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
Devuelve la longitud de un archivo en bytes.
Sintaxis Variable = FileLen(nombreRuta)
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.
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.
Sintaxis Variable = GetAttr(nombreRuta)
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
El valor devuelto por GetAttr es la suma de los siguientes valores de atributos:
Valor Constante Descripción
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
Establece los atributos de un archivo.
Sintaxis SetAttr nombreRuta;atributos
nombreRuta Expresión de
cadena que especifica un nombre de archivo
se puede incluir el
directorio
o carpeta y la unidad de disco.
atributos Constante
o expresión numérica cuya suma especifica los atributos de archivo.
Las constantes y valores de atributos son los mismos
que para la instrucción GetAttr
Si se trata de establecer los atributos de un archivo
abierto, se producirá un error en tiempo de
ejecución.
FREEFILE
Devuelve el siguiente número de archivo
disponible para ser usado con la instrucción Open.
Sintaxis FreeFile[(númerodeintervalo)]
El argumento númerodeintervalo especifica
el intervalo desde el que el siguiente número de archivo libre se va a
devolver. Se especifica 0 (predeterminado) para devolver un número de archivo
en el intervalo 1 a 255, inclusive. Se especifica 1 para devolver un número de
archivo en el intervalo 256 a 511.
Observaciones Se usa FreeFile
cuando se necesita proveer un número de archivo y se quiere asegurar que el
número de archivo no está ya en uso.
Visual Basic - Guía del
Estudiante Cap. 9
INTERFACE DE
DOCUMENTOS MULTIPLES. (Multiple
Document Interface MDI )
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 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.
En
una aplicación MDI pueden coexistir formularios hijo y formularios normales.
Propiedades de los formularios MDI
Aparte
de las propiedades de un formulario normal, un formulario MDI tiene las
siguiente propiedades :
AutoShowChildren. Muestra
los formularios hijo nada mas cargarlos.
Esta
propiedad puede verse si se carga un formulario hijo mediante la
sentencia :
Load NombreFormularioHijo
Si
la propiedad AutoShowChildren está a True, el formulario cargado se verá
inmediatamente. Si está a False, será necesario ejecutar la sentencia
NombreFormularioHijo.Show para presentarlo.
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
MiVariable contendrá el Caption (Barra de Titulo) del formulario
activo.
ActiveForm.Backcolor = RGB
(255,0,0)
pondrá
el fondo del formulario activo de color rojo.
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.
Inserción de Controles Solamente
podrán introducirse en un formulario MDI aquellos controles que tengan la
propiedad Align. (Picture, Data, DBGrid) y solo permiten que
se presenten con alineación a uno de los lados del Formulario (Top, Bottom,
Left o Right)
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.
Línea de Menú. Cuando
existe la línea de Menú en un Formulario MDI y en el Formulario Hijo que
introduzcamos en él, la línea de menú del Formulario MDI se sustituye por la
línea de menú del Formulario Hijo introducido.
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.
A
esas “fotocopias” de un formulario las llamamos Instancias. Al original le llamaremos Clase.
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.
La
Instancia es la réplica de una
clase. Puede ser la réplica de un Formulario, de un control o de otro objeto.
La Instancia lleva las mismas Propiedades que la clase. Se dice que hereda
las propiedades. (Excepto la propiedad Visible, que siempre, por defecto,
aparece a False). Cuando se varía una propiedad de una Instancia, no se altera
el valor de esa propiedad en la Clase
ni en ninguna de las restantes Instancias.
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 :
Declarar
una variable tipo Objeto. No se asuste. Para declarar que una variable es un
Formulario basta con declararla de la siguiente forma :
Dim MiVentana As
Form
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)
Set MiVentana = New
FormularioHjo
Podemos
hacer las dos operaciones a un tiempo : declarar y crear la copia :
Dim MiVentana As New
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.
Documento 1, Documento 2, Documento 3, etc.
Ese
procedimiento quedará de la siguiente forma :
Static contador As Integer
Dim MiVentana As
New FormularioHijo
MiVentana.Caption = “Documento “ & Str
(contador)
MiVentana.Show
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
Me se refiere concretamente a ese
formulario.
Colocación de los Formularios Hijo -
Método ARRANGE
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.
Sintaxis NFMDI.Arrange distribución
donde
NFMDI = Nombre del Formulario MDI
distribución puede tomar los siguientes valores o
constantes :
Constante Valor Descripción
vbCascade 0 Dispone
todos los formularios MDI secundarios no minimizados
en cascada.
vbTileHorizontal 1 Dispone
todos los formularios MDI secundarios no minimizados
en mosaico horizontal.
vbTileVertical 2 Dispone
todos los formularios MDI secundarios no minimizados
en mosaico vertical.
VbArrangeIcons 3 Dispone
los iconos de los formularios MDI minimizados.
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.
Posición de los Formularios en el Eje
Z -
Método ZOrder
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.
Sintaxis
NFH.ZOrder posición
Donde
NFH = Nombre del Formulario Hijo
posición puede se 0 ó 1.
Si es 0 (o si se omite) el formulario se coloca en primer plano. Si es 1 el formulario se coloca en el fondo del
eje Z.
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.
Mostrar los Formularios existentes mediante el
Menú -- Propiedad WindowList
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.
Visual
Basic - Guía del Estudiante Cap. 10
El Objeto Printer
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.
Lo mismo que para escribir en un formulario,
escribíamos el código
Form1.Print
"ABCD"
Para escribir en el objeto Printer el código será:
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 :
Printer.ScaleWidth = 2100 :
Printer.ScaleHeight =
2970
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.
(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.
Las principales propiedades del objeto Printer son :
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.
Sintaxis Printer.ColorMode [= valor]
Valor puede ser un número o una constante
de VB.
Si es un 1 (o la constante
vbPRCMMonochrome) imprimirá en blanco y negro (normalmente en escala de
grises).
Si es 2, o la constante vbPRCMColor
imprimirá en color.
El valor predeterminado depende del
controlador de la impresora y de la configuración actual de la impresora. Las
impresoras en blanco y negro ignoran esta propiedad.
Copies
Devuelve o establece un valor que
determina el número de copias que se van a imprimir.
Sintaxis Printer.Copies [= número]
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
Devuelven o establecen las coordenadas horizontal (CurrentX) o vertical (CurrentY) para un método gráfico o de
impresión. No disponible en tiempo de diseño.
Sintaxis
Para
forzar las coordenadas del cursor de escritura del objeto Printer :
Printer.CurrentX
[= x] Printer.CurrentY [=y]
Para
conocer las coordenadas del cursor de escritura del objeto Printer
Posx = Printer.CurrentX Posy = Printer.CurrentY
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 :
Printer.Line (200,50) - (2870,50)
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 :
Printer.CurrentX = 300 : Printer.CurrentY
= (lo que corresponda a esa fila)
Printer.Print
MiVariable ‘ donde
MiVariable contiene el dato a escribir
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 :
Circle El centro del
objeto.
Line El punto
final de una línea.
El método Print establece como CurrentX la coordenada correspondiente a la
parte derecha de la última letra impresa.
Como CurrentY depende de si ha terminado la sentencia Printer.Print
MiVariable con punto y coma ( ;) o sin el. En el primer caso, CurrentY es
el mismo que tenía antes de realizar ese método. En el segundo caso, avanza
automáticamente una línea.
Cuando se envía la instrucción EndDoc establece los valores de estas
propiedades a 0, 0. NewPage
establece igualmente los valores 0, 0.
DeviceName
Devuelve el nombre del dispositivo permitido por un
controlador. Esta propiedad es solo de lectura
Sintaxis Printer.DeviceName
Cada controlador de impresora acepta uno o más
dispositivos por ejemplo, HP LaserJet III es un nombre de dispositivo.
DrawMode
Devuelve o establece un valor que determina el
aspecto de la salida de un método gráfico. Vea la Ayuda de VB para mayor
detalle.
DrawStile
Devuelve o establece un valor que determina el estilo
de línea de la salida de métodos gráficos.
Sintaxis Printer.DrawStyle [= número]
El número especifica el estilo de línea :
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
Devuelve o establece la anchura de línea de lo
dibujado con los métodos gráficos.
Sintaxis Printer.DrawWidth [= tamaño]
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 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.
Sintaxis Printer.Duplex [= valor]
Donde valor es un valor o constante que
especifica el tipo de impresión, tal como se describe a continuación
Constante Valor Descripción
bPRDPSimplex 1 Impresión en una sola cara con la orientación actual.
vbPRDPHorizontal 2 Impresión
en dos caras con vuelta de página
horizontal.
vbPRDPVertical 3 Impresión
en dos caras con vuelta de página vertical.
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.
Sintaxis Printer.FillColor [ = valor]
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.
Sintaxis printer.FillStyle [= número]
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.
6 Cruzado.
7 Diagonal Cruzada.
Cuando la propiedad FillStyle se define con su valor predeterminado, 1 (Transparente),
el valor de FillColor se ignora.
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
Podemos averiguar que fuente está usando
el objeto Printer :
Tipofuente
= Printer.Font.Name
FontCount
Devuelve el número de fuentes disponibles
para el dispositivo de presentación actual o la impresora activa. (Devuelve un número) Es solamente de
lectura.
Sintaxis numerodefuentes
= Printer.FontCount
FontName
Devuelve el nombre de la fuente que está
usando el objeto Printer
Sintaxis nombredelafuente
= Printer.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
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.
Sintaxis Printer.FontSize [= puntos]
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.
(El objeto Printer acepta tanto Font.Size
como FontSize)
FontBold, FontItalic, FontStrikethru y FontUnderline
Devuelve o establece los estilos de
fuente en los siguientes formatos: Negrita, Cursiva, Tachada y Subrayada.
Printer.FontBold [= lógico] ‘ p.e Printer.FontBold = True
escribiría con
Printer.FontItalic [= lógico] ‘ letra negrita
Printer.FontStrikethru [= lógico]
Printer.FontUnderline [= lógico]
Para el objeto Printer, el establecimiento de estas propiedades no afecta al texto
ya escrito, solamente para lo que se escriba después de cambiar la propiedad.
Aprovecha esta facilidad para cambiar de letra a lo largo de un documento.
En general, deberá modificar la propiedad
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.
Printer acepta FontBold ó
Font.Bold, FontItalic ó
Font.Italic ....
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.
Sintaxis Printer.FontTransparent [= lógico]
La modificación de FontTransparent en tiempo de ejecución no afecta a los gráficos ni
el texto ya dibujados en un objeto Printer
.
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.
hDC
Devuelve un controlador proporcionado por
el entorno operativo Microsoft Windows para el contexto de dispositivo de un
objeto.
Sintaxis Printer.hDC
Esta propiedad es un controlador de
contexto de dispositivo del entorno operativo Windows. El entorno operativo
Windows se encarga de la presentación del sistema asignando un contexto de
dispositivo al objeto Printer. Se puede usar la propiedad hDC para referirse al controlador del contexto de dispositivo de un
objeto. Así se obtiene un valor que se pasa en las llamadas al API de Windows.
Nota
El valor de la propiedad hDC
puede cambiar en tiempo de ejecución, así que no se debe almacenar en una
variable. En su lugar, use la propiedad hDC
cada vez que lo necesite.
Height Width
Devuelven o establecen las dimensiones
del objeto Printer. No están disponibles en tiempo de diseño.
Sintaxis Printer.Height [= número]
Printer.Width [=
número]
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.
Sintaxis Printer.Orientation [= valor]
valor es un valor o constante que
determina la orientación de la página, según se describe a continuación :
Constante Valor Descripción
vbPRORPortrait 1 Los
documentos se imprimen con el lado más corto
arriba.
vbPRORLandscape 2 Los
documentos se imprimen con el lado más largo
arriba.
Page
Devuelve el número de página actual.
Sintaxis Variable
= Printer.Page ‘Variable contiene el número de la pág. actual
Visual Basic mantiene un contador de
páginas impresas desde el inicio de la aplicación o desde la última vez que se
utilizó la instrucción EndDoc en el
objeto Printer. Este contador comienza
por uno y se incrementa en uno cada vez que:
Se utiliza el método NewPage.
Se utiliza el método Print y el texto a imprimir no cabe en la página 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.
Sintaxis Printer.PaperBin [= valor]
valor es un valor o constante que
especifica la bandeja predeterminada, según se describe a continuación :
Constante Valor Descripción
vbPRBNUpper 1 Utilizar papel de la bandeja superior.
vbPRBNLower 2 Utilizar papel de la bandeja inferior.
vbPRBNMiddle 3 Utilizar papel de la bandeja intermedia.
vbPRBNManual 4 Esperar
a la inserción manual de cada hoja.
vbPRBNEnvelope 5 Utilizar
sobres del alimentador de sobres.
vbPRBNEnvManual 6 Utilizar
sobres del alimentador de sobres, pero esperar
a
la inserción manual.
vbPRBNAuto 7 (Predeterminado)
Utilizar papel de la bandeja
predeterminada
actual.
vbPRBNTractor 8 Utilizar papel del alimentador por tracción.
vbPRBNSmallFmt 9 Utilizar
papel del alimentador de papel pequeño.
vbPRBNLargeFmt 10 Utilizar
papel de la bandeja de papel grande.
vbPRBNLargeCapacity 11 Utilizar
papel del alimentador de gran capacidad.
vbPRBNCassette 14 Utilizar
papel del cartucho de cassette adjunto.
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.
Sintaxis Printer.PaperSize [= valor]
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 .
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
Al establecer las propiedades Height o Width de una impresora, se establece automáticamente vbPRPSUser en PaperSize.
Port
Devuelve el nombre del puerto a través
del cual se envía un documento a una impresora.
Sintaxis puertousado
= Printer.Port
El sistema operativo determina el nombre
del puerto, como por ejemplo LPT1: o LPT2:.
PrintQuality
Devuelve o establece un valor que indica
la resolución de la impresora. No disponible en tiempo de diseño.
Sintaxis Printer.PrintQuality [= valor]
valor es un valor o una constante que
especifica la resolución de la impresora, según se describe a continuación :
Constante Valor Descripción
vbPRPQDraft -1 Resolución borrador
vbPRPQLow -2 Resolución
baja
vbPRPQMedium -3 Resolución
media
vbPRPQHigh -4 Resolución
alta
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.
El valor predeterminado depende del
controlador de la impresora y de su configuración actual. El efecto de estos
valores varía según la impresora y el controlador. En ciertas impresoras,
algunas opciones, o todas ellas, pueden producir el mismo resultado.
ScaleHeight, ScaleWidth
¡ Estas propiedades ya se comentaron mas
atrás. Es completamente necesario entender estas propiedades para poder manejar
y dominar el objeto Printer. !
Devuelven o establecen el número de unidades de
medida horizontal (ScaleWidth) y vertical (ScaleHeight) del interior del papel
donde vamos a volcar la información del objeto Printer.
Sintaxis Printer.ScaleHeight [= valor]
Printer.ScaleWidth [= valor]
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
Devuelven o establecen las coordenadas horizontal (ScaleLeft) y vertical (ScaleTop) de los
bordes izquierdo y superior de un objeto al utilizar
métodos gráficos o al situar controles.
Sintaxis Printer.ScaleLeft [= valor]
Printer.ScaleTop [= valor]
donde valor es una expresión numérica que especifica
la coordenada horizontal o vertical. El valor predeterminado es 0.
Con estas propiedades y las relacionadas ScaleHeight y ScaleWidth, puede configurar un sistema de coordenadas completo,
con coordenadas positivas y negativas. Estas cuatro propiedades de escala se
relacionan con la propiedad ScaleMode
de la siguiente forma:
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.
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 :
Printer.Circle
(0,1000), 300
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.
Si hubiésemos puesto Printer.ScaleTop = -
1500 estaríamos diciendo que la
coordenada Y absoluta de la parte superior del papel es - 1500. En ese caso, el círculo anterior se
colocaría a una distancia de 2500
(2500 = 1000 + 1500) del borde 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.
Sintaxis Printer.ScaleMode [= valor]
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.
Sintaxis Printer.TrackDefault [= lógico]
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.
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.
Al modificar el valor de la propiedad TrackDefault mientras se realiza un trabajo
de impresión, se envía una instrucción EndPage
implícita al objeto Printer.
TwipsPerPixelX, TwipsPerPixelY
Devuelve el número de twips per pixel de
un objeto medido horizontal (TwipsPerPixelX)
o verticalmente (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
Devuelve o establece el porcentaje en que
se amplía o reduce el resultado impreso. No está disponible en tiempo de
diseño.
Sintaxis Printer.Zoom [= numero]
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
El valor de la propiedad Zoom ajusta el tamaño de la página
impresa, en un factor de Zoom/100,
en relación con el tamaño aparente de la salida impresa. Por ejemplo, una
página de tamaño carta impresa con Zoom
establecido como 50 contiene tantos datos como una página de tamaño 17 por 22
pulgadas, porque el texto y los gráficos impresos se reducen a la mitad de su
altura y anchura originales.
El objeto
Printers (Colección de objetos Printer)
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
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.
METODOS DEL
OBJETO PRINTER
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
Vea
una explicación completa de este método en el capítulo 7 Métodos Gráficos.
EndDoc
Termina una operación de impresión
enviada al objeto Printer, liberando el documento al dispositivo de impresión o
a la cola.
Sintaxis Printer.EndDoc
Si EndDoc
se invoca inmediatamente después del método NewPage, no se imprime la página en blanco adicional.
KillDoc
Termina inmediatamente el trabajo de impresión
actual.
Sintaxis Printer.KillDoc
Si el Administrador de impresión del
sistema operativo controla el trabajo de impresión (el Administrador de
impresión está ejecutándose y la impresión en segundo plano está activada), KillDoc elimina el trabajo de impresión
actual y la impresora deja de recibir datos.
Si el Administrador de impresión no está
controlando el trabajo de impresión (la impresión en segundo plano está
desactivada), puede que algunos o todos los datos se envíen a la impresora
antes de que KillDoc pueda tener
efecto. En este caso, el controlador de la impresora inicializa la impresora en
cuanto puede y termina el trabajo de impresión.
Line
Dibuja líneas y rectángulos en un objeto. No acepta
argumentos con nombre.
Sintaxis Printer.Line Step (x1, y1) - Step (x2,
y2), color, BF
Vea este
método mas ampliamente en el capítulo 7 Métodos Gráficos.
NewPage
Termina la página actual y avanza a la página
siguiente en el objeto Printer.
Sintaxis Printer.NewPage
NewPage avanza a la página siguiente y restablece la
posición de impresión en la esquina superior izquierda de la nueva página.
Cuando se le llama, NewPage
incrementa la propiedad Page del
objeto Printer en 1.
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
Print
Imprime texto en el objeto Printer.
Sintaxis Printer.Print lista_salida
Donde lista_salida es una expresión o
lista de expresiones a imprimir. Si se omite, se imprimirá una línea en blanco.
En el argumento lista_salida puede poner un texto directamente (Printer.Print
“Hola”) o una variable (Printer.Print Textoaescribir).
Puede también introducir algunas funciones de cadena como la siguiente:
Spc(n) Se utiliza para insertar caracteres espacio en la salida, donde n es el número de espacios a insertar.
Puede introducir también Tabuladores :
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.
Al terminar de imprimir Cualquier
carácter o tabulador, el objeto Printer generará un Retorno de Carro y un Avance
de Línea, excepto que terminemos el método Print con un punto y coma :
Las instrucciones :
Printer.Print “Hola”
Printer.Print “¿Qué tal ?” generarán la siguiente salida por
impresora :
Hola
¿Qué
tal ?
Si pusiésemos
Printer.Print “Hola ” ;
Printer.Print “¿Qué tal ?” la salida por impresora sería :
Hola ¿Qué tal ?
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
Puede conocer la anchura que va a ocupar
un texto en la impresora. (o en un Formulario, en un Picture) usando el Método TextWidth
AnchodelTexto =
Printer.TextWidth (Textoaescribir)
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 :
Haríamos un bucle mas o menos como
este :
Dim Ancho as Long ‘Ancho será una variable Long
For I = 1 To N ‘Imprimiremos N datos
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
Asigna a un punto de un objeto Printer un color especificado. No
acepta argumentos con nombre.
Sintaxis Printer.PSet Step (x,
y), color
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.
(x,
y) Requeridos.
Valores de simple precisión que indican las coordenadas horizontales (eje x) y
verticales (eje y) del punto a establecer.
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.
Visual Basic - Guía del Estudiante Cap. 11
FUNCION DoEvents
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.
Precaución
Asegúrese de que el procedimiento que ha cedido el control con DoEvents
no se ejecute de nuevo desde una parte diferente del código antes de que
regrese la primera llamada a DoEvents. Esto podría causar resultados
impredecibles. Además, no use DoEvents si existe la posibilidad de que otras
aplicaciones interactúen con el procedimiento, de formas imprevistas, durante
el tiempo en éste ha cedido el control.
EJEMPLO
Para explicar la función DoEvents se ha
preparado un pequeño ejercicio con un formulario principal (Form1) y dos
formularios auxiliares, estos últimos solamente a efectos de contar, mediante DoEvents
el número de formularios abiertos.

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.
Private Sub Command1_Click()
Label1.BackColor = RGB(0,
255, 0)
Do While PARAR = False
N
= N + 1
If
N = 1000 Then 'Cada vez que N=1000
ejecuta la función DoEvents.
DoEvents
N = 0
End If
Loop
End
Sub
En el formulario Form1, al que previamente le hemos
puesto la propiedad KeyPreview a True, se le ha puesto este código en su
procedimiento KeyPress:
Private Sub
Form_KeyPress(KeyAscii As Integer)
PARAR = True
Label1.BackColor = RGB(255,
255, 0)
End Sub
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.
El
botón ROJO tiene este código:
Private Sub Command2_Click()
PARAR
= True
Label1.Caption
= DoEvents 'Aquí
comprobamos los Formularios que tenemos
Label1.BackColor
= RGB(255, 0, 0) 'abiertos en este
momento.
End
Sub
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.
Private Sub Command4_Click()
Form2.Show
End Sub
Private Sub Command6_Click()
Form2.Hide
End Sub
Private Sub Command5_Click()
Form3.Show
End Sub
Private Sub Command7_Click()
Form3.Hide
End Sub
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.
Private Sub
Command3_Click()
End
End Sub
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.
(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
Ejecute
la aplicación y comprobará como se comporta un formulario mostrado como Modal.
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 :
La caja de Mensajes. MessageBox o MsgBox
Las
cajas de mensajes o MessageBox, tienen una función clara, que es la de mostrar
una determinada información, aviso, o pregunta para que el usuario tenga
conocimiento de ella y actúe.
Hay 2 formas diferentes de mostrar información:
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:

Debe darse cuenta de algunas
cosas:
En primer lugar el mensaje, "Hola"
que se escribe a continuación de la palabra MsgBox, también debe darse
cuenta del botón Aceptar que tiene el Focus de la ventana activa
y que sólo hay ese botón, y por último el título de la ventana.
Podemos modificar estos
parámetros para alcanzar nuestros objetivos, por eso, vamos a escribir ahora
este código: MsgBox "Hola", ,"Ejemplo" .
El resultado es:

Como podemos apreciar en el
código, la caja de mensaje posee un título Ejemplo y el mensaje, pero es
posible que deseemos escribir un mensaje en varias líneas con salto de párrafo.
Nada tan fácil como este código por ejemplo: MsgBox "Hola" &
vbCrLf & "Esto es un ejemplo.", , "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:
![]()
Estos iconos corresponden a
los siguientes mensajes:
Mensaje crítico.
Mensaje de pregunta.
Mensaje exclamativo.
Mensaje de información.
(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:
Mensaje crítico. VbCritical ó 16
Mensaje de pregunta. VbQuestion ó 32
Mensaje exclamativo. VbExcalamqtion ó 48
Mensaje de información. VbInformation ó 64
Note que es lo mismo
insertar VbCritical o 16.
Vamos a ver un ejemplo
añadiendo un icono al último ejemplo:
MsgBox "Hola"
& vbCrLf & "Esto es un ejemplo.", VbQuestion ,
"Ejemplo"
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 predeterminado vbDefaultButton2 ó 256
Tercer botón predeterminado vbDefaultButton3 ó 512
Por ejemplo: MsgBox
"Hola" & vbCrLf & "Esto es un ejemplo.", VbQuestion
+ vbYesNo + vbDefaultButton2, "Ejemplo"
El resultado es:

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
Así por ejemplo, el siguiente
código:
Dim Resp As Integer
Resp =
MsgBox("Hola" & vbCrLf & "Esto es un ejemplo.",
VbQuestion + vbYesNo + vbDefaultButton2, "Ejemplo")
If Resp = 6 Then
MsgBox "Ha pulsado SI"
Else
MsgBox "Ha pulsado NO"
End If
Tiene el resultado siguiente:


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:
MsgBox Mensaje, Botones, Título de la ventana
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.
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.
La sentencia es: Val = InputBox (Mensaje, Titulo,
ValorPredeterminado)
Val almacenará el texto escrito por el usuario, que
puede ser una cantidad, cadena string, … etc.
Por ejemplo:
Dim Val As String
Val = InputBox("Deme
su nombre", "Ejemplo")
MsgBox "Su nombre
es: " & Val
Tiene como resultado:

(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:
Dim Val As String
Val = InputBox("Deme
su nombre", "Ejemplo", "Mundo Visual")
MsgBox "Su nombre
es: " & Val
Obtendremos como resultado:

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 ="".
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:
Dim Val As String
Val = InputBox("Deme
su nombre", "Ejemplo", "Mundo Visual", 1200, 1400)
Situará la ventana en el eje
de las X a 1200 Twips (posición horizontal) y la Y a 1400 twips
(posición vertical).
Salto de
página
En versiones anteriores de
Visual Basic, la forma de realizar un salto de página en un TextBox era
cambiando la propiedad Multiline a True y escribiendo una
constante string cualquiera con valor igual a Chr$(13) & Chr$(10), es decir
salto de párrafo.
Con la versión Visual Basic
4.0, se usa una constante vbCrLf que realiza esta función.
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.
Visual Basic - Guía del Estudiante Cap. 12
EL CONTROL RICH
TEXT BOX
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 :
SelLenght Devuelve o
establece el número de caracteres seleccionados. Los caracteres
seleccionados son aquellos que se ponen en vídeo
inverso cuando arrastramos con el ratón.
SelStart Devuelve
o establece el número del carácter de comienzo del texto
seleccionado.
SelText Devuelve o establece la cadena de caracteres
seleccionados. Si no hay ningún
carácter seleccionado devuelve la
cadena “” (cadena vacía)
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 :
SelLenght = 21 (Recuerde
que el espacio también es un carácter)
SelStart = 5 (La
e de ejemplo es la sexta letra, pero empieza a contar por la 0)
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 :
SelBold, SelItalic, SelStrikethru, SelUnderline
Estas
propiedades son del tipo Booleano (True/False) y nos permitirán poner el texto
seleccionado en Negrita, Cursiva, Tachada y Subrayada
respectivamente.
Por
ejemplo, RTB.SetBold =
True pondrá el negrita el texto
seleccionado.
RTB.SelItalic = True pondrá en
cursiva el texto seleccionado.
RTB.SelStrikethru = True pondrá en tachado el texto seleccionado.
RTB.SelUnderline = True pondrá en subrayado el texto seleccionado.
(
RTB = Nombre del control RichTextBox )
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.
SelFontName Esta
propiedad devuelve o establece el nombre de la fuente en el texto
seleccionado.
P.e. RTB1.SelFontName = “Arial”
SelFontSize Devuelve
o establece el tamaño de la fuente en el texto seleccionado.
P.e. RTB1.SelFontSize
= 10
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.
Pero
el RichTextBox tiene propiedades exclusivas.
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.
Sintaxis NombredelRTB.SelRTF [= cadena]
Donde
cadena es una expresión de cadena en
formato .RTF.
Esta
propiedad es equivalente a la propiedad SelText
y funciona de forma idéntica, pero en este caso el texto reemplazado o devuelto
mediante la propiedad SelRTF está en
formato RTF. Esta propiedad devuelve una cadena de longitud cero ("")
si no hay texto seleccionado en el control.
Puede
utilizar la propiedad SelRTF junto
con el Método Print para escribir
archivos .RTF. En el siguiente ejemplo, el código abre un fichero
(mitexto1.rtf) y guarda en él el texto seleccionado en el control RichTextBox1
Open
"mitexto.rtf" For Output As 1
Print #1, RichTextBox1.SelRTF
Close 1
TextRTF
Devuelve
o establece el texto de un control RichTextBox, incluido todo el código .RTF.
Sintaxis objeto.TextRTF [= cadena]
Donde
cadena es una expresión de cadena con
formato .RTF.
Al
establecer la propiedad TextRTF se
reemplaza el contenido completo de un control RichTextBox por la nueva cadena.
Puede
utilizar la propiedad TextRTF junto
con el Método Print para escribir
archivos .RTF. Cualquier procesador de textos capaz de leer texto codificado en
formato RTF puede leer el archivo resultante.
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.
Sintaxis NombredelRichTextBox.AutoVerbMenu = True / False
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.
Sintaxis NombredelRichTextBox.BulletIndent [= entero]
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.
Si
queremos activar (o desactivar) el estilo de viñeta en un párrafo, usaremos la
sintaxis :
NombreRichTextBox.SelBullet = True /
False
Si
activamos el estilo viñeta, aparecerá un punto a la izquierda del párrafo.
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
En
este caso podemos tener tres valores :
Null. La selección abarca más de un párrafo y contiene una mezcla de estilos
de viñeta y no viñeta.
True. Los párrafos de la selección
tienen estilo de viñeta.
False. La párrafos de la selección no tienen estilo de viñeta.
DisableNoScroll
Devuelve
o establece un valor que determina si están desactivadas las barras de
desplazamiento en el control RichTextBox.
Sintaxis NombredelRichTextBox.DisableNoScroll = True / False
Si
es False, las barras de desplazamiento aparecen normalmente. Si es True, las
barras de desplazamiento aparecen atenuadas.
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 :
RTB1.Filename =”C :\CursoVB\Mitexto.rtf”
lo
que ocurrirá es que nuestra aplicación cargará el fichero
C :\CursoVB\Mitexto.rtf en el RichTextBox RTB1. Es decir, hace lo mismo que el Método LoadFile (Vea mas abajo).
Sólo
puede especificar los nombres de archivos de texto o archivos .RTF válidos para
esta propiedad.
Le
recomendamos que para cargar un texto en un RTB use siempre el método LoadFile en vez de la propiedad Filename.
Si
lo que hacemos con esta propiedad es consultar el fichero cargado en el
RTB :
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.
Sintaxis NombreRTB.HideSelection = True / False
para establecer la
propiedad
Variable =
NombreRTB.HideSelection para
leerla
Si
la propiedad HideSelection está a True, el texto seleccionado no aparece resaltado
cuando el control pierde el enfoque. Si está en False, el texto seleccionado
aparece resaltado cuando el 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.
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.
Sintaxis NombredelRichTextBox.RightMargin [ =
valor]
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
Devuelve
o establece un valor que controla la alineación de los párrafos de un control
RichTextBox. No está disponible en tiempo de diseño.
Sintaxis NombreRTB.SelAlignment [= valor]
valor
= Un entero o una constante que determina la alineación del párrafo, como se
describe a continuación.
Los
valores admitidos para valor son:
Constante Valor Descripción
Null Ninguno. La selección actual abarca más de un párrafo con distintas
alineaciones.
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.
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:
If
IsNull(RichTextBox1.SelAlignment) = True Then
' Código que se
ejecuta cuando la selección es mixta.
ElseIf
RichTextBox1.SelAlignment = 0 Then
' Código que se ejecuta cuando la selección está
alineada a la izquierda.
...
End
If
SelProtected
Devuelve
o establece un valor que determina si está protegida la selección actual. No
está disponible en tiempo de diseño.
Sintaxis NombreRTB.SelProtected [ = valor ]
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.
Sintaxis NombreRTB.SelCharOffset [= desplazamiento]
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.
Los
valores de desplazamiento son:
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
Devuelven
o establecen el número de tabulaciones y las posiciones absolutas de tabulación
de texto de un control RichTextBox. No están disponibles en tiempo de diseño.
Sintaxis
NombreRTB.SelTabCount [= contador]
NombreRTB.SelTabs(índice) [= ubicación]
Las
sintaxis de las propiedades SelTabCount y SelTabs constan de las siguientes
partes:
NombreRTB
Nombre del RichTextBox
contador Un entero que determina el número de
posiciones de tabulación del párrafo o
los párrafos seleccionados o en el párrafo o los
párrafos que siguen al punto de inserción.
índice Un entero que identifica una
tabulación específica. La primera ubicación de
tabulación tiene un índice cero (0). La última
ubicación de tabulación tiene un índice igual SelTabCount menos 1.
ubicación Un entero que especifica la ubicación de
la tabulación designada. Las unidades
empleadas para expresar posiciones de tabulación
están determinadas por el modo de escala del objeto Form u otro objeto que
contenga el control RichTextBox .
De
forma predeterminada, al presionar TAB mientras escribe en un control
RichTextBox el enfoque pasa al siguiente control del orden de tabulación, según
especifica la propiedad TabIndex. Un modo de insertar una tabulación en el
texto consiste en presionar CTRL+TAB. Sin embargo, a los usuarios habituados a
trabajar con procesadores de texto la combinación de teclas CTRL+TAB puede
resultarles extraña. Puede activar el uso de la tecla TAB para insertar una
tabulación en un control RichTextBox si cambia temporalmente la propiedad
TabStop de todos los controles del objeto Form a False mientras el control
RichTextBox tenga el enfoque. Por ejemplo:
Private
Sub RichTextBox1_GotFocus()
' Pasa por alto los errores de
controles sin la propiedad TabStop.
On Error Resume Next
' Desactiva el
cambio de enfoque al presionar TAB.
For Each Control In Controls
Control.TabStop = False
Next Control
End
Sub
Restablezca
la propiedad TabStop de los otros controles cuando el control RichTextBox
pierda el enfoque.
METODOS DEL CONTROL RichTextBox
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.
Sintaxis NombredelRTB.SaveFile(nombre_ruta, tipo_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 :
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.
El
valor predeterminado es 0. Si no se pone este parámetro, toma el valor 0 por
defecto.
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:
Open
"mitexto.rtf" For Output As 1
Print #1,
RichTextBox1.TextRTF
Close #1
METODO LoadFile
Carga
un archivo .RTF o un archivo de texto en un control RichTextBox.
Sintaxis NombreRTB.LoadFile nombre_ruta, tipo_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 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
0 rtfRTF El
archivo cargado debe ser un archivo .RTF válido.
1 rtfText El
control RichTextBox carga cualquier archivo de texto.
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:
Open
"C :\CursoVB\mitexto.rtf" For Input As 1
RichTextBox1.TextRTF
= Input$(LOF(1), 1)
Close #1
METODO Find
Busca
una cadena específica en el texto de un control RichTextBox.
Sintaxis Variable = NombreRTB.Find (cadena, inicio, fin, opciones)
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
búsqueda.
Opciones (Opcional) Una
o más valores o constantes utilizadas para especificar
características opcionales, como se
describe a continuación.
Valor Constante Descripción
1 rtfWholeWord Determina si una coincidencia se basa en una palabra
completa o en
parte de una palabra.
4 rtfMatchCase Determina si una coincidencia se basa el uso de mayúsculas
y
minúsculas de la cadena especificada
además del texto de la cadena.
8 rtfNoHighlight Determina si una coincidencia aparece resaltada en el control
RichTextBox.
Puede
combinar múltiples opciones si utiliza el operador Or.
Si
se encuentra el texto buscado, el método Find resalta el texto especificado y
devuelve un número con la posición del primer carácter resaltado. Si no se
encuentra el texto especificado, el método Find
devuelve –1.
Si
utiliza el método Find sin la opción
rtfNoHighlight aunque la propiedad HideSelection sea True y el control
RichTextBox no tenga el enfoque, el control seguirá resaltando el texto
encontrado. Los usos posteriores del método Find sólo buscarán el texto
resaltado hasta que se mueva el punto de inserción.
El
comportamiento de búsqueda del método Find varía según la combinación de
valores especificados para los argumentos inicio y fin. Esta tabla describe los
comportamientos posibles:
Inicio Fin Comportamiento
de búsqueda
Especificado Especificado Busca
desde la ubicación inicial especificada hasta la
ubicación final especificada.
Especificado Omitido Busca
desde la ubicación inicial especificada hasta el final del
texto del control.
Omitido Especificado Busca desde el punto de inserción actual hasta la ubicación
final especificada.
Omitido Omitido Busca
en la selección actual si el texto está seleccionado o en
todo el contenido del control si no hay
texto seleccionado.
METODO GetLineFromChar
Devuelve
el número de la línea que contiene una posición de carácter especificado en un
control RichTextBox.
Sintaxis Variable = NombreRTB.GetLineFromChar (pos_carácter)
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
Envía
texto con formato de un control RichTextBox a un dispositivo de impresión.
Sintaxis NombreRTB.SelPrint(hdc)
Donde
hdc es el contexto de dispositivo del dispositivo que va a utilizar para
imprimir el contenido del control.
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
Selecciona
texto en un control RichTextBox basándose en un conjunto de caracteres
especificado.
Sintaxis NombreRTB.Span juego_caracteres, hacia_adelante, negado
donde :
juego_caracteres (Requerido) Una expresión de cadena que especifica
el juego de caracteres que se va a buscar al ampliar la selección, basándose en
el valor de negado.
hacia_adelante (Opcional) Una expresión booleana que determina en
qué sentido se mueve el punto de inserción, como se describe mas adelante.
Negado (Opcional) Una expresión booleana que determina si
los caracteres de juego_caracteres
definen el conjunto de caracteres de destino o se excluyen del conjunto de
caracteres de destino, como se describe mas adelante.
Los
valores para hacia_adelante son:
True (Predeterminado) Selecciona
texto desde el punto de inserción actual o desde el principio de la selección
actual hacia delante, hacia el final del texto.
False Selecciona texto desde el punto
de inserción actual o el principio de la selección actual hacia atrás, hacia el
principio del texto.
Los
valores para negado son:
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
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.
Sintaxis NombredelRTB.Upto (juego_caracteres, hacia_adelante, negado)
Donde :
juego_caracteres (Requerido) Una expresión de cadena que especifica el
conjunto de caracteres que se va a buscar al mover el punto de inserción,
basándose en el valor de negado.
hacia_adelante (Opcional)
Una expresión booleana que determina en qué sentido se mueve el punto de
inserción, como se describe en Valores.
negado (Opcional)
Una expresión booleana que determina si los caracteres de juego_caracteres definen el conjunto de caracteres de destino o se
excluyen del conjunto de caracteres de destino, como se describe en Valores.
Valores
Los
valores de hacia_adelante son:
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.
Los
valores para negado son:
True Los caracteres no especificados
en el argumento juego_caracteres se utilizan para mover el punto de inserción.
False (Predeterminado) Los caracteres
especificados en el argumento juego_caracteres se utilizan para mover el punto
de inserción.
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 :
Clipboard.SetText RTB1.SelRTF, vbCFRTF
guarda
en el portapapeles el texto seleccionado
en ese momento. La línea
Clipboard.SetText RTB1.TextRTF, vbCFRTF
guarda
en el portapapeles todo el contenido
del RichTextBox (llamado RTB1 en los ejemplos) en formato RTF
Las
líneas :
Clipboard.SetText RTB1.SelRTF, vbCFText
Clipboard.SetText RTB1.TextRTF, vbCFRTF
guardarán,
respectivamente, el texto seleccionado y todo el texto de RTB1, en formato de
texto plano (el texto ASCII solamente)
APENDICE
Constantes del control RichTextBox
Constante Valor Descripción
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.
Métodos LoadFile y SaveFile
rtfRTF 0 (Predeterminado)
RTF. El archivo cargado debe ser un archivo .RTF
válido (método LoadFile) o el contenido del control
se guarda en un archivo .RTF (método SaveFile).
rtfText 1 Texto.
El control RichTextBox carga cualquier archivo de texto
(método LoadFile) o el contenido del control se
guarda en un archivo de texto (método SaveFile).
Propiedad MousePointer
rtfDefault 0 (Predeterminado)
La forma está determinada por el objeto.
rtfArrow 1 Flecha.
rtfCross 2 Cruz (cursor en forma de cruz).
rtfIbeam 3 Cursor
en forma de I.
rtfIcon 4 Icono
(cuadrado pequeño dentro de un cuadrado).
rtfSize 5 Tamaño
(flecha de cuatro puntas que señala al norte, sur, este y oeste)
rtfSizeNESW 6 Tamaño
NE-SO (flecha de dos puntas que señala al nordeste y al
sudoeste).
rtfSizeNS 7 Tamaño
N S (flecha de dos puntas que señala al norte y al sur).
rtfSizeNWSE 8 Tamaño
NO, SE.
rtfSizeEW 9 Tamaño
EO (flecha de dos puntas que señala al este y al oeste).
rtfUpArrow 10 Flecha
hacia arriba.
rtfHourglass 11 Reloj
de arena (espere).
rtfNoDrop 12 No
colocar.
rtfArrowHourglass 13 Flecha
y reloj de arena.
rtfArrowQuestion 14 Flecha
y signo de interrogación.
rtfSizeAll 15 Ajustar
todo.
rtfCustom 99 Icono personalizado especificado por la
propiedad MouseIcon.
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
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
{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss
MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fswiss MS Sans Serif;}}
{\colortbl\red0\green0\blue0;}
\deflang1034\pard\plain\f2\fs17
Este es un texto utilizado para explicar el Formato de Texto Enriquecido (RTF).
El Formato de
\par Texto Enriquecido es un
formato de intercambio de textos entre distintos procesadores. Es, en
\par esencia, una idea para
crear una forma com\'fan de intercambiar textos.
\par El RTF guarda los datos
codificados en ASCII, es decir, el fichero resultante es legible plenamen-
\par te ya que los
caracteres que utiliza son ASCII, pero lleva una determinada codificaci\'f3n
para poder
\par cambiar de letra, de
tama\'f1o, etc.
\par Puede guardar
gr\'e1ficos tal como lo har\'eda cualquier procesador de textos.
\par Fin
\par
\par
\par }
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.
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.
Visual Basic - Guía del
Estudiante Cap. 13
La Ayuda de Windows . El Objeto App.
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.
La
presentación de la ayuda podría hacerse mediante un formulario, donde se
presentan distintos ficheros según las necesidades del usuario. Sin embargo
esta forma de presentar la ayuda nunca llegará a ser tan completa como la que
brinda Windows, y el trabajo a desarrollar para igualar la presentación de
Windows sería laborioso. Solución : utilizar los recursos de Windows.
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.
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 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
El
mismo texto en ASCII puro :
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.
{\rtf1\ansi
\deff5\deflang1033{\fonttbl{\f5\fswiss\fcharset0\fprq2 Arial;}}_
_{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;_
_\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;
\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\_
_green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\_
blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue_
_192;}{\stylesheet{\widctlpar
\f5\fs20\lang1034 \snext0
Normal;}{\*\cs10 \additive Default Paragraph Font;}_
_}{\info{\author
LUIS SUAREZ BERNALDO}{\operator LUIS SUAREZ BERNALDO}_
_{\creatim\yr1997\mo3\dy9\hr11\min8}{\revtim\yr1997\mo3\dy9\hr11\min9}_
_{\version1}{\edmins1}{\nofpages1}
{\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.
Para
acceder a la ayuda, Windows ofrece la posibilidad de pulsar F1 . Nuestras
aplicaciones deben sacar la ayuda pulsando F1. Lo podrán hacer mediante otros
procedimientos. Comencemos por lo mas sencillo, una ayuda de una única página.
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
Este
archivo no lo puede utilizar directamente el programa WINHELP.EXE. Hay que compilarlo. Para ello utilizamos el
compilador HC.EXE. Este compilador no es una herramienta Windows, por lo que
tendrá que ir al DOS y ejecutarlo. El programa HC.EXE se encuentra en el
directorio C :\ ..... \VB\HC
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
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
Vayamos
al directorio C :\ ......
\VB\HC (en MS-DOS) y tecleemos
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á 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)
Imaginemos
que tenemos esta configuración del fichero :
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
Esta
aplicación está realizada para . . . . . . . . . .
-
- - - - - - - - - - - - - salto de
página manual - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Acceso
a la Base de Datos
Para
abrir la Base de datos . . . . . . . .
.
-
- - - - - - - - - - - - - salto de
página manual - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Introducción
de datos
Para
introducir datos . . . . . . . . . . .
.
-
- - - - - - - - - - - - - salto de
página manual - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Lectura
de datos
Para
leer los 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 :

Introduzca
una almohadilla (#) en el TextBox Marca personal. Haga click sobre
Aceptar.
Le
aparecerá en la parte inferior de la pantalla un cuadro para introducir el
identificador de esa página. Repita el proceso para todas las páginas
insertándoles una Nota al pié a cada una. Al final obtendrá este
resultado :
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
Esta
aplicación está realizada para . . . . . . . . . .
-
- - - - - - - - - - - - - - - - - - - -
salto de página manual - - - -
- - - - - - - - - - - - - - - - - - -
#
Acceso a la Base de Datos
Para
abrir la Base de datos . . . . . . . .
.
-
- - - - - - - - - - - - - - - - - - - -
salto de página manual - - - -
- - - - - - - - - - - - - - - - - - - -
#
Introducción de datos
Para
introducir datos . . . . . . . . . . .
.
-
- - - - - - - - - - - - - - - - - - -
salto de página manual - - - -
- - - - - - - - - - - - - - - - - - -
#
Lectura de datos
Para
leer los datos . . . . . . . . . . . .
. . . .
EN ESTA PARTE DE LA PAGINA
VERA UNA SEPARACION QUE PONE, A LA
IZQUIERDA
Todas
las notas al pie
# Introducción
# Acceso
# Meterdatos
#
Leerdatos
(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)
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 :
Volvamos
a la primera página del documento Word, donde tenemos el índice.
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.

Al
ponerles doble subrayado, le aparecerán en la ayuda de color verde, y el
puntero se le transformará en una mano
cuando lo ponga encima de una de esas líneas. Pero todavía queda asociarlas a
cada uno de los identificadores. Para ello tiene que llevar el puntero del
ratón justamente al final de cada una de las líneas. Al hacer click el puntero
de escritura se coloca en ese punto. Tiene que escribir a continuación de cada
línea el nombre del identificador que corresponda. Pero lógicamente no querrá
que se vea en la pantalla de ayuda. Por lo tanto debe hacerlo invisible. Para
escribir un texto invisible en Word hay que pulsar las teclas Control + Mayúsculas
+ O. Pulse las tres al mismo tiempo y a
continuación escriba el nombre del identificador que corresponda. No verá lo
que escribe pues para eso está escribiendo con texto invisible. Puede
visualizarlo mediante el botón
![]()
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.
¡
Ya tenemos una ayuda de varias páginas !
Ventanas Emergentes
Es
posible que dentro de la información presentada en cualquiera de las páginas
anteriores, exista una palabra o frase que quisiera explicar con mas detalles.
Habrá observado en las ayudas de Windows que algunas frases dentro de las
páginas de ayuda están en verde, y al acercar el puntero del ratón a ellas se
convierte en una mano. Para poder hacer lo mismo en nuestra ayuda, volvamos al
documento Word.
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
Esta
aplicación está realizada para . . . . . . . . . .
-
- - - - - - - - - - - - - - - - - - - -
salto de página manual - - - -
- - - - - - - - - - - - - - - - - - -
#
Acceso a la Base de Datos
Para
abrir la Base de datos . . . . .
. . . .
-
- - - - - - - - - - - - - - - - - - - -
salto de página manual - - - -
- - - - - - - - - - - - - - - - - - - -
#
Introducción de datos
Para
introducir datos . . . . . . . .
. . . .
-
- - - - - - - - - - - - - - - - - - -
salto de página manual - - - -
- - - - - - - - - - - - - - - - - - -
#
Lectura de datos
Para
leer los datos . . . . . . . . .
. . . . . . .
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 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.
Si
repasamos las propiedades de los controles, seguro que se acuerda de la
propiedad HelpContextID que tenían
la mayoría de los controles VB. En
aquel momento decíamos que esa propiedad que establece un número de contexto
asociado para este control. Este número se aplica para determinar la ayuda
interactiva asociada a este control. Ha
llegado el momento de sacarle partido a esa propiedad.
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.
Añada
a su aplicación 4 TextBox y asígneles los valores 1, 2, 3 y 4 a sus propiedades
HelpContextID. Vuelva a compilar la ayuda y ejecute la aplicación. Vaya pasando
el foco de uno a otro TextBox y comprobándolo.
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 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.
El
fichero FICHAYUD.HPJ queda de momento con la siguiente forma :
[FILES]
AYUDA1.RTF
AYUDA2.RTF
[MAP]
Identificador1 1
Identificador2 2
Identificador3 3
Identificador4 4
Este
procedimiento de acudir rápidamente a la ayuda de un determinado control puede
que no sea el ideal, ya que en una aplicación, siempre tiene el foco algún
control. Si ese control que ahora mismo tiene el foco tiene activado el
HelpContextID, y el usuario pulsa F1, con la intención de ir a ver cualquier
cosa no relacionada con el control que tiene actualmente el foco, se verá
sorprendido con que aparece una información que nada tiene que ver con la
esperada (índice). En cualquier caso,
siempre podrá ir al índice haciendo click en el botón CONTENIDO de la ventana
de ayuda, pero en principio no está bien que le aparezca en pantalla una
información no esperada. Tiene solución,
incluya en el menú (palabra Ayuda) o en un control Image con el símbolo
? una llamada al programa WINHELP.EXE,
pasándole como parámetro el nombre del fichero de ayuda. Esto lo podemos hacer mediante la función
SHELL
SHELL “WINHELP.EXE
C:\DIRAYUDA\FICHAYUD.HLP “, 1
(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)
También
puede utilizar para este fin el CommonDialog. Introduzca un CommonDialog en su
aplicación y ponga en su propiedad HelpFile
el nombre del fichero de ayuda. La
propiedad HelpCommand de este
CommonDialog debe estar puesta a 3 para que comience mostrando el índice de la
ayuda. En estas condiciones, en vez de acudir a la función Shell para ejecutar
el WINHELP.EXE, ejecute CommonDialog.ShowHelp. Vea con mas detalles las propiedades del
CommonDialog, pues le permite presentar otras funciones de la ayuda de Windows
(Ayuda de la Ayuda, etc.)
Titulo de la ventana de Ayuda
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
Identificador4 4
El
dato introducido en la línea COPYRIGHT sale en el menú de la pantalla de ayuda,
en Ayuda | Versión.
Gráficos en la ventana de Ayuda.
Si
necesita introducir un gráfico en la ventana de ayudas puede hacerlo de dos
formas :
-
Introducirlo en el fichero Word. Esta opción es recomendable si el gráfico es
muy pequeño.
-
Introducirlo directamente desde un fichero .BMP ó .WMF (Metarchivo).
Recomendable cuando el gráfico es
grande. Este método se denomina de referencia a un gráfico.
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
supone que el gráfico está en un fichero llamado GRAFICO1.BMP en el directorio
C:\DIRAYUDA. Vayamos al documento Word, y en el sitio donde desee introducir el
gráfico inserte la(s) línea(s) :
{bmc c:\dirayuda\grafico1.bmp}Le colocará este gráfico en medio de la ventana de
ayuda, y este texto inmediatamente debajo del gráfico.
o
{bml c:\dirayuda\grafico1.bmp}Le colocará este gráfico a la izquierda de la ventana
de ayuda, y este texto a la derecha del gráfico.
o
{bmr c:\dirayuda\grafico1.bmp}Le colocará este gráfico a la derecha de la ventana
de ayuda, y este texto a la izquierda del gráfico.
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 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.
Usar los Gráficos de la Ayuda como
enlaces a páginas
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()
El
fichero FICHAYUD.HPJ quedará 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
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.
Esta
segunda ventana se comporta de manera idéntica a la primera, en cuanto a
llamadas a otras páginas o a menús emergentes.
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)
Para
llevar la información a una de estas ventanas, en vez de a la ventana
principal, se añadirá tras el
identificador de la página que queremos enviar a la nueva ventana el símbolo > y a continuación el nombre de la
ventana.
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
Como
la propiedad HelpFile también es de
escritura, se puede cambiar en tiempo de ejecución el fichero de ayuda. Piense
lo útil que puede resultar esto para cambiar el idioma de la ayuda de una
aplicación. Para ello basta con imponer el nombre (con su Path) del nuevo
fichero de ayuda :
App.HelpFile = "C:\ .....
\ ..... \
nuevaayuda.hlp"
(Vea
un poco mas adelante mas información sobre el Objeto App)
Otros Compiladores de Ayuda (HCP.EXE,
HCW.EXE, ...)
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.
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.
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.
Alguna
de estas informaciones se le pueden introducir al proyecto en tiempo de diseño,
en el cuadro de Opciones. Para ello basta con ir, en la Barra de Menú
de Visual Basic a Herramientas |
Proyecto | Opciones y hacer click en Proyecto. Otra parte donde se introducen es en el
cuadro de diálogo Opciones de EXE. Para ver este cuadro proceda de la misma
forma que si fuese a crear un archivo .EXE de la Aplicación, Haga click en Archivo | Crear Archivo EXE de la Barra de Menú, y una vez que le
aparezca el cuadro de diálogo para introducir el nombre, haga click en
OPCIONES.
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
Se
establece esta propiedad en tiempo de diseño usando el cuadro Opciones de EXE.
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
Se
establece esta propiedad en tiempo de diseño usando el cuadro de Opciones de
EXE. Visual Basic toma por defecto el nombre de la compañía con que se cargó
VB.
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
Se
establece esta propiedad en tiempo de diseño usando el cuadro Opciones de EXE.
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.
hInstance (Propiedad)
Devuelve
el controlador de la instancia de la aplicación.
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.
El
valor de esta propiedad lo pone directamente Windows.
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
Esta
propiedad se establece en el cuadro de diálogo Opciones de EXE.
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.
Major Minor (Propiedades)
Devuelven
o establecen el número mayor (menor) de la versión del proyecto. Es de sólo lectura en tiempo de ejecución.
Sintaxis App.Major App.Minor
El
valor de estas propiedades están dentro del rango 0 a 9999.
Proporcionan
información sobre la versión de la aplicación en ejecución. Se establecen 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.
Sintaxis App.PrevInstance
Puede
utilizar esta propiedad en un procedimiento de evento Load para determinar si
el usuario ya está ejecutando una instancia de una aplicación. Dependiendo de
la aplicación, puede ser conveniente que sólo haya una instancia de la misma en
ejecución al mismo tiempo en el entorno operativo Microsoft Windows.
ProductName (Propiedad)
Devuelve
o establece un valor de tipo String que contiene el nombre de producto de la
aplicación en ejecución. Es de sólo
lectura en tiempo de ejecución.
Sintaxis App.ProductName
Establezca
esta propiedad en tiempo de diseño usando el cuadro de diálogo Opciones de EXE.
Revision (Propiedad)
Devuelve
o establece el número de revisión de la versión del proyecto. Es de sólo lectura en tiempo de ejecución.
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.
Sintaxis App.StartMode
= Valor
Donde
Valor es un número o una constante que determina la forma de inicio :
Constante Valor Descripción
vbSModeStandalone 0 (Predeterminado)
La aplicación se inicia como proyecto
independiente.
vbSModeAutomation 1 La
aplicación se inicia como servidor de automatización OLE.
TaskVisible (Propiedad)
Devuelve
o establece un valor que determina si la aplicación aparece en la lista de
tareas de Windows.
Sintaxis App.TaskVisible
[= booleano]
Donde
booleano puede tomar los valores True o False :
True (Predeterminado) La aplicación aparece en la lista de tareas
de Windows.
False La aplicación no aparece en la
lista de tareas de Windows.
La
propiedad TaskVisible sólo puede
establecerse a False en aplicaciones que no presenten interfaz, como servidores
OLE que no contengan o presenten objetos Form.
Mientras la aplicación disponga de interfaz gráfica, la propiedad
TaskVisible se establece automáticamente a True.
Title (Propiedad)
Devuelve
o establece el título de la aplicación que aparecen en la Lista de tareas de
Microsoft Windows. Si se modifica en tiempo de ejecución, los cambios no se
guardarán con la aplicación.
Sintaxis App.Title [= valor]
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.
Visual
Basic - Guía del Estudiante Cap. 14
Procedimientos
y funciones en VB
Procedimiento
Un
Procedimiento en Visual Basic es un trozo de código que realiza una determinada
tarea. Un procedimiento es el código que asociamos a un evento de un control
(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.
Un
procedimiento puede insertarse en un Módulo o en Formulario. Para crear un Procedimiento
basta con hacer click en la Barra de Menú de VB en Insertar | Procedimiento. Observará que la palabra Procedimiento del Menú desplegable está
deshabilitada si no está abierta ninguna ventana de código. Para habilitarla,
abra la ventana de código del Formulario o Módulo donde quiere insertar el
nuevo Procedimiento.
Una
vez hecho Click en Insertar |
Procedimiento le aparecerá esta ventana :

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 :
Public. Se podrá acceder a él desde cualquier Formulario o
Módulo del programa.
Dependiendo
de donde se haya insertado el Procedimiento (Formulario o Módulo), debe citarse
de la siguiente forma :
Si
se ha insertado en un Módulo, puede citarse solamente por su nombre. Puede
citarse también por el nombre del módulo seguido por el nombre del
procedimiento, separando ambos por un punto. Si el procedimiento tiene por
nombre NombreProcedimiento y se ha
insertado en el Módulo1 puede citarse
de las dos formas siguientes en cualquier parte del programa:
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 cero o nulo su
valor cuando salimos y volvemos a entrar en ese procedimiento). Puede
ahorrarnos un poco de código.
El código de los
Procedimientos se guarda en el General del Formulario o Módulo donde se han
insertado :

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.
El
ámbito de una Función es el mismo que el un Procedimiento. Si se declara
Pública puede usarse en toda la aplicación. Si se declara Privada, solamente en
el Formulario o Módulo donde se haya insertado.
Para
llamar a una Función son válidos igualmente los criterios expuestos para los
Procedimientos.
Parámetros de una Función
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
Public Function
MiFuncion(ByVal Variable1 as String, ByVal Variable2 as Integer)
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.
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)
Si,
por ejemplo, le pasásemos los valores :
Variable1
= Guía del Estudiante
Variable2
= 14
Obtendríamos
como resultado la cadena Guía del Estud
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 :
Public Function
MiFuncion(ByVal Variable1 as String, ByVal Variable2 as Integer)
resultado =Left (Variable1, Variable2)
End
Function
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 :
Public Function
MiFuncion(ByVal Variable1 as String, ByVal Variable2 as Integer) As String
MiFuncion =Left (Variable1, Variable2)
End Function
(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)
En
cualquier parte del programa podemos poner :
Label1.caption = MiFuncion (Guía del Estudiante, 14)
y
Label1 tomará como Caption la cadena Guía
del Estud
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 :
Private Sub Command1_Click()
Label1.Caption =
MiFuncion(Text1.Text, Val(Text2.Text))
End Sub
Public Function
MiFuncion(ByVal Variable1 As String, ByVal Variable2 As Integer) As String
MiFuncion = Left(Variable1,
Variable2)
End Function
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 :
Label1.Caption =
Left(Text1.Text, Val(Text2.Text))
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.
Public Function
MultiplicaA(ByVal X1 As Integer, ByVal X2 As Integer) As Integer
x1
= x1 + 2
MultiplicaA
= x1 * x2
End Function
Public Function
MultiplicaB(ByRef X1 As Integer, ByRef X2 As Integer) As Integer
x1
= x1 + 2
MultiplicaB
= x1 * x2
End
Function
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
Private Sub Command1_Click()
Dim pepe As Integer
Dim
juan As Integer
pepe
= Val(Text1)
juan
= Val(Text2)
Label1
= MultiplicaA(pepe, juan)
Label2
= pepe
Label3 = juan
End Sub
Tras
esto, se pone en Lable2 el valor pepe
Private Sub Command2_Click()
Dim pepe As Integer
Dim
juan As Integer
pepe
= Val(Text1)
juan
= Val(Text2)
Label1
= MultiplicaB(pepe, juan)
Label2
= pepe
Label3 = juan
End Sub
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 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 :
Public
Sub sumacifras(ParamArray cifra())
Dim I As Integer
Dim suma As Integer
For I = LBound(cifra) To
UBound(cifra)
suma
= suma + CInt(cifra(I))
Next I
Label1.Caption = suma
End Sub
Private Sub Command2_Click()
sumacifras
1, 2, 3, 4, 5, 6, 7, 8
End
Sub
Este
código nos suma las cifras 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8
La
variable que se pasa con ParamArray debe ser Variant
Existe
otra forma de pasar parámetros : Optional
Cuando
se declara una función con un determinado número de parámetros, es necesario
pasárselos todos. Si no se hace así, VB nos dará un error. Pero puede que algún
parámetro no exista siempre. Cuando uno o varios de los parámetros que se pasan
a una función son opcionales, se le pueden pasar como Optional.
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
Hagamos
un ejemplo en el que vamos a poner en un TextBox (TB4) el nombre y apellidos de
una persona. El segundo apellido se lo pasamos como Opcional. La declaración de
la función será :
Public Function
SUMANOMBRES(NOMBRE As String, APE1 As String, Optional APE2 _
As
Variant)
‘
Debemos detectar si se le ha pasado el parámetro opcional. Usamos para ello IsMissing
If IsMissing (APE2) Then
TB4.Text
= NOMBRE & " " & APE1
Else
TB4.Text = NOMBRE &
" " & APE1 & " " & APE2
End If
End Function
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 :
Private Sub Command1_Click()
If TB3 <> ""
Then
SUMANOMBRES TB1, TB2, TB3
Else
SUMANOMBRES
TB1, TB2
End If
End Sub
Salir de una función
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
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
()
Tal como se ha visto en el
capitulo 2
Funciones
API de Windows
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 :
TITULO API de Win32. Guía del
Programador de Visual Basic
AUTOR Daniel Appleman. Editorial InforBooks - Barcelona
ISBN 84-89700-22-2
Citaremos este libro
repetidas veces a lo largo de este capítulo.
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
Declare Function GetVolumeInformation Lib "kernel32" Alias
"GetVolumeInformationA" (ByVal _ lpRootPathName As String, ByVal
lpVolumeNameBuffer As String, ByVal nVolumeNameSize _ 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
segundo lugar, vemos que el nombre de esta función es GetVolumeInformationA, que es lo que figura entre paréntesis en la
declaración, y es el nombre que esa dll kernel32 tiene escrito dentro de ella.
El nombre GetVolumeInformation que
figura como nombre de la función, al principio de la declaración, es el nombre
por el que nos vamos a referir a la función en nuestra aplicación. Ese nombre
puede cambiarse, cambiando también el nombre con el que vamos a llamar a esta
función a lo largo de nuestra aplicación. Esto
se lo digo solamente a nivel informativo. No
lo haga. Su aplicación no podría ser interpretada por otra persona. No es profesional y quien mas perderá
por ello es Vd. Le hago especial hincapié en esto, porque es una forma de
proteger sus programas por parte de algunos programadores. Pero un analista
experto encuentra enseguida el truco. Y algunos no perdonan. Seamos
profesionales
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.
Dim volbuf As String
Dim sysname As String
Dim
serialnum As Long ‘esta
variable será la que contenga el número del disco
Dim sysflags As Long ‘lpFileSystemFlags
Dim componentlength As Long ‘lpMaximumComponentLength
Dim res As Long
volbuf = String(256, 0)
sysname = String(256, 0)
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 :
lpRootPathName Se lo metemos
directamente : “C :\” - no olvidar la barra \
lpVolumeNameBuffer volbuf
nVolumeNameSize Tamaño del
buffer anterior. Directamente 255
lpVolumeSerialNumber serialnum.
Contendrá el número del disco
lpMaximumComponentLength componentlength
lpFileSystemFlags sysflags
lpFileSystemNameBuffer sysname
nFileSystemNameSize Tamaño buffer anterior.
Directo, 255
res =
GetVolumeInformation("C:\", volbuf, 255, serialnum, componentlength,
sysflags, _
sysname,
255)
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 :
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.
Error en el fichero Win32Api.txt de la
versión en castellano de Visual Basic 4
En
las declaraciones de APIs que usan la librería kernel32, se ha traducido el
nombre de la librería. Esta es la declaración que trae para la función
Sleep :
Declare
Sub Sleep Lib "núcleo32" Alias "Sleep" (ByVal
dwMilliseconds As Long)
Como
podrá darse cuenta, el haber traducido el nombre de la librería llevará a V.B.
a buscar una DLL llamada núcleo32 que no existe, y dará error.
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 :
Declare Sub GetSystemTime Lib
"kernel32" Alias "GetSystemTime" (lpSystemTime _
As
SYSTEMTIME)
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 :
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 :
Private Sub Command1_Click()
Dim
Pepe As SYSTEMTIME ‘Pepe es una variable del tipo SYSTEMTIME
GetSystemTime Pepe
Text1 = Str(Pepe.wYear)
Text2 = Str(Pepe.wMonth)
Text8 = (Pepe.wDayOfWeek)
Text3 = Str(Pepe.wDay)
Text4 = Str(Pepe.wHour)
Text5 = (Pepe.wMinute)
Text6 = (Pepe.wSecond)
Text7 = (Pepe.wMilliseconds)
End Sub
Este
programa nos mostrará la hora (hasta milésimas de segundo), la fecha y el día
de la semana.
Aún
queda otro apartado en la ventana Tipo API : Las constantes.
En
muchas declaraciones de funciones API se utilizan constantes, bien numéricas o
expresiones. El Visor de testo API nos muestra también las constantes que nos
podemos encontrar en las declaraciones. Vayan un par de Ejemplos
Public Const SCROLLLOCK_ON =
&H40 ' The scrolllock light is on.
Public Const
SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege"
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..
Visual
Basic - Guía del Estudiante Cap. 15
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 es un estándar
desarrollado por Microsoft para la comunicación entre aplicaciones,
incrustación de objetos de algún tipo dentro de una aplicación, reutilización
de código y uso de servicios que ofrece una aplicación desde otra distinta (a
esto se le llama automatización OLE). Ejemplos de lo que podemos hacer con OLE
son:
Introducir
un documento de Word o de Excel desde nuestro programa usando el mismo entorno
de Word o de Excel (en un formulario de VB).
Llamada
a Word o Excel (o muchos otros programas) desde nuestra aplicación con una
serie de datos.
Uso de
alguna característica en particular de Word, por ejemplo el corrector
ortográfico.
Insertar
un gráfico de Excel en un documento de Word.
Crear
una aplicación que ofrezca servicios OLE a cualquier otra aplicación que desee
usarlos.
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 ser dotada de características OLE, para que se pudieran
hacer operaciones matemáticas desde otro programa que no posea estas
características.
Es decir, básicamente OLE
permite dos cosas:
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.
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.
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.
Veamos primero un pequeño
ejemplo del uso de OLE desde fuera de VB, para ello sigamos los siguientes
pasos:
Creemos
un documento nuevo en Word.
Elijamos
la opción Objeto del menú Insertar.
Seleccionar
el tipo de objeto que queremos insertar en nuestro documento. En este punto
seleccionaremos una imagen de PaintBrush, otras cosas que podemos seleccionar
son si vamos a crear un objeto nuevo (en este caso una imagen de PaintBrush) o
seleccionar una imagen que ya existe, en este caso seleccionamos una imagen de
nuestro disco (c:\windows\logowin.bmp). También podemos elegir otras opciones:

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.
.
Fig. 16-2. La ventana de insertar objeto.
Fig. 16-3. Crear objeto desde archivo con la posibilidad de
vincular.
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.
Ya hemos usado OLE desde
fuera de Visual Basic, para poder hacerlo desde VB tenemos varias
posibilidades, la primera es usar el control contenedor OLE:
Fig. 16-5.
El control OLE en la barra de herramientas.
Si seleccionamos el control
OLE de la caja de herramientas y lo arrastramos a un formulario, nos aparece la
pantalla de la figura 16-2 otra vez para que lo asociemos a un documento de
Word, imagen de PaintBrush, vídeo avi,...CUALQUIER documento de cualquier
aplicación que tengamos instalada en nuestro ordenador que soporte OLE. En este
momento si pulsamos el botón Cancelar
en nuestro formulario habrá un control OLE que no está asociado a ningún objeto
(a ninguna aplicación), lo podremos asociar más tarde en tiempo de diseño
sacando el menú contextual del control pulsando el botón derecho del ratón
sobre el control, o en tiempo de ejecución mediante código.
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.
Además podemos decidir
asociarlo en tiempo de ejecución en vez de en tiempo de diseño, o cambiar esta
asociación más tarde, para ello lo haremos en tiempo de diseño pinchando con el
botón derecho del ratón sobre el objeto OLE, con lo que nos aparece un menú
emergente contextual del objeto, o en tiempo de ejecución con las propiedades y
métodos del objeto OLE.

Fig. 16-6. Un clip avi incrustado en nuestro formulario.
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).

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.
Tenemos una gran cantidad de
propiedades para controlar el comportamiento de nuestro control OLE:
Action
Su uso
está obsoleto, Microsoft lo ha mantenido en esta versión por motivos de
compatibilidad con versiones anteriores, ahora se deben usar los métodos del
control OLE equivalentes.
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:
|
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.
BackColor, BackStyle, BorderStyle
Igual
que para todos los controles que tienen estas propiedades.
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.:
Si creamos un formulario con un botón de
comando y un control OLE que no asociemos a nada en tiempo de diseño (pulsamos Cancelar cuando nos aparezca la pantalla
de insertar objeto), y añadimos el siguiente código a la sección de
declaraciones del formulario:
Private Sub Command1_Click ()
Dim
Msg, NL, TB ' Declara variables.
TB = Chr(9) ' Carácter Tab.
NL = Chr(10) ' Carácter Nueva línea.
' Crea
datos para reemplazar los datos predeterminados de Graph.
Msg = TB + "Drew" & TB &
"Teresa" & TB & "Bob"
Msg = Msg + NL & "Eric" & TB
& "1" & TB & "2" & TB & "3"
Msg = Msg + NL & "Ted" & TB
& "11" & TB & "22" & TB &
"33"
Msg = Msg + NL & "Arthur" &
TB & "21" & TB & "32" & TB &
"23"
' Envía el
dato utilizando la propiedad DataText.
' Activa
MSGRAPH como oculto.
Ole1.DoVerb - 3
If Ole1.AppIsRunning Then
Ole1.DataText
= Msg
'
Actualiza el objeto.
Ole1.Update
Else
MsgBox
"Graph no está activado."
End If
End Sub
Sub Form_Load ()
Ole1.Format
= "CF_TEXT" ' Establece
el formato de archivo como de texto.
Ole1.SizeMode = 2 ' Autosize.
Ole1.CreateEmbed "",
"MSGRAPH"
End Sub
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:
Ole1.Format
= "CF_METAFILEPICT" (para
fijar el formato como el de los metaarchivos de Windows, esto es, los ficheros
de imágenes con extensión WMF).
Nótese
que el valor de esta propiedad es una cadena de caracteres.
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:
|
Constante |
Valor |
Descripción |
|
vbOLEMiscFlagMemStorage |
1 |
Provoca que el control use memoria para almacenar el
objeto mientras está cargado, esto hace que sea más rápido que la acción
predeterminada del objeto, que es almacenarlo en disco como archivo temporal.
Sin embargo, este valor puede usar gran cantidad de memoria para objetos
cuyos datos requieran mucho espacio, como mapas de bits. |
|
vbOLEMiscFlagDisableInPlace |
2 |
Desactiva el comportamiento predeterminado del control de
permitir edicición in-situ en los objetos que lo acepten. Si un objeto acepta
activación in situ, el valor vbOLEMiscFlagDisableInPlace se puede usar para
forzar que el objeto se active en una ventana separada. |
Los
valores se pueden combinar sumándolos.
Object
Se usa
para controlar un objeto de automatización OLE. El uso de esta propiedad es el
siguiente:
objeto.Object[.propiedad | .método]
Para
saber que propiedades y métodos admite el objeto se debe buscar en la documentación
de la otra aplicación. Más adelante hablaremos de automatización OLE.
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:
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.
Su
formato es el mismo que el de la propiedad ObjectAcceptFormats.
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.
Los valores
que devuelve son:
|
Constante |
Valor |
Descripción |
|
vbOLEFlagChecked |
&H0008 |
El elemento del menú está verificado. |
|
vbOLEFlagDisabled |
&H0002 |
El elemento del menú está deshabilitado (pero no
atenuado). |
|
vbOLEFlagEnabled |
&H0000 |
El elemento del menú está habilitado. |
|
vbOLEFlagGrayed |
&H0001 |
El elemento del menú está atenuado. |
|
vbOLEFlagSeparator |
&H0800 |
El elemento del menú es una barra separadora. |
El
primer verbo de la matriz ObjectVerbs es el verbo predeterminado. El resto de
los verbos de esta matriz pueden ser presentados en un menú. La matriz
ObjectVerbFlags contiene información sobre el estado del menú (como atenuado,
verificado y demás) de cada verbo de la matriz ObjectVerbs.
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)
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. |
Estos
verbos pueden no estar enumerados en la matriz de propiedades ObjectVerbs.
El
primer verbo de la matriz ObjectVerbs,
ObjectVerbs(0), es el verbo
predeterminado. Mientras no se especifique otra cosa, este verbo activa el
objeto.
El
resto de los verbos de la matriz pueden presentarse en un menú. Si se considera
apropiado presentar el verbo predeterminado en un menú, el verbo predeterminado
tiene dos entradas en la matriz ObjectVerbs.
Las
aplicaciones que presentan objetos incluyen normalmente un comando Objeto en el
menú Edición. Cuando el usuario elige
Edición Objeto, un menú presenta los
verbos del objeto. Las propiedades ObjectVerbs, ObjectVerbsCount y ObjectVerbFlags se usan para crear dicho menú en tiempo de
ejecución.
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.
Para
presentar automáticamente los verbos de la matriz ObjectVerbs en un menú emergente cuando el usuario haga clic en un
objeto con el botón secundario del Mouse, se debe establecer la propiedad AutoVerbMenu a True.
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
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.
El
valor de la propiedad OLETypeAllowed debe ser 1 (vbOLEEmbedded) o 2
(vbOLEEither) para mover o copiar el objeto que se puede vincular o incrustar o
0 (vbOLELinked) o 2 para vincular el objeto. Soltar un objeto cuando
OLEDropAllowed es True tiene el mismo efecto en los valores de las propiedades
Class, SourceDoc y SourceItem que utilizar el método Paste del control
contenedor OLE.
Si la
propiedad OLEDropAllowed se establece como True,
el control contenedor OLE no recibe eventos DragDrop o DragOver al arrastrar un
objeto, y el valor de la propiedad DragMode no tiene ningún efecto en el
comportamiento de arrastrar y soltar del control contenedor OLE.
OLEType
Indica
si el control contenedor OLE contiene un objeto o para determinar el tipo de
objeto que contiene. Puede tomar los siguientes valores:
|
Constante |
Valor |
Descripción |
|
vbOLELinked |
0 |
El control contenedor OLE
contiene un objeto vinculado |
|
vbOLEEmbedded |
1 |
El control contenedor OLE
contiene un objeto incrustado |
|
vbOLENone |
3 |
El control contenedor OLE
no contiene ningún objeto. |
OLETypeAllowed
Devuelve
o establece el tipo de objeto que el control contenedor OLE puede contener.
Puede tomar los siguientes valores:
|
Constante |
Valor |
Descripción |
|
vbOLELinked |
0 |
El control contenedor OLE
sólo puede contener un objeto vinculado. |
|
vbOLEEmbedded |
1 |
El control contenedor OLE
sólo puede contener un objeto incrustado. |
|
vbOLEEither |
2 |
El control contenedor OLE
puede contener un objeto vinculado o uno incrustado. Es el valor
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:
|
Constante |
Valor |
Descripción |
|
vbOLESizeClip |
0 |
El objeto se presenta con
su tamaño real. Si el objeto es más grande que el control contenedor OLE, su
imagen se recorta por los bordes del control. Es el valor predeterminado |
|
vbOLESizeStretch |
1 |
La imagen del objeto
adapta su tamaño para ajustarse al control contenedor OLE. La imagen puede no
mantener las proporciones originales del objeto. |
|
vbOLESizeAutoSize |
2 |
El control contenedor OLE
cambia su tamaño para presentar el objeto entero. |
|
vbOLESizeZoom |
3 |
El objeto cambia su tamaño
para rellenar el control contenedor OLE tanto como fuera posible manteniendo
las proporciones originales del objeto. |
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.
La
propiedad SourceDoc se usa para especificar el archivo que se va a vincular
cuando se crea un objeto vinculado usando la propiedad Action. La propiedad
SourceItem se usa para especificar los datos dentro del archivo vinculado.
Cuando
se crea un objeto incrustado usando la propiedad Action, si la propiedad
SourceDoc se define con un nombre de archivo válido, se crea un objeto incrustado
usando el archivo especificado como plantilla.
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.
Cuando
se usa esta propiedad OLETypeAllowed tiene que ser 0 (Vinculado) o 2
(Cualquiera). La propiedad SourceDoc se usa para especificar el archivo vinculado.
Cada
objeto usa su propia sintaxis para describir sus unidades de datos. Para
definir esta propiedad, se especifica una unidad de datos reconocible por el
objeto. Por ejemplo, cuando se vincula con Microsoft Excel, SourceItem se
especifica usando una referencia de celda o de rango de celdas como R1C1 o
R3C4:R9C22 o un rango con nombre como Beneficios. Para determinar la sintaxis
que describe las unidades de datos de un objeto, se debe consultar la
documentación de la aplicación que ha creado el objeto, también se puede ver
creando un objeto vinculado en tiempo de diseño usando el comando Pegado especial, una vez que el objeto
ha sido creado, se selecciona la propiedad SourceDoc en la ventana Propiedades, en la mayoría de los
objetos, esta cadena contiene la ruta del archivo vinculado, seguida de una
exclamación (!) o una barra diagonal inversa (\) y la sintaxis de los datos
vinculados.
TabIndex, TabStop,
Tag, Top
Igual
que para otros controles.
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:
|
Constante |
Valor |
Descripción |
|
vbOLEAutomatic |
0 |
El objeto es actualizado
cada vez que los datos vinculados cambien. Es el valor predeterminado. |
|
vbOLEFrozen |
1 |
El objeto es actualizado
cuando el usuario guarda los datos vinculados desde la aplicación con la que
fueron creados. |
|
vbOLEManual |
2 |
El objeto es solamente
actualizado usando el método Update del control contenedor OLE. |
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.
Visible, WhatsThisHelpID, Width
Igual
que para otros controles.
Close
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:
objeto.CreateEmbed docorigen[, clase]
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.
Antes
de usar este método, se debe establecer la propiedad OLETypeAllowed a 1 (Incrustado) o 2 (Cualquiera). Para ver la lista
de nombres de clases válidos disponibles en el sistema, seleccione la propiedad
Class en la ventana Propiedades y haga clic en el botón Propiedades.
Cuando
se usa el método CreateEmbed para crear un objeto incrustado, no es necesario
definir las propiedades Class y SourceDoc.
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
Crea un
objeto vinculado en un control contenedor OLE a partir del contenido de un archivo.
Su formato es:
objeto.CreateLink docorigen [, elemorigen]
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.
Antes
de usar este método, se debe establecer la propiedad OLETypeAllowed a 0 (Vinculado) o 2 (Cualquiera). Si se especifican
los valores de los argumentos de este método, dichos valores prevalecen sobre
los valores de las propiedades SourceDoc
y SourceItem, que se actualizan
automáticamente.
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.
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)
Si no
se especifica el parámetro verbo, se
ejecuta el verbo predeterminado. El valor de este argumento puede ser uno de
los verbos estándar aceptados por todos los objetos o un índice de la matriz de
propiedades ObjectVerbs.
Si la
propiedad AutoActivate se establece
a 2 (Doble clic), el control contenedor OLE activa automáticamente el objeto
actual cuando el usuario hace doble clic en el control. Cada objeto puede
aceptar su propio juego de verbos. Los verbos estándar (aceptados por todos los
objetos) se enumeran en la siguiente tabla:
|
Constante |
Valor |
Descripción |
|
vbOLEPrimary |
0 |
La acción predeterminada
del objeto. |
|
VbOLEShow |
-1 |
Activa el objeto para
edición. Si la aplicación que ha creado el objeto acepta activación in situ,
el objeto se activa dentro de el control contenedor OLE |
|
vbOLEOpen |
-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. |
|
vbOLEHide |
-3 |
En objetos incrustados,
oculta la aplicación que ha creado el objeto. |
|
vbOLEUIActivate |
-4 |
Si el objeto acepta
activació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. |
|
vbOLEInPlaceActivate |
-5 |
Si el objeto acepta
activació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. |
|
vbOLEDiscardUndoState |
-6 |
Si el objeto acepta
activació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. |
No
todos los verbos de esta tabla pueden enumerados en la matriz de propiedades ObjectVerbs.
Drag
Igual
que para cualquier control que acepte operaciones de arrastrar y soltar (drag
and drop)
FetchVerbs
Actualiza
la lista de verbos aceptados por un objeto. Su formato es:
objeto.FetchVerbs
La
lista actualizada de verbos se puede leer usando la propiedad ObjectVerbs.
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.
Después
de ejecutar el método Paste, la
propiedad OLEType es vbOLELinked (0) o vbOLEEmbedded (1), si no se ha ejecutado el método Paste, la
propiedad OLEType es vbOLENone (3).
Si el
valor de la propiedad PasteOK es
True y Visual Basic no puede pegar el objeto, el control contenedor OLE elimina
cualquier objeto existente en el control.
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.
Si el
valor de la propiedad PasteOK es True y Visual Basic no puede pegar el objeto,
el control contenedor OLE elimina cualquier objeto existente en el control.
ReadFromFile
Carga
un objeto desde un archivo de datos creado mediante el método SaveToFile. Su formato es:
objeto.ReadFromFile numarchivo
donde
numarchivo es el número de un archivo binario abierto por la aplicación.
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
donde
numarchivo es el número de un archivo binario abierto por la aplicación.
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.
Un
objeto guardado en un archivo de datos puede cargarse con el método
ReadFromFile, pero no puede cargarse directamente por la aplicación asociada al
control contenedor OLE (por ejemplo Word no podrá recuperar directamente un
documento guardado con este método, pero desde la aplicación VB se podrá
recuperar con el método ReadFromFile
y tratarlo utilizando Word).
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
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
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.
Cuando
un usuario mueve o ajusta el tamaño de un control contenedor OLE, la aplicación
puede utilizar el evento ObjectMove para determinar si debe cambiar el tamaño y
la posición del control. Si el procedimiento de evento ObjectMove no cambia la
posición o el tamaño del control contenedor OLE, el objeto dentro del control
contenedor OLE vuelve a su posición original y se informa de su nuevo tamaño.
Las coordenadas pasadas como argumentos a este evento incluyen el borde del
control contenedor OLE.
Los
eventos ObjectMove y Resize se desencadenan cuando el control contenedor OLE
recibe información sobre el tamaño del objeto que contiene. Sin embargo, el
evento Resize no recibe información sobre la posición del control. Si el
control contenedor OLE sale del formulario, los argumentos tendrán valores
negativos o positivos que representan la posición del objeto en relación con la
parte superior e izquierda del formulario.
El
formato del procedimiento asociado a este evento es el siguiente:
Private Sub object_ObjectMove(left
As Single, top As Single, width As Single, height As Single)
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.
El
formato del procedimiento asociado a este evento es el siguiente:
Sub
objeto_Updated (código As Integer)
donde
código especifica cómo ha sido actualizado el objeto, puede tomar los
siguientes valores:
|
Constante |
Valor |
Descripción |
|
vbOLEChanged |
0 |
Los datos del objeto han
cambiado. |
|
vbOLESaved |
1 |
Los datos del objeto han
sido guardados por la aplicación que ha creado el objeto. |
|
vbOLEClosed |
2 |
El archivo que contiene
los datos del objeto vinculado ha sido cerrado por la aplicación que ha
creado el objeto. |
|
vbOLERenamed |
3 |
El archivo que contiene los datos del objeto vinculado ha
sido renombrado por la aplicación que ha creado el objeto. |
A estas alturas habremos
notado que cuando tenemos un objeto OLE en un formulario de VB y lo activamos,
nos aparece la barra de menús del objeto dentro del formulario, cuando el
objeto está incrustado; y cuando el objeto OLE deja de estar activo (porque
otro control del formulario pase a ser el control activo) desaparece el menú
del objeto OLE y aparece otra vez el del formulario (si lo tiene, en caso de
que no lo tenga no aparece ningún menú como es de esperar).
Este comportamiento lo
podremos controlar con dos propiedades:
La
propiedad NegotiateMenus de un formulario.
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.
La
propiedad NegotiatePosition de los elementos de un menú de un formulario.
Establece
un valor que determina si los elementos de
nivel superior de un menú se muestran en la barra de menús mientras un
objeto vinculado o incrustado de un formulario está activo y mostrando sus
menús. No está disponible en tiempo de ejecución. Puede tomar los siguientes
valores:
|
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. |
Si
la propiedad NegotiateMenus se establece como False, el valor de la propiedad
NegotiatePosition no tendrá ningún efecto.
Ej:

Fig. 16-8. El objeto incrustado no
está activo

Fig. 16-9. El objeto incrustado está activo.
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; 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).
Consideremos una pequeña
aplicación de prueba, que tiene unas funciones muy básicas:
Cargar
imágenes en una PictureBox o en un objeto OLE, según se haya determinado en la
barra de menús.
Grabar
la imagen del PictureBox o del objeto OLE
Llevar
la imagen del PictureBox al control contenedor OLE y viceversa mediante Drag and Drop
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.

Fig. 16-10. Aplicación de ejemplo.
En el
menú archivo se carga la imagen seleccionada en la lista de ficheros, bien en el
PictureBox o bien en el control OLE, según el formato que se haya elegido en el
menú Formato.
Si se
hace doble click sobre un archivo sucede lo mismo que si se selecciona la
opción Abrir fichero
Mediante
Drag and Drop podemos llevar la
imagen del PictureBox al control OLE (objeto de PaintBrush), donde se puede
modificar el dibujo (edición in-situ), usando las capacidades de PaintBrush y
después volverlo a llevar al PictureBox
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
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
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
Private Sub Drive1_Change()
Dir1.Path = Drive1.Drive
End Sub
Function TrataBarra(ByVal ruta As String, ByVal archivo As String) As
String
If Right(ruta, 1) = "\" Then
TrataBarra = ruta & archivo
Else
TrataBarra = ruta & "\" & archivo
End If
End Function
Private Sub File1_Click()
archivo =
TrataBarra(File1.Path, File1.filename)
End Sub
Private Sub File1_DblClick()
On Error GoTo fin
Picture1.Picture = LoadPicture(archivo)
Exit Sub
fin:
MsgBox Error(Err)
End Sub
Private Sub HScroll1_Change()
OLE1.Left = -HScroll1.Value
OLE1.Width = Abs(OLE1.Left) +
HScroll1.Width
End Sub
Private Sub mnuabrir_Click()
Dim i As Integer
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
Private Sub mnuaole_Click()
If Not mnuaole.Checked Then
mnuaimagen.Checked = False
mnuaole.Checked = True
End If
End Sub
Private Sub mnuaimagen_Click()
If Not mnuaimagen.Checked Then
mnuaole.Checked = False
mnuaimagen.Checked = True
End If
End Sub
Private Sub mnugimagen_Click()
If Not mnugimagen.Checked Then
mnugOLE.Checked = False
mnugimagen.Checked = True
End If
End Sub
Private Sub mnugOLE_Click()
If Not mnugOLE.Checked Then
mnugimagen.Checked = False
mnugOLE.Checked = True
End If
End Sub
Private Sub mnuguardar_Click()
Dim i As Integer
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
Private Sub mnusalir_Click()
Unload Me
End Sub
Private Sub OLE1_DragDrop(Source As Control, X As Single, Y As Single)
If TypeOf Source Is PictureBox Then
OLE1.CreateEmbed
TrataBarra(File1.Path, File1.filename)
End If
End Sub
Private Sub OLE1_Resize(HeightNew As Single, WidthNew As Single)
altura = HeightNew
ancho = WidthNew
VScroll1.Max = altura - OLE1.Height
HScroll1.Max = ancho - OLE1.Width
End Sub
Private Sub Picture1_DragDrop(Source As Control, X As Single, Y As
Single)
Dim alt1 As Long, anc1 As Long
If TypeOf Source Is OLE Then
OLE1.DoVerb (0)
OLE1.Copy
Picture1.Picture = Clipboard.GetData
Picture1.SetFocus
End If
End Sub
Private Sub VScroll1_Change()
OLE1.Top = -VScroll1.Value
OLE1.Height = Abs(OLE1.Top) +
VScroll1.Height
End Sub
Visual
Basic Guía del Estudiante Cap. 16
MULTIMEDIA. REPRODUCCION DE SONIDOS E IMÁGENES
Visual
Basic dispone de un control para aplicaciones multimedia : el Multimedia MCI ó MMControl. (Media Control Interface)
No
está normalmente en la caja de herramientas. Deberá introducirlo desde Proyecto
| Componentes de la barra de menú, y se llama Microsoft Multimedia Control 5.0
(VB5) (MCI32.ocx)
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.
Sintaxis NombredelControlMM.DeviceType = dispositivo$
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
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
Esta
propiedad no es estrictamente necesario establecerla. No será necesario cuando
tenga que ejecutar un fichero y reconozca la extensión de ese fichero como una
extensión asociada a un dispositivo MCI. Será necesario cuando sea la única
forma de saber que dispositivo tiene que abrir. Es necesario por ejemplo en el
caso de CDAudio, pues en este caso
no va a reproducir ningún fichero, sino un disco, y esta es la única forma de
que lo sepa.
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
MMControl.Command = “Eject”
Sin
darnos cuenta hemos hecho un reproductor de CDs.
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.

El
control MCI se llama MMControl1. Vamos a ponerle la propiedad DeviceType como
CDAudio. ¡ Cuidado ! No existe espacio entre CD y Audio. Si lo
pone no funcionará. Lo verá fácilmente pues los botones seguirán desactivados
(tal y como los muestra la figura anterior) Esta propiedad puede cambiarla
marcando el control y pulsando F4, o haciendo click con el botón derecho, y le
aparecerá el típico cuadro de los controles OCX
Todavía
no funciona. Debemos abrir el
control. Podemos hacerlo en el Load del formulario :
Private
Sub Form_Load()
MMControl1.Command
= "Open"
End Sub
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.
Para
qué sirven entonces os comandos anteriores ?
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.

Ya
tenemos un reproductor de CDs personalizado. No es una gran cosa como programa
multimedia pero podrá ilustrarnos para seguir estudiando el control MCI.
Lo
botones Prev, Next, Play, Paus y Stop tiene el siguiente código :
Private
Sub BPrev_Click()
MMControl1.Command
= "Prev"
End
Sub
Private Sub BNext_Click()
MMControl1.Command =
"Next"
End Sub
Private Sub BPlay_Click()
MMControl1.Command =
"Play"
End Sub
Private Sub BPausa_Click()
MMControl1.Command =
"Pause"
End Sub
Private Sub BStop_Click()
MMControl1.Command =
"Stop"
End Sub
El
botón Info devuelve la información
de la pista que hayamos introducido en el TextBox TBTrack, información que le introducimos al control MCI con la
propiedad Track. El resultado se presenta en los labels inferiores.
Private Sub BInfo_Click()
Dim MinutosD As Integer,
SegundosD As Integer, SegunD As Long
Dim MinutosI As Integer,
SegundosI As Integer, SegunI As Long
Dim MinutosDD As Integer,
SegundosDD As Integer, SegunDD As Long
MMControl1.TimeFormat = 0
Ltracks = MMControl1.Tracks
MMControl1.Track =
Val(TBTrack)
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
Veamos las propiedades
usadas en este código :
Tracks Indica el número de pistas (Canciones) de un CD de
audio
Track Especifica la pista acerca de la cual
van a devolver información las
propiedades
TrackLength y TrackPosition. NO indica la pista que se está reproduciendo
actualmente.
TimeFormat Especifica el formato de presentación del
tiempo. Vea la ayuda de esta
propiedad.
En el ejemplo se pone = 0, lo que significa que indicará los tiempos en milésimas
de segundo.
Length Indica
la duración total del CD. (En el formato dispuesto en TimeFormat)
TrackPosition Posición (en tiempo) del
comienzo de la pista (Pista = canción) respecto al
origen del disco.
TrackLength Duración de la pista
Position Posición (en tiempo) de lectura actual
respecto al inicio del disco
Los botones Comienza en y Solo Esta nos ilustran acerca de la propiedades From y To
Private Sub BSoloEsta_Click()
MMControl1.Command =
"Stop"
MMControl1.From =
Val(LTrackPosition)
MMControl1.To =
Val(LTrackPosition) + Val(LTrackLenght)
MMControl1.Command =
"Play"
End Sub
From Especifica el punto (en tiempo)
donde comenzará a ejecutarse el próximo
comando Play .
To Especifica el punto (en tiempo)
donde terminará la ejecución.
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 :
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
Private
Sub BExpulsar_Click()
MMControl1.Command
= "Eject"
End Sub
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?
Podríamos saberlo leyendo la
propiedad CanEject
(Vea Observación al final de las
propiedades CanXxx)
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.
Sintaxis Variable = ControlMM.CanEject
El valor devuelto es True si puede expulsar el disco, y False si no lo puede expulsar.
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.
Sintaxis Variable = ControlMM.CanPlay
Los
valores devueltos son True si puede reproducir, y False si no puede.
El
valor de CanPlay se recupera mediante MCI_GETDEVCAPS durante el procesamiento
de un comando Open.
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.
Sintaxis Variable = ControlMM.CanRecord
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.
Sintaxis Variable =
ControlMM.CanStep
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.
Sintaxis Variable = ControlMM.Mode
Variable
puede tomar uno de estos valores o constantes, dependiendo del estado del
control.
Valor Constante Descripción
524 mciModeNotOpen El dispositivo no está abierto.
525 mciModeStop El
dispositivo está detenido.
526 mciModePlay El
dispositivo está reproduciendo.
527 mciModeRecord El dispositivo está grabando.
528 mciModeSeek El
dispositivo está buscando.
529 mciModePause El
dispositivo está en pausa.
530 mciModeReady El
dispositivo está preparado.
El
tipo de datos para Variable es Long
Podemos
de esta forma averiguar el estado del control MCI antes de efectuar cualquier
operación con él.
Otra
propiedad importante : Wait
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.
Sintaxis ControlMM.Wait = {True | False}
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.
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.
Sintaxis Control.Shareable = {True | False}
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.
Pero continuemos con la
Propiedad DeviceType
Nos
hemos alargado mucho con el valor CDAudio.
Posiblemente porque didácticamente sea la mas divertida. Existen otras y no
menos divertidas. Pero también existen otras que no podemos explicar en este
curso por falta de medios, ya que cada una de estas propiedades exige un
determinado Hardware para que puedan funcionar. El valor CDAudio exigía una tarjeta de sonido y unos altavoces. Hoy casi
todos los PCs lo tienen. El valor DAT
exige tener una unidad de cinta DAT, no muy usual en PCs domésticos o de
enseñanza. Lo mismo podemos decir de DigitalVideo,
MMMovie, Other, Overlay, Scanner, VCR y Videodisc.
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.
Sequencer,
para trabajar con un secuenciador MIDI
WaveAudio.
Para reproducir un fichero de audio en formato .WAW
Realicemos un nuevo ejemplo
para ensayar estos tres valores :

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
Para la reproducción de ficheros de sonido .Wav
Private Sub LElegir_Click()
CD1.Filter = "Ficheros Wav |*.WAV"
CD1.ShowOpen
If CD1.filename <> "" Then
ComboSonidos.AddItem CD1.filename
End If
End Sub
Private Sub
ComboSonidos_Click()
If ComboSonidos.Text <> "" Then
LEjecutar.BackColor = RGB(0,
255, 0)
Else
LEjecutar.BackColor = RGB(255, 0, 0)
End If
End Sub
Private Sub LEjecutar_Click()
If LEjecutar.BackColor = RGB(0, 255, 0) Then
MMControl1.Command = "Open"
MMControl1.DeviceType = "WaveAudio"
MMControl1.filename = ComboSonidos.Text
MMControl1.Wait = True
‘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
Para la reproducción de Avi Vídeo
Private Sub LElegir3_Click()
CD1.Filter = "Ficheros Avi |*.AVI"
CD1.ShowOpen
If CD1.filename <> "" Then
ComboAvis.AddItem CD1.filename
End If
End Sub
Private Sub ComboAvis_Click()
If ComboAvis.Text <> "" Then
LEjecutar3.BackColor =
RGB(0, 255, 0)
Else
LEjecutar3.BackColor = RGB(255, 0, 0)
End If
End Sub
Private Sub LEjecutar3_Click()
If LEjecutar3.BackColor = RGB(0, 255, 0) Then
MMControl1.Command = "Open"
MMControl1.DeviceType = "AviVideo"
MMControl1.filename = ComboAvis.Text
MMControl1.Wait = True
MMControl1.Command = "Play"
MMControl1.Command = "Stop"
MMControl1.Command = "Prev"
End If
End Sub
Para el secuenciador MIDI
Private Sub LElegir2_Click()
CD1.Filter = "Ficheros Mid |*.Mid"
CD1.ShowOpen
If CD1.filename <> "" Then
ComboMidi.AddItem CD1.filename
End If
End Sub
Private Sub ComboMidi_Click()
If ComboMidi.Text <> "" Then
LEjecutar2.BackColor =
RGB(0, 255, 0)
Else
LEjecutar2.BackColor = RGB(255, 0, 0)
End If
End Sub
Private Sub LEjecutar2_Click() ‘GG1 = Control Gauge
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"
'Analiza el estado en el que está el control MCI y lo
pone en la etiqueta LEstado
Select Case MMControl1.Mode
Case 524
LEstado = "No está abierto"
Case 525
LEstado =
"Detenido"
Case 526
LEstado = "Reproduciendo"
Case 527
LEstado = "Grabando"
Case 528
LEstado = "Buscando"
Case 529
LEstado = "Pausa"
Case 530
LEstado = "Preparado"
End Select
On Error Resume Next 'Necesario por si el fichero .Mid es de
longitud 0
MMControl1.TimeFormat = mciFormatMilliseconds
TTotal = MMControl1.Length
LDuracion = TTotal / 1000 & " Seg."
GG1.Max = TTotal / 1000
End If
End Sub
Private Sub LParar_Click()
MMControl1.Command = "Stop"
End Sub
Existe un control Timer (Que
obviamente no se ve en el programa) con este código :
Private Sub Timer1_Timer()
TTransc = (CDbl(MMControl1.Position / 1000))
GG1.Value = TTransc
Select Case MMControl1.Mode
Case 524
LEstado = "No está abierto"
Case 525
LEstado = "Detenido"
Case 526
LEstado = "Reproduciendo"
Case 527
LEstado = "Grabando"
Case 528
LEstado = "Buscando"
Case 529
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)
Espero
que el alumno tenga ya conocimientos suficientes de los comandos de VB para
entender perfectamente este código.
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.
Las APIS de Multimedia
Con
este título genérico parece que se van a explicar todas las Apis aplicables a
multimedia. Y no puede ser así. El tema
sería tan amplio que se saldría del nivel que se quiere dar a esta Guía de
Estudiante.
Ya
se ha citado un libro estupendo acerca de Apis que volvemos a recomendar :
API de Win32 - Guía del programador de
Visual Basic, de Daniel Appleman editado en español por InforBook’s.
(ISBN 84-89700-22-2). Pero el tema de Apis es tan extenso que no puede
abarcarlo todo. Y justamente la parte de multimedia no la toca.
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.
Hecha
esta aclaración continuamos.
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.
Vayamos al módulo con las
declaraciones :
Option Explicit
Declare Function mciExecute
Lib "winmm.dll" (ByVal lpstrCommand As String) As Long
Declare Function mciSendCommand
Lib "winmm.dll" Alias "mciSendCommandA" (ByVal _ wDeviceID
As Long, ByVal uMessage As Long, ByVal dwParam1 As Long, ByVal dwParam2 _ As
Any) As Long
Declare Function mciSendString
Lib "winmm.dll" Alias "mciSendStringA" (ByVal _
lpstrCommand As String, ByVal
lpstrReturnString As String, ByVal uReturnLength As Long, _ ByVal hwndCallback
As Long) As Long
Declare Function sndPlaySound
Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal _
lpszSoundName As String, ByVal uFlags As Long) As Long
Declare Function auxSetVolume
Lib "winmm.dll" (ByVal uDeviceID As Long, ByVal _ dwVolume As Long)
As Long
Declare Function auxGetVolume
Lib "winmm.dll" (ByVal uDeviceID As Long, lpdwVolume _
As Long) As Long
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.
Option Explicit ‘Declaraciones en la sección de
declaraciones
Dim NombreFicheroMIDI As String
Dim NombreFicheroWav As String
Dim VolCDIzd As Long
Dim VolCDDch As Long
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
Private Sub cmdPlay_Click()
Dim Resultado As Long
Resultado =
mciSendString("Open cdaudio alias cd wait", 0&, 0, 0)
‘Al poner alias
cd estamos diciendo que, a partir de ahora, ese dispositivo abierto (el cdaudio)
‘se llama cd, y podemos referirnos a él por ese
nombre a lo largo de toda la aplicación.
Resultado = mciSendString("Play cd", 0&, 0, 0)
‘Aquí le hemos mandado la orden de que se ponga a
ejecutar (Play) el dispositivo cd, que el
‘programa ya sabe que es el cdaudio abierto por la
instrucción anterior.
‘Los parámetros 0&,0,0 son los que completan la
función, que como no los vamos a usar, se
‘ponen a cero (incluso un string 0&)
End Sub
El
procedimiento anterior ejecuta el CD desde el principio. Podemos empezar en un
Track distinto (ojo, aquí un Track no significa una canción, sino una división
del disco que no tiene porqué coincidir con una canción)
Private Sub BPlayCD2_Click()
Dim Resultado As Long
Dim PistaActual As Integer
Resultado =
mciSendString("Open cdaudio alias cd wait", 0&, 0, 0)
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
Mediante este procedimiento, iniciamos
el cd en el Track introducido en TBPista, y se parará en el Track introducido
en TBHasta (Si no le ponemos nada en este TB ejecuta el CD hasta el final.
Para detener la ejecución del CD usamos este
procedimiento :
Private Sub cmdStop_Click()
Dim lRet As Long
lRet =
mciSendString("Stop cd wait", 0&, 0, 0) ‘Primero lo paramos
lRet =
mciSendString("Close cd", 0&, 0, 0) ‘Y cerramos la
sesión
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.
Private Sub BPlayWav_Click()
On Error Resume Next
Dim iResult As Integer
‘Seleccionamos el fichero a reproducir mediante el
CommonDialog CD1
cd1.Filter = "Ficheros Wav |*.Wav"
cd1.ShowOpen
‘NombreFicheroWav se declaró como String en el
formulario.
NombreFicheroWav = cd1.filename
iResult = sndPlaySound(NombreFicheroWav,
0)
‘En el parámetro 0 (uFlags en la declaración),Se
puede poner cualquier número.
End Sub
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)
Otra forma de ejecutar un Wav es mediante la función mciExecute
Private Sub BPlayWav2_Click()
Dim Resultado As Long
cd1.Filter = "Ficheros Wav |*.Wav"
cd1.ShowOpen
NombreFicheroWav = cd1.filename
Resultado = mciExecute("Play
" & NombreFicheroWav)
End Sub
Veamos ahora como podemos
interpretar una secuencia MIDI (Ficheros *.Mid). También con mciExecute
Private Sub
BPlayMIDI_Click()
On Error Resume Next
Dim iResult As Integer
cd1.Filter = "Ficheros Mid |*.Mid"
cd1.ShowOpen
NombreFicheroMIDI =
cd1.filename
‘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)
Private Sub BPararMIDI_Click()
On Error Resume Next
Dim iResult As Integer
iResult = mciExecute("Stop " & NombreFicheroMIDI)
End Sub
Vayamos
ahora al tema del volumen, que afecta solamente al CD, tal como se citó al
comenzar.
Private Sub HScroll1_Change() ‘HSCroll1 es el control de volumen
HScroll2.Max = HScroll1.Value - Int(HScroll1.Value / 10)
HScroll2.Min = -HScroll1.Value + Int(HScroll1.Value / 10)
VolCD ‘VolCD es el procedimiento de cambiar el volumen al
CD
End Sub
Private Sub HScroll2_Change() ‘HScroll2 es el control de Balance
HScroll2.Max = HScroll1.Value - Int(HScroll1.Value / 10)
HScroll2.Min = -HScroll1.Value + 1
VolCD
End Sub
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.
Vayamos
a estudiar la forma de cambiar el volumen.
Lo haremos con la función auxSetVolume.
Esta función controla la entrada auxiliar de audio de la tarjeta de sonido.
Recordemos la declaración de
la función auxSetVolume
Declare Function auxSetVolume
Lib "winmm.dll" (ByVal uDeviceID As Long, ByVal _ dwVolume As Long)
As Long
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.
Como complemento a auxSetVolume tenemos auxGetVolume que nos devuelve el valor
actual del volumen. (No se usa en el ejemplo)
Declare Function auxGetVolume
Lib "winmm.dll" (ByVal uDeviceID As Long, lpdwVolume _
As Long) As Long
Si quisiéramos conocer el
volumen del CD, haríamos un procedimiento parecido a este.
Public Sub VerVolumen
Dim iResult As Long, lpdwVolumen as Long
iResult = auxGetVolume (1,
lpdwVolumen)
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 :
Label1 = Hex(Val(label1) ‘Y
tendría ese dato en hexadecimal, donde ya podrá apreciar
‘la
variación de los dos canales
Vayamos al procedimiento que
cambia el volumen en el ejemplo
Public Sub VolCD() ‘Procedimiento
de cambio de volumen
Dim iResult As Long
Dim L1 As String, L2 As String, L3 As String, L4 As String
If HScroll2.Value < 0 Then
VolCDDch = HScroll1.Value +
HScroll2.Value
Else
VolCDDch = HScroll1.Value
End If
If HScroll2.Value > 0 Then
VolCDIzd = HScroll1.Value -
HScroll2.Value
Else
VolCDIzd = HScroll1.Value
End
If
‘Como el valor máximo de HScroll no puede pasar de
31.000 y pico, y necesitaríamos 65535,
‘se pone como valor máximo esta cantidad dividida por
4. Ahora multiplicamos por 4 para que
‘el valor sea el correcto.
VolCDDch = VolCDDch * 4 - 1
VolCDIzd = VolCDIzd * 4 - 1
L1 = Hex(VolCDDch)
L2 = Hex(VolCDIzd)
‘Las variables L1 y L2 son Strings que
contienen el valor hexadecimal del volumen derecho y
‘del volumen izquierdo. La variable L3,
también String, es la concatenación de L1 y L2
L3 = L1 & L2
‘Y L4 será un String con ese valor hexadecimal
convertido a decimal
L4 = CDec("&H" & L3)
iResult = auxSetVolume(1, Val(L4))
End Sub
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.
Aquí lo dejamos. El alumno tiene en la
multimedia una ventana abierta a la investigación.
Visual Basic - Guía del Estudiante -
Capitulo 17
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.
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.
Cuando
terminamos un programa, lo normal es que no funcione bien. Mucho antes de
terminarlo ya habremos tenido la sorpresa de que Visual Basic ha detectado un
error y detiene la ejecución del programa. Iremos corrigiendo los errores
elementales que van apareciendo, errores de sintaxis, ficheros que ya estaban
abiertos, End If que nos faltaban, etc. Y el programa parece que ya puede
funcionar hasta el final. El programa debe entrar entonces en la fase de
corrección de errores y optimización.
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.
Es
un error de código, por ejemplo, la siguiente línea de programa:
Open A:\MiFicher.Txt For
Input as #1
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:
Open
“A:\MiFicher.Txt” For Input as #1
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.
En
cualquiera de estos dos últimos casos se produce un Error de Ejecución.
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.
No
solamente existen estos errores, también hay errores no catalogados y
aplicables solamente al programador. Piense en un bucle infinito. Un bucle
infinito es una secuencia de instrucciones tal como:
Do While n < 2000
n = n + 1
If n = 1000 then n = 0
Loop
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.
Veamos
lo que dice la ayuda de VB para este tema:
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
Al
objeto Error se le designa por Err
Las
propiedades del Objeto Error son:
Description, HelpContext,
HelpFile, LastDLLError, Number, Source
Propiedad Description
Devuelve
o establece una cadena descriptiva asociada a un error.
Sintaxis Variable = Err.Description
Err.Description = Cadena
descriptiva del error
Veremos
un ejemplo mas adelante.
Propiedad HelpContext
Devuelve
o establece el identificador de contexto de un tema para un archivo de Ayuda de
Microsoft Windows.
Sintaxis Err.HelpContext [= id_contexto]
Variable = Err.HelpContext
Esta
propiedad y la siguiente le permiten presentar automáticamente la ayuda cuando
se produce un error.
Propiedad HelpFile
Devuelve
o establece la ruta completa del archivo de Ayuda de Microsoft Windows que debe
mostrarse al producirse el error.
Sintaxis Err.HelpFile = “C:\MiCarpeta\MiFicherodeAyuda.Hlp”
También
puede leer el valor de esta propiedad:
Variable = Err.HelpFile
Cuando
se especifica un archivo de Ayuda de Microsoft Windows en HelpFile, se le llama
automáticamente cuando el usuario presiona el botón Ayuda (o la tecla F1) del
cuadro de diálogo del mensaje de error. Si la propiedad HelpContext contiene un
identificador de contexto válido para el archivo especificado, se mostrará
automáticamente el tema correspondiente. Si no se especifica nada en HelpFile,
aparecerá el archivo de Ayuda de Visual Basic.
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
¡¡¡ Number es una variable
tipo Long !!!
Sintaxis Variable = Err.Number
Al
ser la propiedad predeterminada, no es necesario poner Number. La siguiente
línea es operativamente igual a la anterior:
Variable = Err
Source
Devuelve
o establece el nombre del objeto o aplicación que ha generado el error
originariamente.
Sintaxis Variable = Err.Source
Err.Source = expresión_cadena
Vea
en la ayuda de VB la explicación (muy ilustrativa) de esta propiedad.
El
Objeto Error tiene solamente dos métodos:
Método Clear
Borra
los valores de todas las propiedades del objeto Err.
Sintaxis Err.Clear
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:
Cualquier tipo de instrucción Resume
Exit
Sub,
Exit Function, Exit Property
Cualquier
instrucción On Error
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.
Sintaxis Err.Raise(Número, Origen, Descripción, ArchivoAyuda, ContextAyuda)
Los
argumentos de Raise se describen a
continuació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.
Control de los errores
Ya
sabemos que herramienta usa Visual Basic para detectar errores. Vamos a ver
ahora como usarla. Pero veamos previamente lo que es en Visual Basic una Rutina. No se extrañe si alguien le llama Label o Etiqueta. En
otros lenguajes se llama así, incluso en Q-Basic, donde no existían los
controles Visual Basic llamados etiquetas, se usaba esta denominación. En
Visual Basic no podemos usarla, para no confundirla con el control.
Una
Rutina es un trozo de código escrito
en un procedimiento, que tiene un nombre. El nombre de la Rutina puede ser
cualquiera, y debe terminar con el carácter dos puntos (:) Por ejemplo:
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:
Private Sub Command1_Click()
If Text1 = "Text1" Then
GoTo Rutina
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.
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.
Sintaxis On Error GoTo Rutina ‘Va a la
Rutina especificada
On Error Resume Next ‘Pasa del error y continúa en la línea siguiente a la
‘que
provocó el error
On Error GoTo 0 ‘Desactiva
todo el tratamiento de errores que haya
‘activado
en el procedimiento actual.
Veamos el ejemplo anterior,
con la instrucción On error GoTo.
Private Sub Command1_Click()
On Error Resume Next
‘Con la línea anterior le
decimos que se olvide del error y siga en la línea siguiente
‘a la que provocó el error
If Text1 = "Text1" Then
GoTo Rutina
Else
On Error GoTo 0
‘La línea anterior desactiva
el tratamiento de errores generado en la línea segunda (On
‘Error Resume Next). Pruebe a
quitar y poner esta línea (On error GoTo 0)
Err.Raise 53
‘En la línea anterior
generamos “artificialmente” el error 53
MsgBox "No pasa por la
Rutina"
Exit Sub
End If
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.
Hagamos un ejemplo donde al
pulsar un botón (Command2) se busca el fichero Mificher.Txt en el disco A: y el
contenido de ese fichero se coloca en Label1
Private Sub Command2_Click()
Dim Variable As String
Open "A:\Mificher.Txt" For Input As #1
Line Input #1, Variable
label1.Caption = Variable
Close #1
End Sub
Si no está metido el disco
en la unidad A nos dará el siguiente error:
Se ha producido el Error ‘71’ de tiempo
de ejecución. El disco no está listo
Si
estuviese metido el disco, pero no tuviera un fichero llamado Mificher.Txt,
daría este error:
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:
Sintaxis Resume [0]
Resume Next
Resume Rutina
Resume [0] Si el error se ha producido en el procedimiento que
contiene el controlador de errores, la ejecución continúa con la instrucción
que lo causó.
Puede
ocurrir que el error no se haya producido en el mismo procedimiento que
contiene la rutina de tratamiento de errores, sino en otro al que se le ha
llamado desde este. En este caso, la ejecución continúa en la instrucción del
procedimiento que contiene la rutina de tratamiento de errores desde la que se
llamó a otro procedimiento.
Resume Next Si el error
se ha producido en el procedimiento que contiene el controlador de errores, la
ejecución continúa con la instrucción inmediatamente posterior a la que lo
causó. Si el error se ha producido en un procedimiento llamado, la ejecución
continúa en la instrucción del procedimiento que contiene la rutina de
tratamiento de errores (o la instrucción On Error Resume Next) inmediatamente
posterior a aquélla desde la que se llamó a otro procedimiento.
Resume Rutina La ejecución
continúa en la rutina citada en la instrucción. La rutina debe encontrarse en
el mismo procedimiento que el controlador de errores.
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:
Private Sub Command2_Click()
On Error GoTo RutinaErrores
Dim Variable As String
Open "A:\Mificher.Txt" For Input As #1
Line Input #1, Variable
Label1.Caption = Variable
Close #1
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
‘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
If Err = 53 Then ‘Aquí hemos puesto
solamente Err
MsgBox "El disco A no
tiene ningún fichero llamado Mificher.Txt. Ponga el disco correcto"
Resume
End If
End Sub
Es
momento ahora de hablar de la ventana de depuración. Esta ventana permite que
Visual Basic se comunique con nosotros en tiempo de ejecución. Es la ventana de
Debug. No está presente normalmente en la pantalla, pero se presenta haciendo
click en Ver | Ventana de Depuración de la barra de menú de Visual Basic. En esta
ventana se presenta lo que escribamos en un objeto preparado para ayudarnos en
la corrección de errores, que se llama precisamente Objeto Debug:
Este
objeto no tiene propiedades y tiene solamente un método: el Método Print
En
esta ventana podemos presentar otro tipo de datos, por ejemplo el valor de una
variable en un determinado momento:
Debug.Print MiVariable
Veremos
en el ejemplo de este capítulo una aplicación de la ventana de depuración que
le dejará claras las ideas.
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:
Debug.Print Err.Number o simplemente
Debug.Print Err
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.
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.
La rapidez se consigue mediante el
programa y con los recursos de la máquina. Para conseguir rapidez en una
aplicación deben tenerse en cuenta estos detalles:
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.
Descargue
los formularios. Si utiliza la expresión FormX.Hide, el formulario queda en
memoria RAM ocupando sitio. Use preferentemente Unload Me con lo que liberará
la memoria que ocupaba ese formulario. No se preocupe si lo tiene que volver a
cargar a lo largo de la evolución del programa. Tarda muy poco.
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.
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.
La
mejor forma de comprobar la calidad de la interfaz es dársela a juzgar al
compañero de trabajo más próximo. No piense nunca que Vd. tiene la verdad
absoluta en este tema. Y no la tiene porque depende del gusto de cada uno.
Debe
poder variar las dimensiones de los formularios dependiendo de la dimensión de
la pantalla (Resolución de la pantalla). Puede hallar la resolución actual de
la pantalla mediante APIs
Dim
ancho As Integer, alto As Integer
ancho
= GetDeviceCaps(Me.hdc, 8)
alto
= GetDeviceCaps(Me.hdc, 10)
Una
vez conocido el ancho de la pantalla, reorganice las medidas de cada control:
If ancho = 1024 Then
With CBP1L1
.Left = 120
.Width = 2412
End With
With CBP1L2
.Left = 2640
.Width = 2292
End
With
No
tiene necesidad de complicarse la vida con APIs. Puede hallar el ancho de su
pantalla mediante el objeto Screen
Ancho =
Screen.Width Alto =
Screen.Height
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.
Facilidad de programación de parámetros
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 inicialización se ejecuta en el Load del formulario Inicial, si va a marcar
los parámetros de partida del programa, o puede leerse en cualquier parte del
programa para introducir datos a una parte del mismo. Un fichero de inicialización clásico es el que
pone el título (Caption del formulario principal) al programa, le dice en qué
carpeta está y como se llama el fichero de ayuda, carpeta donde están los
archivos o las bases de datos del programa, etc. Mediante estos ficheros puede
usar el mismo programa para clientes distintos, y personalizárselo en su
domicilio mediante estos ficheros.
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:
////////////////////////////////////////////////////////////////////////////////////////////////////// Siempre debe estar bien
//
// indicado en su
cabecera
// FICHERO DE INICIALIZACION DEL PROGRAMA
PEPE //
// //
//////////////////////////////////////////////////////////////////////////////////////////////////////
[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.
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
Public Sub LeeDatos()
Dim LineaEntrada As String, TipoDatos As Byte
Open App.Path & "\MisDatos.Ini" For
Input As #1
Do Until EOF(1)
Line
Input #1, LineaEntrada
If
LineaEntrada = "[TITULO]" Then TipoDatos = 1: GoTo Termina
If
LineaEntrada = "[BASEDATOS]" Then TipoDatos = 2: GoTo Termina
If
LineaEntrada = "[USUARIOS]" Then TipoDatos = 3: GoTo Termina
If
LineaEntrada = "[TECNICOS]" Then TipoDatos = 4: GoTo Termina
If
LineaEntrada = "[BASECLIENTES]" Then TipoDatos = 5: GoTo Termina
If
LineaEntrada = "[FIN DATOS]" Then TipoDatos = 0: GoTo Termina
If Ucase(Trim(Left(LineaEntrada, 3))) =
"REM" Then GoTo Termina
‘La
línea anterior quita los datos de las líneas que comiencen por REM. Observe que
se
‘han
tomado todas las seguridades para aceptar mayúsculas y minúsculas (Ucase) y
‘que
lleven espacios iniciales (Trim)
Select Case TipoDatos
Case 1
Me.Caption = LineaEntrada
Case
2
BaseDatos1 = LineaEntrada
Case 3
ComboUsuarios.AddItem LineaEntrada
Case
4
ComboTecnicos.AddItem LineaEntrada
Case
5
BaseDatos2 = LineaEntrada
End
Select
Termina: 'Esta
rutina no contiene código. Solamente se usa para
'dirigir
la ejecución del programa a este punto desde
'las
líneas iniciales y evitar que pase por el Select Case
Loop
Close #1
End Sub
Al
terminar la ejecución de este procedimiento, tenemos, en la barra de título del
programa, la línea Talleres Pepe.
Programa de Recepción de Vehículos para Reparar, en las variables BaseDatos
1 y 2 los nombres (y Path) de las dos bases de datos, y en los ComboBox
ComboUsuarios y ComboTecnicos, los nombres indicados en el fichero de datos. Ya
tenemos esos datos disponibles en nuestra aplicación para lo que haga falta. Es
decir, hemos personalizado la aplicación mediante un fichero de inicialización.
DISTRIBUCION DE APLICACIONES
Una
vez terminado un programa y realizado su correspondiente ejecutable (Fichero
.EXE), observaremos con gran asombro que si copiamos ese ejecutable en otro
ordenador, lo mas probable es que no funcione. Esto es Visual Basic.
La
razón para que no funcione es que un programa realizado en VB necesita,
lógicamente, el ejecutable, y además, todas las DLLs y OCX (que contienen los controles y las funciones
usadas en el diseño) que están asociadas al programa. Esto implica que un
programa VB no es un programa compacto, sino que está formado por varios
ficheros, que deben montarse en el ordenador destino de nuestra aplicación.
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
Se deben quitar de la caja de herramientas
todos los controles no usados en la aplicación.
Por
el mismo motivo, se deben quitar todas
las Referencias no necesarias.
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.

Pantalla
Inicial del Asistente para Instalar Aplicaciones.
Una
vez elegido el proyecto a distribuir, haga click en Siguiente
A
continuación le pregunta si quiere distribuir alguno de los motores de bases de
datos. Lo veremos mas adelante. Si hubiese empleado alguna base de datos ya le
sale marcado el motor correspondiente. Haga click en Siguiente.
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
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=
; Puede eliminar las siguientes líneas para
obtener espacio adicional
; para personalizar este archivo en un disco
de instalación completa.
;
;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Analicemos
el contenido del fichero.
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
Sigamos
por atrás.
[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
De
cualquier forma, a la hora de realizar la instalación, puede cambiar este
directorio. No es necesario que exista el directorio indicado aquí. Si ni
existe, lo crea.
La
línea Setup indica el fichero que le va a ejecutar la instalación. No la toque.
App.Exe
es el nombre del ejecutable. No lo cambie.
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.
Imprima
y encuaderne estos 18 capítulos. Recuerde que es IMPOSIBLE estudiar sobre la
pantalla del ordenador. Es imprescindible imprimirlos. Y también
encuadernarlos. El orden siempre ha ayudado a estudiar
Visual
Basic - Guía del Estudiante Cap. 18
BASES DE DATOS EN VISUAL BASIC (1)
Visual Basic nos permite trabajar
directamente con distintas bases de datos (ACCESS, dBaseIII, dBaseIV , dBase
5, Excel3, Excel4, Excel5, Excel7, FoxPro2.x, Foxpro3.0, LotusWK1, LotusWK3,
LotusWk4, Paradox3.x, Paradox4.x y
Paradox5.x
Para acceder a estas Bases de Datos basta
con introducir un control Data en el formulario, y fijarle las propiedades
apropiadas para que trabaje sobre uno u otro tipo de base de datos. El control
Data nos permite acceder de una forma sencilla a cualquier base de datos de
estos tipos, y sirve de enlace entre la base de datos y los controles que son
habilitados para presentar los datos de esa base.
El
Control Data
El control Data puede tomarse
directamente de la caja de herramientas. En el formulario tiene el aspecto de
una barra deslizante :

El control Data proporciona acceso a
datos almacenados en bases de datos usando uno de los tres tipos de objetos Recordset. El control Data le permite
ir de registro en registro y presentar y manipular los datos de los en
controles enlazados. Sin un control Data, los controles enlazados con datos de un formulario no pueden tener
acceso automáticamente a los datos.
Los controles
enlazados solamente pueden tener acceso a un control Data si este está en el mismo Formulario.
En el tema de Bases de Datos se emplean
términos no conocidos aún. Se irán viendo a lo largo del curso, pero no queda
otro remedio mas que comenzar a utilizarlos. Se irán haciendo avances de estos
términos, que serán explicados en profundidad en su momento.
Avance de
los términos empleados :
Objeto Recordset (conjunto de registros)
Es
un conjunto lógico de registros. Los tres tipos de objetos Recordset son dynaset, (Permite la lectura y
escritura de un registro) snapshot (Realiza una lectura instantánea de los
registros, no permitiendo modificarlos) y table. (Representación en el código de una tabla
base que puede utilizarse para agregar, modificar o eliminar registros de una
sola tabla).
Controles enlazados
Son
los controles que pueden presentar directamente datos de uno o varios campos de
una Base de Datos. Los controles DBList, DBCombo y DBGrid tienen la posibilidad
de presentar un conjunto de registros cuando se asocian con un control Data.
Los controles CheckBox, TextBox, Label, Picture, Image, ListBox y ComboBox
también son controles enlazados con datos y pueden asociarse a un único campo
de un Recordset administrado por un control Data.
La mayoría de las operaciones de acceso a
datos se pueden realizar usando el control Data sin escribir ningún código. Los
controles enlazados con un control Data presentan de forma automática los datos
de uno o más campos del registro actual o, en algunos casos, de un conjunto de
registros a ambos lados del registro
actual. El control Data realiza todas las operaciones sobre el registro actual.
Avance
de términos
Registro Actual. Un
registro es un conjunto completo de campos. Una base puede tener muchos
registros, pero el “puntero” de la base de datos apunta a un único registro en
cada momento. Ese registro al que apunta el puntero se llama registro actual.
Si el control Data recibe instrucciones
de moverse a un registro diferente, todos los controles enlazados pasan
automáticamente los cambios al control Data para ser guardados en la base de
datos. El control Data se sitúa después en el registro requerido y pasa los
datos del registro actual a los controles enlazados donde son presentados. Esto
significa que se pueden modificar los datos de una base de datos simplemente
cambiando los datos en los controles enlazados que lo permitan, y moviendo el
puntero de la base de datos, es decir, cambiando el registro actual.
Una vez iniciada la aplicación, Visual
Basic usa las propiedades del control Data para abrir la base de datos
seleccionada, abrir un objeto Database y crear un objeto Recordset. Las
propiedades Database y Recordset del control Data hacen referencia a los
objetos Database y Recordset recién creados que pueden ser manipulados por el
control Data. Siempre podremos conocer el Recordset usado por el control Data
leyendo esa propiedad
VariabletipoRecordset
=Data1.Recordset
Cuando se usa un control Data para crear
un objeto Recordset o cuando se crea un objeto Recordset en el código y se
asigna al control Data, el motor de base de datos Jet de Microsoft puebla
automáticamente el objeto Recordset. Como resultado, los marcadores (y en los
objetos Recordset de tipo snapshot, los datos del conjunto de registros) se
guardan en la memoria local; el usuario no necesita manipular el control Data y
no es necesario invocar el método MoveLast en el código. Los bloqueos de página
usados para crear el Recordset se liberan más rápidamente, haciendo posible que
otros objetos Recordset accedan a los mismos datos. Los objetos Recordset
creados en el código pero que no se asignan a un control Data no son poblados
automáticamente por el motor Jet. Se deben poblar desde el código.
El párrafo
anterior exige al menos una explicación.
Cuando
se crea un Recordset mediante un control Data, se leen inmediatamente todos los
registros que forman parte de ese Recordset (Recuerde que un Recordset es un
conjunto de registros). De esta forma, en una base que estuviera compartida por
varios usuarios a través de una Red de Area Local (RAL) un usuario leería todos
los datos en el mismo momento de la creación del Recordset por el control Data,
llevaría esos datos a su memoria RAM y no volvería a estorbar en la base de
datos (cuando un usuario de una RAL lee un dato en una BD, bloquea esta BD
mientras dura su lectura y no pueden acceder a ella otros usuarios) Si el
Recordset se crea por código, se lee solamente un registro (la base se bloquea
en el momento de la lectura e inmediatamente se libera), y cuando se le pide
otra operación (p.e. que avance un registro) vuelve a bloquear la BD, lee ese
registro y la desbloquea. En principio el leer el Recordset de una vez parece
que tiene ventajas en aquellas instalaciones que tienen una base de datos
compartida. Todo ello a un precio. Ocupar mas memoria RAM en cada uno de los
PCs de los usuarios. Esta limitación hace en algún caso que no sea posible
utilizar un control Data por falta de memoria RAM en los puestos de usuario.
El control Data puede manipularse con el
mouse, moviéndose de registro en registro o al principio o al final del
Recordset. El control Data no permite que el usuario se pase de los límites del
Recordset usando el mouse. No se puede mover el enfoque al control Data.
Observación
muy importante
El control Data crea un objeto Database y
un objeto Recordset automáticamente. Estos objetos de acceso a datos son
idénticos a los creados mediante código, y tienen las mismas propiedades y
métodos. Podemos referirnos a ellos usando el nombre del control Data seguido
del nombre del objeto (Database o Recordset). Por ejemplo :
Data1.Database Data1.Recordset
El objeto Database creado por un control
Data no se cierra aunque se cambie la propiedad DatabaseName del control Data.
Lo mismo ocurre con el objeto Recordset. Solamente podemos cerrarlos utilizando
el método Close :
Data1.Database.Close Data1.Recordset.Close
Esta observación debe ser tenida muy en
cuenta sobre todo cuando la el control Data abre la Base de Datos de forma
exclusiva, o cuando tenemos que hacer una operación con la Base de Datos que
exija que esté cerrada. Por ejemplo, el método CompactDatabase y otros métodos que veremos mas adelante.
Objetos para
acceso a datos
Los objetos para acceso a datos Database y Recordset creados por el control Data pueden usarse en los procedimientos. Los objetos Database y Recordset tienen cada uno sus propiedades y métodos propios y se
pueden escribir procedimientos que usen estas propiedades y métodos para
manipular los datos.
Por ejemplo, el método MoveNext de un objeto Recordset mueve
el registro actual al siguiente registro del Recordset. Para invocar este
método, se podría usar el siguiente código:
Data1.Recordset.MoveNext
El control Data tiene la capacidad de
tener acceso a cualquiera de los tres tipos de objetos Recordset del motor Jet
versión 2.0. Si no se selecciona el tipo de conjunto de registros, se crea un
Recordset de tipo Dynaset.
Nota. Las constantes usadas para requerir
un tipo específico de Recordset cuando se usa un control Data son diferentes de
las constantes usadas para determinar el tipo de Recordset creado o que se va
crear usando el método OpenRecordset.
Para seleccionar un tipo específico de Recordset, establezca la propiedad RecordsetType del control Data a:
Tipo de Recordset Valor Constante control Data Constante OpenRecordset
Table 0 vbRSTypeTable dbOpenTable
Dynaset 1 vbRSTypeDynaset dbOpenDynaset
Snapshot 2 vbRSTypeSnapshot dbOpenSnapshot
Diferencias entre la Edición Standard y la Edición
Profesional de Visual Basic
En cuanto al acceso a datos, la
diferencia principal entre las ediciones Estándar y la Profesional de Visual
Basic es la capacidad de crear nuevos objetos para acceso a datos. En la
edición Estándar NO se pueden
declarar en el código (con la palabra clave Dim) variables como objetos para
acceso a datos. Esto quiere decir que sólo el control Data puede crear objetos
Database y Recordset.
En la edición Profesional de Visual Basic, SI se puede crear un nuevo objeto
Recordset y asignarlo a la propiedad Recordset del control Data. Todos los
controles enlazados conectados con el control Data permiten la manipulación de
los registros del Recordset creado. Asegúrese de que las propiedades DataField
de los controles enlazados están definidas con nombres de campo válidos del
nuevo Recordset.
¡Esta diferencia ha llevado a la locura a muchos
alumnos y programadores usando la versión de su casa y la de su empresa o centro
escolar !
Consultas
almacenadas
Otra opción importante cuando se usa el
control Data es la posibilidad de ejecutar consultas almacenadas. Si se ha
creado previamente un objeto QueryDef,
(No se asuste, Un QueryDef no es ni mas ni menos que una consulta en la base de
datos ACCES) el control Data puede ejecutarlo y crear un Recordset usando las
propiedades almacenadas SQL, Connect y otras del objeto QueryDef. Para ejecutar
un QueryDef, establezca la propiedad RecordSource del control Data al nombre del
objeto QueryDef (En vez de poner el
nombre de una tabla, ponga el nombre de la consulta. Cuando está rellenando
esta propiedad, le aparecen, al mismo tiempo que el nombre de las tablas, el
nombre de las consultas existentes).
Si el objeto QueryDef almacenado contiene
parámetros, es necesario crear el Recordset y pasárselo al control Data.
Es mucho mas rápida una consulta
utilizando un QueryDef que
introduciendo la consulta SQL. La razón es muy sencilla. Al crear un QueryDef
(Ya verá como) el motor Jet (Es decir ACCESS) crea esa consulta en la propia
base de datos. Si lo que hace es una consulta SQL, se debe obtener la
información registro a registro según las condiciones establecidas en la
cláusula SQL. Esta segunda opción tarda logicamente mas.
Administración
de BOF/EOF
BOF (Begin Of File). Se produce el BOF cuando el control Data se posiciona sobre el registro
inmediatamente anterior al primero (No es un juego de palabras). Este registro
será el -1.
EOF
(End Of File) Se produce la
condición EOF cuando el control Data se posiciona en el registro inmediatamente
posterior al último. Este registro será también el -1.
El control Data también puede controlar
la situación en la que se encuentra con objetos Recordset sin registros.
Cambiando la propiedad EOFAction, se
puede programar el control Data para que pase automáticamente al modo AddNew.
El control Data puede programarse para
que se ajuste automáticamente a la parte superior o inferior de su formulario
primario usando la propiedad Align.
En cualquier caso, el control Data ajusta su tamaño horizontal al de su
formulario primario cuando el tamaño de éste cambia. Esta propiedad permite
situar un control Data en un
formulario MDI sin requerir un
control Picture que lo contenga.
Propiedades
del control Data
Align El hecho de
que tenga esta propiedad nos permite colocar un control Data en un formulario MDI hijo.
Appearance Flat y 3-D
Backcolor Color
de fondo de la parte intermedia del control
BOFAction
Esta propiedad establece el comportamiento del Control Data
cuando tiene seleccionado como registro actual el registro -1 (los registros
van del 0 a un número positivo). Esta situación se da cuando se va bajando el
número del registro actual mediante el método MovePrevious y nos pasamos
del registro 0, o cuando el Recordset no tiene ningún registro. En esta
propiedad podemos establecer que se mueva al primer registro (MoveFirst)
o que se quede donde está (BOF Begin Of File).
Caption
El nombre que figurará en la parte intermedia del control.
Connect Muy
Importante. En esta propiedad debemos indicarle al control Data el tipo de base
de datos a la que va a conectarse. Admite todas las bases enumeradas al
principio de este capítulo.
DatabaseName En esta
propiedad se le indica el nombre (Con su Path) de la base de datos a la que
debe conectarse. Para facilitar la búsqueda de la base de datos, haciendo click
en esta propiedad en la caja de propiedades, podemos sacar un cuadro de diálogo
haciendo click de nuevo en los tres puntos que aparecen a la derecha de la
propiedad. El cuadro de diálogo
seleccionará directamente las extensiones de los ficheros de bases de datos
acordes con el tipo de base de datos seleccionada en la propiedad Connect.
Database (Solo
en ejecución)
Esta propiedad es sólo de lectura.
Devuelve una referencia a un objeto Database subyacente de un control Data.
Sintaxis Variable = nombredelcontroldata.Database
El objeto Database creado por el control
Data se basa en las propiedades DatabaseName, Exclusive, ReadOnly y Connect del
control.
Los objetos Database tienen propiedades y
métodos que puede utilizar para administrar los datos. Puede utilizar cualquier
método de un objeto Database con la propiedad Database de un control Data, como
Close y Execute. También puede examinar la estructura interna de la Database
empleando su colección TableDefs y, a su vez, las colecciones Fields e Indexes
de objetos TableDef individuales.
Aunque puede crear un objeto Recordset
y pasarlo a la propiedad Recordset de un control Data, no puede abrir una base
de datos y pasar el objeto Database recién creado a la propiedad Database del
control Data.
DragIcon, DragMode
, Enabled Igual que todos los controles.
EditMode
Solo lectura. Devuelve un valor que
indica el estado de modificación del registro actual.
Sintaxis Variable = objeto.EditMode
Variable tomará uno de los siguientes
valores :
dbEditNone No se está realizando ninguna operación de modificación.
dbEditInProgress Se ha invocado el método Edit y el registro actual se encuentra
en el
búfer
de copia.
dbEditAdd Se
ha invocado el método AddNew y el registro actual del búfer de
copia es un
registro nuevo que aún no se ha guardado en la base de datos.
La propiedad EditMode es especialmente útil cuando se desea partir de la
funcionalidad predeterminada de un control Data, o cuando no se utiliza un
control Data en Visual Basic Edición profesional. Puede comprobar el valor de
la propiedad EditMode y el del
parámetro acción del procedimiento del evento Validate para determinar si se
debe invocar el método Update.
También puede comprobar si el valor de la
propiedad LockEdits es True y el de EditMode es dbEditInProgress para
determinar si la página de datos actual se encuentra bloqueada.
EOFAction Establece
el comportamiento del control Data
cuando se sobrepasa el último registro. Podemos indicarle que se mueva al
último registro (MoveLast), que se
quede donde está (EOF), o que
introduzca un nuevo registro (AddNew)
Exclusive Devuelve o
establece un valor (True / False) que indica si la base de datos está abierta
para acceso de un único usuario o de múltiples usuarios.
Font, ForeColor,
Height, Index, Left, MouseIcon, MousePointer, Name,
igual que el resto de los controles.
Negotiate Propiedad característica de los controles que tienen
la propiedad Align. Establece un
valor que determina si se muestra un control que puede alinearse cuando un
objeto activo del formulario muestra una o más barras de herramientas. No está
disponible en tiempo de ejecución.
Options Devuelve
o establece un valor que especifica una o más características del objeto
Recordset de la propiedad Recordset del control Data. Puede ponerse en el
cuadro de propiedades o en tiempo de ejecución. Puede tomar los siguientes
valores o nombres de constantes (estos nombres solo si los introduce en tiempo
de ejecución)
1 dbDenyWrite En un entorno multiusuario, otros usuarios no
pueden realizar
cambios
en registros del Recordset.
2 dbDenyRead En un entorno multiusuario, otros usuarios no pueden
leer
registros
(sólo Recordset de tipo tabla).
4 dbReadOnly No se pueden realizar cambios en registros del
Recordset.
8 dbAppendOnly Puede agregar nuevos registros al Recordset, pero no puede
leer
los registros existentes.
16 dbInconsistent Las actualizaciones pueden aplicarse a todos los campos del
Recordset,
aunque infrinjan la condición de unión.
32 dbConsistent (Predeterminado) Las actualizaciones sólo se
aplican a los
campos
que no infringen la condición de unión.
64 dbSQLPassThrough Cuando se utilizan controles Data con una instrucción SQL en
la propiedad
RecordSource, envía la instrucción SQL a una base de datos ODBC, como SQL
Server o Oracle, para su procesamiento.
256 dbForwardOnly El Recordset es un desplazamiento sólo hacia adelante. El
único método de
movimiento permitido es MoveNext. Esta opción no puede utilizarse en objetos
Recordset manipulados con el control Data.
512 dbSeeChanges Genera un
error interceptable si otro usuario está cambiando
datos
que usted edita.
Para establecer mas de un valor de los
descritos, basta con sumar sus valores. También puede establecer más de un valor para esta propiedad, combinando
opciones sumando valores entre sí. Por ejemplo, para establecer dbReadOnly y dbInconsistent puede utilizar este código:
Data1.Options
= dbAppendOnly + dbInconsistent
Para determinar si la propiedad contiene
un valor específico, puede utilizar el operador And. Por ejemplo, para
averiguar si el Recordset está abierto para acceso de sólo lectura, podría usar
este código:
If Data1.Options And dbReadOnly Then...
Si cambia la propiedad Options en tiempo de ejecución, deberá
utilizar el método Refresh para que
el cambio sea efectivo.
ReadOnly Devuelve o
establece un valor que determina si la Database del control está abierta para
acceso de sólo lectura.
RecordsetType
Devuelve o establece un valor que indica
el tipo de objeto Recordset que desea que cree el control Data.
Los valores o nombre de la constante que
puede adoptar son los siguientes:
0 vbRSTypeTable Un Recordset de tipo tabla.
1 vbRSTypeDynaset (Predeterminado) Un Recordset de tipo hoja de respuestas
dinámica.
2 vbRSTypeSnapshot Un Recordset de tipo instantánea.
Si no especifica un RecordsetType antes de que el control Data cree el Recordset, se
creará un Recordset de tipo hoja de respuestas dinámica. (Dynaset)
Recordset
Devuelve o establece un objeto Recordset
definido por las propiedades de un control Data o por un objeto Recordset
existente.
Veremos mas adelante las propiedades de un
objeto Recordset, propiedades que son en todo aplicables al Recordset del
control Data.
El Recordset es como se adelantó, un
conjunto de registros. Si las propiedades Connect, DatabaseName, Options,
RecordSource, Exclusive, ReadOnly y RecordsetType establecidas para el control
Data son válidas, se crea un Recordset automáticamente basándose en dichas
propiedades. Ese será el Recordset del control Data. Pero también puede crearse
previamente un Recordset mediante la instrucción OpenRecordset y forzar que el
Recordset del control Data sea justamente ese mediante la instrucción Set
Data1.Recordset = MiRecordset
Sea cual fuera la forma de crearlo, a
partir del momento en que el Data tenga su Recordset podemos referirnos a él,
por ejemplo para ir al primer registro (Data1.Recordset.MoveFirst), avanzar un
registro (Data1.Recordset.MoveNext), al
anterior (Data1.Recordset.MovePrevious)
ir al último (Data1.Recordset.MoveLast),
añadir un registro (Data1.Recordset.AddNew), guardar los cambios en la Base de
Datos (Data1.Recordset.Update), o borrar el registro actual
(Data1.Recordset.Delete)
Si se cambia alguna de las propiedades
citadas al principio que cambien el Recordset, es necesario volver a crearlo.
Para ello basta con utilizar el Método Refresh. (Data1.Refresh)
RecordSource
Devuelve o establece la tabla, el objeto
QueryDef (Consulta) o la instrucción SQL subyacente para un control Data. Esta
propiedad puede fijarse en el cuadro de propiedades del control data, (el caso
mas usado) o introducirse como código. En los dos primeros casos, lo normal es
introducir el nombre de una tabla o una consulta de las existentes en la base
de datos especificada en la propiedad DatabaseName, nombres que se pueden
elegir desplegando la lista que se obtiene haciendo click sobre la flecha que
aparece al lado de la casilla de esta propiedad. Observe que en la lista
desplegada figuran los nombres de las tablas y de las consultas que tiene la
Base de Datos elegida en la propiedad DatabaseName. Ni que decir tiene que para
poder introducirla de esta forma es necesario fijar previamente la propiedad
DatabaseName.
Puede introducirse en tiempo de ejecución
mediante código con la siguiente expresión :
objeto.RecordSource [= valor ]
Donde objeto
es el nombre del control Data, y valor
es una expresión de cadena que especifica el nombre de una Tabla o una Consulta, de
las que componen la base de datos especificada en la propiedad DatabaseName, o
una consulta SQL válida que utiliza sintaxis apropiada para la base de datos
especificada en la propiedad DatabaseName, o una QueryDef, que es una consulta
almacenada, que como en los casos anteriores, debe referirse a la base de datos
especificada en la propiedad DatabaseName.
La propiedad RecordSource especifica el origen de los recursos accesibles a
través de controles enlazados del formulario. Si establece la propiedad RecordSource como el nombre de una
tabla existente en la base de datos, todos los campos de esa tabla serán
visibles a los controles enlazados adjuntos a este control Data. El orden de
los registros recuperados lo establece el objeto Index que selecciona mediante
la propiedad Index del Recordset. Si no establece la propiedad Index, los datos
se devolverán sin ningún orden concreto.
Si establece la propiedad RecordSource como el nombre de una
consulta (QueryDef) existente en la base de datos, todos los campos devueltos
por la QueryDef serán visibles a los controles enlazados adjuntos al control
Data. El orden de los registros recuperados lo establece la consulta del objeto
QueryDef. Si la QueryDef no especifica un orden, los datos se devolverán sin
ningún orden concreto.
Si establece la propiedad RecordSource como una instrucción SQL
que devuelve registros, todos los campos devueltos por la consulta a SQL serán
visibles a los controles enlazados adjuntos al control Data. Esta instrucción
puede incluir una cláusula ORDER BY para cambiar el orden de los registros
devueltos por el Recordset creado por el control Data o una cláusula WHERE para
filtrar los registros.
Después de cambiar el valor de la
propiedad RecordSource en tiempo de
ejecución, deberá utilizar el método Refresh
para activar el cambio.
Nota. Asegúrese de que cada control enlazado tiene un
valor válido para su propiedad DataField.
Si cambia el valor de la propiedad RecordSource
de un control Data y, a continuación, utiliza Refresh, el Recordset identificará el nuevo objeto. Esto puede
invalidar los valores de DataField
de controles enlazados y producir un error interceptable.
Las Propiedades Tag, Top, Visible, WhatThisHelpID, Width,
igual que el resto de los controles.
METODOS
DEL CONTROL DATA
(Se explican aquí los métodos que inciden directamente en el
tratamiento de bases de datos. Obviamos los métodos Drag, Move y ZOrder que son
idénticos a los del resto de controles)
Método
Refresh
De momento es aplicable al control Data.
Veremos que también es aplicable a otros objetos de acceso a datos (QueryDef). El
método Refresh no puede utilizarse con colecciones que no sean persistentes,
como Databases, Recordsets o Workspaces.
Actualiza los objetos de una colección
para reflejar la base de datos actual. El método Refresh también se utiliza
para cerrar y volver a generar el objeto Recordset o las estructuras de datos
creadas por un control Data.
Sintaxis nombredelcontrolData.Refresh
Debe utilizar el método Refresh en los entornos multiusuario en
los que otros usuarios puedan modificar la base de datos. También puede ser
necesario su uso en las colecciones afectadas de forma indirecta por los
cambios en la base de datos.
Puede utilizar el método Refresh sobre un control Data para
abrir o reabrir la base de datos (si han variado las propiedades DatabaseName,
ReadOnly, Exclusive o Connect) y volver a generar el objeto Recordset indicado
por la propiedad Recordset del control.
Método UpdateControls
Obtiene el registro actual del objeto
Recordset de un control Data y muestra los datos de los controles vinculados al
control Data.
Sintaxis nombredelcontroldata.UpdateControls
Utilice este método para restablecer en
los controles enlazados sus valores originales, por ejemplo cuando un usuario
modifica los datos y luego decide cancelar los cambios.
Este método produce el mismo efecto que
hacer actual de nuevo al registro actual, excepto en que no se produce ningún
evento ni introduce en la Base de Datos los posibles valores que se hubiesen
cambiado en los controles enlazados.
Método UpdateRecord
Guarda los valores actuales de los
controles enlazados.
Sintaxis nombredelcontrolData.UpdateRecord
Puede utilizar este método para guardar
el contenido actual de los controles enlazados en la base de datos durante el
evento Validate sin desencadenar de nuevo el evento Validate. El uso de este
método evita los eventos en cascada.
El método UpdateRecord tiene el mismo efecto que ejecutar el método Edit, modificar un campo y luego
ejecutar el método Update, excepto
en que no se produce ningún evento.
Puede utilizar este método para evitar
desencadenar el evento Validate.
En algunos casos, la actualización puede
no tener lugar, debido a que la operación vulnere las restricciones de
integridad referencial, o que la página que contiene el registro esté
bloqueada, o que la base de datos u objeto Recordset no sean actualizables, o a
que el usuario no cuente con el permiso adecuado para la operación. En
cualquiera de estas circunstancias, se producirá un error interceptable.
Estos son los métodos del Control Data.
Este control tiene su Recordset, y el Recordset del control Data tiene sus
métodos, idénticos a los de un Recordset creado por código.
EVENTOS
DEL CONTROL DATA
Error
Se produce solamente como resultado de un
error de acceso a datos que tiene lugar cuando no está ejecutando código Visual
Basic.
Private Sub Data1_Error ([índice As Integer,] datoserr As Integer, respuesta
As Integer)
índice es el índice de ese control si existen varios con el
mismo nombre
datoserr es el número del error.
Respuesta es un número que se corresponde con la respuesta que
se va a tomar, como se describe a continuación :
Constante Valor Descripción
0 vbDataErrContinue Continuar.
1 vbDataErrDisplay (Predeterminado) Presentar el mensaje de
error.
Normalmente las aplicaciones proporcionan
la funcionalidad del control de los errores de tiempo de ejecución dentro del
código. Sin embargo, los errores de
tiempo de ejecución pueden ocurrir cuando no se está ejecutando código de la
aplicación, por ejemplo cuando:
Un usuario hace clic en un botón del
control Data.
El control Data abre automáticamente una
base de datos y carga un objeto Recordset después de un evento Form_Load.
Un control personalizado ejecuta una
operación como los métodos MoveNext, AddNew o Delete.
Si se produce un error en cualquiera de
estas acciones, se produce el evento Error.
Si no se escribe código para el
procedimiento de evento Error,
Visual Basic presenta el mensaje asociado con el error.
Reposition
Se produce después de que un registro se
convierte en el registro actual.
Private
Sub Objeto_Reposition()
Donde
objeto = Nombre del control Data
Cuando se carga un control Data, El
primer registro de su objeto Recordset se convierte en el registro actual,
provocando el evento Reposition. Cuando quiera que un usuario haga clic en
uno de los botones del control Data, moviéndose de registro en registro o si se
usa uno de los métodos Move del objeto Recordset asociado al control data, como
MoveNext, MoveFirst, MovePrevious, los métodos Find, como FindFirst,
FindNext, o cualquier otra propiedad o
método que cambie el registro el actual, se produce el evento Reposition después de que cada registro
se convierta en el actual.
Este evento se puede usar para realizar
cálculos basándose en los datos del registro actual o para cambiar el
formulario en respuesta a los datos del registro actual.
Validate
Se produce antes de que un registro
diferente se convierta en el registro actual; antes del método Update (excepto
cuando los datos se guardan con el método UpdateRecord); y de los métodos
Delete, Unload o la operación Close.
Private Sub objeto_Validate ([ índice As Integer,] acción As Integer, guardar
As Integer)
objeto = Nombre del control Data
índice = Indice del control Data dentro de una matriz de
controles (Si ha lugar)
acción = Un entero que indica la operación que ha producido
el evento, como se describe mas
adelante
guardar = una expresión booleana que especifica si los datos
asociados han cambiado, como
se describe mas
adelante.
Acción puede tomar estos valores :
0 vbDataActionCancel Cancela la operación cuando
se sale del
procedimiento
Sub.
1 vbDataActionMoveFirst Método MoveFirst.
2 vbDataActionMovePrevious Método MovePrevious.
3 vbDataActionMoveNext Método MoveNext.
4 vbDataActionMoveLast Método MoveLast.
5 vbDataActionAddNew Método AddNew.
6 vbDataActionUpdate Operación Update (no
UpdateRecord).
7 vbDataActionDelete Método Delete.
8 vbDataActionFind Método Find.
9 vbDataActionBookmark La propiedad Bookmark no ha sido
definida.
10 vbDataActionClose Método Close.
11 vbDataActionUnload El formulario se va a descargar.
Los valores de guardar son:
True Los
datos asociados han cambiado.
False Los
datos asociados no han cambiado.
El evento Validate se usa para realizar las últimas comprobaciones sobre los
registros que se van a escribir en la base de datos.
Vea la ayuda de Visual Basic para mayor
detalle de este evento.
Para los demás eventos, es aplicable lo
mismo que para el resto de los controles.
CONTROLES
ENLAZADOS A DATOS
Los controles enlazados a datos permiten
crear aplicaciones con acceso a datos con muy poco código, o incluso ninguno.
Para utilizar cualquiera de estos controles enlazados conectables a datos debe
incluir uno o más controles Data en
un formulario. El control Data establece un enlace entre la base de datos y los
controles enlazados para la manipulación de los datos. El control Data que sirve de enlace entre la Base
de Datos y los controles enlazados debe estar obligatoriamente en el mismo
formulario que los controles.
Existen en Visual Basic diez controles
enlazados a datos, además del control Data :
Data
Ya comentado, se utiliza para tener acceso a los datos de las
bases a través de controles enlazados de un formulario. Crea y administra los
objetos Database y Recordset para su uso por parte de los
controles enlazados. Requerido para su uso con todos los demás controles
enlazados.
DBCombo Se utiliza
para obtener una combinación enlazada formada por un cuadro de lista y un
cuadro de texto. La lista puede llenarse automáticamente a partir de un control
Data. El usuario puede elegir un elemento de la lista o introducir un valor en
el cuadro de texto. Puede utilizarse para proporcionar acceso de lectura /
escritura a un campo de texto específico seleccionado en la lista.
DBList
Se usa para mostrar una lista generada a partir de un control Data
en la que el usuario puede elegir un elemento. La lista puede rellenarse
automáticamente desde un control Data, y puede proporcionar acceso de lectura /
escritura a un campo de texto específico seleccionado en ella.
DBGrid
Se utiliza para obtener una
combinación enlazada formada por varios registros. La cuadrícula puede
rellenarse automáticamente a partir de un control Data. El usuario puede elegir
un elemento de la cuadrícula o introducir un valor en un nuevo registro. Puede
utilizarse para proporcionar acceso de lectura / escritura a un objeto
Recordset, y para mover el registro actual del objeto Recordset asociado al
control Data.
Label
Se usa para el texto que el usuario no debe modificar. Puede
utilizarse para ofrecer acceso de sólo lectura a un campo de texto específico.
TextBox
Se utiliza para almacenar texto que el usuario puede introducir o
modificar. Puede utilizarse para proporcionar acceso de lectura / escritura a
un campo de texto específico.
CheckBox Se utiliza
para crear un cuadro que el usuario puede elegir de forma sencilla para indicar
si algo es verdadero o falso, o para mostrar varias opciones entre las que el
usuario pueda elegir más de una. Puede utilizarse para proporcionar acceso de
lectura / escritura a un campo booleano o de bit específico.
ComboBox Se utiliza
para obtener una combinación de un cuadro de lista y un cuadro de texto. La
lista se rellena con el método AddItem.
El usuario puede elegir un elemento de la lista o introducir un valor en el cuadro
de texto. Puede utilizarse para proporcionar acceso de lectura / escritura a un
campo de texto seleccionado en la lista. Consulte el control DBCombo
ListBox Se utiliza
para mostrar una lista en la cual el usuario puede elegir un elemento. La lista
se rellena con el método AddItem.
Puede usarse para proporcionar acceso de lectura / escritura a un campo de
texto específico seleccionado en la lista. Consulte el control DBList
PictureBox Se usa para
mostrar una imagen gráfica de un mapa de bits, un icono o un meta-archivo en un
formulario. Puede utilizarse para proporcionar acceso de lectura / escritura a
un campo de imagen o binario específico.
Image Se utiliza
para mostrar una imagen gráfica de un mapa de bits, un icono o un meta-archivo
en un formulario. Las imágenes mostradas en un control Image utilizan menos
recursos que las de los controles PictureBox. Puede usarse para proporcionar
acceso de lectura / escritura a un campo de imagen o binario específico.
PROPIEDADES
RELACIONADAS CON DATOS COMUNES A ESTOS CONTROLES
Los controles enlazados a datos tienen
unas propiedades para el acceso a datos basadas en el enlace con la base de
datos a través del control Data. Las propiedades comunes a todos ellos
son :
DataSource Fuente de datos. Es el nombre del control Data que lo enlaza con la B.D. Este
control Data es el que determina la Tabla donde están los campos con los datos.
Esta Tabla se determina mediante la propiedad RecordSource del control Data.
DataField Es el nombre del campo, dentro de la Tabla
de la base de datos, que se va a presentar en el control enlazado a datos. Esta
propiedad no la tiene el DBGrid
debido a que presenta todos los campos de la Tabla de la base de datos
seleccionada en el control Data. Si se le ha forzado al control Data la
propiedad Recordset, los campos que se pueden mostrar en los controles
enlazados a datos son justamente, los de ese Recordset.
Cada uno de los controles enlazados a
datos tiene su aplicación específica dentro del proceso de presentación y escritura
de una Base de Datos.
Control
Label
Posiblemente el control Label es el
control mas sencillo para mostrar el contenido de un campo de una base de
datos. Como todos los controles enlazados a datos, el Label permite presentar
los datos e introducirlos en la base a través del control Data. Lo que ocurre
con el Label es que su propiedad Caption no se puede introducir directamente
por teclado, y deberá cambiarse por código. Esto puede ser una ventaja (no hay
posibilidad de introducirlo accidentalmente) y un inconveniente, al tener que
escribir código para hacerlo.
El control Label, al poder ser origen (a
través del formulario que lo contiene) y destino de un enlace DDE, esto nos
puede resolver muchos problemas de introdución de distintos datos de otras
aplicaciones que no tengan acceso directo a una base de datos.
El control Label, en lo referente al
enlace a datos, solamente tiene las propiedades mencionadas de DataSource y DataField.
Control
TextBox
Todo lo dicho del control Label es
aplicable al TextBox, que además
presenta la particularidad de que en este control sí se puede escribir
directamente desde el teclado.
Control
CheckBox
El control CheckBox permite presentar e
introducir datos de tipo Booleano. Tiene las propiedades DataSource y DataField
en lo relativo a acceso a datos.
Controles
ListBox y ComboBox
Estos controles tienen una característica
especial respecto a su comportamiento con el enlace a la base de datos. La
lista no se puede cargar directamente desde la base de datos, sino a través de
un control intermedio, por ejemplo un Label, donde presentaremos un campo de la
base de datos. El texto de la propiedad Caption de este Label se introduce en
el ListBox o ComboBox mediante el método AddItem. Una vez introducidos todos los
elementos de ese campo que nos interesen, cada vez que la base de datos se
sitúa sobre el registro correspondiente a uno de los elementos que está en el
ListBox o ComboBox, éste cambia su ListIndex para seleccionar el elemento
correspondiente al registro actual del control Data.
El ListBox puede contener elementos
correspondientes a la base de datos y otros ajenos. Puede emplearse esta
característica del ListBox para seleccionar un elemento entre varios elementos
tomados de la BD y otros introducidos por otro procedimiento, con la
particularidad de que el ListIndex de este ListBox irá a posicionarse sobre el
elemento de la BD correspondiente al registro actual del Control Data.
Tiene las propiedades DataSource y DataField
en lo relativo a acceso a datos.
Control
PictureBox y Control Image
Pueden mostrar una imagen almacenada en
una Base de Datos. Mediante el control Data, se puede introducir la imagen
presente en uno de estos controles en la Base de Datos.
El campo que contenga una imagen en una
BD debe ser BINARIO LARGO, y el tipo
de imágenes que se pueden introducir son los mapas de bits (Archivos con
extensión .BMP), los archivos de icono, (Extensión .ICO) y los metaarchivos.
(Metafiles, extensión .WMF)
Para introducir un gráfico en una BD es
mas práctico introducirlo mediante un control Data y un control Picture o Image
que creando por código un Recordset. En realidad deberíamos decir que es el
único método práctico de introducir / sacar imágenes de una Base de Datos
Control
DBGrid
Es posiblemente el control que mas se use
para presentar y modificar datos de una B.D. El control DBGrid presenta todos los registros y todos los campos de la Base
de Datos. Por eso, necesita obligatoriamente un control Data para poder
presentar datos. Otros controles (Label, TextBox, Picture, etc.) que solamente
presentan un dato (un campo de un registro) pueden trabajar sin necesidad de un
control data, creando un Recordset mediante código. (Lo veremos un poco mas
adelante). Sin embargo el control DBGrid, al presentar todos los datos de la
base de datos necesita un control Data. Veamos porqué.
Cuando creamos un objeto Recordset
mediante la instrucción : (se verá mas adelante)
Set
Mirecordset = MiDataBase.Openrecordset (“Select campo1, campo2 from Mitabla”)
lo que estamos haciendo es seleccionar,
de todos los campos que pueda tener la tabla llamada Mitabla, los denominados
campo1 y campo2. Cada vez que seleccionemos un registro, es ese registro
solamente el que se mantiene en la memoria del ordenador, (el registro actual)
y de ese registro, solamente metemos los datos del campo1 y campo2.
Cuando creamos un Recordset mediante un
control Data, se meten en la memoria TODOS los registros de la tabla
especificada en el control data. Por lo tanto, al permanecer todos los
registros de esa tabla en memoria, podremos presentar sus valores en el control
DBGrid. No lo podremos hacer con un
Recordset creado mediante código, que solamente mantiene un registro en
memoria.
Deberemos explicar qué ocurre cuando se
crea un Recordset mediante código, y posteriormente se fuerza a que el
Recordset del control data sea igual a ese Recordset creado.
Con el Recordset creado con la
instrucción anterior, podemos forzar a un control Data que su Recordset sea
igual al ya creado mediante la instrucción :
Set Data1.Recordset=MiRecordset
En este caso, el control Data1 tomará
todos los registros con los campos campo1 y campo2 de la base de datos y los
meterá en la memoria RAM. Así ya podemos rellenar las cuadrículas del control
DBGrid.
Observe que una aplicación de acceso a
datos ocupará mucha mas memoria RAM si establecemos el enlace con la base de
datos mediante un control Data que si lo hacemos creando Recordsets a medida. Pero si necesitamos presentar los
datos en un DBGrid, no quedará mas remedio que usar un control Data. Si nuestra
aplicación no tiene que presentar en el DBGrid todos los campos de la tabla de
la B.D. podemos crear previamente un Recordset mediante código y a continuación
forzar que el Recordset del control Data sea igual al Recordset creado,
utilizando la expresión anterior.
El control DBGrid tendrá tantas columnas
como campos tenga el Recordset. El número de filas será igual al número de
registros que tiene la tabla. Si se sobrepasa el espacio físico del DBGrid para
poder presentarlos, aparecerán automáticamente flechas de deslizamiento
vertical. El ancho de las columnas puede cambiarse mediante la propiedad Width del objeto Columns del DBGrid.
DBGrid1.Columns(n).Width = Valor
Donde n es el número de la columna (la
primera es la 0) y el valor debe expresarse según las unidades de medida
(ScaleWidth) del Formulario que lo contiene.
Del control DBGrid podemos destacar estas
propiedades :
AllowAddNew
Devuelve o establece un valor que indica
si el usuario puede agregar nuevos registros al objeto Recordset subyacente a
un control DBGrid.
La última fila que se muestra en el
control DBGrid se deja en blanco para permitir a los usuarios introducir nuevos
registros. Si la propiedad AllowAddNew es
False, los usuarios no pueden establecer el foco en dicha fila.
El Recordset subyacente puede, por otras
razones, no permitir inserciones incluso en el caso de que la propiedad
AllowAddNew sea True. En este caso, se producirá un error si el usuario intenta
agregar un registro.
AllowDelete
Devuelve o establece un valor que indica
si el usuario puede eliminar registros del objeto Recordset
subyacente a un control DBGrid.
Utilice la propiedad AllowDelete para impedir que los usuarios eliminen registros del conjunto
de registros a través de la interacción con el control DBGrid.
El objeto Recordset subyacente puede, por
otras razones, no permitir eliminaciones incluso en el caso de que la propiedad
AllowDelete sea True. En este caso, se producirá un error si el usuario intenta
eliminar un registro.
AllowRowSizing
Devuelve o establece un valor que indica
si un usuario puede modificar el tamaño de las filas del control DBGrid.
Sintaxis nombre.AllowRowSizing = [True / False]
Si la propiedad AllowSizing es True, el
puntero del mouse se convierte en una flecha de doble cabeza (Size N S) cuando
se sitúa sobre el divisor de filas entre selectores de registro, y el usuario
puede modificar el tamaño de las filas mediante arrastre. Cualquier cambio de
tamaño de columna provoca un evento RowResize.
AllowUpdate
Devuelve o establece un valor que indica
si un usuario puede modificar datos del control DBGrid.
Sintaxis nombre.AllowUpdate = [True / False]
Cuando la propiedad AllowUpdate es False, el usuario puede aún desplazarse a través del
control DBGrid y seleccionar datos, pero no puede modificar ninguno de los
valores; cualquier intento de hacerlo se ignora.
Puede también hacer uso de las
propiedades del objeto Columns para
hacer que columnas individuales del control DBGrid sean de sólo lectura, pero
los valores de la propiedad AllowUpdate tienen prioridad sobre los valores
establecidos para las columnas (sin modificar éstos).
Nota
El objeto Recordset puede no permitir actualizaciones incluso si
AllowUpdate es True para el control DBGrid; en este caso se produce un error
interceptable cuando el usuario intenta cambiar el registro.
ColumnHeaders
Devuelve o establece un valor que indica
si los encabezados de columna se muestran en el control DBGrid.
Sintaxis objeto.ColumnHeaders = [True / False]
Si es True se muestran los encabezados de
columna del control DBGrid, y si es False no se muestran.
DataMode
Establece un valor que especifica si el
control DBGrid funciona en modo enlazado o no enlazado. Esta propiedad no está
disponible en tiempo de ejecución.
Los valores que puede tomar la propiedad DataMode son:
0-Bound. El control DBGrid está enlazado con el control Data.
1-Unbound. El control DBGrid no está enlazado directamente al control Data.
Un DBGrid está enlazado cuando se le
asigna un control Data en su propiedad DataSource. En este caso, presenta sin
mas los datos del Recordset de ese control Data. Si le especificamos en la
propiedad DataMode que no esté enlazado, utilizaremos código en los
procedimientos del control Data para pasarle los datos cuando nos interese.
DefColWidth
Devuelve o establece un valor que indica
el ancho de columna predeterminado para todas las columnas del control DBGrid.
Sintaxis objeto.DefColWidth [= valor]
donde valor es un entero basado en el
modo de escala del control.
Si se da a la propiedad DefColWidth el
valor 0, el control establece automáticamente el tamaño de todas las columnas
en base al ancho del encabezado de columna o al valor de la propiedad Size del
campo subyacente, seleccionando el más largo de los dos.
RecordSelectors
Los selectores de registros aparecen a la
izquierda de las filas en el control DBGrid. Cuando el usuario elige el
selector, el registro completo (fila del control DBGrid) se selecciona.
La propiedad RecordSelectors devuelve o establece un valor que indica si se
muestran los selectores de registro en el control DBGrid.
Sintaxis objeto.RecordSelectors = [True / False]
El
Objeto Columns aplicado al control DBGrid.
El objeto Columns es un objeto no
privativo del control DBGrid, que contiene todas las columnas y las propiedades
de las columnas de un control. Podemos cambiar las propiedades de cada una de
las columnas de un DBGrid mediante las propiedades del objetos Columns asociado
a él. Por ejemplo, el encabezamiento de una columna en un DBGrid es, por
defecto, el nombre del campo que se va a presentar en esa columna. Si queremos
poner otro encabezamiento a una columna,
ejecutaremos la expresión :
DBGrid1.Columns(0).Caption = "Cabecera"
donde el 0 entre paréntesis significa que
estamos afectando a la columna número 0 (la primera por la izquierda).
Si queremos cambiar su anchura :
DBGrid1.Columns(3).Width = 1000
En este caso estamos fijando la anchura
de la columna cuarta por la izquierda a 1000 unidades de medida de las del
Formulario que contiene al DBGrid.
CONTROLES
DBList y DBCombo
Los dos controles DBList y DBCombo se
implementan de la misma manera. Las dos
únicas diferencias estriban en la forma en que se presenta la información al
usuario y la presencia de la porción del control DBCombo en el cuadro de texto, que se emplea para introducir
valores.
Los controles DBList y DBCombo tienen
dos modos que pueden utilizarse individualmente o al mismo tiempo:
Autollenado: Llena automáticamente la lista con un campo
seleccionado de entre todos los registros administrados por el control Data
especificado por la propiedad RowSource del control DBList o
DBCombo.
Actualización automática: Enlaza el registro seleccionado en el control a un
campo específico del objeto Recordset administrado por el control Data
especificado por la propiedad DataSource.
Esto explicado en otras palabras
significa lo siguiente :
En control DBList o DBCombo puede
trabajar sobre dos controles Data. Uno para rellenar la lista. El control Data
y el campo que rellena la lista son los especificados en las propiedades RowSource
y ListField
del control DBList o DBCombo. Respecto a este control Data estos controles funcionan
solamente como receptores de datos : No pueden cambiar el contenido de los
registros con los que rellenan su
lista. (Llamemos a esta base de datos
Base A en esta explicación)
El otro control Data es el que estos
controles usan para introducir datos en su BD asociada. El control Data y el
campo de la BD asociados a estos controles DBList y DBCombo, son los
especificados en las propiedades DataSource y DataField. Es sobre esta
base de datos y el campo correspondiente sobre los que estos controles DBList y
DBCombo actúan cambiando o introduciendo datos. (Llamemos a esta otra base de
datos Base B)
Basta con seleccionar un elemento de la
lista (que pertenece a la base A) y ese elemento se colocará en el campo
correspondiente (el indicado en la propiedad DataField del control
DBList o DBCombo) de la base B. En el
caso del DBCombo, podemos escribir directamente el dato en su caja de texto en
vez de seleccionarlo de la lista.
No tiene porqué ser el elemento que vemos
en la lista el que pasemos a la otra base de datos. Puede ser otro campo del
mismo Recordset. Depende de la propiedad BoundColumn que viene a
continuación. Léasela con la atención que se merece.
Vemos pues que estos controles pueden
servir como un puente entre dos bases de datos.
Veamos unas propiedades especificas de
estos dos controles :
BoundColumn
Devuelve o establece el nombre del campo
de origen de un objeto Recordset que se utiliza para suministrar un valor de
datos a otro Recordset, o el nombre del campo empleado para rellenar un control
DBList o DBCombo.
Resumamos. En un DBList o DBCombo
presentamos en su lista un determinado campo de una BD. Esa BD tendrá mas
campos. Un poco mas arriba decíamos que ese elemento de la lista podíamos
pasarlo a otra BD (La especificada en la propiedad DataSource, y en su campo
DataField). ¿Podríamos pasar a esa BD, en vez del
elemento de la lista, otro campo de esa BD origen ?. Podríamos, por ejemplo, presentar en la
lista el nombre de una persona, nombre que hemos tomado de un listín telefónico,
y en vez de pasar el nombre que es el que figura en la lista, pasar su número
de teléfono, que es otro campo de la misma BD. La respuesta es SI. Para ello,
pongamos en la propiedad BoundColumn del DBList o DBCombo que
estamos usando, el nombre del campo que contiene el número de teléfono. Observe
que por defecto, esa propiedad se rellena con el mismo campo que el
especificado en la propiedad ListField. Eso no quiere decir que
no se pueda cambiar. Para cambiarlo, haga click en la flecha vertical que aparece
en la casilla de propiedades, y donde verá que aparecen todos los campos de la
base de datos seleccionada en el control Data asociado a este control. También
puede cambiarlo en tiempo de ejecución con la siguiente sintaxis :
nombredelDBList.BoundColumn = nombredelcampo
Con estas ideas expresadas aquí, puede
comenzar a leer el texto de ayuda de esta propiedad. No se desespere si no
entiende algo de lo allí expresado.
BoundText
Devuelve o establece el valor de la
propiedad BoundColumn de un control DBCombo o DBList pasado desde o hacia la
propiedad DataField después de realizar una selección. Es decir, es el
contenido del campo especificado en la propiedad BoundColumn comentada
anteriormente.
Esta
propiedad está disponible solamente en tiempo de ejecución.
Esta propiedad es de lectura y escritura.
Es sencilla de usar en para conocer el contenido del campo especificado en
BoundColumn. (lectura del valor)
Cuando la queramos utilizar para forzar
el valor de esta propiedad a un valor determinado, debemos utilizar la
siguiente sintaxis :
objeto.BoundText [= valor]
En este caso, el DBList o DBCombo intenta
buscar un elemento coincidente en el campo especificado en la propiedad BoundColumn
de todos los registros de la BD asociada. Si encuentra uno igual , se establece
el valor de la propiedad BoundText basándose en el campo
especificado por la propiedad BoundColumn. Si no se encuentra
dicha coincidencia, la propiedad BoundText se establece en el valor
Null.
Es decir, si hay coincidencia con algún
valor de ese campo, BoundText seguirá con el valor especificado. Si no la hay,
BoundText se pone a Nulo.
MatchWithList
Propiedad solo de lectura. Devuelve True
si el contenido actual de la propiedad BoundText coincide con uno de los
registros de la parte de lista del control.
Sintaxis Variable
= objeto.MatchWithList
Si Variable = True el contenido de la
propiedad BoundText coincide con uno de los registros de la lista. Si es False,
el contenido de la propiedad BoundText no coincide con ninguno de los registros
de la lista.
Cuando introduce un valor en la parte de
texto del control DBCombo, la propiedad MatchWithList se establece como True si
el valor introducido es uno de los elementos que aparecen en la lista. Usando
esta propiedad, el código puede interceptar entradas que no están la lista, o
proporcionar código para agregar la nueva entrada a la tabla de origen.
DataChanged
Devuelve o establece un valor que indica
que han cambiado los datos del control enlazado por algún proceso distinto de
la recuperación de datos del registro actual. No está disponible en tiempo de
diseño.
Sintaxis objeto.DataChanged [=Variable] ‘establece la
propiedad
Variable = objeto.DataChanged ‘lee el
valor actual de esta propiedad
Variable puede ser True, indicando que los datos que hay
actualmente en el control no son iguales que los del registro actual, y False
(Predeterminado) que indica que los datos que hay actualmente en el control (si
los hay) son iguales que los del registro actual.
Comentarios
Cuando un control Data se mueve de un
registro a otro, pasa datos desde los campos del registro actual a controles
enlazados al campo específico o el registro completo. Cuando se muestran datos
en los controles enlazados, la propiedad DataChanged
se establece como False. Si el usuario o alguna operación cambia el valor del
control enlazado, la propiedad DataChanged se establece como True. Si pasa a
otro registro la propiedad DataChanged no se ve afectada.
Cuando el control Data comienza a mover a
otro registro, se produce el evento Validate. Si DataChanged es True para algún
control enlazado, el control Data invoca automáticamente los métodos Edit y
Update para enviar los cambios a la base de datos.
Si no desea guardar los cambios de un
control enlazado en la base de datos, puede establecer la propiedad DataChanged
como False en el evento Validate.
MatchEntry
Devuelve o establece un valor que indica
cómo el control DBCombo o DBList realiza búsquedas basándose en la entrada del
usuario.
Sintaxis objeto.MatchEntry [= valor ]
Donde valor es una constante o un valor
que define el comportamiento de un control cuando tiene el enfoque y el usuario
introduce uno o más caracteres.
0 vbMatchEntrySimple
Coincidencia básica: (Predeterminado) El control busca la siguiente
coincidencia del carácter introducido usando la primera letra de entradas de la
lista. Al escribir repetidamente la misma letra se recorren todas las entradas
de la lista que comienzan por esa letra.
1 vbMatchEntryExtended Coincidencia ampliada: El control busca una entrada que coincida
con todos los caracteres introducidos. La búsqueda se realiza a medida que se
escriben los caracteres, refinando progresivamente la búsqueda.
Cuando la propiedad MatchEntry se
establece como vbMatchEntryExtended y el usuario presiona la tecla de retroceso
o espera varios segundos, la cadena de coincidencias de restablece.
SelectedItem
(Solo DBCombo)
Devuelve un valor que contiene un
marcador para el registro seleccionado en un control DBCombo.
Sintaxis DBCombo1.SelectedItem
Cuando selecciona un elemento de la parte
de lista del control DBCombo, la propiedad SelectedItem contiene un marcador
que puede utilizar para reposicionar el registro seleccionado en el Recordset
como especifica la propiedad RowSource.
SelText
SelText
devuelve o establece una cadena con el texto actualmente seleccionado, o
es una cadena de longitud cero () si no hay caracteres seleccionados.
VisibleCount
Devuelve un valor que indica el número de
elementos visibles del control DBCombo o DBList.
Sintaxis objeto.VisibleCount
La propiedad VisibleCount devuelve un
entero desde 0 al número de elementos visibles del control. Un elemento se
considera visible únicamente si una parte del texto es visible.
VisibleItems
Devuelve una matriz marcadores, uno para
cada elemento visible de la lista del control DBCombo o DBList.
Sintaxis objeto.VisibleItems
Estos marcadores pueden emplearse para
obtener registros individuales del conjunto de registros empleado para rellenar
la lista.
Visual
Basic Guía del estudiante Cap. 19
OPERACIONES CON BASES DE DATOS
SIN UTILIZAR EL CONTROL DATA
En el capítulo anterior hemos visto los
controles capaces de acceder a un Base de Datos, enlazados mediante un control
Data. Se comenzó a exponer que no es necesario usar un control Data para
acceder a leer datos, añadir registros o cambiar su contenido.
Una base de datos puede abrirse sin
necesidad de un control Data. Puede también crearse un Recordset o una consulta
simplemente escribiendo código. También puede crearse una base de datos ACCESS
u otro tipo soportado por el Motor de Bases de Datos MicrosoftJet.
La elección de un sistema u otro no es
arbitraria. El control Data será necesario en aquellas aplicaciones en las que
se va a usar un control DBGrid, pues como se recordará, mediante el uso de un
control Data metemos en memoria RAM todo el contenido de la base de datos
relativo al Recordset que hemos creado. El control Data será necesario en aquellas
aplicaciones donde utilicemos un DBGrid, un DBList o un DBCombo. Veremos mas adelante que también será
necesario cuando queramos guardar
imágenes en una Base de Datos.
El control Data también permite consultas
mas rápidas a la BD. El hecho de guardar el contenido completo del Recordset en
la memoria hace que cualquier consulta sea mas rápida. Eso sí, estamos
empleando mucha mas memoria RAM.
Puesto que queremos trabajar con una Base
de Datos sin emplear controles Data de enlace, tendremos que crear otro tipo de
objetos: Los Objetos de Acceso a
Datos (DAO - Data Access Objet). Estos objetos, pese a que no tienen
representación en la interface gráfica,
son objetos Visual Basic como los demás, y nos podremos referir a ellos
por su nombre como hacíamos con todos los controles. Eso sí, debemos
declararlos como se declaran las variables, y siguen siendo válidos los
criterios de declaración de variables en cuanto al ámbito de aplicación. Si
declaramos un DAO en un procedimiento, no nos podremos referir a él fuera de
ese procedimiento. Si queremos que sea válido en toda la aplicación deberemos
declararlo en la sección de declaraciones de un módulo, o en la sección de
declaraciones de un formulario si fuese suficiente ese ámbito para nuestra
aplicación.
Objetos de Acceso a Datos
Veamos un gráfico muy
ilustrativo tomado de la ayuda de VB con todos los objetos DAO.

Podemos
observar en la Leyenda : Objeto y Colección. Esto significa que un objeto DAO puede ser
un determinado objeto (Por ejemplo el
Recordset). Puede haber varios objetos Recordset abiertos al mismo tiempo. Al
conjunto de los objetos Recordset abiertos le llamamos Colección de Recordsets,
y es a su vez un objeto DAO :
El objeto Recordsets (Fíjese en el plural) El Objeto Workspace representa una sesión. El Objeto Workspaces representa la colección de todos los objetos Workspace abiertos en ese momento. Dado
que las colecciones representan un conjunto de objetos, uno de estos objetos de
la colección puede representarse, bien por el nombre que tenga (Misesion,
nombre típico de un objeto Workspace), o por el nombre de la colección seguido
del índice que representa a ese objeto concreto dentro de la colección
[Workspaces (0)]
Objeto DBEngine
El
DBEngine es el Motor de Bases de
Datos. Es el objeto de acceso a datos de mayor jerarquía. De hecho es quien le
va a realizar todas las operaciones de acceso a datos. Como cualquier Objeto
DAO tiene sus Métodos, Propiedades y Colecciones:
Métodos
CreateWorkspace, CompactDatabase,
RepairDatabase, Idle, RegisterDatabase
Propiedades
DefaultPassword, DefaultUser, IniPath, LoginTimeout, Version
Colecciones
Errors, Properties,
Workspaces (predeterminada)
A
estas alturas aún no sabemos lo que es una Base de Datos. Logicamente no vamos
a explicar aquí lo que es compactar una base de datos cuando no sabemos ni lo
que es (Entienda esta aclaración
solamente en el sentido estricto del orden que debe llevar este capítulo. De
sobra sabemos que Vd. sí sabe lo que es una BD). Por lo tanto, la
explicación de estos métodos, propiedades u colecciones lo irá viendo según
vayamos avanzando en el estudio de los objetos DAO.
Objeto Workspace
Un
objeto Workspace define una sesión para un usuario específico. Cuando se inicia
Visual Basic, se crea automáticamente un Workspace con palabra clave y nombre de usuario Admin. Este Workspace es precisamente el que ocupa el número cero
de la colección de Workspaces. Es decir, es el Workspaces(0).
El
objeto Workspace es la sesión de
trabajo abierta sobre la que estamos trabajando. El objeto Workspace contiene todo lo relativo a una sesión de trabajo en el
mas puro estilo informático. Contiene :
Grupos de trabajo, que es un grupo de usuarios de un entorno
multiusuario que comparten datos y el mismo sistema de base de datos. Grupos
de usuarios, que es una colección de cuentas de usuario. Estos objetos,
que no son objetos de acceso a datos, sino de explotación de los recursos del
sistema, están enfocados a la seguridad respecto al acceso a las bases de datos
que se trabajan conjuntamente. No tendría sentido hablar aquí de ellos si no
fuese porque encontrará referencias a estos objetos continuamente en la ayuda
de Visual basic.
Bases de Datos (Databases). Este el objeto que ahora nos interesa del objeto
Workspace. Un objeto Database es una base de datos abierta.
Al
objeto Workspace se le puede dar un nombre definido por el usuario. Ese nombre
habrá que declararlo como nombre de una variable objeto Workspace :
Dim Misesion as Workspace
La
declaración de la variable Objeto tiene las mismas características que
cualquier variable en cuanto al ámbito en el que se puede usar. Para que pueda
usarse en toda la aplicación deberemos declararla en un Módulo con la sentencia
Global ó Public
Public Misesion as Workspace
Esta
advertencia es válida para la declaración de todos los objetos DAO.
Una
vez declarado el nombre del objeto Workspace, hay que crearlo. En realidad, y
tal como citábamos mas atrás, cada vez que se inicia una sesión de Visual Basic,
se crea automáticamente un Workspace. El número 0 A este Workspace no podemos
ponerle ningún tipo de palabra de acceso, ya que se la ha puesto VB : Admin. Utilicemos este Workspace, el
número 0 de la colección Workspaces, para comenzar a trabajar.
Set Misesion = Workspaces(0)
Mediante
esta sentencia hemos hecho que Misesion
sea el Workspace creado automáticamente por Visual Basic .
Pero
si no queremos aprovechar este Workspace creado automáticamente por Visual
Basic, y queremos usar otro, usemos el método CreateWorkspace. Este método es un método del Objeto DBEngine.
Creación de Objetos DAO
Para
crear un objeto DAO (Cualquiera que sea) debemos usar una forma que se va a
repetir a lo largo de toda su vida profesional, mientras trabaje con Visual
Basic y Bases de Datos:
Set
ObjetoDAOInferior = ObjetoDAOSuperior.Método ( Aquí .... alguna cosa )
Logicamente
el término Aquí .... alguna cosa va a depender de cada método y de lo que Vd.
quiera hacer, pero la estructura Set
DAOInferior = DAOSuperior.Método ( - -
- - - - - - - - ) se mantendrá en todas las operaciones de
creación y manipulación de objetos DAO. Tan simple como un “juego de niños” . No lo olvide y se
le quitará el miedo al manejo de bases de datos mediante código. Posiblemente hasta ahora le haya parecido
muy difícil y haya optado por usar el control Data para todas sus aplicaciones.
Si recuerda este Juego de niños verá que es
mas sencillo crear objetos DAO que poner un control Data en un formulario.
Método CreateWorkspace (Método del
DBEngine)
Usaremos
la regla anterior para crear este objeto DAO. Suponemos que ya está declarado
en alguna parte el nombre del objeto Workspace
(Public Misesion as Workspace)
Set Misesion
= DBEngine.CreateWorkspace(Nombre, Usuario, Contraseña)
Donde
Misesion es la variable declarada como tipo objeto Workspace.
Nombre es una variable de tipo String que da un nombre
único al nuevo objeto Workspace.
Usuario
es una variable de tipo String
que identifica al propietario del nuevo objeto Workspace. Este propietario
deberá estar en la colección de Usuarios (Users)
Contraseña es una variable de tipo String que contiene la
contraseña del usuario propietario de este Workspace. Debe coincidir
(logicamente) con la contraseña declarada para el User Usuario citado en el parámetro anterior.
Deben especificarse TODOS estos
argumentos. Si el usuario no tiene
contraseña, se ingresará el valor “” caso de introducirlo mediante código, o
una variable vacía.
Primer problema (Los objetos DAO no están exentos de ellos). Seguro
que al intentar crear un Workspace le aparezca un mensaje de error :
No
pasa nada. Simplemente que hemos corrido mucho y nos acabamos de estrellar. Y
nos hemos estrellado con las seguridades del motor de bases de datos JET (Si lo
prefiere, con las seguridades de ACCESS). No podemos abrir un Workspace sin ser
un usuario registrado en la colección Users,
y no podemos explicar, de momento, como se crea esta colección. Mas adelante sí
podremos, una vez que conozcamos mas acerca de bases de datos. No se preocupe
que el tema de seguridades se explicará concienzudamente en un capítulo
posterior y la creación de Workspaces no tendrá secretos en ese momento.
Confórmese
de momento con trabajar con el Workspace creado automáticamente por Visual Basic.
Este Workspace es el número 0 de la colección Workspaces. Este Workspace se
llama #Default Workspace#, y el nombre del propietario es Admin. Este propietario sí está registrado en la Colección
Users. Para usar este Workspace creado por Visual Basic basta con la
instrucción indicada mas atrás :
Set Misesion = Workspaces(0)
Veamos
a modo de adelanto, las Propiedades, Métodos y Colecciones del objeto
Workspace :
Propiedades Name,
Password, UserName
Métodos BeginTrans, CreateGroup,
Close, CreateUser, CommitTrans
OpenDatabase, CreateDatabase,
Rollback
Colecciones Databases
(predeterminada), Groups, Users
Al
conjunto de Workspaces existentes se le llama Colección Workspaces. Solamente tiene una propiedad : Count, y un solo Método : Refresh
Objeto Database
Un
objeto Database representa una base
de datos abierta. Una colección Databases
contiene todos los objetos Database
abiertos o creados en un objeto Workspace del motor de bases de datos Microsoft
Jet. Para manipular una base de datos abierta se utiliza un objeto Database y sus métodos y propiedades.
Al
objeto Database se le debe dar un
nombre definido por el usuario. Eso sí, hay que declararlo como una variable
objeto Database
Dim MiDataBase As Database
Colección Databases
Es el conjunto de Objetos Database
existentes. La colección Databases pertenece al Workspace.
Abrir una Base de Datos ya existente.
Método OpenDatabase
Para
abrir una base de datos existente deberemos usar el método OpenDatabase. Pero previamente deberemos declarar el nombre que se
le va a dar a ese objeto Database mediante la instrucción Dim si queremos que el ámbito de ese Database
sea un formulario, o Global o Public, (en la sección de declaraciones de un Módulo o Formulario)
si queremos que el ámbito sea toda la aplicación.
Por
ejemplo, si queremos abrir una base de datos y poder referirnos a ella en toda
la aplicación, debemos declararla de esta forma en la sección de declaraciones
de un módulo :
Public MiBaseDatos as Database
Método OpenDatabase
Abre
la base de datos existente. La base de datos abierta se agrega automáticamente
a la colección Databases.
Sintaxis Recuerde la expresión general: Set
DAOInferior = DAOSuperior.Método ( - - - - - -)
Set
MiBaseDatos = Misesion.OpenDatabase(nombre_bd[,
exclusivo[, sólo-lectura[, origen]]])
La
sintaxis del método OpenDatabase consta de las siguientes partes:
MiBaseDatos Variable
de tipo de dato objeto Database que representa el objeto DAO
Database que se va a abrir.
Misesion Variable
de tipo de dato objeto Workspace que representa el objeto
Workspace existente que va a contener a
la base de datos.
nombre_bd Expresión de
cadena con el nombre de un archivo (y su Path) de una base de
datos existente. Si el nombre de archivo tiene
extensión, es necesario especificarla. Si la red lo admite, también puede
especificar una ruta de red, como por ejemplo
"\\MISERVID\MICOMP\MIDIR\MIBD.MDB". nombre_bd también puede
ser un origen de datos OBDC. Lo veremos en otro capítulo.
Al especificar nombre_bd hay que tener en cuenta
algunas consideraciones:
Si se refiere a una base de datos ya
abierta por otro usuario con acceso
exclusivo, se producirá un error.
Si
no se refiere a una base de datos existente o a un origen de datos ODBC
válido, se producirá un error.
Si es una cadena de longitud cero ("") y
origen es "ODBC;", aparecerá un cuadro de diálogo con todos los
nombres de orígenes de datos ODBC registrados, en el que el usuario podrá
elegir una base de datos.
exclusivo Valor de
tipo Boolean que es True si la base de datos se va a abrir con acceso
exclusivo (no compartido) o False si se va a abrir
con acceso compartido. Si se omite este argumento, la base se abrirá con acceso
compartido.
sólo_lectura Valor de tipo
Boolean que es True si la base de datos se va a abrir con acceso
de sólo lectura o False si se va a abrir con acceso
de lectura/escritura. Si se omite este argumento, la base se abrirá para lectura/escritura.
origen Expresión
de cadena utilizada para abrir la base de datos. Esta cadena
constituye los argumentos de conexión ODBC. Para
especificar una cadena de origen deberá especificar también los argumentos
exclusivo y sólo_lectura. Consulte la sintaxis en la propiedad Connect.
p.e. Set MiBaseDatos = Misesion.OpenDatabase (“C:\CursoVB\MiBase.MDB”)
abre
la base de datos cuyo fichero está en C :\CursoVB y se llama MiBase.MDB.
Al no expresarle mas parámetros la abre de modo no exclusivo, y de lectura y
escritura. Al no especificar nada en el parámetro origen entiende que la base es ACCESS
Nota
para todo este capítulo. No es necesario cambiar el nombre del Workspace. Si
Misesion = Workspaces (0), la sentencia anterior podemos ponerla también :
Set MiBaseDatos = Workspaces(0).OpenDatabase (“C:\CursoVB\MiBase.MDB”)
El hecho de poner siempre un nombre al
Workspace es solamente a efectos didácticos
Para
cerrar una base de datos y retirar así su objeto Database de la colección
Databases, utilice sobre el objeto el método Close.
Crear una Base de Datos ACCESS. Método
CreateDatabase
Veamos
de forma breve como se crea una base de datos. Mas adelante se explicará con
detalles.
Para
crear una base de datos deberemos utilizar el método CreateDatabase. Previamente debemos declarar el nombre que queremos
dar a esa nueva base de datos como un objeto Database :
Dim MiBaseDatos as Database
Si
tenemos declarado un Workspace llamado Misesion mediante la declaración :
Dim Misesion as Workspace
podremos
usar el método del Workspace CreateDatabase
para crear esa base de datos. Nos creará una base de datos ACCESS
Set MiBaseDatos = Misesion.CreateDatabase
(“C:\MiCarpeta\MiBase.MDB”,
Idioma [, opciones])
Una
Base de Datos ACCESS tiene tablas. Para crear una tabla debemos usar el método CreateTableDef. Declaremos ahora el
nombre de un nuevo objeto : El Objeto
TableDef.
Dim Mitabla As TableDef
y
crearemos las tablas necesarias mediante CreateTableDef
Set Mitabla = MiBaseDatos.CreateTableDef ([nombre[, atributos[, origen[, conexión]]]])
Una
Tabla tiene Campos (Fields). Para crear un campo debemos usar el método CreateField
Previamente
declararemos el nombre del Objeto Field
Dim MiCampo as Field
Set MiCampo = Mitabla.CreateField ([nombre[, tipo [, tamaño]]])
Observe
el mencionado “juego de niños”. El método correspondiente para crear un objeto
DAO pertenece al objeto DAO inmediatamente superior en jerarquía, es decir,
CreateDatabase es un método del objeto Workspace, CreateTableDef es un método
del objeto Database, CreateField es un
método del objetos TableDef.
Las
colecciones pertenecen también al objeto inmediatamente superior en jerarquía
al tipo de objetos que forman la colección. La colección Fields (Objeto Fields)
pertenece a un objeto TableDef, la
colección TableDefs (objeto TableDefs) pertenece a un objeto Database, y la
colección Databases (Objeto Databases) pertenece a un objeto Workspace. La
colección Workspaces pertenece al DBEngine, y el DBEngine ya no podemos
asignarlo a ningún objeto DAO. Tendremos que decir que pertenece al sistema.
Recordemos
ese “juego de niños” :
Set DAOInferior = DAOSuperior.Método (
- - - - - -)
Veremos
que después de crear un objeto, debemos añadirlo a la colección a la que debe
pertenecer con el método Append. El
agregarlo a la colección es imprescindible en el caso de los objetos TableDef,
Field, QueryDef. El procedimiento es
siempre el mismo :
Objeto superior.Colección.Append Objeto a añadir
Veamos
con detalle cada uno de los métodos para ir creando la Base de Datos Completa.
Método CreateDatabase
Crea
un nuevo objeto Database, guarda la base de datos en disco y devuelve un objeto
Database abierto.
Sintaxis
Set
MiBaseDatos = Misesion.CreateDatabase
(nombre_base, inf_local [, opciones])
Donde
MiBaseDatos es el nombre del objeto Database por el cual nos
referiremos a esa base de datos, NO
el nombre del archivo con el que quedará guardada en el disco.
Misesion es el nombre del objeto Workspace existente que
contendrá la base de datos. Si se omite este argumento, se utilizará el objeto
Workspace predeterminado.
nombre_base es el nombre del archivo de base de datos que se va
a crear. Es decir, el nombre del archivo en el disco. Puede ser una ruta
completa y un nombre de archivo, como por ejemplo "C:\MIBD.MDB". Si
no se indica una extensión, se agregará .MDB. Si la red lo admite, también
puede especificar una ruta de red, como por ejemplo
"\\MISERVID\MICOMP\MIDIR\MIBD". Con este método sólo pueden crearse
archivos de base de datos .MDB.
(ACCESS)
inf_local es una expresión de cadena utilizada para
especificar el orden alfabético que se va a usar en esta Base de Datos. Debe especificar este argumento o se
producirá un error. Consulte la tabla de constantes para inf_local incluida más adelante en este tema.
En
el argumento Opciones puede combinar varias opciones, según se especifica a
mas adelante. Puede combinar varias opciones sumando las constantes
correspondientes.
VALORES
En
el argumento inf_local se suministra
información de la lengua empleada para especificar la propiedad CollatingOrder del texto para las
comparaciones entre cadenas. Es un argumento
obligatorio. Para los idiomas
Inglés, alemán, francés, portugués, italiano y español moderno se usa la
siguiente constante :
dbLangGeneral
Para
el Español tradicional se usará la constante dbLangSpanish. No use esta constante, pues no hace nada especial
respecto a dbLangGeneral
Consulte
la ayuda de Visual Basic para información de otras lenguas.
Este
parámetro es obligatorio. Piense que una vez creada la Base de Datos, alguna
vez le pedirá que le obtenga un Recordset con los datos ordenados
alfabéticamente ( acuérdese de la
sentencia SQL ORDER BY Nombredelcampo )
Para
Opciones
se pueden usar las siguientes constantes :
Constante Descripción
dbEncrypt Crea una base de datos codificada.
dbVersion10 Crea una base de datos que utiliza la versión
1.0 del motor de base de datos
Microsoft Jet.
dbVersion11 Crea una base de datos que utiliza la versión
1.1 del motor de base de datos
Microsoft Jet.
dbVersion25 Crea una base de datos que utiliza la versión
2.5 del motor de base de datos
Microsoft Jet.
dbVersion30 Crea una base de datos que utiliza la versión
3.0 del motor de base de datos
Microsoft Jet. Esta
Version es compatible con la 3.5
Si
se omite la constante de codificación, se creará una base de datos no
codificada. Sólo es posible especificar una constante de versión. Si se omite
la constante de versión, se creará una base de datos que utilizará la versión
2.5 del motor de base de datos Microsoft Jet (para 16 bits) o la versión 3.0
(para 32 bits), dependiendo del entorno en el que se trabaje.
Puede
utilizar el método CreateDatabase para crear una plantilla de una nueva base de
datos que acceda al motor Jet. El método CreateDatabase abre esta nueva base de
datos y devuelve un objeto Database, cuya estructura y contenido deberá
completar utilizando objetos de acceso a datos adicionales. Es decir, crear una Base de Datos sin nada
para pode rellenarla posteriormente.
Estos
objetos que se pueden añadir son : Objetos
TableDef, TableDefs, Field, Fields, QueryDef, QueryDefs
El
Objeto TableDef es una tabla de una
base de datos ACCESS. El Objeto TableDefs
es una colección que contiene todas las tablas de la base de datos
Una
colección TableDefs contiene todos
los objetos TableDef almacenados de
una base de datos. El objeto TableDefs, la colección de tablas, pertenece al
objeto DataBase.
Un
objeto Field representa una columna
de datos con un tipo de datos y un conjunto de propiedades comunes. La
colección Fields contiene todos los
objetos Field almacenados de un objeto Index, QueryDef, Recordset, Relation o
TableDef.
Un
objeto QueryDef representa una
consulta de la base de datos. El objeto QueryDefs
es la colección de objetos QueryDef.
La diferencia entre una consulta (Un QueryDef) y una tabla (Un TableDef) es que
la Tabla tiene dentro de sí los datos. La consulta tiene dentro una referencia
al lugar de las tablas donde se encuentran los datos.
CREACION DE LAS TABLAS DE ESTA BASE DE
DATOS
Dado
que una base de datos ACCESS debe tener Tablas, deberemos crear estas una vez
que hayamos creado la base de datos. La forma de crearlas es utilizando el
método CreateTableDef. Para ello, declararemos tantos objetos DAO
tipo TableDef como tablas tengamos.
Le daremos un nombre definido por el usuario, que NO será el nombre de las
tablas, sino el nombre por el que nos referiremos al objeto DAO TableDef en el
código de nuestra aplicación.
Para
declarar las variables Objeto TableDef
usaremos la misma lógica que
para todos las variables en cuanto a ámbito de aplicación.
Public Mitabla01 as TableDef
Public Mitabla02 as TableDef
Una
vez declarados todos los Objetos TableDef, procederemos a crearlos usando el
método CreateTableDef.
Método CreateTableDef.
Crea
un nuevo objeto TableDef.
Sintaxis La de siempre : Set
DAOInferior = DAOSuperior.Método ( - - - - - -)
Set
Mitabla = MiBaseDatos.CreateTableDef([nombre[,
atributos[, origen[, conexión]]]])
Observe
que el método CreateTableDef es un
método del objeto Database (MiBaseDatos
en este caso)
La
sintaxis del método CreateTableDef consta de las siguientes partes:
Mitabla Variable
declarada como tipo de dato objeto TableDef.
MiBaseDatos Nombre
de variable del objeto Database que se desea usar para crear el
nuevo objeto TableDef.
nombre nombre del nuevo objeto
TableDef. (Nombre de la Tabla que acabamos de
crear)
atributos Variable de tipo Long que indica una o
más características del nuevo objeto
TableDef. Para mayor información acerca de los valores para atributos vea
la
Ayuda de Visual Basic correspondiente a
CreateTableDef.
origen Variable de tipo String que contiene
el nombre de la tabla de una base de
datos externa de la que proceden
originariamente los datos. La cadena origen
pasa a ser el valor de la propiedad SourceTableName del nuevo objeto
TableDef.
conexión Variable de tipo String que contiene
información sobre el origen de una base
de datos abierta, de una base de datos
utilizada en una consulta de paso a
través o de una tabla adjunta. Si desea
más información sobre las cadenas de
conexión válidas, consulte la propiedad Connect.
Si
omite uno o más de los argumentos opcionales al utilizar CreateTableDef, puede utilizar después una instrucción de
asignación para definir o restablecer la propiedad correspondiente antes de
agregar el nuevo objeto a una colección. Una vez agregado, sólo podrá modificar
los valores de algunas de las propiedades del nuevo objeto. Si desea más
información, consulte los temas individuales de las propiedades.
Ya
tenemos creadas las tablas que componen la base de datos. Pero una tabla
contiene campos, y estas tablas creadas con el método CreateTableDef están, de momento, vacías. Deberemos crear
los campos con el método CreateField.
Antes
de usar el método CreateField
deberemos declarar tantos objetos DAO tipo Field como campos vayamos a crear.
Por ejemplo, para declararlos en un módulo y que su ámbito sea toda la
aplicación :
Public MiCampo01 as Field
Public MiCampo02 as Field
Un
objeto Field es un campo de la base
de datos. El Objeto Fields es la
colección de los objetos Field
existentes en una Tabla.
Método CreateField
Crea
un nuevo objeto Field. Este es un procedimiento del objeto TableDef
Sintaxis Set DAOInferior = DAOSuperior.Método
( - - - - - -)
Set MiCampo = Mitabla.CreateField ([nombre[, tipo [, tamaño]]])
Donde :
MiCampo Variable
declarada como tipo de dato objeto Field.
Mitabla Nombre
de variable del objeto TableDef que se desea utilizar para crear el
nuevo objeto Field.
nombre Variable
de tipo String que da el nombre al campo creado.
tipo Constante
de tipo Integer que determina el tipo de datos del nuevo campo.
Consulte la propiedad Type para obtener información sobre los tipos de datos válidos.
tamaño Entero que indica el tamaño máximo, en
bytes, de los objetos Field que
contengan texto. Consulte en la propiedad Size los valores válidos para tamaño.
Este argumento se ignora en el caso de campos numéricos o de anchura fija.
Es
posible que quiera que alguno de los campos creados tenga unas características
o Atributos especiales. (Por
ejemplo, que sea un contador) Vea la Propiedad
Attributes mas adelante.
Ya
tenemos creada la Base de Datos, sus
Tablas y los Campos de cada tabla. Sin embargo esto todavía no es una base de
datos completa. Una vez creados todos los campos, debemos añadirlos a su tabla, y una vez que la tabla ya tiene añadidos
todos sus campos, debemos añadir es tabla a la base de datos. Si no
lo hacemos así, la base de datos continuaría vacía.
Para
ello, utilizaremos el Método Append (Lo
veremos mas adelante)
MiTabla1.Fields.Append
MiCampo11
MiTabla1.Fields.Append
MiCampo12
MiTabla1.Fields.Append
MiCampo13
Añadiríamos
todos los campos a todas las tablas existentes....
MiTabla2.Fields.Append
MiCampo21
MiTabla2.Fields.Append
MiCampo22
MiTabla2.Fields.Append
MiCampo23
Y
ahora añadiríamos todos los TableDef ya llenos de campos, al objeto TableDefs
de la Base de Datos :
MiBaseDatos.Tabledefs.Append
Mitabla1
MiBaseDatos.Tabledefs.Append
Mitabla2
Método CreateIndex
Otro
método del objeto TableDef es CreateIndex,
y tiene una colección denominada Indexes. El método CreateIndex crea un nuevo
objeto : un objeto Index. (Para no
liarnos, un objeto Index es un índice de una tabla.)
Los
objetos Index especifican el orden en que se accede a los registros de las
tablas de una base de datos y si se aceptan o no registros duplicados. Además,
los objetos Index permiten un acceso eficiente a los datos. En el caso de las
bases de datos externas, los objetos Index describen los índices establecidos
para las tablas externas.
Sintaxis Set NombreIndice = NombreTabledef.CreateIndex([Nombre])
Donde
NombreIndice es el nombre de una
variable declarada como tipo de dato objeto Index.
NombreTabledef es el nombre de variable del objeto TableDef que se
desea usar para crear el nuevo objeto Index.
Nombre es una variable de tipo String que da un nombre
único al nuevo objeto Index.
Para
retirar un objeto Index de una colección, utilice en ella el método Delete.
Un
objeto Index tiene las siguientes propiedades :
Clustered
- El objeto Index representa un índice agrupado de una tabla.
Primary - El objeto Index representa un índice
primario de una tabla.
Foreign
- El objeto Index representa una clave externa en una tabla
Unique - El objeto Index representa un índice
único (clave) de una tabla.
IgnoreNulls
- Indica si permite valores Nulos en los campos del índice.
Required - Indica si objetos Field o Index requieren
valores no Nulos.
Name - Nombre del Objeto Index
DistinctCount
- Devuelve un valor que indica el número de valores únicos del objeto Index que
se incluyen en la tabla asociada. La propiedad DistinctCount devuelve un tipo
de datos Long.
Para
crear un índice proceda de la siguiente forma :
Set Indice = mitabla01.CreateIndex("indiceID") ‘Se asigna un nombre al objeto Index
Set micampo1N = Indice.CreateField("ID", 4) ‘Asocia el campo deseado al
objeto
‘índex. El campo debe estar ya creado.
Indice.Required = True ‘ No admite
valores Nulos
Indice.Primary = True ‘ Se trata del
índice primario
Indice.Fields.Append micampo1N ‘ se añade el campo a
la colección
‘ Fields del objeto Index.
mitabla01.Indexes.Append Indice ‘ Se añade el objeto
Index a la
‘ colección Indexes del objeto Tabledef
(Añadir
un índice a una tabla es una tarea que ha dado mas de un quebradero de cabeza.
No se desanime si no sale a la primera)
Como
primera advertencia de lo incomprensible que puede ser trabajar con índices
vemos la segunda línea del código anterior :
Set micampo1N = Indice.CreateField("ID", 4)
Parece
que estamos creando el campo “ID”. Pues
no. Ese campo ya debe estar creado mediante el método del objeto TableDef
CreateField. En realidad lo que hacemos mediante ese CreateField del objeto
Indice es asociar ese campo al Indice.
Una
vez creado el Indice puede darle las propiedades deseadas (hacerlo Indice
Primario - Clave Maestra en Access - , que no acepte valores nulos - Required -
o cualquiera de las propiedades expuestas mas atrás. No se olvide, una vez con
todas sus propiedades, agregar primero el campo a la colección Fields del
Indice, y a continuación el índice a
la colección Indexes del
Tabledef :
MiIndice.Fields.Append
MiCampo
MiTableDef.Indexes.Append
MiIndice
PROPIEDADES
TYPE, ATTRIBUTES Y SIZE REFERIDAS A LOS CAMPOS
Propiedad Type
Devuelve
o establece un valor que indica el tipo de datos de un objeto. En objetos
Field, el valor de esta propiedad es de lectura/escritura hasta que el objeto
se agrega a una colección o a otro objeto, después de lo cual es de sólo
lectura.
Sintaxis objeto.Type [= valor]
objeto Nombre
del Objeto Field.
valor Un
entero o constante de los descritos a continuación. (El tipo de datos es
Integer).
Dependiendo
de la versión del motor de bases de datos usado, puede tomar los siguientes
valores
Versión
2 (16 bits)
Valor Constante Descripción
8 dbDate Fecha/Hora Sirve para guardar fechas
y horas
10 dbText Texto Sirve para texto
hasta 255 bytes
12 dbMemo Memo Para textos sin
limitación
1 dbBoolean Yes/No Booleanas
3 dbInteger Integer de -32.768 a 32.767
4 dbLong Long de -
2.147.483.648 y 2.147.483.647
5 dbCurrency Currency Long
en Pesetas (Euros)
6 dbSingle Single Coma flotante,
simple precisión
7 dbDouble Double Coma
flotante, doble precisión
2 dbByte Byte de 0 a 255
11 dbLongBinary Long Binary (Objeto OLE) Para
meter Imágenes u otros datos
binarios
largos.
En
VB5 que trabaja con la versión 3.5 del motor de bases de datos JET, tiene los
siguientes valores :
Constante Descripción
dbBigInt Big
Integer
dbBinary Binary
dbBoolean Boolean
dbByte Byte
dbChar Char
dbCurrency Currency
dbDate Date/Time
dbDecimal Decimal
dbDouble Double
dbFloat Float
dbGUID GUID
dbInteger Integer
dbLong Long
dbLongBinary Long Binary (Objeto OLE)
dbMemo Memo
dbNumeric Numeric
dbSingle Single
dbText Text
dbTime Time
dbTimeStamp TimeStamp
dbVarBinary VarBinary
Vea
la propiedad Type de VB5 para ver los detalles de cada tipo de dato.
Propiedad Attributes
Devuelve
o establece un valor que indica una o más características de un objeto Field. En un objeto que no ha sido
agregado a una colección, esta propiedad es de lectura/escritura.
Sintaxis objeto. Attributes [= valor]
objeto Nombre
del Objeto Field cuya característica se va a leer o cambiar.
valor Una constante que
especifica las características de un objeto, como se
describe a continuación.
En
un objeto Field, valor especifica
las características del campo representado por el objeto Field y puede ser una
suma de las siguientes constantes::
Constante Descripción
dbFixedField El tamaño del campo es fijo
(predeterminado en campos numéricos).
dbVariableField El tamaño del campo es variable
(Sólo campos de texto).
dbAutoIncrField El valor del campo en los
registros nuevos es incrementado
automáticamente a un valor Long integer único que no
puede ser modificado. Sólo aceptado en tablas bases de datos Jet.
dbUpdatableField El valor del campo no puede ser modificado.
dbDescending El campo está ordenado de
forma descendente (Z-A o 100-0) (sólo se
aplica a objetos Field de una colección Fields de un
objeto Index). Si se omite esta constante, el campo se ordena ascendentemente
(A-Z o 0-100) (predeterminado).
dbAutoIncrField es la constante a utilizar cuando queremos crear un
campo que se vaya incrementando cada vez que se introduce un nuevo registro (Campo Contador). Por ejemplo, si hemos
creado un campo denominado ID que será el contador de una serie de registros, y
queremos que se incremente en 1 cada vez que añadamos un registro, debemos usar
la propiedad Attributes ANTES de añadir ese campo al objeto TableDef
correspondiente, de la siguiente forma :
Set
micampo1N = mitabla01.CreateField("ID", 4) ‘ Creamos el campo ID
micampo1N.Required
= True ‘
La propiedad Required la veremos
micampo1N.Attributes
= dbAutoIncrField ‘ Le
damos atributo de contador
mitabla01.Fields.Append
micampo11 ‘
Añadimos el campo a la tabla
Propiedad Size
Devuelve
o establece un valor que indica el tamaño máximo, en bytes, de un objeto Field
que contiene texto o el tamaño fijo de un objeto Field que contiene texto o
valores numéricos. En objetos no agregados a una colección Fields, esta
propiedad es de lectura/escritura.
Sintaxis objeto.Size [= valor]
objeto Nombre del objeto Field.
valor Una constante o valor que indica el
tamaño máximo, como se describe a
continuación. (El tipo de datos es
Integer).
Constante Valor Descripción
dbBoolean 1 True/False
dbByte 1 Byte
dbInteger 2 Integer
dbLong 4 Long
dbCurrency 8 Currency
dbSingle 4 Single
dbDouble 8 Double
dbDate 8 Fecha/Hora
dbText 1-255 Texto
dbLongBinary 0 Long
Binary (Objeto OLE)
dbMemo 0 Memo
FIN DE LAS PROPIEDADES TYPE, ATTRIBUTES
Y SIZE REFERIDAS A LOS CAMPOS
CONSULTAS DE ACCESS
Pero
habrá observado que una base de datos ACCESS puede contener, además de tablas,
CONSULTAS. Estas consultas son los objetos QueryDef. Vamos a crear una consulta
en la base ACCESS mediante el Método CreateQueryDef
Método CreateQueryDef
Antes
de utilizar el método CreateQueryDef
debe declarar el nombre de los objetos a crear, declarándolos como Variables
Objeto tipo QueryDef . El ámbito es igual que para cualquier variable:
Public MiConsulta1 as QueryDef
Public MiConsulta2 as QueryDef
Ahora
podemos utilizar el método CreateQueryDef
para crear el nuevo objeto QueryDef en la base de datos.
Sintaxis Con la fórmula de siempre :
Set MiConsulta1
= MiBaseDatos.CreateQueryDef ([Nombre][, Texto_sql])
Donde
MiConsulta1 es una
variable del tipo QueryDef que previamente se ha declarado como tal. Será el
nombre por el que llamemos al Objeto QueryDef en el código de nuestra
aplicación.
MiBaseDatos es el nombre del objeto Database abierto en el que
vamos a introducir el nuevo objeto
QueryDef.
Nombre es una expresión de cadena que representa el nombre
de la nueva consulta que vamos a crear. Puede omitir este parámetro a la hora
de crear el QueryDef, y ponerle el nombre con posterioridad.
Texto_sql es una
expresión de cadena (instrucción SQL válida) que define el objeto QueryDef.
Lógicamente
una consulta nos debe suministrar una serie de datos de una o mas tablas. Esos
datos no tienen porqué ser todos los datos de las tablas. Texto_sql es precisamente el filtro de esos datos (expresado
mediante una cláusula SQL). Si se omite el argumento Texto_sql, puede definirse el objeto QueryDef estableciendo un
valor en su propiedad SQL antes o después de agregarlo a una colección.
Vea
la Ayuda de Visual Basic para mayor información.
Una
vez creado el objeto QueryDef, no es necesario añadirlo a la colección
QueryDefs de la Base de Datos, excepto que hayamos creado el objeto QueryDef
sin nombre. (Sin haber puesto el parámetro Nombre, según se comentó mas atrás).
Para añadirlo a la colección QueryDefs :
MiBaseDatos.QueryDefs.Append MiConsulta1
Veamos
ahora con detalle el Método Append
Método Append
Agrega
un nuevo objeto para acceso a datos a una colección. Observe que Append añade un objeto a una colección.
Por ejemplo, añade un campo a la colección Fields (Fíjese en el plural) de un
objeto TableDef, o una tabla a la colección TableDefs de un Objeto Database.
Sintaxis colección.Append objeto
colección Cualquier
colección que admita nuevos objetos (las limitaciones se indican en
la tabla siguiente).
objeto Variable
de un tipo de dato objeto que identifica el objeto a agregar, que debe
ser del mismo tipo que los elementos de
colección.
Entre
los usos del método Append se encuentran
agregar una nueva tabla a una base de datos, agregar un campo a una tabla o un
campo a un índice.
El
objeto agregado se convierte en un objeto persistente y se almacena en disco,
hasta que se lo elimine con el método Delete.
Si la colección es Workspaces (que sólo se almacena en la memoria), el objeto
seguirá activo hasta que se lo elimine con el método Close.
La
adición de un nuevo objeto se produce inmediatamente, pero se debe utilizar el
método Refresh en las restantes
colecciones que puedan verse afectadas por los cambios en la estructura de la
base de datos.
En
la tabla siguiente se muestran algunas limitaciones en el uso del método
Append. El objeto de la primera columna contiene a la colección de la segunda.
La tercera columna indica cuándo se puede agregar un objeto a la colección.
Esta lista contempla solamente los objetos estudiados hasta ahora. Consulte la
Ayuda de VB para ver la lista completa de limitaciones.
Objeto Colección Cuándo puede utilizarse Append
DBEngine Workspaces Siempre
DBEngine Errors Nunca.
Los errores se anexan automáticamente..
Workspace Databases No.
Con el método OpenDatabase se anexan automáticamente.
Workspace Groups Sí
Workspace Users Sí
Database QueryDefs Sólo
cuando el QueryDef lo hemos creado sin
nombre.
Database Recordsets No.
Se anexan automáticamente.
Database TableDefs Sí
Group Users Sí
User Groups Sí
QueryDef Fields No
Recordset Fields No
TableDef Fields Sólo
cuando la propiedad Updatable del objeto TableDef se
establece a True o cuando el objeto TableDef no está
anexado.
Tabledef Indexes Sólo
cuando la propiedad Updatable del objeto TableDef se
establece a True o cuando el objeto TableDef no está
anexado.
Index Fields Sólo cuando el objeto Index es un objeto nuevo no anexado.
Como
ejemplo, para añadir los campos MiCampo11, ....., MiCampo13 al objeto TableDef
MiTabala1, los campos MiCampo21, ..... , MiCampo23 al Objeto MiTabla2, y los
campos MiCampo31, .... , MiCampo33 al objeto Mitabla3, y estas tres tablas al
Objeto MiBaseDatos, usaremos las siguientes sentencias :
MiTabla1.Append MiCampo11
...
MiTabla1.Append MiCampo13
MiTabla2.Append MiCampo21
...
MiTabla2.Append MiCampo23
MiTabla3.Append MiCampo31
...
MiTabla31.Append MiCampo33
MiBaseDatos.Append MiTabla1
MiBaseDatos.Append MiTabla2
MiBaseDatos.Append MiTabla3
El
orden debe ser el indicado, primero se añaden los campos a la tabla y luego las
tablas a la base de datos.
Los
nombres MiCampoxx, Mitablax y MiBaseDatos son los nombres de los objetos DAO
que ha creado, NO los nombres ‘físicos’ del campo, de la tabla o de la base de
datos, entendiendo por nombres ‘físicos’ el nombre del fichero de la base de
datos, el nombre de la tabla en esa base de datos o el nombre del campo dentro
de esa tabla.
Relaciones
Ya
tenemos la base de datos completamente creada. Sin embargo alguien dirá que le
falta algo : Relacionar dos tablas
Una
Relación es una asociación establecida entre dos campos del mismo tipo ubicados
en dos tablas distintas. Se pueden establecer relaciones uno a uno ó uno a
varios. Para relacionar un campo con otros, ese campo debe ser clave maestra. A
la tabla que contiene a este campo se le llama Tabla principal. A la tabla que
contiene el campo (o los campos) relacionados se le llama Tabla Relacionada.
Para
crear una relación, usaremos un nuevo objeto DAO : El objeto Relation. Este objeto forma parte de
una colección, que es a su ves otro objeto DAO : el objeto Relations.
Para
crear una relación usaremos el Método CreateRelation,
que es un método del objeto Database. Como para cualquier otro objeto DAO, es
necesario declararlo :
Dim MiRelacion as Relation
Declaramos
también un objeto DAO tipo Field, llamado MiCampo, pues deberemos hacer una
cosa similar a la que hacíamos para el método CreateIndex
Dim MiCampo as Field
Supongamos
que queremos crear una relación en la base de datos creada en el ejemplo
anterior, y queremos relacionar el campo Campo11
que está en Tabla1 y que lo habíamos
hecho clave maestra, con el campo Campo21
de Tabla2. Tabla1 y Tabla2
son los nombres reales de las tablas, NO los nombres de los objetos Tabledef.
El
ejemplo que trae la ayuda de VB puede ser muy aclaratorio, pero le advertimos
lo mismo que para los índices,
paciencia. Una vez creada la
relación, podrá comprobarlo visualizándola con el visor de relaciones del
Access
Suponemos
que la base de datos está abierta. Si no lo está, la abrimos.
Set MiBaseDatos =
Workspaces(0).OpenDatabase("MIBD.MDB")
Creamos
el objeto Relation, que tendrá por nombre RelacionUno, pero este nombre NO debe
confundirse con el nombre del objeto DAO Relation, que es MiRelacion
Set MiRelacion = MiBaseDatos.CreateRelation("RelacionUno")
Una
vez creada, le decimos a MiRelacion cual es la Tabla principal
MiRelación.Table
= "MiTabla1" 'Nombre de la
tabla principal.
Le
decimos cual es el nombre de la tabla relacionada
MiRelación.ForeignTable = "Tabla2"
Le
ponemos los atributos a la relación. En este caso dbRelationUpdateCascade, para
que, si hacemos un cambio en el valor del campo de la tabla principal, ese
cambio se refleje en el campo o los campos relacionados con el.
MiRelación.Attributes
= dbRelationUpdateCascade
Le
decimos cual es el nombre del campo de la tabla principal que vamos a
relacionar
Set MiCampo = MiRelación.CreateField("Campo11")
Le
recordamos lo de antes. Campo11 debe
estar ya creado en la tabla Tabla1. Parece un poco ilógico usar el método CreateField para un campo que ya está
creado. Pero eso sí, aquí CreateField es un método del objeto DAO Relation, no
del objeto DAO Tabledef.
Le
decimos ahora cual es el nombre del campo en la tabla relacionada
MiCampo.ForeignName
= "Campo21"
Añadimos
el campo creado a la colección Fields del objeto Relation
MiRelación.Fields.Append MiCampo
Y
ahora añadimos el objeto Relation recién creado a la colección Relations del
objeto Database
MiBaseDatos.Relations.Append MiRelación
Solamente
nos falta ver que valores puede tener la propiedad Attributes del objeto Relation
dbRelationUnique La relación es uno a uno.
dbRelationDontEnforce La relación no es impuesta (no
hay integridad referencial).
dbRelationInherited La relación existe en una base de
datos no activa que contiene
las dos tablas vinculadas.
dbRelationUpdateCascade Las actualizaciones se realizarán en cascada.
dbRelationDeleteCascade Las eliminaciones se realizarán en cascada.
PROPIEDADES DEL OBJETO DATABASE
Name (Aplicable a todos los objetos DAO)
Devuelve
el nombre, definido por el usuario,
de un objeto de acceso a datos.
Sintaxis Nombre
= objeto.Name
donde
nombre es una expresión de cadena que especifica un nombre. El nombre debe
empezar por una letra y puede contener un máximo de 40 caracteres. Puede
incluir números subrayados pero no puede incluir signos de puntuación ni
espacios. (El tipo de datos es String).
Los
objetos TableDef y QueryDef no pueden compartir el
mismo nombre, ni tampoco los objetos User y Group.
El
uso de lectura/escritura en la propiedad Name depende del tipo de objeto al que
se aplica, pero independientemente del tipo de objeto, la propiedad Name es de
sólo lectura, una vez que se haya agregado a una colección.
Recuerde
que la Propiedad Name de un Objeto DAO es el nombre por el que nos referimos a
ese objeto en el código de la aplicación, NO, por ejemplo, el nombre del
fichero que contiene la Base de Datos en el disco.
El
fichero que contiene la base de datos puede ser C :\CEU\ALUMNOS.MDB, y en
nuestra aplicación el Name del
objeto Database es MiBase, ya que la hemos abierto con la sentencia :
Set MiBase =
Workspaces(0).OpenDatabase (“C :\CEU\ALUMNOS.MDB”)
Connect
Esta
propiedad nos permite indicarle el origen de la base de datos. No es necesario
para bases de datos Access. Es necesario para anexar tablas de otras bases de
datos. Lo verá en el siguiente capítulo.
Updatable
Devuelve
un valor que indica si pueden hacerse cambios sobre un objeto de acceso a
datos. Esta propiedad es solo de lectura. Devuelve un valor True / False que
indica si la base abierta permite ser cambiada o actualizada, y False en caso
contrario.
Sintaxis objeto.Updatable
CollatingOrder
Devuelve
un valor que especifica la secuencia del orden del texto en comparación de
cadenas u ordenación. El valor de esta propiedad es de sólo lectura. Esta
propiedad corresponde al parámetro inf_local introducido al crear la base de datos.
Sintaxis Variable
= NombredelaBase.CollatingOrder
Variable
contendrá el valor de la constante, p. e. dbLangGeneral
QueryTimeout
Devuelve
o establece un valor que especifica el número de segundos que el motor de base
de datos Microsoft Jet espera antes de producir un error de tiempo de espera
cuando se ejecuta una consulta en una base de datos ODBC.
Sintaxis objeto.QueryTimeout [= valor]
objeto Nombre del
objeto Database
valor Un entero que representa el
número de segundos que el motor de base de datos Jet
espera antes de devolver un error de tiempo de
espera. (El tipo de datos es Integer).
Cuando
se usa con objeto Database, la propiedad QueryTimeout
especifica un valor global para todas las consultas asociadas con dicha base de
datos.
El
valor de tiempo de espera predeterminado es de 60 segundos. El valor asignado a
QueryTimeout en un objeto Database prevalece sobre el valor predeterminado.
Count
Devuelve
el número de objetos de una colección. Al referirse a una colección, no se
puede referir a un objeto Database, sino a un objeto Databases (plural) o a cualquier colección (plural) de
objetos DAO.
Sintaxis Variable = objeto.Count
El
valor de la propiedad Count es un entero de tipo Long.
Los
miembros de una colección se numeran a partir de 0, de forma que los bucles
siempre se codifican comenzando por el miembro número 0. Por ejemplo:
For I = 0 To Workspaces(0).Databases.Count
- 1
...
Next
I
Nota También puede utilizar la sintaxis For Each objeto In Colección para
enumerar todos los miembros de una colección. Por ejemplo:
Dim
MiBd as Database
For Each MiBd In
Workspaces(0).Databases
Debug.Print MiBd.Name
Next
El
valor de la propiedad Count nunca es Null. Cuando es 0, no hay ningún objeto en
la colección. No existiría esa colección.
Version
Devuelve
un valor que indica la versión de la base de datos o motor de base de datos
asociado con el objeto. El valor de esta propiedad es de sólo lectura.
Sintaxis objeto.Version
Valores
devueltos
El
valor devuelto por la propiedad Version es una expresión de cadena cuyo
resultado es un valor, que para el objeto Database identifica la versión del
motor de base de datos Jet que ha creado la base de datos.
METODOS
DEL OBJETO DATABASE
Se
enumeran los métodos del objetos Database,
resaltando en negrita los vistos hasta este momento. Se verán al final del
capítulo los métodos no vistos mas importantes.
BeginTrans Close CommitTrans CreateDynaset
CreateProperty CreateQueryDef CreateRelation CreateSnapshot
CreateTableDef DeleteQueryDef Execute ExecuteSQL
OpenQueryDef OpenRecordset OpenTable Rollback
Objeto TableDef
Un
objeto TableDef representa la
definición de una tabla de una base
de datos.
Una
colección TableDefs contiene todos
los objetos TableDef almacenados de
una base de datos. Como ya se ha comentado la forma de crear una tabla, vamos a
comentar solamente las propiedades y métodos del objeto TableDef
Un
objeto TableDef contiene las
siguientes colecciones, métodos y propiedades: (las que ya se han visto están
resaltadas en negrita)
COLECCIONES
Fields (predeterminada) Indexes Properties
METODOS
CreateField CreateIndex CreateProperty OpenRecordset RefreshLink
PROPIEDADES
Attributes RecordCount Connect SourceTableName DateCreated
Updatable LastUpdated ValidationRule Name ValidationText
Una
colección TableDefs contiene los
siguientes métodos y propiedades:
METODOS
Append Delete Refresh
PROPIEDAD : Count
Comentaremos
en primer lugar los métodos. Uno de ellos, CreateField
ya se ha visto, y su misión es crear los campos que van a formar parte de
una tabla.
Otro
de los métodos es OpenRecordset. Este método se emplea para abrir un
Recordset. Observe que este método también lo tiene el objeto Database. Pero
también es un método del objeto QueryDef y del propio objeto Recordset. Esto
significa que este método bien lo podemos emplear con un objeto Database (Así
se hace normalmente) o con un objeto TableDef, QueryDef o incluso con otro
Recordset. Poco podríamos explicar este
método si no sabemos que es un Recordset. Por ello, se va a explicar a
continuación.
EL OBJETO RECORDSET ( O la mitad de lo que Vd. necesita saber
de Bases de Datos)
Un
objeto Recordset representa
registros de una tabla base o los registros resultantes de la ejecución de una
consulta.
La
colección Recordsets contiene todos
los objetos Recordset abiertos de un
objeto Database.
Al
utilizar objetos de acceso a datos, casi toda la interacción con los datos se
produce a través de objetos Recordset.
Todos los objetos Recordset están
formados por registros (filas) y campos (columnas). Existen tres tipos de
objetos Recordset:
Recordset
de tipo tabla: Representación en
código de una tabla base de datos que puede utilizarse para agregar, modificar
o eliminar registros de una sola tabla de base de datos. Un Recordset tipo
Tabla contiene todos los campos de una tabla y no puede contener campos que no
pertenezcan a esa tabla.
Recordset
de tipo hoja de respuestas dinámica: Resultado de una consulta que puede tener registros actualizables. Un
Recordset de tipo hoja de respuestas dinámica es un conjunto dinámico de
registros que puede utilizarse para agregar, modificar o eliminar registros de
una o más tablas de una base de datos subyacente. Este tipo de objeto Recordset
puede contener campos de una o más tablas de una base de datos.
Recordset
de tipo instantánea: Copia
estática de un conjunto de registros que puede utilizarse para buscar datos o
generar informes. Los objetos Recordset de tipo instantánea pueden contener
campos de una o más tablas de una base de datos, pero no pueden actualizarse.
Puede
elegir el tipo de objeto Recordset a crear mediante el argumento tipo del método OpenRecordset.
Resumiendo,
un Recordset es un conjunto de registros. Recuerde cuando explicábamos en
control Data se decía que este control creaba un Recordset a partir de sus
propiedades DatabaseName y RecordSource. De esta forma, el conjunto de
registros que tiene ese control Data es la totalidad de los registros de la
tabla (o consulta) que poníamos en la propiedad RecordSource. Pero siempre
podemos asignar a la propiedad Recordset de ese control Data un Recordset ya
creado mediante código. Y en ese caso, solamente contendrá los campos que a
nosotros nos interese, incluso campos de distintas tablas, cosa que viene muy
bien algunas veces.
Un
Recordset lo crearemos con el método OpenRecordset
que estamos estudiando. Como se trata de un método de los objetos Database, y
de los objetos TableDef , QueryDef y Recordset, podemos abrir un Recordset desde cualquiera de ellos. Antes de
abrirlo, debemos declarar de la forma correcta el nombre que va a tener el
Objeto Recordset que se va a abrir :
Public Mirecordset As Recordset
Una
vez declarado, para abrirlo basta con ejecutar la sentencia :
Set
Mirecordset = base_datos.OpenRecordset (origen[, tipo[, opciones]])
Set
Mirecordset = Objeto.OpenRecordset ([tipo[, opciones]])
La
diferencia entre las dos formas, es que en la primera se ha abierto
directamente desde el Objeto Database,
(base_datos = nombre del
objeto Database), y en origen le
debemos expresar la tabla o tablas (Objetos TableDef) (o QueryDef, consulta)
donde debe buscar los registros. En la segunda forma, se abre directamente de
un objeto TableDef, QueryDef o Recordset, con lo que ya no es necesario expresar la tabla o tablas
de origen, ya que cualquiera de estos tres objetos lleva implícito la elección
de una serie de registros de una o varias tablas. Observe que si abre un Recordset desde una Tabla o QueryDef, ese
Recordset contendrá todos los registros de esa Tabla o QueryDef. No puede
elegir solo una parte de los registros que contiene esa tabla o QueryDef
Al
crear un nuevo objeto Recordset se agrega automáticamente a la colección
Recordsets.
Si
Objeto
hace referencia a un objeto Recordset de tipo instantánea u hoja de respuestas
dinámica, el tipo del nuevo objeto será el mismo. Si objeto se refiere a un
objeto Recordset de tipo tabla, el nuevo será un Recordset de tipo hoja de
respuestas dinámica.
Origen en la primera expresión es una variable de tipo
String que especifica el origen de los registros del nuevo objeto Recordset. El
origen puede ser un nombre de tabla, un nombre de consulta o una instrucción
SQL que devuelva registros. En el caso de los objetos Recordset de tipo tabla,
el origen sólo puede ser un nombre de tabla.
Tipo es el tipo de Recordset que se quiere crear. Si no se
especifica un tipo, OpenRecordset creará un objeto Recordset de tipo tabla
cuando sea posible. (Cuando especifica como Origen
el nombre de una Tabla) Si se especifica una consulta o una tabla adjunta,
OpenRecordset creará un objeto Recordset de tipo hoja de respuestas dinámica.
El tipo del nuevo objeto Recordset se define mediante una de las siguientes
constantes :
dbOpenTable para abrir un
objeto Recordset de tipo tabla.
dbOpenDynaset para abrir un
objeto Recordset de tipo hoja de respuestas dinámica.
dbOpenSnapshot para abrir un
objeto Recordset de tipo instantánea.
El
parámetro opciones permite especificar las características del nuevo
objeto Recordset tales como las restricciones de edición y consulta para otros
usuarios. Vea la Ayuda de VB para mayor detalle.
Los
objetos Recordset se eliminan automáticamente de la colección Recordsets al
cerrarlos con el método Close.
Ejemplo de creación de un Objeto
Recordset
Decíamos
que se puede crear un Recordset con la sentencia :
Recuerde
la Fórmula general Set DAOinf = DAOsup.Método ( - - - - - - - )
Set
Mirecordset = base_datos.OpenRecordset (origen[, tipo[, opciones]])
Si
tenemos abierta una base de datos llamada MiBaseDatos,
podemos crear el objeto MiRecordset
eligiendo de la tabla MiTabla de esa
base de datos los campos Campo1, Campo2 y Campo3, y que sea del tipo de hoja de respuestas dinámica, de la
siguiente forma :
Set Mirecordset = MiBaseDatos.OpenRecordset (“SELECT Campo1, Campo2, Campo3 _ FROM MiTabla”, dbOpenDynaset)
Si
deseamos que el Recordset contenga todos los campos de esa misma tabla :
Set Mirecordset=MiBaseDatos.OpenRecordset (“SELECT * FROM MiTabla”, dbOpenDynaset)
o
simplemente sin utilizar la sentencia SQL :
Set Mirecordset = MiBaseDatos.OpenRecordset (MiTabla, dbOpenDynaset)
En
los ejemplos anteriores no se ha establecido ningún parámetro en Opciones.
Si
desde el Recordset anterior, queremos crear un nuevo Recordset denominado
MiRecordset1, que tenga la condición de que sea solo lectura, usaremos la
sentencia :
Set Mirecordset1 = Mirecordset.OpenRecordset (dbReadOnly)
Este
nuevo Recordset contendrá los mismos campos que el Recordset origen, pero no
podremos cambiar datos en él.
Pueden
crearse tantos Recordsets como se necesiten. Estos Recordsets pueden tener
campos comunes. Es más, podríamos crear dos Recordsets exactamente iguales.
Pero
en la mayoría de los casos, necesitaremos crear un Recordset donde se elijan
varios campos de una o varias tablas, seleccionando de esos campos unos
determinados valores. Por ejemplo, en una base con las direcciones de los
clientes, a lo mejor queremos seleccionar todas aquellas direcciones en las
cuales el código postal sea el 28700 (San Sebastián de los Reyes). Imaginemos
que hemos abierto la base de datos con el nombre CLIENTES (Recuerde que este es
el nombre del objeto DAO usado para abrir la B.D., no el nombre que pueda tener
esa B.D. en el disco), y esta base de datos tiene una tabla llamada DIRECCIONES
(Este sí es el nombre real de la tabla dentro de la B.D.) Vamos a abrir un Recordset con todos los
clientes de San Sebastián de los Reyes :
Set Mirecordset2 = CLIENTES.OpenRecordset (“SELECT * FROM
DIRECCIONES WHERE COD_POSTAL = 28700“, dbOpenDynaset)
El
Recordset Mirecordset2 contiene todos los campos de todos los registros de la
tabla DIRECCIONES que cumplan la condición de que el código postal (campo
COD_POSTAL en el ejemplo) sea igual a 28700.
Observe
en esta y anteriores expresiones, que la sentencia SQL está entre doble
comilla.
Podemos
introducir cualquier sentencia SQL para determinar qué registros introducimos
en el Recordset. Por ejemplo, si queremos seleccionar todos los clientes de
Madrid (su código postal comenzará necesariamente por 28 y le seguirán tres
cifras) :
Set Mirecordset2 = CLIENTES.OpenRecordset (“SELECT * FROM
DIRECCIONES WHERE COD_POSTAL LIKE 28???“, dbOpenDynaset)
Propiedad RecordCount
Devuelve
el número de registros accedidos en un objeto Recordset. El valor de esta
propiedad es de sólo lectura. (El
objeto TableDef también tiene la propiedad RecordCount)
Sintaxis NombredeMiRecordset.RecordCount
Donde
NombredeMiRecordset ES un objeto Recordset. El valor devuelto por la
propiedad RecordCount es un Long in
(NombredeMiRecordset
puede ser también un objeto Dynaset, un objeto Snapshot o un objeto Table.
Los objetos Dynaset, Snapshot y Table son objetos obsoletos que se mantienen
por razones de compatibilidad)
(Puede
emplear la misma sintaxis para conocer los registros de un objeto TableDef)
Use
la propiedad RecordCount para saber a cuantos registros se accede en un objeto
Recordset o TableDef. RecordCount no indica cuantos registros se contienen en
un Recordset de tipo hoja de respuestas dinámica o instantánea hasta que se ha
accedido a todos los registros.
Para
que el método RecordCount le
devuelva el número de registros existentes, tiene que acceder previamente al primero y al último. El acceder al primero es fácil, ya que nada mas crearse el
Recordset, el primer registro se convierte en Registro actual. Pero si en estas
condiciones intenta usar el método RecordCount, la respuesta será que tiene 0
registros. Acceda al último registro mediante el método MoveLast. A partir de
ese momento, ya le indicará el número correcto de registros existentes.
Un
Recordset o TableDef sin registros tienen 0 como valor de la propiedad
RecordCount.
Veamos
unos Métodos importantes del Objeto Recordset para añadir o modificar el
contenido de registros :
Si
queremos añadir un registro a un Recordset, se utilizará el Método AddNew :
Método AddNew
Crea
un nuevo registro en un objeto Recordset de tipo tabla u hoja de respuestas
dinámica.
Sintaxis MiRecordset.AddNew
El
método AddNew crea un nuevo registro que puede editar y agregar al objeto
Recordset. Este método establece en los campos el valor Null (predeterminado
para los objetos Recordset de tipo tabla) o los valores predeterminados, si
existen. El registro creado queda en la memoria, y ahí se puede modificar
simplemente asignando a cada campo el valor deseado. Para asignar un valor a un
campo simplemente tenemos que poner la expresión :
MiRecordset ! MiCampo1 = “Dato
tipo string”
MiRecordset ! MiCampo2 = Dato
tipo numérico
Una
vez que se hayan introducido los datos en el nuevo registro, debe utilizar el
método Update para guardar los
cambios y agregarlo al conjunto de registros. No se modificará la base de datos
hasta que se utilice el método Update.
La
posición del nuevo registro depende del tipo de objeto Recordset:
En
un objeto Recordset de tipo hoja de respuestas dinámica, los registros se
insertan al final del conjunto, independientemente de las reglas de ordenación
que pueda haber en vigor al abrir el conjunto de registros. En un objeto
Recordset de tipo tabla cuya propiedad Index esté definida, los registros se
agregan en el lugar correspondiente al orden. Si no se ha establecido la
propiedad Index, los nuevos registros se agregan al final del conjunto.
El
registro que era actual antes de utilizar el método AddNew continúa siéndolo después. Esto puede comprobarlo asignando
a un Label el contenido de un campo, añadir un registro con un valor para ese
campo distinto al que está presente en el Label y comprobar que el contenido
del Label no se ve afectado por haber introducido un registro nuevo. Si desea
hacer que el nuevo registro sea el actual, puede establecer en la propiedad Bookmark el marcador identificado por
el valor de la propiedad LastModified.
En la práctica anterior observará tras este proceso que se cambia el contenido
del Label al nuevo valor.
Vea
la propiedad LastModified un poco
mas adelante.
Si
queremos modificar el contenido de un registro ya existente en un Recordset,
utilizaremos el Método Edit :
Método Edit
Copia
el registro actual de un objeto Recordset de tipo hoja de respuestas dinámica o
tabla en el búfer de copia para su edición.
Sintaxis MiRecordset.Edit
Donde
MiRecordset representa el nombre de un objeto Recordset abierto y actualizable
que contiene el registro a editar.
Una
vez invocado el método Edit, los cambios efectuados en los campos del registro
actual se copian en el búfer de copia. Al terminar de realizar los cambios
deseados, utilice el método Update para guardarlos. Como en el caso del método
AddNew este registro modificado está en la memoria y es necesario introducirlo
en la BD.
El
registro actual continúa siéndolo después de utilizar Edit. Para poder usar
Edit debe existir un registro actual. Si no es así o si MiRecordset no se
refiere a un objeto Recordset de tipo tabla u hoja de respuestas dinámica, a un
objeto Table o a un objeto Dynaset abierto, se producirá un error.
El
uso de Edit producirá un error en las condiciones siguientes:
No hay registro actual.
La base de datos o el conjunto de
registros es de sólo lectura.
Ningún campo del registro es
actualizable.
Otro usuario ha abierto la base de
datos o el conjunto de registros para uso exclusivo.
Otro usuario ha bloqueado la página
que contiene el registro.
Una
vez añadido el registro, o cambiados los datos de un registro, debemos utilizar
el Método Update para guardar los datos en la BD.
Método Update
Guarda
el contenido del búfer de copia en un objeto Recordset de tipo hoja de
respuestas dinámica o tabla especificado.
Es
decir, mete en la Base de Datos el contenido del registro que estaba en la
memoria, bien por haber utilizado el método Update, bien por haber utilizado el
método Edit.
Sintaxis MiRecordset.Update
Donde
MiRecordset representa el nombre de un objeto Recordset de tipo hoja de
respuestas dinámica o tabla, abierto y actualizable.
Utilice
Update para guardar el registro actual y los cambios que haya realizado en él.
Los
cambios en el registro actual se perderán en las siguientes situaciones:
Uso
del método Edit o AddNew y desplazamiento a otro registro sin utilizar antes
Update.
Uso
de Edit o AddNew y utilización de nuevo de Edit o AddNew sin especificar antes
Update.
Establecimiento
de otro registro en la propiedad Bookmark.
Cierre
del conjunto de registros indicado en MiRecordset sin utilizar antes Update.
Cada
vez que se crea o edita un registro se cambia el valor de la propiedad LastModified, que tomará el marcador de
ese registro creado o editado.
Método CancelUpdate
Cancela
todas las actualizaciones pendientes del objeto Recordset.
Sintaxis recordset.CancelUpdateTipo
Tipo
puede tomar los siguientes valores
dbUpdateRegular Cancela los cambios pendientes que no están
en la memoria caché.
dbUpdateBatch Cancela los cambios pendientes
en la memoria cache actualizada.
Comentarios
El
método CancelUpdate cancela todas las actualizaciones pendientes a causa de una
operación Edit o AddNew. La utilización del método CancelUpdate tiene el mismo
efecto que moverse a otro registro sin utilizar el método Update, salvo que el
registro activo no cambia y algunas propiedades, como BOF y EOF, no se
actualizan.
Método Delete
Este
método elimina el registro actual de un objeto Recordset de tipo hoja de
respuestas dinámica o tabla. Para eliminar un registro, debe haber un registro
actual en el Recordset antes de utilizar Delete,
pues de lo contrario se producirá un error interceptable. Una vez eliminado,
este registro sigue siendo el registro actual. Puede observar, que si a
continuación de Delete utiliza AbsolutePosition para conocer en que registro
está, la respuesta será -1, prueba de que está sobre un registro inexistente.
Propiedad Bookmark
Devuelve
o establece un marcador que identifica de forma única el registro actual de un
objeto Recordset o define el registro actual de un Recordset como marcador
válido.
Sintaxis MiRecordset.Bookmark [= valor]
Donde
MiRecordset es el nombre del Recordset, y valor es una expresión de cadena o
expresión Variant cuyo resultado es un marcador válido. (El tipo de datos es
String o Variant).
En
un Recordset basado completamente en tablas del motor de base de datos Microsoft
Jet, el valor de la propiedad
Bookmarkable es True y pueden usarse marcadores. Sin embargo, otros
productos de bases de datos pueden no aceptar los marcadores. Por ejemplo, no
se pueden usar marcadores en un Recordset basado en una tabla anexa Paradox que
no tiene clave principal.
Cuando
se abre o se crea un objeto Recordset, cada uno de sus registros tiene un
marcador único. El marcador del registro actual puede guardarse asignando el
valor de la propiedad Bookmark a una variable. Para volver a dicho registro
rápidamente después de haberse movido a un registro diferente, establezca la
propiedad Bookmark del objeto Recordset al valor de dicha variable.
En
Visual Basic versión 4.0, la propiedad Bookmark se almacena internamente como
matriz de Byte. Por esta razón, si se intenta usar la propiedad Bookmark en una
operación de comparación, se producirá un error interceptable. Antes de tener
acceso a la propiedad Bookmark, copie los valores de los marcadores a variables
cadena y efectúe las comparaciones usando dichas variables cadena. Por ejemplo,
el siguiente código compara marcadores en dos objetos Recordset:
Dim Marca1 as String, Marca2
as String
Dim Rs1 as Recordset, Rs2 as
Recordset
Set Rs1 =
Db.OpenRecordset("Títulos")
Set Rs2 = Rs1.Clone()
Marca1 = Rs1.Bookmark
Marca2 = Rs2.Bookmark
If
Marca1 = Marca2 Then Print "Esta comparación es válida "
No
intente realizar la siguiente comparación, aunque a primera vista parezca igual :
If Rs1.Bookmark = Rs2.Bookmark Then ..... Porque dará error.
No
hay límite en el número de marcadores que pueden establecerse. Para crear un
marcador para otro registro distinto del registro actual, muévase al registro
deseado y asigne el valor de la propiedad Bookmark a una variable String que
identificará el registro.
Para
asegurarse de que el Recordset acepta marcadores, inspeccione el valor de su
propiedad Bookmarkable antes de usar la propiedad Bookmark. Si Bookmarkable es
False, el Recordset no acepta marcadores, y el uso de la propiedad Bookmark
produce un error interceptable.
Si
la propiedad Bookmark se establece a un valor que corresponda a un registro
eliminado, se produce un error interceptable.
Para
actualizar el contenido de un registro, vuelva a definir la propiedad Bookmark
a sí misma. (Sin embargo, esta técnica, también cancela todas las operaciones
pendientes invocadas por los métodos Edit o AddNew). Por ejemplo:
Rst.Bookmark
= Rst.Bookmark
¡¡¡ El valor de la propiedad Bookmark no es
igual que el número de un registro. !!!
Propiedad LastModified
Devuelve
un marcador que indica el registro más recientemente agregado o modificado.
Sintaxis NombreRecordset.LastModified
El
valor devuelto por esta propiedad es un tipo de datos Variant o String. (Similar al devuelto por
Bookmark) LastModified se puede usar
para colocarse en el registro más recientemente agregado o actualizado.
Esta
propiedad puede usarse para volver al último registro que ha sido modificado.
Basta para ello igualar la propiedad Bookmark a la propiedad
LastModified :
NombreRecordset.Bookmark = NombreRecordset.LastModified
Métodos
MoveFirst, MoveLast, MoveNext, MovePrevious
Se
sitúan en el primer, el último, el siguiente o el anterior registro del objeto
Recordset especificado y lo convierten en el registro actual.
Sintaxis MiRecordset.{MoveFirst | MoveLast | MoveNext | MovePrevious}
Puede
utilizar los métodos Move para
desplazarse de un registro a otro sin aplicar una condición.
Al
abrir el conjunto de registros indicado en Recordset, el primer registro pasa a
ser el registro actual y en la propiedad BOF se establece False. Si el conjunto
no contiene ningún registro, se establecerá en BOF el valor True y no habrá
registro actual.
Si
el primer o el último registro ya es el actual al utilizar MoveFirst o MoveLast, el
registro actual no varía.
Si
utiliza MovePrevious cuando el
registro actual sea el primero, en la propiedad BOF se establecerá True y no
habrá registro actual. Si utiliza de nuevo MovePrevious, se producirá un error
y BOF continuará con el valor True.
Si
utiliza MoveNext cuando el registro
actual sea el último, en la propiedad EOF se establecerá True y no habrá
registro actual. Si utiliza de nuevo MoveNext, se producirá un error y EOF
continuará con el valor True.
Si
Recordset hace referencia a un objeto Recordset de tipo tabla o a un objeto
Table, el movimiento se hará según el índice actual de la tabla. Para
establecer el índice actual puede usar la propiedad Index. Si no establece un
índice actual, el orden de los registros devueltos no estará definido.
Si
utiliza MoveLast en un objeto
Recordset basado en una consulta SQL o QueryDef, se forzará la terminación de
la consulta, poblando completamente el objeto Recordset.
No
es posible utilizar los métodos MoveFirst
ni MovePrevious en los Recordset tipo
snapshot de desplazamiento hacia delante.
Para
desplazar la posición del registro actual en un objeto Recordset un número de
registros determinado hacia adelante o hacia atrás, utilice el método Move.
Método Move
Desplaza
la posición del registro actual en un objeto Recordset.
Sintaxis MiRecordset.Move filas[, inicio]
Donde :
filas es un valor de tipo Long con signo que especifica el
número de filas (de registros) que se desplaza la posición. Si filas es mayor
que 0, la posición se desplaza hacia adelante (hacia el final del archivo). Si
es menor que 0, la posición se desplaza hacia atrás (hacia el principio del
archivo).
Inicio (opcional) es un valor de tipo String que identifica
un marcador. Si se especifica inicio, el desplazamiento será relativo al
marcador indicado. Si se omite, Move comenzará por el registro actual. El
marcador que debe utilizarse para definir el registro Inicio debe ser un
Bookmark o similar (LastModified, por
ejemplo)
Si
se especifica una posición anterior al primer registro, la posición del
registro actual se situará al principio del archivo (BOF). Si se especifica una
posición posterior al último registro, la posición del registro actual se
situará al final del archivo (EOF).
Si
el objeto Recordset no contiene registros y el valor de su propiedad BOF es
True, el uso de este método para desplazarse hacia atrás producirá un error
interceptable en tiempo de ejecución. Lo mismo ocurrirá si el valor de la
propiedad EOF es True y pretende desplazarse hacia adelante. Si las propiedades
BOF o EOF tienen el valor True y se intenta usar el método Move sin un marcador
válido, se generará un error interceptable.
Si
el objeto Recordset está basado en una consulta, la operación forzará la
ejecución de la consulta en el número de filas especificado..
Métodos
FindFirst, FindLast, FindNext, FindPrevious
Buscan
el primer, el último, el siguiente o el anterior registro de un objeto
Recordset de tipo instantánea u hoja de respuestas dinámica, que satisfaga el
criterio especificado y lo convierte en el registro actual.
Sintaxis MiRecordset.{FindFirst |
FindLast | FindNext | FindPrevious}
criterio
MiRecordset es el nombre de un objeto Recordset.
Criterio es una expresión de cadena (como la cláusula WHERE
de una instrucción SQL, sin la palabra WHERE) que se utiliza para buscar un
registro.
Si
no se encuentra ningún registro que satisfaga el criterio, el puntero de
registro actual se situará en el primer registro del objeto Recordset y se
establecerá en la propiedad NoMatch
el valor True. Si Recordset contiene más de un registro que satisfaga el
criterio, FindFirst hallará el
primero de ellos, FindNext el
siguiente y así sucesivamente.
Compruebe
siempre el valor de la propiedad NoMatch
para determinar si la operación de búsqueda ha tenido éxito. Si la búsqueda ha
tenido éxito, NoMatch se establece a
False. Si ha fracasado, NoMatch se establece a True y el registro actual pasa a ser el
primero del objeto Recordset. Por ejemplo:
Dim Estabaaqui as String
Estabaaqui = Recordset.Bookmark
Recordset.FindFirst "Nombre = 'Luis' " ' Busca un nombre. Recuerde siempre las
comillas dobles para la expresión de búsqueda y las
comillas simples si se trata de un dato string.
If
Recordset.NoMatch Then '
¿Se ha encontrado?
Recordset.Bookmark = Estabaaqui ' Si no se ha encontrado, vuelve al que
era el
‘registro actual.
Else '
Sí se ha encontrado.
. Aquí las instrucciones adecuadas
.
End If
No
es posible utilizar estos métodos en un objeto Recordset de tipo snapshot de
desplazamiento hacia delante.
Al
buscar campos que contengan fechas,
deberá utilizar el formato de fecha de los Estados Unidos (mes-día-año), incluso cuando no utilice la versión para este país
del motor de base de datos Jet, pues de lo contrario es posible que no se
encuentren los datos buscados. Puede utilizar la función Format para convertir la fecha. Por ejemplo:
Mirecordset.FindFirst "fecha > #"
& Format(mifecha, 'm/d/yy' ) & "#"
Observe
que las fechas, aparte de ponerlas en americano, hay que presentarlas entre
almohadillas (#). Observe lo dicho mas atrás para las comillas dobles en la
expresión de búsqueda.
De cualquier forma, cuando vaya a
buscar registros por fechas, comparar fechas o hallar diferencias de tiempo,
ármese de mucha paciencia. No se desanime si no le sale a la primera.
Método Clone
En
muchas ocasiones es necesario crear un Recordset que sea copia exacta de otro.
Las ocasiones en las que es necesario hacer esto pueden ser variadas, pero
vamos a destacar una : crear un Recordset idéntico al Recordset de un
control Data, para trabajarlo con código durante una parte de la ejecución del
programa. Otras aplicaciones pueden ser copiar el Recordset de otra máquina a
través de la Red de Area Local, ... y donde podamos llegar con nuestra imaginación.
La
sintaxis de Clone es la siguiente :
Crea
un objeto Recordset duplicado referido al objeto original. También puede
utilizar el método Clone con los antiguos objetos Dynaset, Snapshot y Table.
Sintaxis Set Duplicado = Original.Clone( )
Donde
Duplicado es una variable tipo Recordset, y Original es el Recordset que se va
a duplicar.
Con
el método Clone puede crear múltiples Recordsets. Cada uno de ellos puede tener
su propio registro actual. El uso de Clone no modifica los datos de los
registros. Puede modificar un registro desde cualquier Recordset, bien desde el
que sirvió de original, bien desde cualquiera de sus copias, pero debe hacerlo
invocando los métodos Edit - Update. Puede compartir marcadores entre dos o más
Recordsets creados de esta forma.
Puede
utilizar el método Clone cuando desee realizar en un conjunto de registros una
operación que requiera varios registros actuales. Este método es más rápido y
eficiente que crear un nuevo Recordset.
Inicialmente,
un Recordset creado con Clone carece de registro actual. Para hacer que un
registro sea el actual antes de utilizar el Recordset copia, puede utilizar
cualquiera de los métodos Move, Find o Seek (solo para Recordsets tipo Tabla),
o establecer su propiedad Bookmark
El
hecho de cerrar el Recordset original no afecta al duplicado y viceversa.
Nota No es posible utilizar este método con
snapshots de desplazamiento hacia delante (objetos Recordset de tipo
instantánea con la opción dbForwardOnly activada).
Ejemplo
de Clone
Cuando
tenemos un control Data que maneja un campo Fecha, si queremos cambiar el dato
de la fecha no tendremos problemas. Pero si lo que queremos es quitar la fecha,
es decir, poner ese campo con el valor Null,
el control Data no nos dejará. Ello sucede
porque Null no es una fecha válida, y
si lo intentamos nos dará Error de
Conversión de Datos
Para
poder anular ese dato de fecha vamos a crear un Recordset idéntico al del
control data mediante Clone. En ese
nuevo Recordset sí podemos poner ese campo fecha a Null. Lo cambiamos, y una vez cambiado hacemos que el Recordset del
control data sea igual al Recordset ya modificado.
Dim
CopiaDelRecordset as Recordset 'declaramos el nombre del
nuevo objeto DAO
Dim
Pepe as string 'declaramos
una variable tipo string para
‘llevar a ella el registro actual del
C. Data
Pepe=Data1.Recordset.Bookmark
Set
CopiaDelRecordset =Data1.Recordset.Clone
'Hacemos un Recordset idéntico
'ya
está creado el Recordset clónico. Hacemos que su registro actual sea el mismo
que el del ‘control Data
CopiaDelRecordset.Bookmark
= Pepe
'Ahora
editamos el nuevo Recordset y le metemos el valor Null el campo fecha.
CopiaDelRecordset.Edit
CopiaDelRecordset!CampodeLaFecha
= Null
CopiaDelRecordset.Update
'Ya
tenemos el dato Null en el Recordset copia del original. Ahora solo hay que
ponerlo
'como
Recordset del control Data
Set Data1.Recordse t=
CopiaDelRecordset
'Se
le da un Refresh al control Data para que refresque todos sus controles
asociados
Data1.Refresh
'
ahora cerramos el Recordset creado.
CopiaDelRecordset.Close
Y
mediante este pequeño truco podemos hacer que un campo fecha se ponga a Null. No es el único truco para
conseguirlo.
Método Requery
El
método Requery actualiza los datos de un objeto Recordset, volviendo a ejecutar
la consulta con la que se ha creado ese Recordset. Este método debe usarse cada vez que se sospeche que los datos de
la Base de datos han cambiado, y se quieran presentar los datos actualizados.
Es un método típico de una BD que se está usando desde varios puestos a través
de una Red de Area Local.
Sintaxis NombreRecordset.Requery [NuevoQueryDef]
Donde NombreRecordset es el nombre del Recordset,
y NuevoQueryDef (opcional) es una consulta almacenada
No
es posible utilizar el método Requery en objetos Recordset tipo Snapshot o en los Dynaset que tengan la
propiedad Restartable a False, ni tampoco en los objetos Recordset de
tipo Tabla.
Si
los valores de las propiedades BOF y
EOF del objeto Recordset son ambos True después de utilizar el método
Requery, la consulta no habrá devuelto ningún registro y el objeto Recordset no
contendrá datos.
Métodos
BeginTrans, CommitTrans y Rollback
Estos
métodos son métodos del Objeto Workspace
Veamos
estos tres métodos que, dadas sus funciones, deben estudiarse conjuntamente.
Supongamos
un Banco. Debe hacer una transferencia entre dos cuentas corrientes que están
en la misma base de datos. La operación es sencilla : Busca la cuenta
origen y crea un nuevo registro. Apunta en el campo OPERACIÓN una T de
Transferencia, en el campo IMPORTE apunta el valor del dinero a transferir, y
en el campo SALDO pone la diferencia entre lo que había en ese campo en la
última operación, menos el importe del dinero transferido.
A
continuación hace un proceso similar con la cuenta destino, pero en este caso,
sumándole el importe de la transferencia. No hay problemas. Pero que pasa si,
una vez sacado el dinero de la cuenta destino, no se puede ingresar en la
cuenta destino, por la razón que sea (cuenta bloqueada, no existe esa cuenta,
fallo de la red de área local)
Obviamente la operación no se ha completado, y hay que devolver el
dinero a la cuenta origen. Podría hacerse un apunte, metiendo la misma cantidad
de dinero que se ha extraído anteriormente,
y su saldo no se verá afectado. Pero no sé lo que pensaría el cliente
cuando vea un estadillo de su cuenta, en la que le han sacado una cantidad de
dinero, aunque en el siguiente apunte se lo hayan vuelto a introducir.
Para
evitar estas situaciones usamos estos métodos. Con el método BeginTrans iniciamos lo que se llama
una Transacción. Con CommitTrans
terminamos la transacción y se guardan los cambios realizados (En ambas cuentas
a la vez, en el caso del ejemplo). Con Rollback se termina la transacción sin llegar a guardar los cambios,
quedando el Objeto Workspace afectado por las operaciones internas a esa
transacción tal y como estaba antes de comenzar dicha transacción.
Dado
que una transacción pertenece a un Workspace, deberemos aplicar estos métodos
al Workspace que ese usuario tenga abierto. Es decir, en un sistema con varios
usuarios que están trabajando simultáneamente sobre una Base de Datos, un
determinado usuario deberá entrar con un Workspace propio (una sesión de
trabajo solo para él). En estas condiciones podemos crear una transacción.
Sintaxis MiSesión.BeginTrans
MiSesión.CommitTrans
MiSesión.Rollback
Puede
usar estos métodos con un objeto Database, pero no es recomendable, ya que han quedado obsoletos (y posiblemente no le funcione en versiones nuevas del
motor de Bases de Datos) para los objetos Database.
MiBase.BeginTrans MiBase.CommitTrans MiBase.Rollback
Dentro
de un objeto Workspace, las transacciones son siempre globales y no se limitan
sólo a la base de datos o al conjunto de registros. Si realiza operaciones en
más de una base de datos o conjunto de registros durante una transacción en un
objeto Workspace, el método Rollback deshará todas las operaciones en todos
ellos. Quiere esto decir que una transacción debe iniciarse al comenzar una
determinada operación, realizar esa operación sin realizar ninguna otra durante
ese tiempo, terminar la operación y finalizar la transacción, bien con
CommitTrans o con Rollback.
Si
desea tener transacciones simultáneas, lo mas indicado es crear varios objetos
Workspace para usar uno con cada transacción.
Puede
anidar transacciones. Es posible tener hasta cinco niveles de transacciones
abiertos a un tiempo en un mismo objeto Workspace utilizando múltiples
combinaciones anidadas de BeginTrans y CommitTrans o Rollback. En este caso, el
orden de finalización de una transacción debe ser siempre de menor a mayor
nivel jerárquico, es decir, se deberá cerrar primero la transacción que esté
mas interior dentro del anidamiento, y así sucesivamente. Si cierra una
transacción anidada mediante CommitTrans, y posteriormente cierra una
transacción que abarque a esta última con Rollback, los cambios de la primera
transacción NO quedarán guardados.
(Cuando
se utilizan bases de datos SQL ODBC externas no es posible anidar las
transacciones).
Si
cierra un objeto Workspace sin guardar o deshacer las transacciones pendientes,
éstas se desharán automáticamente.
Algunas
bases de datos pueden no admitir las transacciones. En este caso la propiedad Transactions del objeto
Database o Recordset tendrá el valor False. Lea detenidamente la Ayuda de estos
métodos antes de trabajar con ellos.
El
hecho de usar transacciones, aparte de lo que significa para asegurar la
integridad de los datos, ahorra accesos al disco (Importantísimo en algunas
redes LAN y WAN), ya que los cambios a introducir se van almacenando en un
búfer en la memoria, y se vuelcan al disco solamente en el momento de terminar
la transacción de modo afirmativo con CommitTrans.
Mantenimiento y Copia de Bases de
Datos.
Vamos
a ver dos métodos del Objeto DBEngine
para el mantenimiento y copia de Bases de Datos ACCESS.
En
una Base de Datos ACCESS, cuando borramos un dato en realidad no lo estamos
borrando, sino marcándolo como borrado. (No intente recuperar un dato marcado y
no borrado porque no se puede.) Por lo tanto, verá que tras sucesivas
operaciones de escritura / borrado en una BD, esta va aumentando su tamaño. Se
necesita un método que limpie todos los datos inservibles de la BD para disminuir
su tamaño. Este método también deberá reorganizar los índices y marcadores
internos a esa BD. El objeto DAO que debe hacer estas cosas es el Motor de
Bases de Datos. Es decir, el Objeto DBEngine.
Los métodos son CompactDatabase,
que hace una copia de la base de datos (no borra la BD original) sin copiar los
datos inútiles, y RepairDatabase,
que intenta (no siempre lo consigue) reparar los datos internos de una BD que
presente datos corruptos (Se generan con bastante facilidad cuando apagamos el
ordenador con la base abierta, metemos datos burlando los elementos de
protección de la BD,....
Método CompactDatabase
Copia,
compacta y da la opción de modificar la versión, el orden de intercalado y la
codificación de una base de datos cerrada.
Sintaxis
DBEngine.CompactDatabase BaseDatosAnt,
BaseDatosNva [, inf_local [, opciones]]
BaseDatosAnt es el nombre del fichero de la base de datos a compactar. Debe expresar el Path
completo y el nombre del fichero (C :\MiCarpeta\MiBase.MDB) Si el nombre
de archivo tiene extensión, deberá especificarla. Si la red lo admite, también
puede especificar una ruta de red, como por ejemplo
"\\MISERVID\MIDIR\MiBase.MDB".
BaseDatosNva es el nombre del fichero (con su Path completo) de
la base de datos nueva, creada al copiar la BaseDatosAnt, ya compactada. No es
posible especificar en el argumento BaseDatosNva
el mismo archivo de base de datos que en BaseDatosAnt.
inf_local es una expresión de cadena utilizada para especificar
el alfabeto usado a la hora de ordenar datos de esa Base de Datos. El parámetro
a introducir es el mismo que para el argumento similar usado en la creación de
la Base de Datos (dbLangGeneral para el caso de España). Este argumento es
opcional. Si se omite, la información local de BaseDatosNva será la misma que la de BaseDatosAnt.
Opciones nos permite cambiar alguna característica de la Base
de Datos. Puede elegirse entre cifrarla o no cifrarla y cambiar la versión del
motor de bases de datos que va a usar la nueva Base de Datos.
dbEncrypt Codifica la base de datos durante la
compactación.
dbDecrypt Descodifica la base de datos durante la
compactación.
dbVersion10 Crea una base de datos que utiliza la versión
1.0 del motor Jet
dbVersion11 Crea una base de datos que utiliza la versión
1.1 del motor Jet
dbVersion25 Crea una base de datos que utiliza la versión
2.5 del motor Jet
dbVersion30 Crea una base de datos que utiliza la versión
3.0 del motor Jet
Se
puede usar una constante (solamente) de encriptación y una (solamente) de
Versión. Sólo se puede compactar BaseDatosNva
con una versión igual o posterior a la de BaseDatosAnt.
Lea
detenidamente la ayuda en línea de este Método.
Método RepairDatabase
Intenta
reparar una base de datos dañada que accede al motor de base de datos Microsoft
Jet.
Sintaxis DBEngine.RepairDatabase NombreBase
Donde
NombreBase es el nombre (Y path) del fichero que contiene la Base de Datos a
reparar. Puede especificar una ruta de red. P.e. : "\\MISERVID\
MIDIR\NombreBase.MDB".
Para
poder reparar la base debe estar Cerrada.
Recuerde, si está en un entorno multiusuario, que los demás usuarios tampoco
pueden tenerla abierta mientras la repara.
El
método RepairDatabase también intenta validar todas las tablas del sistema y
todos los índices. Los datos que no puedan repararse se pierden. Si la base de
datos no puede repararse, se producirá un error interceptable.
Sugerencia Después de reparar una base de datos, es aconsejable
compactarla con el método CompactDatabase
para desfragmentar el archivo y recuperar espacio en disco.
METODOS DEL OBJETO DataBase
Método Execute
Este
Método es para el Objeto DataBase y para el Objeto QueryDef.
Ejecuta
una consulta de acciones o una instrucción SQL en el objeto Database
especificado.
Sintaxis Para un objeto DataBase NombreBD.Execute
origen[, opciones]
Donde
NombreBD
es el nombre del objeto DataBase
Origen
es una instrucción SQL
Opciones
es un entero o constante que determina las características de integridad de
datos de la consulta, según se especifica mas
adelante.
Para un objeto QueryDef NombreQuerydef.Execute [opciones]
Donde
NombreQuerydef es el nombre del objeto QueryDef cuya propiedad SQL
especifica la
instrucción SQL a ejecutar.
Opciones igual que para el Objeto Database.
En
opciones puede utilizar las
siguientes constantes:
dbDenyWrite Deniega el permiso de escritura a los
demás usuarios.
dbInconsistent (Predeterminado)
Actualizaciones inconsistentes.
dbConsistent Actualizaciones consistentes.
dbSQLPassThrough Paso a través de SQL. Hace que se pase
la instrucción SQL a una
base de datos ODBC para su
procesamiento.
dbFailOnError Deshace las actualizaciones
en caso de error.
dbSeeChanges Genera un error en tiempo de
ejecución si otro usuario modifica los
datos que se están editando.
El
método Execute sólo es válido para las consultas de acciones. Si utiliza
Execute con otro tipo de consultas, se producirá un error. Debido a que las
consultas de acciones no devuelven registros, Execute no devuelve un conjunto
de registros.
Ejemplo. En el siguiente ejemplo, usamos EXECUTE para
cambiar el campo Nombre en una tabla llamada CLIENTES de una Base de Datos
abierta, cuyo Objeto DataBase se llama BaseDatos. Para poder “jugar” con el
nombre a cambiar y el nombre cambiado, se introduce el nombre que queremos
cambiar en TBNombre2 y el nuevo nombre en TBNombre1
Dim
RegistrosCambiados As Long
Dim MiSQL As String
MiSQL
= "UPDATE CLIENTES SET NOMBRE = '" & TBNombre2 & "'
WHERE NOMBRE= '" & TBNombre1 & "'"
BaseDatos.Execute MiSQL, dbFailOnError
RegistrosCambiados
= BaseDatos.RecordsAffected
MsgBox
RegistrosCambiados
Dada
una instrucción SQL sintácticamente correcta y teniendo los permisos adecuados,
el método Execute no fallará, aún cuando no pueda modificarse ni eliminarse una
línea. Por lo tanto, debe especificar siempre la opción dbFailOnError cuando utilice el método Execute para ejecutar una
consulta de actualización o eliminación. Esta opción generará un error
interceptable y deshará todos los cambios realizados con éxito cuando alguno de
los registros afectados se encuentre bloqueado y no pueda actualizarse o
eliminarse.
Propiedad RecordsAffected
Para
determinar el número de registros afectado por el último método Execute, puede utilizar la propiedad RecordsAffected del objeto Database o
Querydef. Por ejemplo, RecordsAffected contienen el número de registros
eliminados, actualizados o insertados al ejecutar una consulta de acciones. Al
utilizar el método Execute para
ejecutar un objeto Querydef, en la propiedad RecordsAffected del Querydef se
establece el número de registros afectados.
Para
obtener el mejor rendimiento, especialmente en un entorno multiusuario, puede
anidar el método Execute dentro de
una transacción: Utilice el método BeginTrans en el objeto Workspace actual,
use luego el método Execute y complete la transacción con el método CommitTrans
en el objeto Workspace. De esta forma se guardarán los cambios en el disco y se
liberarán los bloqueos que se hayan podido producir durante la ejecución de la
consulta.
IMÁGENES EN UNA BASE DE DATOS ACCESS
Una
imagen (la fotografía de una persona por ejemplo) puede guardarse en una base
de datos tipo ACCESS y presentarse en un control Picture. ¡¡ Imagine una
aplicación que sea una agenda de teléfonos y pueda insertar la foto de la
persona !!
Para
introducir una imagen en una BD, el campo de esa BD donde se va a introducir la
imagen debe ser LongBinary ( si esa
versión de ACCESS lo tiene) u Objeto OLE.
Introducir
y presentar un bit-map en una base de datos es necesario hacerlo mediante un
Control Data. Un bit-map puede presentarse en un control Picture o en un
control Image. Ambos son controles enlazados a datos. Si introducimos un Control Data y un Control Picture o Control
Image en el Formulario, asociamos
el Control Data a la Base de Datos, y el campo que contiene el gráfico a el
Control Picture (o Control Image) mediante sus propiedades DataSource = Nombre
del Control data, DataField = Nombre del Campo, tenemos el problema resuelto.
Para meter un gráfico en la BD basta con introducir ese gráfico en el Picture
(o Image) mediante LoadPicture, por ejemplo, y guardar los datos en la BD, bien
cambiando el registro actual del Control data, bien mediante el método
UpdateRecord de dicho Control Data.
La
asociación de la Base de datos al Control Data puede hacerse, bien mediante sus
propiedades DatabaseName y RecordSource, bien creando un Recordset
con código e igualando la propiedad Recordset del Control Data a ese Recordset.
Es
posible que se pueda introducir y presentar un bit-map en un control Picture o
Image de otra forma, sin usar el control Data. Eso sí, complicando el código.
No merece la pena liarse con esto. Lo mismo que decíamos que necesitamos un
Control Data cuando vamos a usar un DBGrid, debemos usar un Control Data cuando
vayamos a presentar una imagen.