Ver Mensaje Individual
  #5  
Antiguo 10-02-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.610
Reputación: 32
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por Bauhaus1975 Ver Mensaje
prefiero hacerlo con la función puesto que creo que es más 'portable' a mis casos... He probado cambiar Open por CreateDataSet como dices, pero ahora el error (casi me lo esperaba) es: 'No fields defined'.
¿Tengo que definir los campos previamente, con fielddefs?
Ah, claro, el conjunto de datos cliente (TClientDataSet) debe tener ya los campos que usará (lista de objetos TField en la propiedad Fields) o al menos sus definiciones (propiedad FieldDefs). Olvidé ese pequeño detalle.

Cita:
Empezado por ayuda de Delphi
If the FieldDefs property contains values, these values are used to create field definitions. Otherwise the Fields property is used. One or both of these properties must contain values in order to create a dataset. If neither property is set, CreateDataSet raises an exception.

Cita:
Empezado por Bauhaus1975 Ver Mensaje
¿Hay alguna forma de hacerlo automaticamente, es decir que lo coja del resultado de la query?
Desafortunadamente no existe una solución nativa que te copie (clone) los objetos campos de un conjunto de datos en otro. Es medianamente laborioso implementarla con un ciclo For que recorra la propiedad Fields del conjunto de datos origen (el TIBQuery, en este caso) y por cada campo cree una instancia de la misma clase en el conjunto de datos destino (el nuevo TClientDataSet), además de asignar las propiedades de cada campo copiado (al menos las esenciales como FieldName, Size, etc. y otras que requieras como DisplayFormat, Currency, etc.).

Si estás usando Delphi 7 o 2007 y no tienes inconveniente en emplear una de mis funciones, en GH Freebrary encontrarás un procedimiento llamado ghCopyFields que realiza esa tarea de "reproducción de campos". Tu función quedaría más o menos así (eliminé las sentencias innecesarias):

Código Delphi [-]
Uses
  GHFData;
...
function cloneQuery(ibQuery:TIBQuery):TClientDataSet;
var
    Campo :string;
    i :integer;
    tabla : TClientDataSet;
begin
    tabla:= TClientDataSet.Create(nil); // Creamos clientdataset y definimos propiedades
    ghCopyFields (ibQuery, tabla);  // Le creamos los mismos campos que a ibQuery
    tabla.CreateDataSet;  // Abrimos el conjunto de datos vacío

    // En esta sentencia se ejecuta la query que traerá los datos
    with ibQuery do
        begin
        Open;
        while not EOF do // Iteramos para ir insertando cada registro
          begin
          tabla.Append;
          for i := 0 to FieldCount-1 do
            begin
            Campo := Fields[i].FieldName;
            tabla[Campo] := ibQuery[Campo];
          end;
          tabla.Post;
          Next;
        end;
        Close;
    end;

    { Este es el "Close" que sugiero quitar.  Si acabas de crear y rellenar
      el clon, cerrarlo antes de usarlo no tiene sentido.  Ciérralo
      después, fuera de esta función, cuando ya no vayas a usarlo . }
//    tabla.Close;

    result := tabla;
end;


Cita:
Empezado por Bauhaus1975 Ver Mensaje
Otra cosa que me ronda la cabeza es lo que comentas de no poder cerrar ¿Te refieres al clientdataset?... puf, entonces la funcionalidad queda bastante reducida, ¿no?
Me refiero al Close prematuro que comenté arriba, en la función. Lo normal sería cerrar el nuevo conjunto de datos cuando ya no lo necesites (mejor aún, destruirlo por completo), pero no cuando acabas de crearlo. Lo usual sería algo como esto:
Código Delphi [-]
MiCDS := cloneQuery (QueryX);

Try
  // Uso de MiCDS
Finally
  MiCDS.Free;
End;

Espero te sirva lo escrito y mi código. Coméntanos cómo te resulta.

Un saludo.

Al González.

Última edición por Al González fecha: 10-02-2009 a las 01:21:59.
Responder Con Cita