clone cursor e campos lookup

16/07/2008

3

estou com a seguinte situação:

Um clientdataset com dados, nele eu criei um campo lookup pra buscar a descricao em outro clientdataset.até aí tranquilo.
então tive a necessidade de varrer este client sem movimentar o ponteiro dele, usei entao a função CloneCursor pra criar um cursor pra ele. Mas no clientDataSet q criei pra receber esse novo cursor, não foi gerado o campo lookup. eu sei q o clone cursor clona somente o cursor para os dados, e não as caracteristicas adicionais do client de origem, mas eu preciso dessa informação do campo lookup ao varrer esse client clonado.
Aguardo sugestões... Obrigado..


Responder

Posts

16/07/2008

Davicarrano

up


Responder

16/07/2008

Fabianosales

Experimente usar a função abaixo. Mas alguns tipos de dados menos comuns (ftGraphic, por exemplo) eu não tratei, blz?

procedure TForm2.CloneClientDataSet(var Orig, Dest: TClientDataSet);
var
  i: integer;
  c: TClass;
  f: TField;
begin
  Dest.CloneCursor(Orig, False);
  Dest.Close;
  Dest.Fields.Clear;
  for i:=0 to Orig.Fields.Count-1 do
    begin
      c := Orig.Fields[i].ClassType;
      case Orig.Fields[i].DataType of
          ftString     : f := TStringField(c.NewInstance).Create(Self);
          ftInteger    : f := TIntegerField(c.NewInstance).Create(Self);
          ftFloat      : f := TFloatField(c.NewInstance).Create(Self);
          ftTime       : f := TTimeField(c.NewInstance).Create(Self);
          ftTimeStamp,
          ftDateTime   : f := TDateTimeField(c.NewInstance).Create(Self);
          ftDate       : f := TDateField(c.NewInstance).Create(Self);
          ftWideString : f := TWideStringField(c.NewInstance).Create(Self);
          ftMemo       : f := TMemoField(c.NewInstance).Create(Self);
          ftWideMemo   : f := TWideMemoField(c.NewInstance).Create(Self);
          ftSmallint   : f := TSmallintField(c.NewInstance).Create(Self);
          ftVariant    : f := TVariantField(c.NewInstance).Create(Self);
          ftBlob       : f := TBlobField(c.NewInstance).Create(Self);
          ftBCD        : f := TBCDField(c.NewInstance).Create(Self);
          ftBoolean    : f := TBooleanField(c.NewInstance).Create(Self);
          ftBytes      : f := TBytesField(c.NewInstance).Create(Self);
        end;
      f.FieldKind := Orig.Fields[i].FieldKind;
      f.FieldName := Orig.Fields[i].FieldName;
      f.Name:= Dest.Name + f.FieldName;
      //
      f.DisplayLabel      := Orig.Fields[i].DisplayLabel;
      f.DisplayWidth      := Orig.Fields[i].DisplayWidth;
      f.KeyFields         := Orig.Fields[i].KeyFields;
      f.LookupDataSet     := Orig.Fields[i].LookupDataSet;
      f.LookupKeyFields   := Orig.Fields[i].LookupKeyFields;
      f.LookupResultField := Orig.Fields[i].LookupResultField;
      //
      f.DataSet := Dest;
      Dest.FieldDefs.Add(f.Name, f.DataType);
    end;
end;


Para usá-la:
  CloneClientDataSet(ClientDataSet1, ClientDataSet2);
  ClientDataSet2.Open;


Evoé...


Responder

17/07/2008

Davicarrano

fabiano, valeu demais cara.... o código q vc me passou não funcionou mas me deu uma idéia pra eu chegar numa solução.... o código não funcionou pq logo apos eu clonar o cursor, se eu fechar(close) o client q recebeu o clone, funciona, mas ao abrí-lo novamente ele perde o data package... mas eu aproveitei a idéia de limpar todos os fields, ou melhor, o fieldDefs, e coloquei o clone depois q os fields forem criados novamente.... ahhh, e ainda otimizei uma parte do código pra não precisar comparar todos os tipos de dados, ja q eu tenho a classe do field que eu quero criar, eu usei referência de Classe... ficou assim:

type
TClassRefField = class of TField;

.....
......
procedure TForm2.ClonarDadosTo(Origem,Destino: TClientDataSet);
var i:integer;
SizeCampo:integer;
f:TField;
c:TClass;
begin
Destino.FieldDefs.Clear;
for i:=0 to Origem.Fields.Count-1 do
begin
//essa linha é pra desprezar o TdataSetField
if Origem.Fields[i].DataType = ftDataSet then continue;

c := Origem.Fields[i].ClassType;

f := TClassRefField(C).Create(Self);

f.FieldKind := Origem.Fields[i].FieldKind;
f.FieldName := Origem.Fields[i].FieldName;
f.Name:= Destino.Name + f.FieldName;
//
f.DisplayLabel := Origem.Fields[i].DisplayLabel;
f.DisplayWidth := Origem.Fields[i].DisplayWidth;
f.KeyFields := Origem.Fields[i].KeyFields;
f.LookupDataSet := Origem.Fields[i].LookupDataSet;
f.LookupKeyFields := Origem.Fields[i].LookupKeyFields;
f.LookupResultField := Origem.Fields[i].LookupResultField;
//
f.DataSet := Destino;
Destino.FieldDefs.Add(f.Name, f.DataType);
end;

Destino.CloneCursor(Origem,false,false);
end;




ficou blz... a união faz a força ne cara... eu num tinha conseguido sem sua idéia... valeu demais


Responder

17/07/2008

Fabianosales

Puxa. O lance do ´TClassRefField = class of TField´ simplificou bastante o código. Show de bola. :wink:
Já o lance da perda do datapacket me passou despercebido porque o teste que eu fiz só verificava se a lista de campos batia com a origiem e o destino. :oops:
Valeu Davi.

Evoé...


Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira