Ir al contenido


Foto

Crear un ClientDataSet réplica de una tabla

ClientDataSet réplica

  • Por favor identifícate para responder
5 respuestas en este tema

#1 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 824 mensajes
  • LocationMisiones, Argentina

Escrito 04 julio 2017 - 08:25

Estoy creando un método generalizado que será aplicado a un software real.

Se trata de la creación de un clientdataset que replica los campos de una tabla de una base de datos, o mejor dicho, son varios clientdatasets, que replican a varias tablas respectivamente.

 

Más allá de las complicaciones que pueda tener con campos BLOBs, lo que me preocupa es que no puedo crear esta réplica en un DataModule en el momento de su creación.

 

¿alguien sabe por qué?

 

El método de creación del ClientDataset es el siguiente:


delphi
  1. for I:= 0 to dsetUno.FieldCount -1 do cdsUno.FieldDefs.Add(
  2. dsetUno.FieldDefs.Items[I].Name,
  3. dsetUno.FieldDefs.Items[I].DataType,
  4. dsetUno.FieldDefs.Items[I].Size,
  5. false);
  6. cdsUno.CreateDataSet;

La variable I es de tipo integer, por las dudas.

 

Cuando hago esto en un TForm, no hay problema, el problema es cuando lo ejecuto al momento de la creación del TDataModule.

Se supone que los objetos ya se encuentran creados, pues de otro modo el error sería diferente.

Revisé el orden de creación de los objetos.

 

Yo supongo, -alquien me dirá si estoy equivocado-, que es porque aun no se encuentra conformada la estructura de los campos del dataset físico.

 

"No Fields defined to create dataset"

 

 


  • 0

#2 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 04 julio 2017 - 08:49

Y los creas en tiempo de ejecucion a los datasets?

 

Ademas: tienes el componente de conexion seteado previamente, compruebas que este activo(que haya conexion), y se lo asignas al dataset a crear?

 

cdsUno es el TClinetDataSet y dsetUno es una componente tipo tabla? podrias aclarar.

 

la unica forma que se me ocurre es usar un provider. Tabla1 seria dsetUno_:


delphi
  1. var
  2. i: Integer;
  3. Field: TField;
  4. begin
  5. cds.SetProvider(Table1);
  6.  
  7. // add existing fields
  8. cds.FieldDefs.Update;
  9. for i := 0 to cds.FieldDefs.Count - 1 do
  10. cds.FieldDefs[i].CreateField(cds);
  11.  
  12.  
  13.  
  14. cds.Open;
  15. end;

Y que idea tenes? no tener que agregar manualmente todos los dataset necesarios en el desarrollo?


  • 0

#3 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 824 mensajes
  • LocationMisiones, Argentina

Escrito 04 julio 2017 - 05:29

Y los creas en tiempo de ejecucion a los datasets?

 

Ademas: tienes el componente de conexion seteado previamente, compruebas que este activo(que haya conexion), y se lo asignas al dataset a crear?

 

cdsUno es el TClinetDataSet y dsetUno es una componente tipo tabla? podrias aclarar.

 

la unica forma que se me ocurre es usar un provider. Tabla1 seria dsetUno_:


delphi
  1. var
  2. i: Integer;
  3. Field: TField;
  4. begin
  5. cds.SetProvider(Table1);
  6.  
  7. // add existing fields
  8. cds.FieldDefs.Update;
  9. for i := 0 to cds.FieldDefs.Count - 1 do
  10. cds.FieldDefs[i].CreateField(cds);
  11.  
  12.  
  13.  
  14. cds.Open;
  15. end;

Y que idea tenes? no tener que agregar manualmente todos los dataset necesarios en el desarrollo?

 

Disculpas Jiulichajari, la verdad es que pensaba mencionar que era cada cosa, hasta que vi la hora y me apuré.

dsetUno es el dataset que hace referencia a una tabla de la base de datos y cdsUno es el clientdataset o dataset que funciona solo en memoria.

Lo de configurarlo "atado" al dataset (como provider), no es mi idea, pues de ser así lo hubiera hecho de forma visual y sería más fácil (creo que es el uso más común, también).

El uso que le doy es el de una interfaz para los datos de una sola fila seleccionada. Es decir, que al terminar la transacción podré tener el resultado de laúltima fila seleccionada en el ClientDataset.

El método que escribí arriba funciona cuando lo uso en un form si lo pongo al pulsar un botón o al cerrar la ventana, pero el asunto es que como el siguiente paso es sincronizar los datos entre dos ventanas diferentes usando al ClientDataset, prefiero crearlo al inicio, o sea al momento de la creación de los componentes contenedores (TDatamodule, TForm).

 

Al principio sincronizaba los datos mediante el uso de el id de la entidad, pasándola y haciendo uso con el método Locate y en el cierre asignando el valor del id de la tabla a la variable id para sincronización con la ventana llamadora, pero dado que hay un ahorro tremendo en mantener los datos antes que volver a leerlos en otra transacción usando el id.

... ya ni yo me entiendo, espero que me expliques después :| :o :D :D

No en realidad es engorroso para explicarlo, pero una técnica que me permite una interfaz con el usuario muy buena.

 

Saludos y gracias por responder.


  • 0

#4 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.484 mensajes
  • LocationMallorca

Escrito 05 julio 2017 - 12:55

Hola amigo.

 

Cuando dices que ejecutas ese código al momento de la creación del Datamodule, ¿ te refieres a que lo ejecutas dentro de su evento OnCreate ?.

 

¿ Cuál es el mensaje de error que te aparece ?, ¿ un access violation ?, ¿ conexión no disponible ?, ¿ se ejecuta bien pero no hace nada ?, ....

 

Si pones el código completo, con su contexto (la declaración de los métodos y/o eventos donde se ejecuta, tanto la parte del DataModule como las referencias a él que se hacen en el formulario que lo utiliza), será más fácil ver por donde puede estar el problema.

 

Saludos.


  • 0

#5 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 824 mensajes
  • LocationMisiones, Argentina

Escrito 05 julio 2017 - 06:35

Gracias Marc.

 

Ayer lo estuve pensando y dando vueltas, caí en que nunca podría funcionar puesto que en el método OnCreate del DataModule las bases de datos no están abiertas, solo se han creado.

 

"No field defined to create dataset" es el mensaje de error, ya lo había escrito.

 

El método funciona bien en otro momento, pero por supuesto que no funcionaría en OnCreate. Para solucionar lo voy a llevar a un método de "setup" inicial como lo hago siempre al iniciar la aplicación, pero luego de probar conexiones con la base de datos, etc.

 

Si puedo lo marcaré como solucionado.

 

Muchas gracias a ambos

Saludos.


  • 1

#6 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 536 mensajes
  • LocationCali, Colombia

Escrito 11 julio 2017 - 05:36

Hola, normalmente cuando requiero crear un tclientdataset a partir de otro que ya existe y copiar la información de este, prefiero hacerlo con un TDataSetProvider, en tiempo de ejecución

 

algo así


delphi
  1. Procedure CreaDataSet(DataSet: TDataSet; CDS : TClientDataSet)
  2. Var
  3. Provider: TDataSetProvider;
  4. begin
  5. Provider := TDataSetProvider.Create(Self);
  6. Try
  7. Provider.Name := 'Componete' + Round(Random(1000000)).ToString;
  8. Provider.DataSet := DataSet;
  9. CDS.ProviderName := Provider.Name;
  10. CDS.Open;
  11. CDS.ProviderName := '';
  12. Finally
  13. Provider.Free;
  14. End;
  15. end;


  • 0





Etiquetado también con una o más de estas palabras: ClientDataSet, réplica