Ejemplos


Si utilizamos este componente en local, el conjunto de datos lo extraeremos de un fichero local. Este fichero debera ser creado por otro TclientDataSet, por lo tanto tendremos que crear el conjunto de datos. Para crear un conjunto de datos en memoria debemos definir los campos e índices que deseemos y aplicar el método CreateDataSet.
 

 With ClientDataSet1.FieldDefs do
 Begin
   Clear;
   Add('Nombre',ftstring,30,true);
   Add('apellido 1º', ftstring 10, true);
   Add('apellido 2º',ftstring 10,true);
   ...
 End;

 With ClientDataSet1.indexdefs do
 Begin
   Clear;
   Add('xnombre,'nombre',[ixCaseInsensitive]);
   Add...
 End;
 ClientDataSet1.createdataset;

Para cargar y salvar los datos puede utilizar los métodos LoadFromFile y SaveToFile, o bien utilizar la propiedad FileName del componente para no tener que utilizar los dos métodos. Vamos a realizar un ejemplo que nos permitira crear tablas anidadas. Al crear este tipo de tablas, todos los datos se almacenan en el mismo fichero. Las tablas anidadas funcionan a mayor velocidad que las relaciones master/detail. Para realizar el ejemplo seguimos los siguientes pasos:

Insertamos un componente TclientDataSet, modificamos la propiedad FieldsDefs y definimos los campos:

    . Nombre ftstring 20 ftrequired
    . Apellido1 ftstring 15 ftrequired
    . Apellido2 ftstring 15
    ...
    . Telefono ftDataSet

Para definir los campos de la detalle, seleccionamos la definición del campo Teléfono y editamos la propiedad ChildDefs donde definimos los campos:

    . Telefono ftinteger
    . Especif. Ftstring 20

Añadimos dos indices por medio de la propiedad indexdefs (por nombre y apellido).

Para almacenar la estructura pulsamos con el botón derecho del ratón sobre el componente y ejecutamos el comando CreateDataSet. Mediante el editor de campos añadimos los campos y para que los datos aparezcan ordenados por nombre asignamos a la propiedad indexfieldnames el campo nombre. Para la visualización de datos pordemos utilizar un dbgrid. Si queremos que los datos aparezcan en dos dbgrid utilizaremos otro clientdataset utilizando la propieda DataSetField de dicho componente con el TclientDataset anterior. Si deseamos eliminar un dato de la tabla detalle antes de eliminar el maestro realizaremos lo siguiente:
 

 Clientdataset2.first;
 While not ClientDataSet2.eof do
   ClientDataset2.delete;

Al utilizar el componente TclientDataset hay un nuevo campo, los campos calculados internos. Para ello entrar en new field, en este componente podemos ver dos nuevas opciones InternalCalc y Aggregate. El tipo Intercalc se calcula durante la respuesta al evento OnCalcFields. La diferencia de este tipo de campos a los conocidos campos calculados es que el valor de los campos calculados internos se almacenan también junto al conjunto de datos. La principal consecuencia de esta politica de almacenamiento es que se pueden definir indices basados en este campo. Asi que tenemos algo parecido a índices por expressiones para los conjuntos de datos clientes. Si tenemos campos calculados normales e internos, el evento oncalcfields se ejecutara dos veces, una vez para cada campo. Para diferenciarlos utilizaremos la propiedad State del conjunto de datos. En un caso valdrá dsCalcFields y en el otro dsInternalCalc. Partiendo del caso anterior, realizaremos un ejemplo que tendrá dos opciones de menú: Fichero y Editar. Dentro de la opción de fichero podremos elegir: Salvar cambios o salir. Y en Editar elegimos deshacer registro actual o deshacer todos los cambios. El código sería:
 

 unit Unit3;

 interface

 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   StdCtrls, Mask, DBCtrls, ExtCtrls, Grids, DBGrids, Menus, Db;

 type
   TForm3 = class(TForm)
     MainMenu1: TMainMenu;
     File1: TMenuItem;
     Salvarcambios1: TMenuItem;
     Salir1: TMenuItem;
     Editar1: TMenuItem;
     deshacerregistroactual1: TMenuItem;
     deshacertodosloscambios1: TMenuItem;
     DBNavigator1: TDBNavigator;
     DBEdit1: TDBEdit;
     DBEdit2: TDBEdit;
     DBEdit3: TDBEdit;
     DBEdit4: TDBEdit;
     DBEdit5: TDBEdit;
     DBGrid1: TDBGrid;
     Label2: TLabel;
     Label3: TLabel;
     Label4: TLabel;
     Label5: TLabel;
     Label6: TLabel;
     procedure DBGrid1Enter(Sender: TObject);
     procedure DBGrid1Exit(Sender: TObject);
     procedure Salir1Click(Sender: TObject);
     procedure Salvarcambios1Click(Sender: TObject);
     procedure deshacerregistroactual1Click(Sender: TObject);
     procedure deshacertodosloscambios1Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;

 var
   Form3: TForm3;

 implementation

 uses Unit2;

 {$R *.DFM}

 procedure TForm3.DBGrid1Enter(Sender: TObject);
 begin
   DBNavigator1.datasource:=datamodule2.Datasource2;
 end;

 procedure TForm3.DBGrid1Exit(Sender: TObject);
 begin
   DBNavigator1.datasource:=datamodule2.datasource1;
 end;

 procedure TForm3.Salir1Click(Sender: TObject);
 begin
   close;
 end;

 procedure TForm3.Salvarcambios1Click(Sender: TObject);
 begin
   if Datamodule2.ClientDataSet1.state in [dsedit,dsInsert] then
     datamodule2.clientdataset1.post;
   if Datamodule2.clientdataset2.state in [dsEdit,dsInsert] then
     Datamodule2.ClientDataSet2.Post;
     with datamodule2.clientdataset1 do
     begin
       mergechangelog;
       savetofile('clientes');
     end;
     label1.caption:='REGISTROS SALVADOS';
     label1.caption:=inttostr(datamodule2.clientdataset1.aggregates.find('totalrecords').value)
     //'registros salvados';
 end;

 procedure TForm3.deshacerregistroactual1Click(Sender: TObject);
 begin
   datamodule2.ClientDataSet1.revertrecord;
 end;

 procedure TForm3.deshacertodosloscambios1Click(Sender: TObject);
 begin
   datamodule2.ClientDataSet1.cancelupdates;
 end;

 end.

Vamos a realizar otro ejemplo utilizando el TclientDataset para ver una relación maestro detalle utilizando un solo dbgrid.

. Insertamos los dos TDatasource y dos Ttable para establecer la relación maestro/detalle entre las dos tablas.
. Insertamos el TclientDataSet pulsar el boton derecho del raton y elegir la opción "Assign Local Data" y elegir la tabla principal. Entramos en el editor de campos del TclientDataset y asignamos los campos.

Si deseamos visualizar los datos en otro dbgrid utilizaremos otro TclientDataset. Modificamos la propiedad DataSetField y lo unimos con el primer TclientDataSet.

NOTA: Los ejemplos se encuentran en el CD en:
           . \ejemplos\anidadas
           . \ejemplos\TClientDataSet
           . \ejemplos\masterdetail


(C) 1999 Database DM. la reproduccion total o parcial de este documento, asi como la divulgación de parte o la totalidad