12 noviembre 2007

Creando tablas de memoria con ClientDataSet

Una de las cosas que más se necesitan en un programa de gestión es la posibilidad crear tablas de memoria para procesar datos temporalmente, sobre todo cuando los datos origen vienen de tablas distintas.

Es muy común utilizar componentes de tablas de memoria tales como los que llevan los componentes RX (TRxMemoryData) o el componente kbmMemTable. Pues veamos como hacer tablas de memoria utilizando el componente de la clase TClientDataSet sin tener que utilizar ningún componente externo a Delphi.

DEFINIENDO LA TABLA

Lo primero es añadir a nuestro proyecto un componente ClientDataSet ya sea en un formulario o en un módulo de datos. Como vamos a crear una tabla de recibos lo vamos a llamar TRecibos.

Ahora vamos a definir los campos de los que se compone la tabla. Para ello pulsamos el botón [...] en la propiedad FieldDefs. En la ventana que se abre pulsamos el botón Add New y vamos creando los campos:

Name DataTpe Size
-----------------------------------
NUMERO ftInteger 0
CLIENTE ftString 80
IMPORTE ftFloat 0
PAGADO ftFloat 0
PENDIENTE ftFloat 0

Para crear la tabla de memoria pulsamos el componente TClientDataSet con el botón derecho del ratón y seleccionamos Create DataSet. Una vez creado sólo nos falta hacer que los campos sean persistentes. Eso se consigue haciendo doble clic sobre el componente y pulsando la combinación de teclas CTRL + A.

Con estos sencillos pasos ya hemos creado una tabla de memoria y ya podemos abrirla para introducir datos. No es necesario abrir la tabla ya que estas tablas de memoria hay que dejarlas activas por defecto.

DANDO FORMATO A LOS CAMPOS

Como tenemos tres campos de tipo real vamos a dar formato a los mismos del siguiente modo:

1. Hacemos doble clic sobre el componente ClientDataSet.

2. Seleccionamos los campos IMPORTE, PAGADO y PENDIENTE.

3. Activamos en el inspector de objetos su propiedad Currency.

Con esto ya tenemos los campos en formato moneda y con decimales.

REALIZANDO CALCULOS AUTOMATICAMENTE

A nuestra tabla de recibos le vamos a hacer que calcule automáticamente el importe pendiente. Esto lo vamos a hacer antes de que se ejecute el Post, en el evento BeforePost:

procedure TFormulario.TRecibosBeforePost( DataSet: TDataSet );
begin
TRecibosPENDIENTE.AsFloat := TRecibosIMPORTE.AsFloat - TRecibosPAGADO.AsFloat;
end;

De este modo, tanto si insertamos un nuevo registro como si lo modificamos realizará el cálculo del importe pendiente antes de guardar el registro.

AÑADIENDO, EDITANDO Y ELIMINANDO REGISTROS DE LA TABLA

Insertamos tres registros:

begin
TRecibos.Append;
TRecibosNUMERO.AsInteger := 1;
TRecibosCLIENTE.AsString := 'TRANSPORTES PALAZON, S.L.';
TRecibosIMPORTE.AsFloat := 1500;
TRecibosPAGADO.AsFloat := 500;
TRecibos.Post;

TRecibos.Append;
TRecibosNUMERO.AsInteger := 2;
TRecibosCLIENTE.AsString := 'TALLERES CHAPINET, S.L.';
TRecibosIMPORTE.AsFloat := 200;
TRecibosPAGADO.AsFloat := 200;
TRecibos.Post;

TRecibos.Append;
TRecibosNUMERO.AsInteger := 3;
TRecibosCLIENTE.AsString := 'GRUAS MARTINEZ, S.L.';
TRecibosIMPORTE.AsFloat := 625;
TRecibosPAGADO.AsFloat := 350;
TRecibos.Post;
end;

Si queremos modificar el primer registro:

begin
TRecibos.First;
TRecibos.Edit;
TRecibosCLIENTE.AsString := 'ANTONIO PEREZ BERNAL';
TRecibosIMPORTE.AsFloat := 100;
TRecibosPAGADO.AsFloat := 55;
TRecibos.Post;
end;

Y para eliminarlo:

begin
TRecibos.First;
TRecibos.Delete;
end;

MODIFICANDO LOS CAMPOS DE LA TABLA

Si intentamos añadir un nuevo campo a la tabla en FieldDefs y luego pulsamos CTRL + A para hacer el campo persistente veremos que desaparece de la definición de campos. Para hacerlo correctamente hay que hacer lo siguiente:

1. Pulsamos el componente ClientDataSet con el botón derecho del ratón.

2. Seleccionamos Clear Data.

3. Añadimos el nuevo campo en FieldDefs.

4. Volvemos a pulsar el el botón derecho del ratón el componente y seleccionamos Create DataSet.

5. Pulsamos CTRL + A para hacer persistente el nuevo campo.

Estos son los pasos que hay que seguir si se crean, modifican o eliminan campos en la tabla.

CREANDO CAMPOS VIRTUALES PARA SUMAR COLUMNAS

Vamos a crear tres campos virtuales que sumen automáticamente el valor de las columnas IMPORTE, PAGADO y PENDIENTE para totalizarlos. Comencemos con el cálculo del importe total:

1. Pulsamos el componente ClientDataSet con el botón derecho del ratón.

2. Seleccionamos Clear Data.

3. Hacemos doble clic en el componente ClientDataSet.

4. Pulsamos la combinación de teclas CTRL + N para añadir un nuevo campo:

Name: TOTALIMPORTE
FieldType: Agregate

5. Pulsamos Ok. Seleccionamos el campo creado escribimos en su propiedad Expression:

SUM(IMPORTE)

y activamos su propiedad Active. También activamos su propiedad Currency.

6. Creamos en el formulario un campo de tipo DBText y asociamos en nuevo campo creado:

DataSource: TRecibos
DataField: TOTALIMPORTE

7. Volvemos a pulsar el el botón derecho del ratón el componente y seleccionamos Create DataSet.

8. Activamos en el componente TClientDataSet la propiedad AggregatesActive.

Igualmente habría que crear dos campos más para sumar las columnas del importe pagado y el importe pendiente.

Utilizar ClientDataSet para crear tablas de memoria es ideal para procesar listados en tablas temporales sin tener que volcar el resultado en ninguna base de datos. Además podemos importar y exportar datos a XML usando el menú contextual de este componente.

Pruebas realizadas en Delphi 7.

9 comentarios:

ManiacPC (Style) dijo...

He caido varias veces a tu blog por dudas de delphi que he tenido y me ha dirigido aquí por google... He solucionado muchos cachos de cadenas de texto, aprendí a usar rave reports... y tb el clientdataset... Realmente te felicito por tu blog, pedazo de info que has publicado y realmente de utilidad.
Este comentario es para agradecer la publicación de tus conocimientos, a mi por lo menos, me han servido de mucho.

GRACIAS!
Un abrazo
Enrique

Administrador dijo...

Me alegro que tanto esfuerzo haciedo mis apuntes de Delphi, por lo menos lo puedan aprovechar otras personas.

Si todos aportaramos algo de vez en cuando, Delphi estaría muy arriba en el mundo hispano.

Saludos.

Martin dijo...

No dudes que muchas, muchas personas te estarán eternamente agradecidas de todo el esfuerzo descomunal que haces para mantener este bloq.

Dar las gracias queda corto...

Administrador dijo...

Me alegra de que sirva de ayuda a tanta gente.

10.000 visitas al mes en un blog tan pequeño como este demuestra que todavía quedan muchos programadores utilizando Delphi.

Saludos.

Guillem dijo...

Enhorabuena, despues de emplear durante años distintos componentes comerciales este que ademas de gratuito viene incluido con delphi es mucho mejor.
Gracias ....

Guillem dijo...

Enhorabuena, despues de emplear durante años distintos componentes comerciales este que ademas de gratuito viene incluido con delphi es mucho mejor.
Gracias ....

Undest dijo...

hola muchas gracias por la información.

solo añadir que tambien se pueden añadir las columnas programaticamente con clientdataset.FieldDefs.Add
:D esta era la parte que tenía me has iluminado en el resto

Unknown dijo...

Hola que tal todos ocupo que me ayuden en unas praticas sencillas de delphi ya que yo no entiendo como desarrollarlas espero me echen la mano, el primero es poner un numero y un memo y cada vez que se vaya insertando un numero se va dando enter y vaya apareciendo y al ultimo se vaya sumando ....espero me echen la mano alguien que este ahi bien ligado con delphi.. gracias

Unknown dijo...

Hola que tal buenas tardes!
La verdad es que ando investigando acerca de las Tablas Dinámicas, ¿Puedo preguntarte algo? Si la respuesta es SI, por favor sigue leyendo, bueno el planteamiento es el siguiente:
-> Necesito Almacenar de alguna manera la información capturada por el usuario en una Tabla Temporal, el detalle esq puede capturar mucha información de diferentes Artículos en un sólo Formulario... ¿Puedo Vaciar la información de ésa tabla Temporal a SQL Server? Quizás no tiene mucho sentido, pero se me hace una buena soloción a mi 'problema', de antemano muchas gracias.

Publicidad