Vous êtes sur la page 1sur 61

DELPHI PROGRAMACIN ORIENTADA A

OBJETOS. ENTORNO VISUAL

















Miguel Rodrguez Penabad
2006

Delphi 6
1

1 INTRODUCCIN............................................. 3
1.1 CARACTERSTICAS PRINCIPALES DE DELPHI ..........................................................................3
1.2 EL ENTORNO DE DESARROLLO..............................................................................................4
1.2.1 La paleta de componentes...........................................................................................5
1.2.2 El inspector de objetos (Object Inspector) y Object TreeView...................................5
1.2.3 Gestor de Proyectos (Project Manager) .....................................................................6
1.2.4 Formularios ................................................................................................................6
1.3 PERSONALIZACIN DEL ENTORNO.........................................................................................7
2 PROYECTOS.................................................. 9
2.1 FICHEROS DE UN PROYECTO DELPHI......................................................................................9
2.2 EL PRIMER PROYECTO DELPHI ...............................................................................................9
2.2.1 Crear un Nuevo proyecto..........................................................................................10
2.2.2 Aadir los componentes al formulario......................................................................10
2.2.3 Modificar las propiedades de los componentes ........................................................11
2.2.4 Aadir manejadores de eventos ................................................................................12
2.2.5 Compilar y ejecutar la aplicacin.............................................................................12
2.3 PROPIEDADES DE UN PROYECTO..........................................................................................13
3 PROGRAMACIN CON COMPONENTES.. 14
3.1 DESCRIPCIN GENERAL DE LOS COMPONENTES...................................................................14
3.2 PROPIEDADES, MTODOS Y EVENTOS MS IMPORTANTES....................................................14
3.2.1 Propiedades, mtodos y eventos comunes a todos los componentes.........................14
3.2.2 Propiedades, mtodos y eventos de los controles .....................................................15
3.3 EJ EMPLOS............................................................................................................................16
3.3.1 MiniCalculadora.......................................................................................................16
3.3.2 Editor de texto simple ...............................................................................................18
4 TRABAJANDO CON MS DE UN
FORMULARIO........................................................ 19
4.1 CUADROS DE DILOGO PREDEFINIDOS.................................................................................19
4.1.1 ShowMessage............................................................................................................19
4.1.2 MessageDlg...............................................................................................................19
4.1.3 Application.MessageBox...........................................................................................20
4.1.4 InputBox e InputQuery..............................................................................................20
4.1.5 OpenDialog y SaveDialog.........................................................................................20
4.2 VARIOS FORMULARIOS........................................................................................................20
4.2.1 Introduccin..............................................................................................................20
4.2.2 Creacin y destruccin de Ventanas. La ventana principal de la aplicacin. ..........22
4.2.3 Ventanas modales y no modales................................................................................24
4.2.4 Aplicaciones MDI y SDI............................................................................................25
5 APLICACIONES DE BASES DE DATOS .... 27
5.1 COMPONENTES DE ACCESO A BASES DE DATOS ...................................................................27
5.1.1 La capa de acceso a datos ........................................................................................28
5.1.2 TDataSource y Controles de Datos...........................................................................35
5.2 CONSULTAS.........................................................................................................................35
5.2.1 Seleccin de datos.....................................................................................................36
5.2.2 Modificacin de datos...............................................................................................36
5.2.3 Campos y consultas con parmetros.........................................................................36
5.3 EVENTOS.............................................................................................................................37
5.3.1 Eventos del DataSource ............................................................................................37
5.3.2 Eventos de DataSet ...................................................................................................38
5.4 FORMULARIOS MAESTRO-DETALLE....................................................................................38
2
2004 Miguel Rodrguez Penabad

5.4.1 Maestro-Detalle con tablas.......................................................................................39
5.4.2 Maestro-Detalle con Consultas.................................................................................40
6 LISTADOS .................................................... 41
6.1 EJ EMPLO..............................................................................................................................42
7 MANEJO DE EXCEPCIONES...................... 44
8 PROGRAMAS DE EJEMPLO....................... 46
8.1 PROGRAMA BIENVENIDA ..................................................................................................46
8.1.1 Bienvenida.DPR........................................................................................................46
8.1.2 Formulario Principal ................................................................................................46
8.2 MINICALCULADORA (VERSIN 1, MINICALC1) ...................................................................48
8.2.1 MiniCalc1.DPR.........................................................................................................48
8.2.2 Formulario Principal ................................................................................................48
8.3 MINICALCULADORA (VERSIN 2, MINICALC2) ...................................................................51
8.3.1 Formulario principal ................................................................................................51
8.4 EDITOR DE TEXTOS..............................................................................................................52
8.4.1 Editor1.DPR..............................................................................................................52
8.4.2 Formulario principal ................................................................................................52
8.5 AGENDA..............................................................................................................................55
8.5.1 Agenda.DPR..............................................................................................................55
8.5.2 Formulario Principal ................................................................................................55
Delphi 6
3

1 Introduccin
1.1 Caractersticas principales de Delphi
Delphi es un Entorno Integrado de Desarrollo (IDE: Integrated Development
Environment) que permite:
Programacin Visual
Programacin Orientada a Objetos (utilizando Object Pascal)
Acceso a bases de datos, tanto locales como remotas
Generacin de ejecutables (.EXE, sin necesidad de libreras runtime) o
bibliotecas de enlace dinmico (DLLs)

La Figura 1 muestra el entorno Delphi 6 en ejecucin.


Figura 1. Delphi 6
Delphi es una herramienta demasiado compleja para verla completa en un curso de
este tipo. Por ello, nos centraremos slo en alguna de las posibilidades que nos ofrece.
As, por ejemplo:
- Delphi permite generar distintos tipos de aplicaciones, como aplicaciones
normales de Windows, aplicaciones con interfaz MS-DOS, DLLs, mdulos y
aplicaciones para el Panel de Control de Windows, etc., como se ve en la Figura
2. Aqu nos centraremos slo en la creacin de aplicaciones Windows
normales, lo cual quiere decir que ser un aplicacin con una ventana (o ms)
estndar en Windows.
- A partir de la versin 6, Delphi permite usar dos conjuntos diferentes (y
mutuamente exclusivos) de componentes. Uno de estos conjuntos es la
Ventana principal
Editor de cdigo
Formulario
Inspector de Objetos
Object TreeView
4
2004 Miguel Rodrguez Penabad

biblioteca VCL (Visual Component Library), que haba sido usado en todas las
versiones anteriores de Delphi. La otra biblioteca, que no veremos, se denomina
CLX y es usada tanto por Delphi como por Kylix, un entorno de desarrollo
orientado a Linux.
- Delphi permite utilizar otro tipo de componentes estndar en Windows, como
son los componentes VBX y OCX. Dado que no son componentes nativos y que
(y esto es una apreciacin personal del autor) no dan un resultado ptimo y s
causan problemas, no los veremos.


Figura 2. Tipos de proyectos que se pueden crear con Delphi
1.2 El Entorno de Desarrollo
Veamos las ventanas principales que encontramos en Delphi. La ventana en la parte
superior de la Figura 1 es la ventana principal de Delphi, que se muestra tambin en la
Figura 3. En esta ventana podemos ver el men, los botones de acceso rpido (a la
izquierda) y la Paleta de Componentes, que se ver a continuacin.
Adems, normalmente veremos el Inspector de Objetos, un Formulario y el Editor de
Cdigo.


Men
Botones de acceso rpido Paleta de componentes

Figura 3. Ventana principal de Delphi
Delphi 6
5

1.2.1 La paleta de componentes
La paleta de componentes nos da acceso a los componentes, que pueden ser visuales
(llamados controles) o no visuales, y que implementan las funciones bsicas de interfaz
de usuario, acceso a bases de datos, etc.
Ejemplos de controles son botones, campos de edicin, listas desplegables o paneles,
mientras que los componentes de acceso a bases de datos o los temporizadores son
componentes no visuales.
Delphi proporciona una librera, denominada VCL (Visual Component Library) con
una gran variedad de componentes predefinidos, que estn organizados y agrupados
funcionalmente en la paleta de componentes. Pulsando en la pestaa adecuada de la
paleta accedemos a un grupo de componentes. Para incluir un componente en nuestra
aplicacin, simplemente seleccionamos el componente y al hacer clic en el formulario
de nuestra aplicacin se aade a l (en la posicin en donde pulsamos).
La paleta de componentes es tambin configurable: podemos quitar, poner o recolocar
componentes. Para ello, pulsamos con el botn derecho del ratn en la paleta, y
seleccionamos la opcin Properties del men contextual que aparece.
1.2.2 El inspector de objetos (Object Inspector) y Object TreeView
El Inspector de Objectos (a la izquierda en la Figura 4) nos permite ver y modificar
las propiedades de los componentes (incluidos los formularios). Tambin nos permite
asociar event handlers (manejadores de eventos) para estos componentes.



Figura 4. Object Inspector y Object TreeView
6
2004 Miguel Rodrguez Penabad

Podemos acceder al Inspector de Objetos pulsando F11 (o usando la opcin de men
View|Object Inspector), o pulsando sobre l en caso de que est visible. En la parte
superior del mismo se ve nombre del componente seleccionado y su tipo.
El Object TreeView, que se muestra a la derecha en la misma figura, aparece como
novedad en la versin 6 de Delphi. Muestra el formulario y sus componentes en forma
de rbol (existen controles, como los paneles, que pueden a su vez contener otros
componentes). Esta herramienta es muy til para acceder de forma rpida a
componentes que estn ocultos (por ejemplo, si tenemos un panel encima de otro panel,
los controles que estn en el primero no se vern en el formulario).
1.2.3 Gestor de Proyectos (Project Manager)
Como se ha dicho, cada aplicacin Delphi es un proyecto. Cada proyecto estar
formado por varios ficheros (units, formularios, ). Para poder acceder a cada uno de
estos ficheros es til el uso del gestor de proyectos (Project Manager), al que se puede
acceder mediante la opcin de men View|Project Manager, o pulsando las teclas
Ctrl+Alt+F11.

Figura 5. Gestor de proyectos
1.2.4 Formularios
El formulario o Form es el componente principal del desarrollo de aplicaciones
Windows en Delphi. Durante la fase de diseo, se crear un formulario para cada
ventana que se necesite. Los controles que configuran cada formulario se colocarn
sobre el mismo.
Cada formulario se almacena en un fichero con extensin DFM, y tendr asociada una
unit con el mismo nombre y extensin .PAS. En esta unit se almacena tanto la
definicin de la clase del formulario como sus componentes, y el cdigo
correspondiente a los manejadores de eventos (y otras funciones y procedimientos que
se creen) de los componentes del formulario.
Delphi 6
7

1.3 Personalizacin del entorno
Accediendo a la opcin de men Tools|Environment Options, se accede a la ventana
que se muestra en la Figura 6, donde se pueden personalizar diversos aspectos del
entorno de Delphi. Puede consultar la ayuda de Delphi para ver el significado de cada
opcin, de las que podemos destacar las Autosave options: Si se activa la opcin
Editor Files, se grabarn los ficheros del proyecto antes de ejecutarlo, y si se activa
Project Desktop, se grabar el proyecto actual, que se abrir automticamente al abrir de
nuevo Delphi. La primera opcin es especialmente interesante, ya que si ejecutamos el
programa que estamos desarrollando y esto provoca que Delphi (o Windows) se
cuelgue, los ficheros ya habrn sido grabados y no perderemos el trabajo realizado.
En la pestaa Library de esta ventana hay una serie de opciones que se vern ms
adelante, y que sern especialmente importantes si queremos incluir componentes o
paquetes que no vienen por defecto con Delphi, como componentes desarrollados por
terceras partes, o componentes desarrollados por nosotros mismos.

Figura 6. Personalizacin del entorno de Delphi
La Figura 7 nos muestra cmo podemos cambiar el comportamiento y aspecto visual
del editor de cdigo de Delphi. A esta ventana se accede mediante la opcin del men
Tools|Editor options.
8
2004 Miguel Rodrguez Penabad


Figura 7. Propiedades del editor de cdigo
Delphi 6
9

2 Proyectos
2.1 Ficheros de un proyecto Delphi
El desarrollo de aplicaciones en Delphi se lleva a cabo mediante Proyectos, cada uno
de los cuales da lugar a un programa (o a una DLL, a una aplicacin del Panel de
Control, etc.). Adems, estos proyectos se pueden agrupar en grupos de proyectos
(Borland Project Groups). En muchos casos trabajaremos con proyectos
independientes, para los que Delphi crea un grupo con un nico proyecto.
Lo ms recomendable es crear cada proyecto en un directorio separado, de forma que
no tengamos conflictos con ficheros con el mismo nombre.
Al trabajar con Delphi, creamos ficheros de distintos tipos, y adems Delphi crear, al
compilar los ficheros, otros ficheros adicionales. El tipo de fichero se distingue por su
extensin, y los principales tipos de ficheros que aparecen (bien creados por nosotros o
bien generados por Delphi al compilar el proyecto) son los siguientes:
Ficheros creados por nosotros
Extensin Significado
BPG Borland Project Group. Fichero que nos permite agrupar varios proyectos
DPR Delphi PRoject: Proyecto de Delphi, que dar lugar a una aplicacin o DLL con
el mismo nombre
DFM Delphi Form: Formulario o ventana, en la que podremos trabajar de forma
visual aadiendo componentes
PAS Fichero Pascal: En estos ficheros se define
Ficheros generados por Delphi
DCU Delphi Compiled Unit: Resultado de compilar una unit, escrita en un fichero
.PAS y a la que opcionalmente est asociado un formulario (DFM)
EXE Ejecutable que resulta de compilar un proyecto (application)
DLL Biblioteca de Enlace Dinmico, que resulta de compilar un proyecto (Library)

Existen otros tipos de ficheros que se crean cuando compilamos un proyecto Delphi,
pero los citados en la tabla anterior son los ms importantes.
2.2 El primer proyecto Delphi
Vamos a crear una aplicacin Windows que nos sirva para ver la forma bsica de
desarrollar aplicaciones en Delphi. El programa constar de una ventana con un botn y
una etiqueta de texto. Al pulsar el botn, la etiqueta mostrar el texto Bienvenido/a a
Delphi.
Los pasos a seguir sern los siguientes:
1. Crear un nuevo proyecto (nueva aplicacin).
2. En el formulario que aparece, colocar los componentes necesarios.
3. Modificar las propiedades de los componentes.
4. Aadir el cdigo necesario para los manejadores de eventos necesarios.

No es necesario realizar los tres ltimos pasos de forma secuencial, sino que por
ejemplo podemos colocar un componente, modificar sus manejadores de eventos, luego
sus propiedades, y pasar al siguiente componente.
10
2004 Miguel Rodrguez Penabad

2.2.1 Crear un Nuevo proyecto
Accediendo a la opcin de men File|New|Application, se crea un nuevo proyecto,
que tendr como nombre por defecto Project1.DPR. De forma automtica se crea para
el proyecto el formulario principal (Unit1.DFM), con la unit Unit1.PAS.
Es importante saber que el nombre del fichero DPR ser el mismo que el del
ejecutable generado. En este caso sera Project1.EXE.
Grabemos el proyecto. Es conveniente crear una nueva carpeta para cada proyecto, y
darle un nombre significativo. Por ejemplo, grabaremos este proyecto en la carpeta
C:\DELPHI\BIENVENIDA (ver Programa 8.1), renombrndolo como Bienvenida.DPR.
Asimismo, cambiaremos el nombre de Unit1.pas a Principal.pas. Con ello, podemos ver
los ficheros creados en el gestor de proyectos.

Figura 8. Ficheros del primer proyecto Delphi.
2.2.2 Aadir los componentes al formulario
Aadiremos al formulario del proyecto dos componentes: un botn y una etiqueta de
texto. Es decir, un control TButton y un control TLabel. Ambos controles estn el la
pestaa Standard de la paleta de componentes. Si desplazamos el cursor del ratn
sobre los componentes de la paleta, aparecer un pequeo globo de ayuda (hint en la
terminologa de Delphi) con el nombre del componente. El resultado podra ser el que
se muestra en la Figura 9.


Figura 9. Un formulario
Delphi 6
11

2.2.3 Modificar las propiedades de los componentes
Cuando se crea un nuevo elemento, ya sea este un proyecto, un formulario, o
cualquier componente, este tendr una serie de valores por defecto. Entre estos valores
ser el nombre.
Cada componente pertenece a una clase, que por convencin empieza siempre por la
letra T (TForm es la clase de los formularios, TButton la clase de los botones, etc.).
Todos los componentes tienen una propiedad Name, que especifica el nombre del
componente. El nombre por defecto del componente creado ser el nombre de la clase
sin la T seguido de un nmero correlativo. Es decir, si aadimos varios botones a un
formulario, estos se llamarn Button1, Button2, etc. Es una buena idea dar nombres
significativos a los elementos, para que luego al referirnos a ellos el cdigo sea ms
comprensible.
En este caso, cambiaremos la propiedad Name del formulario y de sus controles,
llamndoles FPrincipal, Boton, y Etiqueta. Esto lo haremos usando el inspector de
objetos, como se ve en la Figura 10.


Figura 10. Modificacin de propiedades de un componente
Existen 3 formas bsicas para cambiar los valores de las propiedades de un
componente (no siempre pueden ser aplicadas las 3):
- Usando el inspector de objetos
- De forma visual (si el componente es visual). Propiedades como la posicin
(propiedades Top y Left) y el tamao (Altura: Height, y Anchura: Width)
pueden ser cambiadas directamente en el formulario. Por ejemplo, si
redimensionamos el formulario (pulsando en el borde de la ventana y
arrastrando el ratn, como en cualquier programa Windows), los valores Height
y Width del inspector de objetos reflejarn los nuevos valores.
- Por programa: Usando cdigo ObjectPascal, podemos asignar un valor a una
propiedad, cambiando dinmicamente el valor de la propiedad del objeto. As,
podremos tener en algn lugar del programa la asignacin
f Pr i nci pal . Capt i on: = Vent ana Pr i nci pal , que cambia el ttulo del
formulario.
Nombre y tipo del componente
Nombre de la propiedad
Valor de la propiedad
Acceso a las propiedades del objeto
Acceso a los manejadores de de eventos del objeto
12
2004 Miguel Rodrguez Penabad


2.2.4 Aadir manejadores de eventos
Usando el Inspector de Objetos, en la pestaa Events, se puede aadir el cdigo (en
ObjectPascal) que define cmo un objeto (componente) reaccionar cuando se produzca
determinado evento. Como se muestra en la Figura 11, el evento considerado es
OnClick del componente de tipo TButton, que se produce cuando se hace clic con el
ratn en el botn. Al hacer doble clic en la casilla a la derecha del evento deseado en el
inspector de objetos, se crea un nuevo procedimiento en la unit asociada al formulario
(si no exista ya), y el cursor se sita en el cuerpo del procedimiento, para que podamos
empezar a codificar. El nombre por defecto del procedimiento es el del componente
seguido del evento sin el prefijo On, en este caso BotonClick.
Ah podemos hacer que el texto (Caption) de la etiqueta cambie, mostrando el
mensaje deseado.

Figura 11. Aadir un manejador de eventos
2.2.5 Compilar y ejecutar la aplicacin
Para compilar el proyecto, podemos pulsar Ctrl+F9, o bien ir a la opcin del men
Project|Compile <nombre del proyecto>. Esto hace que se compilen las units que se
hayan modificado, se enlacen las bibliotecas necesarias (proceso de enlazado o linkado)
y se cree el ejecutable final.
La compilacin de Delphi es incremental, esto es, slo compilar aquello que haya
cambiado. A veces Delphi no interpreta bien qu ha cambiado y puede que no compile
correctamente el programa. Si esto sucede, deberemos compilarlo todo, accediendo a la
opcin de men Project|Build <nombre del proyecto> o Project|Build all projects. Esto
nos garantiza que todas las units sern compiladas de nuevo.
Delphi 6
13

Para ejecutar el programa podemos hacerlo desde dentro del entorno IDE de Delphi
o fuera de l, como una aplicacin ms de Windows. Si lo hacemos desde dentro,
podremos depurar la aplicacin haciendo uso del debugger o depurador integrado que
ofrece Delphi. Se ejecuta el proyecto actual pulsando F9, usando la opcin Run|Run, o
pulsando el botn con la flecha verde en la barra de botones.
2.3 Propiedades de un proyecto
El proyecto, la aplicacin desarrollada, tambin tiene una serie de caractersticas o
propiedades que pueden ser modificadas, desde la opcin de men Project|Options.
Entre ellas, podemos cambiar (en la pestaa Application) el ttulo o nombre de la
aplicacin (si no se establece, se usar el nombre del ejecutable como ttulo), el fichero
de ayuda asociado, y el icono de la misma, como se ve en la Figura 12.
En la pestaa Directories/Conditionals podemos cambiar algunos directorios por
defecto. Por ejemplo, si queremos que las units compiladas (ficheros .DCU) no se
guarden con los fuentes, sino en un directorio aparte, lo especificaremos en la opcin
Unit Output Directory.
Existen opciones ms avanzadas, que establecen opciones de compilacin y enlazado,
en las que no entraremos.

Figura 12. Propiedades del proyecto
14
2004 Miguel Rodrguez Penabad

3 Programacin con componentes
3.1 Descripcin general de los componentes
Casi todo el trabajo en Delphi se realiza usando componentes. Por ello, vamos a ver
qu es realmente un componente, y a qu partes de l tenemos acceso.
Un componente es un objeto, que pertenece a una clase, en la que se definirn los
atributos y mtodos asociados a la misma. En un componente distinguimos bsicamente
cuatro partes, algunas de las cuales sern fcilmente reconocibles para el lector que
tenga conocimientos bsicos de Programacin Orientada a Objetos:
Privada: Son atributos (campos o variables del objeto) y mtodos
(procedimientos y funciones) privadas al componente. Es decir, no podemos
acceder a ellos desde fuera del componente (slo estarn disponibles en la
implementacin del mismo).
Protegida: Es una parte que ser accesible por la clase y las clases derivadas de
ella, y no accesible para todas las dems clases. Es til en la creacin de
componentes, para definir una clase genrica y luego derivar otras clases.
Pblica: Sern atributos y mtodos accesibles desde la clase y desde fuera de
ella. Podremos acceder por programa a los atributos y mtodos pblicos de
todos los componentes en los programas que realicemos (es decir, cuando
estemos codificando, no desde el inspector de objetos).
Publicada: Est formada por propiedades (properties), que son un tipo especial
de atributos de los componentes. Es una parte pblica, y adems todas las
propiedades publicadas aparecern en el Inspector de Objetos, en la pestaa de
Properties o la de Events, dependiendo de su naturaleza. Adems, tambin sern
accesibles por programa.

Dado que inicialmente vamos a trabajar con componentes, y no crearlos nuevos, nos
centraremos en aquellas partes que vamos a poder usar, es decir, las partes pblica y
publicada de los componentes. Como ya se ha dicho, la parte publicada aparece en el
inspector de objetos, y podremos acceder a ella desde l (o desde programa). La parte
pblica es accesible nicamente desde el cdigo de nuestra aplicacin.
3.2 Propiedades, mtodos y eventos ms importantes
Cada componente tiene un conjunto de propiedades y eventos particulares, pero
existen algunas propiedades comunes a muchos componentes, que se vern a
continuacin. Ser una relacin muy sucinta, ya que examinar cada una de las
propiedades de cada control excedera en mucho el cometido de este documento.
Consulte la ayuda en lnea de Delphi para obtener informacin especfica de un
componente, o el inspector de objetos (slo para ver las propiedades o eventos)
seleccionando un objeto concreto.
3.2.1 Propiedades, mtodos y eventos comunes a todos los componentes
Propiedades:
Name: Es el nombre del componente
Delphi 6
15

Tag: Es un entero, que no tiene un uso especfico.
Mtodos:
Create: Crea el componente. Puede o no tener un parmetro, el objeto padre
Release/Free/Destroy: Destruye el componente. El mtodo Destroy no es muy
recomendado. Para los formularios se recomienda Release, y para muchos otros
componentes, Free.
Eventos:
OnCreate: Se produce cuando se crea el componente.
OnDestroy: Se produce cuando se destruye (de hecho, justo antes de destruir) el
componente.
3.2.2 Propiedades, mtodos y eventos de los controles
De los controles o componentes visuales destacamos lo siguiente:
Propiedades:
Top, Left: Especifican la posicin (distancia desde arriba y desde la izquierda)
con respecto al contenedor del objeto (el escritorio para un formulario, el
formulario o un panel para otros controles)
Height, Width: Especifican el tamao (altura y anchura).
Caption: Si el control tiene un texto esttico, como botones, etiquetas,
formularios, etc., Caption especifica el texto.
Font: Especifica la fuente del control.
Enabled: Es un valor lgico o booleano que especifica si el componente est
habilitado
Text: Si el texto del control se puede modificar, esta propiedad especifica este
texto. Es el caso de los controles tipo EditBox, ComboBox, o Memo.
Visible: Es un valor lgico que especifica si el componente se ve o no.
TabStop, TabOrder: La tecla Tab permite en Windows desplazarnos por los
controles de un formulario, de forma cclica. Si queremos que se pase por un
control determinado, pondremos TabStop a TRUE, y a FALSE en caso
contrario. El orden en que se visitan los controles se especifica mediante la
propiedad TabOrder. Para variar esta ltima ms fcilmente, podemos pulsar el
botn derecho del ratn en el formulario y acceder a la opcin Tab Order del
men emergente.
Mtodos:
SetFocus: Da el foco al componente, de forma que reaccione ante eventos del
ratn o el teclado. La propiedad ActiveControl del formulario (TForm) tambin
permite establecer (o comprobar) el control activo.
Eventos:
OnClick: Se produce cuando el usuario hace clic con el ratn en el control. En
algunos casos tambin se activa al pulsar ENTER o la barra espaciadora con el
control seleccionado (por ejemplo, en los botones).
16
2004 Miguel Rodrguez Penabad

OnEnter, OnExit: Se producen cuando el control recibe (OnEnter) o pierde
(OnExit) el foco.
3.3 Ejemplos
3.3.1 MiniCalculadora
Vamos a construir una minicalculadora: una aplicacin con dos cuadros de edicin,
un botn de suma, y una etiqueta. El programa debe verificar que el valor introducido
en el primer campo de edicin es un nmero, hacer lo mismo en el segundo y, al pulsar
el botn, mostrar la suma en la etiqueta.
Para la realizacin de este programa debes conocer lo siguiente:
Para la conversin entre cadenas de caracteres y nmeros se pueden usar las
funciones StrToInt e IntToStr. Si la conversin de string a entero no es posible
(porque el texto no representa un nmero), se genera una excepcin, en concreto
del tipo EConvertError.
El mtodo SetFocus de un control, o la propiedad ActiveControl de un
formulario, establece el componente activo.
Primera Aproximacin
El listado completo de la primera aproximacin se encuentra en el apartado 8.2.
Aqu destacaremos los principales pasos para implementarlo.
En primer lugar, debemos crear dos campos de edicin (TEdi t ), que llamaremos
ESumando1 y ESumando2; un botn (TBut t on) bSuma, y una etiqueta (TLabel ),
LTotal. Al crearlos en este orden el componente activo al ejecutar la aplicacin pasa a
ser el primer sumando, y el orden en que se visitan los componentes el deseado, por lo
que no tenemos que modificar el TabOrder.
Una vez que tenemos los componentes, pasaremos a codificar los manejadores de
eventos. El evento OnClick del botn no tiene mayor complicacin: convertimos los
textos de los sumandos a nmero, los sumamos, y ponemos como Capt i on de la
etiqueta esa suma, de nuevo convertida en String.
El control de que los nmeros introducidos en los sumandos son correctos se puede
hacer tratando de convertir el texto (Text ) a nmero. Si da un error, avisamos y
volvemos a poner el control activo, y si no da error es que el nmero introducido es
correcto. Para el primer sumando (haciendo doble clic en el Inspector de Objetos para
aadir el manejador del evento OnExi t ) sera:
pr ocedur e TFor mCal c. ESumando1Exi t ( Sender : TObj ect ) ;
var num: i nt eger ;
begi n
t r y
num: =St r ToI nt ( ESumando1. Text )
except
showmessage( ' El nmer o i nt r oduci do no es vl i do' ) ;
ESumando1. Set Focus;
end;
end;

Para el segundo sumando sera igual, cambiando ESumando1 por ESumando2.
Delphi 6
17

Podemos comprobar, en el listado del apartado 8.2, que el programa funciona
correctamente. Sin embargo, tiene un problema: Hay una duplicidad de cdigo (que
como ya sabemos no es algo deseable), ya que el manejador del evento OnExi t del
primer y segundo sumando son casi iguales.
En la segunda aproximacin veremos cmo podemos mejorar este ejemplo para que
no exista esta duplicidad de cdigo
Segunda aproximacin: Compartir manejador de eventos
Para mejorar el ejemplo, debemos fijarnos en que el manejador de eventos tiene un
parmetro, Sender , que es el objeto sobre el que se produce el evento. Si usamos
Sender en vez de un nombre de control concreto, podemos compartir manejadores de
eventos.
Para ello, en primer lugar borraremos los manejadores que hemos creado. Borrar
un manejador de eventos es un proceso sencillo, pero debemos hacerlo con cuidado
para que el automatismo de Delphi pueda seguir funcionando. No debemos borrar todo
el cdigo, sino slo lo que hemos aadido. Borrando lo que est tachado en el siguiente
fragmento de cdigo,
pr ocedur e TFor mCal c. ESumando1Exi t ( Sender : TObj ect ) ;
var num: i nt eger ;
begi n
t r y
num: =St r ToI nt ( ESumando1. Text )
except
showmessage( ' El nmer o i nt r oduci do no es vl i do' ) ;
ESumando1. Set Focus;
end;
end;

nos queda

pr ocedur e TFor mCal c. ESumando1Exi t ( Sender : TObj ect ) ;
begi n
end;
que es exactamente lo que Delphi haba creado automticamente. Si ahora
grabamos el fichero, ese bloque desaparece, y tambin lo hacen la cabecera que se crea
en la definicin de clase del formulario y la asignacin del manejador al evento (que se
almacena en el propio formulario, en el fichero DFM). As pues, nunca borraremos un
manejador de eventos de forma completa, sino que borraremos lo que aadimos
nosotros y dejamos que Delphi elimine lo que l ha creado.
Ahora, aadiremos un nico manejador de eventos para controlar el evento
OnExi t de ambos sumandos.
Esto se puede hacer de dos formas:
- Seleccionando los dos TEdits (esto hace que lo que modifiquemos afecte a
ambos) y hacer doble clic en el manejador de ese evento (o mejor an, escribir
un nombre distinto del que se creara automticamente para el manejador).
- Crear el manejador para el primer sumando, y para el segundo en vez de crear
uno nuevo, seleccionar el ya existente (en vez de hacer doble clic o escribir un
nombre para el manejador, elegirlo de la lista desplegable)

El siguiente fragmento muestra cmo sera el manejador de eventos para ambos
componentes. Debemos fijarnos en que Sender , el parmetro del manejador, es
siempre de tipo TObj ect , el cual no dispone ni de la propiedad Text ni del mtodo
18
2004 Miguel Rodrguez Penabad

Set Focus. Para acceder a ellos, simplemente usaremos un cast, es decir, forzamos el
cambio de tipo de este parmetro, usando TEdi t ( Sender ) (o de forma equivalente,
Sender as TEdi t ).

pr ocedur e TFor m1. SumandosExi t ( Sender : TObj ect ) ;
var num: i nt eger ;
begi n
t r y
num: =St r ToI nt ( TEdi t ( Sender ) . Text )
except
showmessage( ' El nmer o i nt r oduci do no es vl i do' ) ;
TEdi t ( Sender ) . Set Focus;
end;
end;

3.3.2 Editor de texto simple
Queremos crear un editor de textos muy simple (ms an que el bloc de notas de
Windows) similar al de la Figura 13, con los siguientes componentes:
El componente principal ser de tipo TMemo, que es como un TEdit pero admite
ms de una lnea. De hecho, contiene una propiedad (Lines) de tipo TStrings, que
posee mtodos para cargar o grabar en disco un fichero de texto directamente.
Consulta la ayuda de Delphi para el componente Memo antes de ver este
ejemplo.
Botones para abrir (cargar) un fichero, guardarlo en disco, o borrar el texto actual
del editor.

Figura 13. Editor de texto
La solucin a este ejemplo se muestra en el punto 8.4 de este documento.

Delphi 6
19

4 Trabajando con ms de un formulario
4.1 Cuadros de dilogo predefinidos
La unit Di al ogs, que normalmente se incluye por defecto al crear un nuevo par
unit/formulario, nos proporciona un conjunto de llamadas que muestran cuadros de
dilogo sencillos, y pueden aceptar una respuesta del usuario. Entre todos los existentes,
destacamos los siguientes:
4.1.1 ShowMessage
Es la llamada ms sencilla y proporciona un cuadro de dilogo muy sencillo, con un
texto y un botn Ok para cerrar el cuadro.
ShowMessage( Text o del mensaj e ) ;
El ttulo del cuadro de dilogo ser el nombre del ejecutable, o el ttulo del mismo si
se ha cambiado (mediante la propiedad Appl i cat i on. Ti t l e o en las propiedades
del proyecto).
4.1.2 MessageDlg
An siendo sencillo, permite una mayor personalizacin del cudaro de dilogo,
mediante la sintaxis
MessageDl g( <mensaj e>, <t i po_mensaj e>, <bot ones>, <cont ext o_ayuda>) ;
donde
<t ext o>es el texto del mensaje
<t i po_mensaj e> especificia el tipo de cuadro de dilogo, y puede ser
mtWarning, mtError, mtConfirmation, mtInformation, mtCustom.
<bot ones>indica los botones que aparecen en el cuadro. Es un conjunto con
uno o ms de los siguientes botones: mbYes, mbNo, mbOk, mbCancel,
mbAbort, mbRetry, mbIgnore, mbAll, mbHelp. Existen constantes
predefinidas en Delphi para conjuntos de botones muy usados, como
mbYesNoCancel, que incluira los botones S, No y Cancelar.
<cont ext o_ayuda>: Especifica el contexto (numrico) dentro del fichero de
ayuda asociado a la aplicacin que se activar si pulsamos F1. Podemos
especificar 0 si no usamos un fichero de ayuda.

Dado que hay varios botones, la respuesta del usuario puede variar. Esta respuesta, de
tipo TModalResult (realmente, un valor entero), especifica el botn pulsado, y puede ser
mrYes, mrNo, mrCancel, etc.
Ejemplo:
I f MessageDl g( Fi cher o modi f i cado. Desea gr abar l o? ,
mt Conf i r mat i on, mbYesNo, 0) = mr Yes
t hen Rut i naGr abar Fi cher o;

20
2004 Miguel Rodrguez Penabad

4.1.3 Application.MessageBox
El objeto Application, que representa la aplicacin en ejecucin, tiene el mtodo
MessageBox que permite mostrar mensajes personalizados, incluyendo textos, botones
e incluso iconos. Dado que esta funcin no usa para los mensajes cadenas tipo String
sino PChar, y sus opciones son muy numerosas, no entraremos aqu en detalle sobre
ella. Consulta la ayuda de Delphi para ver sus posibilidades.

4.1.4 InputBox e InputQuery
Estos mtodos se usan para aceptar un texto que el usuario teclear.
La sentencia
t ext o: =I nput Box( T t ul o vent ana , Mensaj e de t ext o , val or por
def ect o ) ;
presenta un cuadro de dilogo con el ttulo y el texto, un cuadro de edicin con valor
por defecto, y los botones de Aceptar y Cancelar. Si se pulsa Aceptar, se devuelve el
texto actual del cuadro de dilogo, y si se pulsa cancelar se devuelve valor por defecto.
La funcin InputQuery es similar, pero devuelve un valor booleano: TRUE si se puls
Aceptar y FALSE si se puls cancelar. La sintaxis sera
i f I nput Quer y( Ti t ul o , Text o , val or por def ect o , val or )
t hen {val or cont i ene el t ext o i nt r oduci do}
el se {se pul s Cancel ar }
4.1.5 OpenDialog y SaveDialog
Estos dos componentes se encuentran en la pestaa Dialogs de la paleta de
componente. Se colocan en el formulario y, tras modificar sus propiedades
(especialmente Filter que controlar los tipos de archivos que queremos abrir, e
InitialDir que indica en qu carpeta se abre), se ejecuta mediante una llamada a la
funcin Execute, que devolver TRUE si se pulsa Aceptar y FALSE en caso contrario.
4.2 Varios formularios
4.2.1 Introduccin
Si queremos que nuestra aplicacin muestre varios tipos de ventanas o formularios
(Forms), debemos disearlos, usando un par unit/form para cada ventana distinta que
queramos crear. Existen diversas combinaciones y posibilidades en el manejo de varios
formularios, como son:
- Crear aplicaciones MDI (Multiple Document Interface) o SDI (Single
Document Interface).
- Dejar que Delphi Cree todos los formularios de forma automtica al inicio de la
ejecucin del programa, o crearlos y destruirlos por programa a nuestro antojo.
- Decidir qu ventana ser la principal.
- Mostrar ventanas de forma modal o no modal.
- Etc.
Delphi 6
21

Todas estas opciones las veremos en este captulo, pero antes veamos un ejemplo de
algo que siempre es igual: la forma de acceder a un formulario desde otro formulario
(que, evidentemente, est en otra unit). Para ello, empecemos con un nuevo proyecto,
que contendr un formulario Form1 asociado a la unit Unit1. Si pulsamos en el botn
rpido New Form (o bien en la opcin de men File|New, seleccionando Form),
Delphi crear en vista de diseo un segundo formulario Form2, en la unit Unit2.
Aunque es muy conveniente cambiar estos nombres, aqu los conservaremos para seguir
ms fcilmente las indicaciones.
Supongamos que en el Form1 aadimos un botn, y queremos que al pulsarlo se
muestre el formulario Form2. Esto se har usando el mtodo Show (o ShowModal)
asociado al formulario. Es decir:
pr ocedur e TFor m1. But t on1Cl i ck( Sender : TObj ect ) ;
begi n
For m2. Show
end;
Pero, dado que la Unit1 no conoce la Unit2, ni el Form2 que esta incluye, es
necesario que la primera haga uso (aadindola a la clusula Uses de la unit) de Unit2.
De hecho, si tratamos de compilar ese simple programa, Delphi nos avisa de ello, y lo
hace automticamente por nosotros.


Figura 14. Aadir una unit a la lista USES
Si decimos que No, el programa no compila. Si respondemos afirmativamente, la
Unit1 quedara as:
uni t Uni t 1;
i nt er f ace
uses Wi ndows, Messages, SysUt i l s, Var i ant s, Cl asses, Gr aphi cs,
Cont r ol s, For ms, Di al ogs, St dCt r l s;
t ype
TFor m1 = cl ass( TFor m)
But t on1: TBut t on;
pr ocedur e But t on1Cl i ck( Sender : TObj ect ) ;
pr i vat e
{ Pr i vat e decl ar at i ons }
publ i c
{ Publ i c decl ar at i ons }
end;
var For m1: TFor m1;

i mpl ement at i on
uses Unit2;
{$R *. df m}
pr ocedur e TFor m1. But t on1Cl i ck( Sender : TObj ect ) ;
begi n
For m2. Show
end;
end.
22
2004 Miguel Rodrguez Penabad

Por supuesto, podemos aadir manualmente Unit2 a la lista Uses de Unit1, o dejar
que Delphi lo haga por nosotros. Si dejamos que Delphi lo haga, es importante ver que
Unit2 se aade a la lista USES de la parte IMPLEMENTATION de Unit1 (y as lo
debemos hacer nosotros si lo hacemos manualmente). Esto se hace as porque
normalmente no es necesario conocer Unit2 en la parte INTERFACE de Unit1 (donde
slo hay declaraciones) y adems (y es el motivo principal) para evitar referencias
cclicas entre units:
Es correcto que Unit1 use Unit2 y Unit2 use Unit1 si ambas lo hacen en la
i mpl ement at i on
Es incorrecto que Unit1 use Unit2 y Unit2 use Unit1 si ambas lo hacen en la
i nt er f ace (de hecho, el proyecto no compilara).

4.2.2 Creacin y destruccin de Ventanas. La ventana principal de la
aplicacin.
Cualquier aplicacin normal de Windows abrir una ventana (la ventana principal), y
cuando esa ventana se cierra, el programa termina. Cuando tenemos una sola ventana en
nuestro proyecto, esta se crea automticamente y por supuesto ser la ventana principal,
pero cuando tenemos varios formularios, debemos decidir cmo y en qu orden se
crean, y cual ser la ventana principal. Esto podemos verlo en dos sitios:
En las opciones del proyecto (opcin de men Project|Options), pestana de
Forms.
En el cdigo del proyecto (para acceder a l usaremos la opcin de men
Project|View Source.

La primera opcin se muestra en la Figura 15, usando el ejemplo anterior. En ella se
ve que ambos formularios, Form1 y Form2, se crean automticamente, y que Form1
ser la ventana principal del programa. El orden en que se crean los formularios se
establece (de arriba abajo) en la lista de Auto-create forms, pudiendo variarse
arrastrando y soltando los nombres de los formularios. La ventana principal se
selecciona de la lista desplegable indicada en la figura.como Main Form.
La misma informacin se ve en el cdigo del proyecto, que se muestra a continuacin.
Aqu (entre el begi n y el end del programa), mediante el mtodo
Appl i cat i on. Cr eat eFor m, se crean los formularios Form1 y Form2, en este
orden. La ventana principal de la aplicacin es el primer formulario que se crea.
pr ogr amPr oj ect 1;
uses
For ms,
Uni t 1 i n Uni t 1. pas {For m1},
Uni t 2 i n Uni t 2. pas {For m2};

{$R *. r es}
begi n
Appl i cat i on. I ni t i al i ze;
Appl i cat i on. Cr eat eFor m( TFor m1, For m1) ;
Appl i cat i on. Cr eat eFor m( TFor m2, For m2) ;
Appl i cat i on. Run;
end.

Delphi 6
23


Figura 15. Opciones del proyecto Formularios
El hecho de crear todos los formularios al inicio y no destruirlos hasta el fin de la
aplicacin tiene sus ventajas, como que siempre podremos acceder a sus componentes
porque sabemos que estarn creados. Sin embargo, tambin tiene inconvenientes: un
excesivo consumo de recursos al tener en memoria (visibles o no) formularios que no
necesitamos, y una excesiva lentitud al arrancar el programa, mientras todos los
formularios se crean.
Si no deseamos crear todos los formularios al inicio, simplemente vamos a la ventana
de la Figura 15, y pasamos a la lista Available forms aquellos que no queremos que se
creen automticamente.
Cuando sea necesario crearlos, lo podemos hacer mediante dos formas:
- El mtodo CreateForm del objeto Application, que toma como parmetros la
clase (descendiente de TForm) y la variable que queremos instanciar:

Appl i cat i on. Cr eat eFor m( TFor m2, For m2) ;
- Creando el formulario como un objeto ms, usando el constructor Create, que en
este caso toma un parmetro que ser el componente dueo del formulario, y
que podemos rellenar con, por ejemplo, Appl i cat i on (el objeto que
representa el programa en ejecucin):

For m2 : = TFor m2. Cr eat e( Appl i cat i on) ;
Una vez creado el formulario se puede mostrar normalmente, usando el mtodo
Show. Evidentemente, debemos comprobar que el formulario no est ya creado. Para
ello podemos compararlo con ni l , ya que si el formulario est creado la variable que lo
almacena no ser ni l . Aunque normalmente Delphi asigna el valor ni l a las variables
que representan objetos antes de que estos se creen, si no confiamos en este
automatismo, podemos usar el bloque I NI TI ALI ZATI ON de la Unit2 para
asegurarnos de ello, aadiendo lo siguiente:
Uni t Uni t 2;
Ventana principal
Formularios que se
crearn automticamente
Formularios que deben
crearse por programa
24
2004 Miguel Rodrguez Penabad

I nt er f ace

I mpl ement at i on

Initialization
Form2:=nil;
End;
Entonces, el cdigo que desde Form1 crea (si es necesario) y muestra Form2 sera el
siguiente.
pr ocedur e TFor m1. But t on1Cl i ck( Sender : TObj ect ) ;
begi n
i f For m2=ni l
t hen For m2: =TFor m2. Cr eat e( Appl i cat i on) ;
{o bien Application.CreateForm(TForm2, Form2)}
For m2. Show
end;
Usando esta tcnica evitamos la lentitud inicial al arrancar el programa (no se nota si
son 2 formularios solamente, pero la cosa cambia bastante si son 40 los distintos
formularios que puede usar una aplicacin). Tambin se evita parcialmente el
desperdicio de recursos al mantener en memoria formularios no usados, ya que no se
crean hasta que se necesiten. Sin embargo, no lo soluciona del todo ya que el formulario
no se destruye cuando se cierra, sino que simplemente se oculta (haciendo una llamada
implcita al mtodo Hi de del formulario). Por ello no slo debemos saber cmo crear
formularios, sino tambin como destruirlos, eliminando los recursos asociados.
Esto se puede hacer en dos lugares:
- En el punto (unit, formulario) desde el que se cre, llamando al mtodo
Rel ease del formulario que queremos eliminar
- Desde el propio formulario que queremos eliminar, en el evento OnClose. El
manejador de este tipo de eventos tiene un parmetro de tipo TCloseAction, que
indica lo que se hace al cerrar el formulario, y puede tener los siguientes
valores:
o caNone: No se permite cerrar el formulario, por lo que nada ocurre.
o caHide: El formulario se oculta, pero no se destruye. La aplicacin an
puede acceder a l, como ocurra en el ejemplo anterior.
o caFree: El formulario se cierra (destruye) y se libera la memoria
asociada.
o caMinimize: El formulario se minimiza. Es el comportamiento por
defecto en los formularios tipo MDIChild, que se vern ms adelante.

Si aadimos el siguiente manejador para el evento OnClose de Form2, el formulario
se destruir y no slo se ocultar:
pr ocedur e TFor m2. For mCl ose( Sender : TObj ect ; var Act i on: TCl oseAct i on) ;
begi n
Act i on: =caFr ee;
end;

4.2.3 Ventanas modales y no modales
Cuando una ventana se muestra, puede hacerlo de dos formas:
Delphi 6
25

- Modal: Slo se puede acceder a la ventana que se muestra, y no al resto de las
ventanas de la aplicacin. Es el caso de los cuadros de dilogo estndar que se
mostraron en el apartado 4.1.
- No modal: La nueva ventana se muestra, pero podemos acceder a las dems
ventanas de la aplicacin.

Para mostrar una ventana de forma no modal se usa el procedimiento Show del
formulario; para mostrarla de forma modal se usa la funcin ShowModal . El
procedimiento Show muestra la nueva ventana y contina la ejecucin en la siguiente
sentencia, mientras que la funcin ShowModal espera a que la nueva ventana sea
cerrada, pudiendo controlar el valor que devuelve al cerrarse, de tipo TModal Resul t
(como MessageDl g, por ejemplo).
El siguiente fragmento sera vlido: crea la ventana, la muestra, y cuando el usuario
la cierre, la destruye (sin necesidad de controlar el evento OnClose de Form2).

pr ocedur e TFor m1. But t on1Cl i ck( Sender : TObj ect ) ;
begi n
i f For m2=ni l t hen For m2: =TFor m2. Cr eat e( Appl i cat i on) ;
For m2. ShowModal ;
For m2. Rel ease;
end;

Sin embargo, el mismo cdigo usando Show no sera vlido, ya que se creara el
formulario Form2, se mostrara e inmediatamente se destruira (Show no espera sino
que la ejecucin contina).

4.2.4 Aplicaciones MDI y SDI
Una aplicacin MDI (Multiple Document Interface) puede abrir varias ventanas
hija dentro de la ventana principal, mientras que una aplicacin SDI (Simple
Document Interface) tendremos normalmente un nico documento. Las aplicaciones
SDI, como todos los ejemplos vistos hasta ahora, pueden usar varias ventanas (Delphi
es un ejemplo de aplicacin SDI) pero no existen varias ventanas hijas dentro de la
principal.
Para crear aplicaciones de ambos tipos utilizaremos la propiedad FormStyle de los
formularios. Esta propiedad puede tener los siguientes valores:
- fsNormal: El formulario no es ni la ventana MDI padre ni hija. Es el valor
por defecto de esta propiedad, y el que usaremos en todos los formularios de
una aplicacin SDI.
- fsMDIChild: Es una ventana MDI hija.
- fsMDIForm: Es la ventana MDI padre. Ntese que slo debe haber un nico
formulario de este tipo en la aplicacin, y que debe ser la ventana principal.
- fsStayOnTop: Siempre encima, este tipo de formularios permanece siempre
visible, por encima de las dems ventanas (tanto de la aplicacin como de las
dems aplicaciones que se estn ejecutando en Windows).

La Figura 16 muestra una aplicacin MDI, creada mediante un asistente de Delphi,
al que se accede en el men File|New|Other, en la pestaa Projects, la opcin MDI
Application.
26
2004 Miguel Rodrguez Penabad


Figura 16. Aplicacin MDI
Delphi 6
27

5 Aplicaciones de Bases de Datos
5.1 Componentes de acceso a bases de datos
Delphi fue diseado desde sus inicios para facilitar la creacin de aplicaciones que
acceden a bases de datos, tanto locales (por ejemplo, usando ficheros de dBase o
Paradox) como servidores de bases de datos remotos (Internase, MySQL, Oracle,
Informix, DB2, PostgreSQL,o cualquier servidor que provea una conexin ODBC o
ADO).
Desde su aparicin, se ha desarrollado para Delphi un gran nmero de componentes
de acceso a bases de datos, cada uno especializado para un tipo de base de datos en
concreto (la mayora de ellos de "terceras partes", no desarrollados por Borland). Esto
hace que el acceso sea eficiente, pero hace la migracin de una aplicacin (por ejemplo,
pasar de usar Paradox a usar un servidor Oracle) imposible o al menos muy difcil. Por
ello no hablaremos de este tipo de componentes en este documento, sino que nos
centraremos en la arquitectura BDE (Borland Database Engine), presente en todas las
versiones de Delphi.
La arquitectura del BDE se divide en tres capas, como muestra la Figura 17. Esta
arquitectura nos permite lograr un cierto nivel de independencia fsica de la aplicacin
con respecto a la base de datos que use

BD STANDARD
Paradox, dBase,
INTERBASE ORACLE
ADO
ODBC
BDE: Borland Database Engine

APLICACIN DELPHI Aplicacin


Alias

Figura 17. Arquitectura de bases de datos usando BDE
En una aplicacin desarrollada en Delphi, tambin tenemos tres capas (en este caso
de componentes):
- Acceso a Datos: Estos componentes se encuentran en la pestaa BDE de la
paleta de componentes. Son componentes no visuales, que realizan el acceso
fsico real a los datos. De ellos veremos en detalle los componentes
TDat abase y TDat aSet (del que usaremos sus descendientes TTabl e y
TQuer y).
- Componentes "puente": Estn colocados en la pestaa Data Access, y se utilizan
para vincular componentes de acceso a datos con los componentes visuales o
Controles de Datos. De este tipo de componentes veremos uno solo: el
TDataSource.
- Controles de datos: Estos componentes estn en la pestaa Data Controls. Son
componentes visuales similares a los componentes que permiten ver o editar
textos en Windows (TLabel , TEdi t , TMemo, ) pero que en este caso nos
28
2004 Miguel Rodrguez Penabad

permiten visualizar y modificar los datos, movernos por los registros o filas, etc.
As, tendremos los componentes TDBLabel , TDBEdi t , TDBMemo,
TDBNavi gat or , etc.

La Figura 18 muestra de forma esquemtica cmo se usaran estas tres capas en una
aplicacin desarrollada en Delphi. Aqu se ve la utilidad de la capa puente, de los
componentes TDataSource: Si tenemos un conjunto de datos (dataset), ya sea una tabla
o una consulta, el DataSource se comunica con todos los controles ligados y hace que
estos muestren la informacin de la fila actual. Si el dataset cambia los datos (por
ejemplo, al moverse a la fila siguiente), es el DataSource el que se encarga de indicar a
los controles que actualicen sus datos, sin que nosotros tengamos que codificar una sola
lnea.
Database1 Query1

TDBGrid
TDBEdit TDBComboBox
DBNavigator
Controles
de
Datos
Capa puente
Acceso
a
Datos
BDE
Base de Datos
Aplicacin Delphi
DataSource1
Table1
DataSource2

Figura 18. Una aplicacin de Delphi que usa BDE

5.1.1 La capa de acceso a datos
Dentro de los componentes de acceso a datos podemos destacar principalmente dos
tipos:
- TDatabase: Sirve para identificar y establecer la conexin con una base de datos
a travs de una serie de parmetros. En el caso de que estemos accediendo a un
servidor remoto, puede ser el nombre de la mquina, un nmero de puerto, el
nombre de la base de datos y un par usuario/clave para identificarnos. Si la
base de datos es del tipo XBase o Paradox (donde no hay realmente una BD
sino un directorio con ficheros que contienen las tablas y los ndices), ser
simplemente el nombre del directorio. A partir de aqu, y aunque suponga un
abuso del idioma, llamaremos base de datos a cualquiera de estos sistemas de
almacenamiento de informacin.
- TDataSet: permite el acceso a los datos. Es el equivalente a lo que se define
como cursor en lenguajes con SQL embebido, o al ResultSet del lenguaje J ava.
Delphi 6
29

La clase TDataSet no se suele usar directamente (de hecho no est en la paleta
de componentes), sino a travs de sus descendientes: TTabl e, que permite
acceder a una tabla de la BD, y TQuer y, que utiliza una sentencia SQL para
acceder a los datos.
En una aplicacin Delphi, todos los componentes TTabl e y TQuer y tienen que
estar asociados a una base de datos. El nombre que se da a una base de datos en BDE
recibe el nombre de Database Alias. Existen 2 tipos de alias: permanentes y temporales
(o de aplicacin):

5.1.1.1 Alias. Alias permanentes y temporales
Los Alias permanentes se crean mediante una aplicacin externa (normalmente
incluida con Delphi) como Database Desktop o SQL Explorer. Usando Database
Desktop, la opcin de men Tools|Alias Manager nos permite gestionar los alias
permanentes. La Figura 19 muestra dos ejemplos. Como se ve, hay que indicar el
nombre del alias, el tipo (para BDs tipo XBase o Paradox se usa el tipo STANDARD),
y los parmetros necesarios, que sern dependientes del tipo de base de datos.
Un alias permanente es conocido por todas las aplicaciones que usen el BDE en la
computadora. Es decir, que cualquier aplicacin que acceda al alias NuevoAliasParadox
estar accediendo a una base de datos Paradox cuyos datos se almacenan en el directorio
C:\Datos\.


Figura 19. Creacin de nuevos alias con Database Desktop


Para crear una aplicacin que acceda a una base de
datos representada por una alias permanente, se
usarn los componentes de acceso a datos
(TDatabase y TTable/TQuery).

Colocaremos un componente TDatabase y lo
enlazaremos con el alias usando la propiedad
AliasName, como muestra la figura.

30
2004 Miguel Rodrguez Penabad






A continuacin, colocaremos componentes TDataset
(TTable o TQuery, segn los necesitemos), y los
enlazaremos, usando la propiedad DatabaseName,
con el componente TDatabase.

OJO! En la propiedad DatabaseName del TDataset
pondremos el nombre que antes hemos dado a la
propiedad DatabaseName del TDatabase, no el
AliasName (que es el alias permanente). Si
pusisemos este ltimo, no estaramos usando el
componente TDatabase.




De hecho, es posible hacer el acceso a datos de forma ms directa, sin usar el
componente TDatabase. Si no lo usamos, y en la propiedad DatabaseName ponemos (o
elegimos de la lista) un nombre de Alias, ser totalmente vlido. Cuando el TDataset se
abre, el propio programa crear de forma dinmica un componente TDatabase
annimo, y lo destruir cuando no sea necesario. Sin embargo, esta opcin NO ES
RECOMENDABLE. Es mejor usar siempre un componente TDatabase
1
.

Si quisisemos realizar los pasos anteriores por programa, en vez de utilizar el
Inspector de Objetos, tambin es posible. La secuencia de instrucciones sera la
siguiente (podramos colocarlas, por ejemplo, en el manejador de eventos
correspondiente al evento OnCr eat e del formulario principal):
pr ocedur e TFor m1. For mCr eat e( Sender : TObj ect ) ;
begi n
Dat abase1. Al i asName: =' NuevoAl i asPar adox' ;
Dat abase1. Dat abaseName: =' Nombr eBD_en_l a_apl i caci on' ;
Tabl e1. Dat abaseName: =' Nombr eBD_en_l a_apl i caci on' ;
{O bi en Tabl e1. Dat abaseName: =Dat abase1. Dat abaseName}
Dat abase1. Connect ed: =t r ue; {Open: abr i mos l a BD}
Tabl e1. Open; {Abr i mos l a t abl a}
end;

El uso de alias permanentes tiene sus ventajas. Por ejemplo, si tenemos varias
aplicaciones que acceden a una base de datos, todas usarn el mismo alias. Si en un
momento dado queremos cambiar de base de datos (o la localizacin de los datos si es
de tipo Standard) simplemente cambiaremos los parmetros del Alias usando Database
Desktop, y no necesitamos cambiar nada en las aplicaciones.

1
Esta es una apreciacin personal del autor de este documento
Delphi 6
31

Sin embargo, tambin tiene desventajas. Entre ellas, la principal es que no
podremos tener dos instalaciones del mismo programa, en dos directorios distintos, que
accedan cada uno de ellos a una base de datos distinta (el alias permanente es nico, no
depende de la aplicacin que lo use).

Para evitar esta desventaja, podremos usar Alias Temporales, tambin
denominados Alias de Aplicacin. Este tipo de alias se crea usando el componente
TDatabase y slo tiene vida mientras la aplicacin se est ejecutando, y slo ser
conocido en la aplicacin que lo define. Es decir, dos ejecuciones simultneas de la
aplicacin pueden usar el mismo nombre de alias de aplicacin, pero sern distintos y
pueden acceder a dos bases de datos distintas.
Para crear un alias temporal lo haremos colocando un componente TDatabase en el
formulario, y en vez de asignarle valor a la propiedad AliasName, configuraremos
manualmente los parmetros que lo caracterizan. Esto se puede hacer desde el Inspector
de Objetos, desde cdigo, o desde el Database Editor, al que se accede haciendo doble
clic en el componente TDatabase, o seleccionando en el men contextual (que aparece
al pulsar el botn derecho del ratn sobre el componente) la opcin Database Editor.

La Figura 20 muestra un ejemplo del Database Editor. Como se ve, en la parte
superior hay 3 parmetros:
- Name: Se corresponde con la propiedad DatabaseName, y ser el nombre del
alias temporal.
- Alias Name: Se deja en blanco, ya que no usamos alias permanentes.
- Driver Name: Dado que no usamos un alias, y que en algn lugar hemos de
decir qu tipo de base de datos vamos a usar, este es el lugar en donde lo
indicamos. Puede ser STANDARD, Informix, INTRBASE, , dependiendo de
la instalacin del ordenador.


Figura 20. Database Editor

Como ya se ha dicho, cada tipo de base de datos tiene una serie de parmetros para
caracterizarlo. En el campo Parameter Overrides podremos especificar estos valores.
Para saber los valores por defecto de determinado Driver, pulsaremos el botn Defaults.
(Ejercicio: Selecciona los distintos tipos de drivers, y pulsa el botn Defaults para ver
qu parmetros caracterizan a cada driver).
32
2004 Miguel Rodrguez Penabad

Para el tipo STANDARD, vemos que existe, entre otros, el parmetro PATH, que
ser el que tendremos que modificar para indicar dnde tenemos los datos. Los otros
dos parmetros que aparecen tienen su valor por defecto, por lo que podemos dejarlos
como estn o incluso borrarlos de ese campo de edicin.

Una vez que el hemos configurado el componente TDatabase, y creado por tanto el
alias temporal, podemos usar los componentes TTable y TQuery exactamente igual que
con los alias permanentes, enlazndolos mediante la propiedad DatabaseName.
El siguiente cdigo crea el alias temporal Nombr eBD_en_l a_apl i caci on.
Puede verse que el parmetro PATH del alias se cambia por programa para que sea el
mismo path del ejecutable de la aplicacin
2
. Si tuvisemos dos copias de la aplicacin
en dos directorios distintos (con sus correspondientes bases de datos), estas podran
ejecutarse sin interferir entre ellas.
pr ocedur e TFor m1. For mCr eat e( Sender : TObj ect ) ;
begi n
Dat abase1. Cl ose;
Dat abase1. Dat abaseName: =' Nombr eBD_en_l a_apl i caci on' ;
Dat abase1. Dr i ver Name: = STANDARD' ;
Dat abase1. Par ams. Cl ear ;
Dat abase1. Par ams. Add( PATH= +Ext r act Fi l ePat h( Par amSt r ( 0) ) ) ;
Tabl e1. Dat abaseName: =' Nombr eBD_en_l a_apl i caci on' ;
{O bi en Tabl e1. Dat abaseName: =Dat abase1. Dat abaseName}
Dat abase1. Connect ed: =t r ue; {Open: abr i mos l a BD}
Tabl e1. Open; {Abr i mos l a t abl a}
end;

5.1.1.2 DataSets
A continuacin veremos una serie de propiedades y mtodos vlidos tanto para
TTabl e como para TQuer y (si se usa con una consulta SELECT). De hecho, son
propiedades y mtodos de la clase TDataSet, redefinidos para ambas subclases:

Propiedades
- Dat abaseName: Esta propiedad ya ha sido explicada en el punto anterior.
- Act i ve: Es una propiedad booleana. Si su valor es falso, la tabla o consulta
estar cerrada, por lo que no se est accediendo a los datos. Al asignarle el
valor cierto la tabla se abre y se realiza el acceso a los datos.
- St at e: Determina el estado del dataset. Puede ser dsI nact i ve (cerrado,
Active=false), dsBr owse (abierto), dsI nser t (estado de insercin, se ha
aadido un registro en blanco que se rellenar con datos), dsEdi t (se est
modificando la fila actual).

Para indicar a qu datos se accede dentro de la base de datos, se hace usando la
propiedad indicada, que ser Tabl eName para los componentes TTabl e, y SQL para
los componentes TQuer y.
- Tabl eName: (Para los componentes TTabl e) Es un String que indica el
nombre de la tabla, o el nombre del fichero si es una base de datos Standard. En
este ltimo caso, no es necesario indicar la extensin del fichero (es decir, si es

2
Si no entiendes la sentencia en negrita, busca ayuda sobre las funciones Ext r act Fi l ePat h y
Par amSt r .
Delphi 6
33

una base de datos Paradox, para acceder a la tabla Persona.db basta indicar
Persona en la propiedad Tabl eName.
- SQL: (Para los componentes TQuery) Contiene la consulta, escrita en SQL. Por
ejemplo, Sel ect * Fr om Per sona. Ms adelante veremos en ms
detalle los distintos tipos de consultas (tanto de consulta como de modificacin
de datos) que podemos usar, aunque en todos los casos la consulta se especifica
en la propiedad SQL.

Mtodos:
1. Open: Abre el dataset. Es equivalente a poner la propiedad Active=TRUE. Si la
ejecucin falla por algn motivo, se genera una excepcin. En caso de xito, el
estado del dataset pasa a ser dsBr owse.

Los siguientes mtodos requieren que la tabla est abierta.
2. Cl ose: Cierra el dataset. Equivale a la asignacin Active:=FALSE.
3. Fi r st , Last , Pr i or , Next : Se usan para navegar por el dataset,
movindonos respectivamente al primer, ltimo, anterior o siguiente registro. Si
el dataset est abierto no produce error, pero para que exista un
desplazamiento real de registro actual, este tiene que existir. Esto se puede
comprobar verificando la propiedad EOF (End Of File) y BOF (Bottom Of File).
Si EOF es cierto estamos en el ltimo registro, por lo que Next no avanza de
registro. Si BOF es cierto, Pr i or tampoco retroceder.

Los siguientes mtodos permiten realizar modificaciones en los datos. Para los
componentes TQuer y, slo funcionar si la propiedad Request Li ve es cierta (el
resultado est vivo).
- Del et e: Borra el registro actual (si no hay registros, se produce una
excepcin).
- Edi t : Pone el dataset en modo dsEdi t . Esto permite modificar los valores de
los atributos de la fila actual.
- I nser t : Pone el dataset en modo dsI nser t , aadiendo una nueva fila (lo
hace temporalmente en memoria, no creando una fila en la base de datos) en la
que todos los atributos tienen un valor nulo, y pueden ser modificados
(asignarles valores).
- Post : Acepta los cambios y los graba en la base de datos. Si el dataset estaba
en modo dsEdi t , modifica en la base de datos la fila actual, y si estaba en
modo dsI nser t , aade la nueva fila. Al trasladar la modificacin a la base de
datos se realizarn una serie de comprobaciones (como integridad de entidad o
referencial, comprobar que los valores de un atributo son vlidos para su tipo,
etc.) y si todo es correcto, el dataset pasa a estado dsBr owse. Si ocurre algn
problema, se genera una excepcin.
- Cancel : Cancela los cambios, ya sea recargando el registro actual con los
valores de la base de datos, si se estaba modificando, o eliminando de la
memoria el nuevo registro si se estaba insertando.
- I nser t Recor d: Toma como parmetros un array de valores. Se inserta una
fila en la tabla con esos valores, en la posicin actual (salvo que existan
ndices).
- AppendRecor d: Similar, pero aade la fila al final (de nuevo, si no hay
ndices).
34
2004 Miguel Rodrguez Penabad


5.1.1.3 TFields: Los atributos de una tabla o consulta
TFi el d es un tipo de datos que permite acceder a los valores de cada atributo
(columna, campo) de un dataset, ya sea este una consulta o una tabla. Podemos crear
TFi el ds (realmente, descendientes de la clase TFi el d) de forma permanente para un
dataset, y si no lo hacemos estos se crearn de forma automtica al abrirlo (de la misma
forma que se creaba un componente TDatabase).
Es recomendable crear los TField, ya que esto tiene algunas ventajas. Una de ellas
es que sabemos el orden en el que se acceder a los campos, lo que es necesario para
algunos mtodos del dataset (como I nser t Recor d). Adems, si queremos acceder a
los valores de los campos por programa, ser ms sencillo, ya que existen gran cantidad
de mtodos que permiten realizar conversin de datos.

Existen los siguientes tipos de descendientes de la clase TFi el d:

TADTFi el d TDat eFi el d TRef er enceFi el d
TAggr egat eFi el d TDat eTi meFi el d TSmal l I nt Fi el d
TAr r ayFi el d TFl oat Fi el d TSQLTi meSt ampFi el d
TAut oI ncFi el d TFMTBCDFi el d TSt r i ngFi el d
TBCDFi el d TGr aphi cFi el d TTi meFi el d
TBi nar yFi el d TGui dFi el d TVar Byt esFi el d
TBl obFi el d TI Di spat chFi el d TVar i ant Fi el d
TBool eanFi el d TI nt eger Fi el d TWi deSt r i ngFi el d
TByt esFi el d TI nt er f aceFi el d TWor dFi el d
TCur r encyFi el d TLar gei nt Fi el d
TDat aSet Fi el d TMemoFi el d

Entre las funciones de conversin aplicables a estos tipos, destacamos las siguientes
(no todas las funciones sern aplicables a todos los tipos):
- Val ue: S es aplicable a todos los tipos, y devuelve el valor en el tipo nativo.
Es decir, un <TSt r i ngFi el d>. Val ue devolver un valor de tipo string, y un
<TI nt eger Fi el d>. Val ue devolver un entero.
- AsI nt eger : Devuelve el valor del campo convertido a entero.
- AsSt r i ng: Devuelve el valor del campo convertido a String.
- AsDat eTi me: Convierte el valor a tipo TDateTime (fecha/hora).

Estas propiedades son de lectura y escritura. Es decir, podemos tanto acceder a sus
valores como modificarlos. Por ejemplo, si tenemos una tabla TPersona con los
siguientes campos:

TPer sona: TTabl e;
TPer sonaDni : TSt r i ngFi el d;
TPer sonaNombr e: TSt r i ngFi el d;
TPer sonaTel ef ono: TSt r i ngFi el d;
TPer sonaFechaNaci mi ent o: TDat eFi el d;
TPer sonaNumer oHi j os: TI nt eger Fi el d;

Las siguientes sentencias seran vlidas.



ShowMessage( ' La per sona se l l ama ' + TPer sonaNombr e. Val ue) ;
ShowMessage( ' La per sona se l l ama ' + TPer sonaNombr e. AsSt r i ng) ;
TPer sonaFechaNaci mi ent o. AsDat eTi me : = Now;
Delphi 6
35

TPer sonaNumer oHi j os. Val ue: =0;

Para aadir los TFi el d a un datasource, accederemos al Editor de Campos. Para
ello haremos doble clic sobre el componente TTabl e o TQuer y (o en la opcin Fields
Editor del men contextual). Una vez tenemos los campos, podremos acceder a diversas
propiedades, como la etiqueta que se mostrar para referirse al campo
(Di spl ayLabel ), que es el que se usa para nombrar la cabecera de cada campo en un
control TDBGr i d.
En el editor de campos podemos aadir los campos existentes (Add Fields, o Add
all fields) o aadir campos nuevos, que no sern normalmente campos calculados (New
Field).
5.1.2 TDataSource y Controles de Datos
Como muestra la Figura 18, las aplicaciones que usan el BDE necesitan controles
(es decir, componentes visuales) de datos, y un componente TDat aSour ce que los
una al datasource que, a su vez, accede a los datos.
Del componente TDataSource destacamos las propiedades Dat aSet (que ser el
componente TTabl e o TQuer y que contiene los datos) y Aut oEdi t . Esta ltima es
una propiedad booleana que, si es cierta, hace que el dataset se ponga en modo de
edicin automticamente si modificamos los datos en el control correspondiente.
De los controles visuales, slo indicaremos de momento que las propiedades ms
importantes, que debemos establecer para que la aplicacin funcione, son las siguientes:
- Dat aSour ce: El TDat aSour ce que enlaza con la fuente de datos.
- Dat aFi el d: El campo del datasource al que hace referencia, si es necesario.
Para los controles TDBEdi t o TDBLabel ser necesario, mientras que para el
TDBNavi gat or o TDBGr i d no, ya que no referencia un campo solamente.

El apartado 8.4 muestra un ejemplo de aplicacin completa, que funciona
simplemente colocando componentes y ajustando propiedades, sin que tengamos que
programar nada.



EJERCICIO 1: Elimina el componente TDBNavigator del programa del punto 8.4.
Coloca una serie de botones primero, anterior, siguiente, etc. y
usa las propiedades del componente TDataSet para realizar las acciones
necesarias.

5.2 Consultas
El componente TQuery permite realizar cualquier tipo de consulta SQL que el
servidor de bases de datos admita. Esto depender del servidor, ya que evidentemente
las capacidades de SQL de una base de datos Paradox (realmente simuladas por el BDE)
no pueden compararse con las ofrecidas por un servidor como Oracle.
De cualquier forma, si usamos el estndar SQL-92, normalmente no tendremos
problemas con ningn servidor. La propiedad SQL del componente TQuer y es de tipo
36
2004 Miguel Rodrguez Penabad

TStrings, y puede modificarse tanto por programa como desde el inspector de objetos
(que abre un minieditor de textos).
5.2.1 Seleccin de datos
La seleccin de datos se har con una sentencia SELECT. Al abrirla, se crea un
cursor sobre los datos que nos permite recorrerlos.
La propiedad booleana Uni di r ect i onal especifica si se podr recorrer el
dataset en ambas direcciones, tanto hacia delante (Next , Last , etc.) como hacia atrs
(Pr i or ). Si se pone a falso, no se podr recorrer el conjunto de datos hacia atrs, pero
en cambio se consumen menos recursos.
La propiedad booleana Request Li ve indica si el dataset est vivo, en el
sentido de poder modificar los datos usando los mtodos I nser t , Del et e, etc. Si es
falso, no se podr hacer. Dependiendo de la consulta, a veces no ser posible poner esta
propiedad a cierto (al igual que no todas las vistas creadas en una base de datos son
actualizables), por ejemplo si la consulta selecciona datos de ms de una tabla.

5.2.2 Modificacin de datos
Tambin se puede usar el componente TQuer y para modificar datos: aadir filas,
borrarlas, o modificarlas, usando respectiva sentencias INSERT, DELETE o UPDATE.
En este caso, la consulta no se abre como las consultas de seleccin de datos, sino
que se ejecuta, mediante el procedimiento ExecSQL. Si la ejecucin no es exitosa se
genera una excepcin de tipo EDBEngi neEr r or , a travs de la cual podemos recoger
el cdigo de error nativo que se produce en el servidor.

5.2.3 Campos y consultas con parmetros
Podemos acceder a los valores obtenidos por una consulta de seleccin usando los
TFi el d si se han definido, al igual que haramos con un TTabl e.
Sin embargo, es muy comn crear consultas dinmicamente, por lo que los TField
estticos no estarn definidos. Por ello, si queremos acceder a los datos por programa,
podemos usar la propiedad Fi el ds (que es un array de 0 al nmero de expresiones
seleccionadas menos 1), o la funcin Fi el dByName, que accede a un campo por su
nombre.
A continuacin se muestra un ejemplo donde creamos la consulta dinmicamente y
mostramos todos los nombres y DNIs de nuestra agenda (NOTA: tanto Fi el ds como
Fi el dByName se puede aplicar tambin a las tablas):

pr ocedur e TFor m2. But t on1Cl i ck( Sender : TObj ect ) ;
var Q: TQuer y;
begi n
t r y
Q: =TQuer y. Cr eat e( Appl i cat i on) ;
Q. Dat abaseName: =' Agenda' ;
Q. SQL. Add( ' SELECT NOMBRE, DNI FROM PERSONA' ) ;
Q. Open;
Whi l e not Q. EOF do begi n
ShowMessage( Q. Fi el ds[ 0] . AsSt r i ng+' con DNI : ' +
Delphi 6
37

Q. Fi el dByName( ' DNI ' ) . AsSt r i ng) ;
Q. Next ;
End;
f i nal l y
Q. Dest r oy;
end;

Algo especfico de las consultas es que la sentencia SQL puede ser dinmica,
admitiendo parmetros, que se rellenarn antes de abrir o ejecutar la consulta. Los
parmetros van precedidos por dos puntos : en la sentencia SQL, y se puede acceder
a ellos a travs de la propiedad Par ams (accesible tambin desde el Inspector de
Objetos) o la funcin Par amByName, de forma similar a los TField.
Por ejemplo, el siguiente cdigo borra de la agenda la persona cuyo DNI
introduzcamos en el control TEdi t 1 (en este caso, suponemos que la consulta Q est
en el formulario For m2).

pr ocedur e TFor m2. But t on1Cl i ck( Sender : TObj ect ) ;
begi n
Q. SQL. Cl ear ;
Q. SQL. Add( ' DELETE FROM PERSONA WHERE DNI =: el _dni ' ) ;
Q. Par amByName( ' el _dni ' ) . AsSt r i ng: =Edi t 1. Text ;
Q. ExecSql ;
end;


EJERCICIO 2: Modifica el programa Agenda aadiendo dos campos de edicin
EHijosMin y EHijosMax, y haciendo que la agenda muestre slo las
personas con un nmero de hijos entre esos dos valores


5.3 Eventos
Existen eventos ante los que los componentes DataSource y DataSet (TTable y
TQuery) responden. A continuacin veremos los eventos principales y sus posibles
utilidades.
5.3.1 Eventos del DataSource
- OnSt at eChange: Se produce cuando el estado del DataSet asociado
(dsEdi t , dsBr owse, etc.) cambia. Es til, por ejemplo, para activar o
desactivar botones que ejecutan determinados mtodos. As, si el estado es
dsEdi t , habilitaramos los botones que ejecuten los mtodos Post o Cancel
del DataSet, pero deshabilitaramos aquellos que ejecuten Pr i or , Next , etc.
- OnDat aChange: Se produce cuando cambian los datos actuales, normalmente
como consecuencia de cambiarnos de fila. Es til para refrescar datos en
controles que no son data-aware (si queremos simular un TDBEdit con un
TEdit, por ejemplo), o de nuevo para habilitar o deshabilitar controles (por
ejemplo, tras una llamada al mtodo Next , se produce este evento y podemos
comprobar si estamos en el ltimo registro, y desactivar el botn que avanza una
fila en el dataset.
38
2004 Miguel Rodrguez Penabad

- OnUpdat eDat a: Se produce al hacer Post el DataSource asociado (realmente,
antes de ejecutar el mtodo Post ). Es til para hacer cambios o validaciones de
datos justo antes de guardarlos en la base de datos.
5.3.2 Eventos de DataSet
Los siguientes eventos se producen para los dos tipos de DataSet que conocemos:
las tablas y las consultas. Dado que algunos de ellos (de hecho, la mayora) de estos
eventos ocurren al modificar datos, slo sern vlidos para las consultas si tienen la
propiedad Request Li ve a cierto.
- OnNewRecord: Se da al pasar a modo de insercin (al usar los mtodos Insert o
Append), y es til para asignar valores iniciales a la nueva fila. Por ejemplo, en
una tabla que guarde facturas, al aadir una nueva fila la fecha ser la actual.
- Bef or eScr ol l / Af t er Scr ol l : Ocurren justo antes y justo despus de
cambiarnos de fila.
- Relacionados con los mtodos que modifican datos, existen eventos que ocurren
justo antes (Before) o despus (After) de la ejecucin del mtodo. As,
tendremos eventos como Bef or eI nser t y Af t er I nser t , que ocurren
justo antes/despus de poner el dataset en modo de insercin, o
Bef or ePost / Af t er Post , que se producen antes/despus de hacer la
operacin de Post .


EJERCICIO 3: Modifica el programa del EJ ERCICIO 1, de forma que los botones se
activen o desactiven automticamente



5.4 Formularios Maestro-Detalle
Hasta ahora hemos visto cmo crear aplicaciones en Delphi que usan una tabla.
Para usar ms de una, de forma independiente, se programara de la misma forma. Sin
embargo, existen casos en los que las tablas estn enlazadas. Es el caso de las relaciones
1:N (del modelo Entidad-Relacin), se suelen transformar en el modelo relacional en 2
tablas, de forma que una de ellas ser la principal, y la otra contendr una clave
fornea hacia ella.
Por ejemplo, es normal disear las tablas de una base que almacenan facturas y sus
lneas usando el siguiente esquema:
Factura (Numero, Fecha)
Linea (NumFac, NumLinea, Producto, Precio)

Si creamos una aplicacin Delphi con dos componentes TTable independientes,
obtendramos algo como lo que se muestra en la Figura 21. Es decir, veremos todas las
facturas en el componente DBGrid superior, y todas las lneas de todas las facturas en el
inferior.
Por supuesto, sera mucho ms cmodo que el DBGrid de las lneas nos mostrase
slo aquellas lneas de la factura actual. Esto se podra programar manualmente
usando diversos eventos (como OnScroll) de la tabla de facturas, pero dada la
Delphi 6
39

frecuencia con que son necesarias, Delphi nos permite hacerlo de forma mucho ms
sencilla.

Figura 21. Gestin de Facturas y Lneas sin usar Maestro-Detalle

5.4.1 Maestro-Detalle con tablas
Siguiendo con el ejemplo anterior, modificaremos las propiedades
Mast er Sour ce y Mast er Fi el ds (en la tabla de detalle) de los componentes
TTabl e:
- Mast er Sour ce: Indica el DataSource asociado a la tabla maestra, en este
caso DSFactura.
- Mast er Fi el ds: Especifica la relacin de clave fornea, como se ve en la
Figura 22. Para acceder a esta ventana, simplemente pulsaremos en los puntos
suspensivos () de esta propiedad, en el Inspector de Objetos. Aqu indicamos
que el campo Numero (de la tabla facturas) se enlaza con el campo NumFac de
la tabla de lneas.


Figura 22. Especificacin de clave fornea en relaciones Maestro-Detalle
40
2004 Miguel Rodrguez Penabad


Haciendo solamente este cambio, la aplicacin ahora se comportar como en la
Figura 23. Tenemos seleccionada la factura nmero 2, por lo que slo vemos las lneas
de la factura nmero 2. De hecho (y sin tener que programar nada) si aadimos una fila
a la tabla de lneas (pulsando la tecla de cursor abajo en el DBGrid inferior) el nmero
de factura adecuado aparece automticamente.

Figura 23. Gestin de Facturas y Lneas usando la relacin Maestro-Detalle

5.4.2 Maestro-Detalle con Consultas
Tambin es posible crear formularios Maestro-Detalle usando consultas (TQuer y)
en vez de tablas. En este caso, no existe la propiedad Mast er Sour ce, por lo que la
relacin tenemos que establecerla de otra forma. Veamos el mismo ejemplo de facturas
y lneas:
- En la consulta maestra (QFact ur a) no hacemos nada especial. En su
propiedad SQL indicamos que queremos obtener todos los datos de facturas:
SELECT * FROM FACTURA.
- En la consulta de detalle haremos uso de los parmetros, para indicar que
cuando se cambie de tupla en la consulta de facturas debemos reejecutar la
consulta de detalle para obtener las lneas de la nueva factura. Esto se consigue
haciendo lo siguiente:
o La propiedad SQL tendr un parmetro, que ser el enlace con la
consulta maestra (NOTA: el parmetro debe llamarse igual que el campo
de la consulta maestra: Numero):
SELECT * FROM LI NEA WHERE NumFac = : Numer o.
o A la propiedad Dat aSour ce de la consulta de detalle se asigna el
DataSource de la consulta maestra: DSFact ur a.
Esto hace que automticamente se cree un parmetro (puede verse en la
propiedad TPar ams de la consulta) llamado Numero, que servir de
enlace entre ambas consultas.

Delphi 6
41

6 Listados
La mayora de las aplicaciones Windows ofrecen la posibilidad de generar un
informe o listado, por impresora, de lo que el programa gestiona. Delphi tambin ofrece
esta posibilidad, a travs de los denominados generadores de informes.
Existe gran variedad de estos generadores, tanto incluidos en Delphi (desde la
versin 3, Delphi incluye QuickReport), como desarrollados por otras compaas
(FastReport y su versin libre FreeReport, Rave Reports, Crystal Reports, etc).
La mayora de ellos permite elaborar informes a partir de datos estticos, incluir
figuras, fragmentos en RTF, etc., pero su mayor utilidad es la de poder generar
fcilmente listados a partir de datos almacenados en una base de datos.
En este captulo veremos cmo crear informes usando QuickReport ya que, aunque
no es un generador especialmente bueno
3
, viene incluido con Delphi.
QuickReport es un generador orientado a bandas. Es decir, en tiempo de diseo
nosotros aadiremos bandas horizontales (ver Figura 24) y colocaremos en ellas los
componentes que queremos que se impriman. El comportamiento de cada banda
depender de su tipo, que bsicamente ser uno de los siguientes (todas son de la clase
TQr Band, y se indica entre parntesis el valor de su propiedad BandType):
- Ttulo (r bTi t l e): Banda de ttulo, que aparecer en la parte superior de la
primera pgina.
- Cabecera (r bCol umnHeader ): Aparecer en todas las pginas en la parte
superior (debajo del ttulo en la primera) para identificar los datos. Es
especialmente til en informes tabulares del estilo de una agenda telefnica o
una factura.
- Detalle (r bDet ai l ): Esta banda se repetir tantas veces como filas tenga el
dataset asociado. Se usa para imprimir los datos que se obtienen de la base de
datos.
- Subdetalle (r bSubdet ai l ): Similar a los formularios maestro-detalle, esta
banda sirve para imprimir valores de un dataset hijo del que gobierna el
informe, por ejemplo las lneas de determinada factura, si queremos imprimir
varias facturas completas.
- Resumen (r bSummar y): Se imprime una vez se acaban de imprimir todas las
bandas de detalle (y subdetalle si hubiese). Servira, por ejemplo, para colocar el
total de una factura una vez impresas todas sus lneas.
- Cabecera o pie de pgina (r bPageHeader , r bPageFoot er )
- Hija (r bChi l d): Es un tipo de banda especial que se puede asociar a cualquier
otro tipo de banda, y se imprimir despus de ella.

En cada banda colocaremos los componentes necesarios para imprimir los datos. De
entre todos los posibles (que se pueden ver en la paleta de componentes, en la pestaa
QReport) destacamos los siguientes:
- QRLabel : Es el equivalente al TLabel en un formulario, y sirve para
imprimir texto esttico (usando la propiedad Capt i on).
- QRDBText : Equivale al TDBText , y a travs de sus propiedades
Dat aSour ce y Dat aFi el d accede al valor de un atributo de una fila de una

3
De nuevo, es una opinin personal del autor.
42
2004 Miguel Rodrguez Penabad

tabla o consulta. Ser el tipo de componente que usaremos normalmente en las
bandas de detalle.
- QRDBExpr : Permite manejar expresiones tales como totales, contadores de
registros (equivalente al sel ect count ). Suele ser usado en la banda de
resumen.
- QRSysDat a: Imprime automticamente valores del sistema (fecha, hora, ) o
del informe (nmero de pgina actual).

Los pasos a seguir para crear un informe son los siguientes:
1. Colocar un componente TQui ckRep en el formulario. Aparecer una
especie de hoja cuadriculada. El tamao y su posicin no importan, ya que
este es el diseador del informe y no se ver en la aplicacin cuando esta
se ejecute.
2. Asignar a la propiedad DataSet la tabla o consulta de la que se obtendrn los
datos a imprimir.
3. Aadir las bandas necesarias para el informe, colocando los componentes de
impresin adecuados. Para aadir una banda podemos seleccionar un
componente QRBand de la paleta de componentes y colocarla en el
diseador del informe, o acceder a la propiedad Bands de este, que nos
permite aadir las bandas ms comunes.


Figura 24. QuickReport diseando un informe
Una vez que el informe est diseado, podemos previsualizarlo en pantalla o
imprimirlo directamente en la impresora. Para lo primero usaremos el mtodo
Pr evi ew del componente QuickRep, y para lo segundo, Pr i nt . En tiempo de diseo,
seleccionando la opcin Preview del men emergente del componente QuickRep,
podemos previsualizar el informe.
6.1 Ejemplo
Para ver un ejemplo real y detallado, expandiremos la agenda del programa 8.4 de
forma que podamos imprimir un listado de las personas almacenadas en la agenda (slo
imprimiremos el nombre y el telfono).
Por la forma en que se disean los informes con QuickReport, necesitaremos un
formulario para colocar el componente QuickRep. Por supuesto, podramos utilizar el
Delphi 6
43

formulario principal de la aplicacin, puesto que el diseador del informe no se vera al
ejecutar la aplicacin, pero sera demasiado engorroso. Por ello, aadiremos un nuevo
formulario al proyecto. Dejaremos que Delphi cree este formulario automticamente.
Este nuevo formulario (FLi st ado, en la unit Li st ado) nunca ser mostrado,
slo lo usaremos como contenedor para poder disear cmodamente el informe, y
realizaremos los pasos siguientes:
1. Colocamos un componente QuickRep en l (llamado LST). Como DataSet que
gobierna el informe pondremos FPr i nci pal . TPer sona (para ello debemos
incluir en la lista Uses de la unit Li st ado la unit Pr i nci pal ).
2. Aadimos una banda de tipo ttulo (por ejemplo, poniendo la propiedad
Bands. HasTi t l e a cierto), y en ella un QRLabel para identificar el listado.
3. Aadimos una banda de tipo r bCol umnHeader para identificar las columnas
del listado Nombre y Telfono, usando de nuevo QRLabel s.
4. Aadimos una banda de tipo detalle (r bDet ai l ) para imprimir los nombres y
telfonos. Para ello usaremos componentes QRDBText , estableciendo sus
propiedades Dat aSet y Dat aFi el d para obtener los datos.
5. En el formulario FPrincipal aadimos un botn que haga que al pulsarlo se
previsualice el informe (FLi st ado. LST. Pr evi ew). Para ello tambin es
necesario usar la unit Listado, que es donde se encuentra el componente
QuickRep.



EJERCICIO 4: Aade un listado (completo, de todos los datos de cada persona) al
programa Agenda.


44
2004 Miguel Rodrguez Penabad

7 Manejo de Excepciones
Delphi, como muchos otros lenguajes de programacin, permite controlar las
excepciones que pueden ocurrir durante la ejecucin de un programa.
Una excepcin es un error de ejecucin, que en Delphi es tambin un objeto (de clase
Except i on y descendientes). Esto nos permite realizar un buen control sobre
fragmentos de cdigo problemtico.
El control de excepciones en Delphi se suele realizar en Delphi mediante un bloque
tryexcept:
t r y
{Bl oque pr ot egi do}
except
{Manej ador es de excepci ones}
end;
El bloque t r y. . except se comporta de la siguiente forma: Las sentencias del
bloque protegido se ejecutan. Si no se produce un error, la parte de Manejadores de
excepciones no se ejecuta y el control se pasa a la lnea siguiente al end. Si se produce
una excepcin en una instruccin, las restantes sentencias del bloque protegido no se
ejecutan, sino que el control pasa a los manejadores de excepciones. As, en el siguiente
fragmento de cdigo, la sentencia c: =a/ b produce un error (en concreto, la excepcin
de tipo EZer oDi vi de), y en vez de continuar la ejecucin en la sentencia c: =c*2, el
control pasa a la sentencia c: =0 (que es el manejador de excepciones en este caso).
t r y
a: =5;
b: =0;
c: =a/ b;
/ / Las sent enci as a par t i r de aqu no se ej ecut ar n
/ / debi do al er r or de di vi si n por cer o
c: =c*2;
except
c: =0;
end;
Existe otro mtodo de control de excepciones, que se usa normalmente para
asegurarnos de que un recurso que es creado dinmicamente se libera cuando ya no es
necesario: el bloque t r yf i nal l y. Por ello, a este bloque se le suele denominar
bloque de proteccin de recursos. Se diferencia de la anterior en que la parte
f i nal l y se ejecuta siempre, ocurra o no un error.
t r y
{Cr eaci n y ut i l i zaci n de r ecur sos}
f i nal l y
{Dest r ucci n del r ecur so}
end;
En el siguiente fragmento de cdigo se crea un objeto de tipo TSt r i ngs, se usa, y
luego se destruye, liberando la memoria asociada. Es decir, si en el manejo de la lista se
produce un error, inmediatamente se pasa el control al bloque de destruccin del
recurso. Si no se produce error, al terminar el bloque de creacin y utilizacin de
recurso tambin se ejecuta el mtodo de destruccin de la parte f i nal l y del bloque.
/ *var l i st a: TSt r i ngs; */
t r y
Delphi 6
45

l i st a : = TSt r i ngLi st . Cr eat e;
/ / oper aci ones con l i st a
f i nal l y
l i st a. Dest r oy;
end;
Los ejemplos anteriores tenan un nico manejador de excepciones. Si sabemos que
se pueden dar varios tipos de excepciones (que sern de clases descendientes de
Except i on), se pueden controlar de forma separada usando la estructura
On <Ti poDeExcepci on> do <Manej ador espec f i co>;
Podemos tener una o varias sentencias de este tipo, y puede haber una parte el se
para manejar el resto de los tipos de excepciones, como en el siguiente ejemplo.
f unct i on Di vi deVal or es( s1, s2: st r i ng) : st r i ng;
var n1, n2, di vi si on: i nt eger ;
begi n
t r y
n1: =St r ToI nt ( s1) ;
n2: =St r ToI nt ( s2) ;
di vi si on: =n1 DI V n2;
Resul t : = I nt ToSt r ( di vi si on)
except
On EConver t Er r or do
ShowMessage( Er r or : Al gn val or no es un nmer o ) ;
On EZer oDi vi de do
ShowMessage( Er r or : Di vi si n por cer o ) ;
el se
ShowMessage( Excepci n no i nesper ada ) ;
end;
end;
Adems, podemos tambin instanciar una variable de tipo Except i on (o derivada)
para acceder, por ejemplo, al mensaje original:
t r y
. . .
except
On E: Except i on do ShowMessage( E. Message) ;
end;
Finalmente, tambin podemos generar excepciones de forma manual, mediante la
sentencia
Rai se Except i on. Cr eat e( Mensaj e de excepci n per sonal i zado ) ;
46
2004 Miguel Rodrguez Penabad

8 Programas de ejemplo
A continuacin se mostrar el cdigo de los programas de ejemplo de este
documento. Se mostrar para cada uno de ellos una imagen del formulario (o
formularios), el fichero DFM de dicho formulario visto como texto, y el cdigo
ObjectPascal de la unit asociada.
8.1 Programa Bienvenida
8.1.1 Bienvenida.DPR
pr ogr amBi enveni da;
uses
For ms,
Pr i nci pal i n Pr i nci pal . pas {f Pr i nci pal };
{$R *. r es}
begi n
Appl i cat i on. I ni t i al i ze;
Appl i cat i on. Cr eat eFor m( Tf Pr i nci pal , f Pr i nci pal ) ;
Appl i cat i on. Run;
end.
8.1.2 Formulario Principal

Figura 25. Formulario del programa Bienvenida
8.1.2.1 Principal.DFM
obj ect f Pr i nci pal : Tf Pr i nci pal
Lef t = 239
Top = 434
Wi dt h = 512
Hei ght = 239
Capt i on = f Pr i nci pal
Col or = cl Bt nFace
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 19
Delphi 6
47

Font . Name = MS Sans Ser i f
Font . St yl e = [ ]
Ol dCr eat eOr der = Fal se
Pi xel sPer I nch = 96
Text Hei ght = 24
obj ect Et i quet a: TLabel
Lef t = 136
Top = 136
Wi dt h = 68
Hei ght = 24
Capt i on = Et i quet a
end
obj ect Bot on: TBut t on
Lef t = 136
Top = 56
Wi dt h = 137
Hei ght = 65
Capt i on = Bot n
TabOr der = 0
OnCl i ck = Bot onCl i ck
end
end
8.1.2.2 Principal.PAS
uni t Pr i nci pal ;
i nt er f ace
uses Wi ndows, Messages, SysUt i l s, Var i ant s, Cl asses, Gr aphi cs,
Cont r ol s, For ms, Di al ogs, St dCt r l s;
t ype
Tf Pr i nci pal = cl ass( TFor m)
Bot on: TBut t on;
Et i quet a: TLabel ;
pr ocedur e Bot onCl i ck( Sender : TObj ect ) ;
pr i vat e
{ Pr i vat e decl ar at i ons }
publ i c
{ Publ i c decl ar at i ons }
end;
var
f Pr i nci pal : Tf Pr i nci pal ;
i mpl ement at i on
{$R *. df m}
pr ocedur e Tf Pr i nci pal . Bot onCl i ck( Sender : TObj ect ) ;
begi n
Et i quet a. Capt i on: = Bi enveni do/ a a Del phi ;
end;
end.
48
2004 Miguel Rodrguez Penabad

8.2 Minicalculadora (versin 1, MiniCalc1)
8.2.1 MiniCalc1.DPR
pr ogr amMi ni Cal c1;

uses
For ms,
FCal c i n ' FCal c. pas' {For m1};

{$R *. r es}

begi n
Appl i cat i on. I ni t i al i ze;
Appl i cat i on. Cr eat eFor m( TFor mCal c, For mCal c) ;
Appl i cat i on. Run;
end.
8.2.2 Formulario Principal

8.2.2.1 FCalc.DPR
obj ect For mCal c: TFor mCal c
Lef t = 192
Top = 107
Wi dt h = 392
Hei ght = 208
Capt i on = ' Mi ni Cal cul ador a ( V1) '
Col or = cl Bt nFace
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 11
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ ]
Ol dCr eat eOr der = Fal se
Pi xel sPer I nch = 96
Text Hei ght = 13
obj ect LTot al : TLabel
Lef t = 16
Top = 72
Wi dt h = 30
Hei ght = 13
Capt i on = ' LTot al '
Delphi 6
49

end
obj ect ESumando1: TEdi t
Lef t = 16
Top = 8
Wi dt h = 121
Hei ght = 21
TabOr der = 0
OnExi t = ESumando1Exi t
end
obj ect ESumando2: TEdi t
Lef t = 16
Top = 40
Wi dt h = 121
Hei ght = 21
TabOr der = 1
OnExi t = ESumando2Exi t
end
obj ect bSuma: TBut t on
Lef t = 152
Top = 8
Wi dt h = 75
Hei ght = 25
Capt i on = ' Suma'
TabOr der = 2
OnCl i ck = bSumaCl i ck
end
end
8.2.2.2 FCalc.PAS
uni t FCal c;

i nt er f ace

uses Wi ndows, Messages, SysUt i l s, Var i ant s, Cl asses, Gr aphi cs,
Cont r ol s, For ms, Di al ogs, St dCt r l s;

t ype
TFor mCal c = cl ass( TFor m)
ESumando1: TEdi t ;
ESumando2: TEdi t ;
LTot al : TLabel ;
bSuma: TBut t on;
pr ocedur e ESumando1Exi t ( Sender : TObj ect ) ;
pr ocedur e ESumando2Exi t ( Sender : TObj ect ) ;
pr ocedur e bSumaCl i ck( Sender : TObj ect ) ;
pr i vat e
{ Pr i vat e decl ar at i ons }
publ i c
{ Publ i c decl ar at i ons }
end;

var
For mCal c: TFor mCal c;

i mpl ement at i on

{$R *. df m}

pr ocedur e TFor mCal c. ESumando1Exi t ( Sender : TObj ect ) ;
var num: i nt eger ;
50
2004 Miguel Rodrguez Penabad

begi n
t r y
num: =St r ToI nt ( ESumando1. Text )
except
showmessage( ' El nmer o i nt r oduci do no es vl i do' ) ;
ESumando1. Set Focus;
end;
end;

pr ocedur e TFor mCal c. ESumando2Exi t ( Sender : TObj ect ) ;
var num: i nt eger ;
begi n
t r y
num: =St r ToI nt ( ESumando2. Text )
except
showmessage( ' El nmer o i nt r oduci do no es vl i do' ) ;
ESumando2. Set Focus;
end;
end;

pr ocedur e TFor mCal c. bSumaCl i ck( Sender : TObj ect ) ;
begi n
LTot al . Capt i on: =
I nt ToSt r ( St r ToI nt ( ESumando1. Text ) +St r ToI nt ( ESumando2. Text ) ) ;
end;

end.

Delphi 6
51

8.3 Minicalculadora (versin 2, MiniCalc2)
8.3.1 Formulario principal
Dado que slo cambia la gestin de eventos, incluimos solamente el cdigo
correspondiente al FCalc.PAS (ambos componentes TEdit tienen como manejador del
evento OnExi t el procedimiento SumandosExi t ):

uni t FCal c;

i nt er f ace

uses Wi ndows, Messages, SysUt i l s, Var i ant s, Cl asses, Gr aphi cs,
Cont r ol s, For ms, Di al ogs, St dCt r l s;

t ype
TFor m1 = cl ass( TFor m)
ESumando1: TEdi t ;
ESumando2: TEdi t ;
LTot al : TLabel ;
But t on1: TBut t on;
pr ocedur e But t on1Cl i ck( Sender : TObj ect ) ;
pr ocedur e SumandosExi t ( Sender : TObj ect ) ;
pr i vat e
{ Pr i vat e decl ar at i ons }
publ i c
{ Publ i c decl ar at i ons }
end;

var
For m1: TFor m1;

i mpl ement at i on

{$R *. df m}

pr ocedur e TFor m1. But t on1Cl i ck( Sender : TObj ect ) ;
begi n
LTot al . Capt i on: =
I nt ToSt r ( St r ToI nt ( ESumando1. Text ) +St r ToI nt ( ESumando2. Text ) ) ;
end;

pr ocedur e TFor m1. SumandosExi t ( Sender : TObj ect ) ;
var num: i nt eger ;
begi n
t r y
num: =St r ToI nt ( TEdi t ( Sender ) . Text )
except
showmessage( ' El nmer o i nt r oduci do no es vl i do' ) ;
TEdi t ( Sender ) . Set Focus;
end;

end;
end.



52
2004 Miguel Rodrguez Penabad

8.4 Editor de textos
8.4.1 Editor1.DPR
pr ogr amedi t or 1;
uses
For ms,
Edi t i n ' Edi t . pas' {For m1};

{$R *. RES}
begi n
Appl i cat i on. I ni t i al i ze;
Appl i cat i on. Cr eat eFor m( TFor m1, For m1) ;
Appl i cat i on. Run;
end.
8.4.2 Formulario principal
8.4.2.1 Edit.DFM


obj ect For m1: TFor m1
Lef t = 260
Top = 445
Wi dt h = 614
Hei ght = 421
Capt i on = ' Edi t or de Text os'
Col or = cl Bt nFace
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 11
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ ]
Ol dCr eat eOr der = Fal se
Pi xel sPer I nch = 96
Text Hei ght = 13
obj ect EFi cher o: TEdi t
Lef t = 230
Delphi 6
53

Top = 2
Wi dt h = 371
Hei ght = 21
TabOr der = 0
Text = ' EFi cher o'
end
obj ect bAbr i r : TBut t on
Lef t = 170
Top = 2
Wi dt h = 53
Hei ght = 23
Capt i on = ' Abr i r '
TabOr der = 1
OnCl i ck = bAbr i r Cl i ck
end
obj ect bBor r ar : TBut t on
Lef t = 8
Top = 2
Wi dt h = 75
Hei ght = 23
Capt i on = ' Bor r ar '
TabOr der = 2
OnCl i ck = bBor r ar Cl i ck
end
obj ect Text o: TMemo
Lef t = 8
Top = 32
Wi dt h = 593
Hei ght = 361
TabOr der = 3
end
obj ect bGuar dar : TBut t on
Lef t = 106
Top = 2
Wi dt h = 53
Hei ght = 23
Capt i on = ' Guar dar '
TabOr der = 4
OnCl i ck = bGuar dar Cl i ck
end
end
8.4.2.2 Edit.PAS
uni t Edi t ;

i nt er f ace

uses
Wi ndows, Messages, SysUt i l s, Cl asses, Gr aphi cs, Cont r ol s, For ms,
Di al ogs,
St dCt r l s;

t ype
TFor m1 = cl ass( TFor m)
EFi cher o: TEdi t ;
bAbr i r : TBut t on;
bBor r ar : TBut t on;
Text o: TMemo;
bGuar dar : TBut t on;
pr ocedur e bAbr i r Cl i ck( Sender : TObj ect ) ;
54
2004 Miguel Rodrguez Penabad

pr ocedur e bGuar dar Cl i ck( Sender : TObj ect ) ;
pr ocedur e bBor r ar Cl i ck( Sender : TObj ect ) ;
pr i vat e
{ Pr i vat e decl ar at i ons }
publ i c
{ Publ i c decl ar at i ons }
end;

var
For m1: TFor m1;

i mpl ement at i on

{$R *. DFM}

pr ocedur e TFor m1. bAbr i r Cl i ck( Sender : TObj ect ) ;
begi n
t r y
Text o. Li nes. LoadFr omFi l e( Ef i cher o. Text ) ;
except
Appl i cat i on. MessageBox(
Pchar ( EFi cher o. Text + ' no exi st e o no se puede l eer ' ) ,
' Er r or al abr i r f i cher o' , MB_I CONERROR)
end
end;

pr ocedur e TFor m1. bGuar dar Cl i ck( Sender : TObj ect ) ;
begi n
t r y
Text o. Li nes. SaveToFi l e( Ef i cher o. Text ) ;
except
Appl i cat i on. MessageBox(
Pchar ( ' No se puede guar dar el t ext o en ' +EFi cher o. Text ) ,
' Er r or al guar dar f i cher o' , MB_I CONERROR)
end
end;

pr ocedur e TFor m1. bBor r ar Cl i ck( Sender : TObj ect ) ;
begi n
Text o. Cl ear ;
end;
end.
Delphi 6
55

8.5 Agenda
8.5.1 Agenda.DPR
pr ogr amagenda;

uses
For ms,
Pr i nci pal i n ' Pr i nci pal . pas' {For m1};

{$R *. r es}

begi n
Appl i cat i on. I ni t i al i ze;
Appl i cat i on. Cr eat eFor m( TFor m1, For m1) ;
Appl i cat i on. Run;
end.
8.5.2 Formulario Principal
8.5.2.1 Principal.DFM


obj ect For m1: TFor m1
Lef t = 317
Top = 353
Wi dt h = 447
Hei ght = 317
Capt i on = ' Agenda'
Col or = cl Bt nFace
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 11
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ ]
Ol dCr eat eOr der = Fal se
56
2004 Miguel Rodrguez Penabad

Pi xel sPer I nch = 96
Text Hei ght = 13
obj ect Label 1: TLabel
Lef t = 8
Top = 8
Wi dt h = 24
Hei ght = 16
Capt i on = ' Dni '
FocusCont r ol = DBEdi t 1
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 13
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ f sBol d]
Par ent Font = Fal se
end
obj ect Label 2: TLabel
Lef t = 8
Top = 48
Wi dt h = 56
Hei ght = 16
Capt i on = ' Nombr e'
FocusCont r ol = DBEdi t 2
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 13
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ f sBol d]
Par ent Font = Fal se
end
obj ect Label 3: TLabel
Lef t = 8
Top = 88
Wi dt h = 63
Hei ght = 16
Capt i on = ' Tel f ono'
FocusCont r ol = DBEdi t 3
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 13
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ f sBol d]
Par ent Font = Fal se
end
obj ect Label 4: TLabel
Lef t = 8
Top = 128
Wi dt h = 148
Hei ght = 16
Capt i on = ' Fecha de Naci mi ent o'
FocusCont r ol = DBEdi t 4
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 13
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ f sBol d]
Par ent Font = Fal se
end
obj ect Label 5: TLabel
Lef t = 8
Top = 168
Delphi 6
57

Wi dt h = 117
Hei ght = 16
Capt i on = ' Numer o de Hi j os'
FocusCont r ol = DBEdi t 5
Font . Char set = DEFAULT_CHARSET
Font . Col or = cl Wi ndowText
Font . Hei ght = - 13
Font . Name = ' MS Sans Ser i f '
Font . St yl e = [ f sBol d]
Par ent Font = Fal se
end
obj ect DBEdi t 1: TDBEdi t
Lef t = 8
Top = 24
Wi dt h = 147
Hei ght = 21
Dat aFi el d = ' Dni '
Dat aSour ce = DSPer sona
TabOr der = 0
end
obj ect DBEdi t 2: TDBEdi t
Lef t = 8
Top = 64
Wi dt h = 369
Hei ght = 21
Dat aFi el d = ' Nombr e'
Dat aSour ce = DSPer sona
TabOr der = 1
end
obj ect DBEdi t 3: TDBEdi t
Lef t = 8
Top = 104
Wi dt h = 199
Hei ght = 21
Dat aFi el d = ' Tel ef ono'
Dat aSour ce = DSPer sona
TabOr der = 2
end
obj ect DBEdi t 4: TDBEdi t
Lef t = 8
Top = 144
Wi dt h = 134
Hei ght = 21
Dat aFi el d = ' FechaNaci mi ent o'
Dat aSour ce = DSPer sona
TabOr der = 3
end
obj ect DBEdi t 5: TDBEdi t
Lef t = 8
Top = 184
Wi dt h = 134
Hei ght = 21
Dat aFi el d = ' Numer oHi j os'
Dat aSour ce = DSPer sona
TabOr der = 4
end
obj ect DBNavi gat or 1: TDBNavi gat or
Lef t = 8
Top = 224
Wi dt h = 240
Hei ght = 25
58
2004 Miguel Rodrguez Penabad

Dat aSour ce = DSPer sona
TabOr der = 5
end
obj ect DSPer sona: TDat aSour ce
Dat aSet = TPer sona
Lef t = 240
Top = 24
end
obj ect Dat abase1: TDat abase
Al i asName = ' per sonal 1'
Connect ed = Tr ue
Dat abaseName = ' BDAgenda'
Sessi onName = ' Def aul t '
Lef t = 176
Top = 24
end
obj ect TPer sona: TTabl e
Act i ve = Tr ue
Dat abaseName = ' BDAgenda'
Tabl eName = ' per sona'
Lef t = 208
Top = 24
obj ect TPer sonaDni : TSt r i ngFi el d
Fi el dName = ' Dni '
Si ze = 11
end
obj ect TPer sonaNombr e: TSt r i ngFi el d
Fi el dName = ' Nombr e'
Si ze = 50
end
obj ect TPer sonaTel ef ono: TSt r i ngFi el d
Di spl ayLabel = ' Tel f ono'
Fi el dName = ' Tel ef ono'
Si ze = 15
end
obj ect TPer sonaFechaNaci mi ent o: TDat eFi el d
Di spl ayLabel = ' Fecha de Naci mi ent o'
Fi el dName = ' FechaNaci mi ent o'
end
obj ect TPer sonaNumer oHi j os: TI nt eger Fi el d
Di spl ayLabel = ' Numer o de Hi j os'
Fi el dName = ' Numer oHi j os'
end
end
end

8.5.2.2 Principal.PAS
Como vemos, en este primer ejemplo de programa que accede a bases de datos,
tenemos un programa de mantenimiento (altas, bajas, modificaciones) sin escribir una
sola lnea de cdigo.

uni t Pr i nci pal ;

i nt er f ace

uses Wi ndows, Messages, SysUt i l s, Var i ant s, Cl asses, Gr aphi cs,
Cont r ol s, For ms, Di al ogs, DB, DBTabl es, Ext Ct r l s, DBCt r l s,
St dCt r l s, Mask;
Delphi 6
59


t ype
TFor m1 = cl ass( TFor m)
DSPer sona: TDat aSour ce;
Dat abase1: TDat abase;
TPer sona: TTabl e;
TPer sonaDni : TSt r i ngFi el d;
TPer sonaNombr e: TSt r i ngFi el d;
TPer sonaTel ef ono: TSt r i ngFi el d;
TPer sonaFechaNaci mi ent o: TDat eFi el d;
TPer sonaNumer oHi j os: TI nt eger Fi el d;
Label 1: TLabel ;
DBEdi t 1: TDBEdi t ;
Label 2: TLabel ;
DBEdi t 2: TDBEdi t ;
Label 3: TLabel ;
DBEdi t 3: TDBEdi t ;
Label 4: TLabel ;
DBEdi t 4: TDBEdi t ;
Label 5: TLabel ;
DBEdi t 5: TDBEdi t ;
DBNavi gat or 1: TDBNavi gat or ;
pr i vat e
{ Pr i vat e decl ar at i ons }
publ i c
{ Publ i c decl ar at i ons }
end;

var
For m1: TFor m1;

i mpl ement at i on

{$R *. df m}

end.

Vous aimerez peut-être aussi