Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: Создать поле в открытом TClientDataset ? 
V.Borzov
Member

Откуда: Саратов
Сообщений: 284
Senya_L


Не все укладывается в эту схему. Считайте это за религию и что не сумел
приготовить :)



А чем пользуетесь?
7 фев 09, 20:45    [6792329]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ? 
Senya_L
Member

Откуда: Москва
Сообщений: 5381

> Автор: V.Borzov
> А чем пользуетесь?
>

ADO и IBX в зависимости от СУБД. Хватает. Когда их перестает хватать и ручки
тянутся к средствам кэширования навроде CDS - это первый признак
проктологии.

Posted via ActualForum NNTP Server 1.4

7 фев 09, 21:53    [6792420]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ? 
V.Borzov
Member

Откуда: Саратов
Сообщений: 284
Ну вот примерный результат:

function ReadDataSet(DestinationCDS :TClientDataSet;
                     SourceDataSet :TDataSet;
                     AddField_Names: array of string;
                     AddField_Types :array of TFieldType ;
                     AddField_Kinds :array of TFieldKind;
                     AddField_Sizes :array of Integer
                     ) :Boolean;

var iC :Integer;
    k :Integer;
    Field :TField;
begin
   iC := High(AddField_Names);
   if (iC <> High(AddField_Names))
      or (iC <> High(AddField_Types))
      or (iC <> High(AddField_Kinds))
   then raise Exception.Create('Íåñîîòâåòñòâèå êîëè÷åñòâà ýëåìåíòîâ â ñïèñêàõ');

   DestinationCDS.DisableControls;
   try
     if iC>=0
     then begin
       if not SourceDataSet.Active then SourceDataSet.Open;

       DestinationCDS.Close;
       DestinationCDS.Fields.Clear;

       with SourceDataSet do
       for k := 0 To FieldCount-1 do
       begin
         Field := TFieldClass(Fields[k].classtype).Create(DestinationCDS.Owner); //  defaultfieldClasses[SourceDataSet.Fields[k].DAtatype].Create(DestinationCDS.Owner);
         Field.FieldName := Fields[k].FieldName;
         Field.Size := Fields[k].Size;
         Field.DataSet := destinationcds;
       end;

       for k := 0 To iC do
       begin
         Field := defaultfieldClasses[addfield_types[k]].Create(DestinationCDS.Owner);
         Field.FieldName := AddField_Names[k];
         Field.FieldKind := addField_kinds[k];
         if High(addField_Sizes[k]) >= ic
         then Field.Size := AddField_Sizes[k];

         Field.DAtaset := DestinationCDS;
       end;

     end;


     DestinationCDS.data := REadDAtaset(SourceDataset);
   finally
     DestinationCDS.EnableControls;
   end;
   Result := True;
end;


function ReadDataset(SourceDataset :TDataSet) :OleVariant;
var  dsp : TDatasetProvider;
begin
  Result := NULL;

  dsp := TDatasetProvider.Create(nil);
  try
     sourcedataset.DisableControls;
     try
       if sourcedataset.Active then sourcedataset.First; // Åñëè ýòîãî íå ñäåëàòü, òî âîçüìóòñÿ äàííûå ñ òåêóùåé ñòðîêè òîëüêî
       dsp.DataSet := sourcedataset;
       result := dsp.data;
     finally
       SourceDataSet.EnableControls;
     end
   finally
     dsp.Free;
   end;
end;


---------------------------------


procedure TForm1.Button1Click(Sender: TObject);
var Field :TField;
begin
  Table1.Open;
  ReadDataSet(CDS2,Table1, ['Field2','Field3'],[ftInteger,ftString],[fkInternalCalc,fkCalculated],[0,100]);
end;

procedure TForm1.CDS2CalcFields(DataSet: TDataSet);
begin
  dataset.FieldByName('field2').AsInteger := dataset.recno;
  dataset.FieldByName('field3').AsString := 'Recno = '+IntToStr(dataset.recno);
end;



Вроде работает :)
8 фев 09, 01:39    [6792712]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ? 
V.Borzov
Member

Откуда: Саратов
Сообщений: 284
V.Borzov


   then raise Exception.Create('Íåñîîòâåòñòâèå êîëè÷åñòâà ýëåìåíòîâ â ñïèñêàõ');




then raise Exception.Create('Несоответствие количества элементов в списках');

Остальное можно не переводить
8 фев 09, 01:44    [6792718]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ? 
Michael Longneck
Member

Откуда: Москва
Сообщений: 2299
Создавая поля не забудьте выставить свойство .Name для полей. Не помню какие, но с этим были проблемы.
8 фев 09, 01:48    [6792722]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ? 
V.Borzov
Member

Откуда: Саратов
Сообщений: 284
ньюанс:


   ...
   Result := DestinationCDS.Active; // true;
end;


хоть и бессмысленный, но рука чешется...
8 фев 09, 01:58    [6792728]     Ответить | Цитировать Сообщить модератору
 Re: Создать поле в открытом TClientDataset ? 
Extender
Member

Откуда: Омск
Сообщений: 90
+
unit FieldInfo;

interface

uses
  Windows, Messages, SysUtils, Classes, Db, DbClient;

type
  PFieldProps = ^TFieldProps;
  TFieldProps = record
    FieldName: string;
    ClassType: TFieldClass;
    MemoryStream: TMemoryStream;
    LookUpDataSet: TDataSet;
  end;

  {New: Add Calculated fields}
procedure AddCalculatedFields(Dataset: TDataSet; const FieldsNames,
  FieldsTypes: array of string);
{New: Assign data and Fields to new structure}
{With this function you can add Data Field (not calculated) to client dataset
but this function is slow and heavy}
procedure AssignData(List: TList; Dataset: TClientDataSet);
{Streams Fields List Clear}
procedure ClearAllFieldsInfo(List: TList);
{New: Copy Old Data in Modified Dataset}
procedure CopyDatasetData(Source, Target: TDataSet);
{New: delete an Item from List}
procedure DeleteField(List: TList; index: integer);
{Get information about Field definition into Dataset and then put into List}
procedure GetAllFieldsInfo(List: TList; DataSet: TDataSet);
{Get information about one Field and then put into List}
procedure GetFieldInfo(List: TList; Field: TField);
{New:  get the FieldIndex of Item}
function GetFieldIndex(List: TList; FieldName: string): integer;
{New:  get the FieldName of Item}
function GetFieldName(List: TList; index: integer): string;
{Get information about Field definition into Stream List and then put into Dataset}
procedure SetAllFieldsInfo(List: TList; DataSet: TDataSet);
{Field Classes register}
procedure RegClasses;
{Field Classes Unregister}
procedure UnRegClasses;

implementation

uses
  Variants;

procedure AddCalculatedFields(Dataset: TDataSet; const FieldsNames,
  FieldsTypes: array of string);
var
  List: TList;
  i: integer;
  oField: TField;
  clFieldClass: TFieldClass;
begin
  if not DataSet.Active then
    raise Exception.Create('I can not create calculated Fields when dataset is closed' + #13
      + 'with function AddCalculatedFields')
  else
  begin
    List := TList.Create;
    GetAllFieldsInfo(List, DataSet);
    for i := Low(FieldsNames) to High(FieldsNames) do
      if not Assigned(Dataset.FindField(FieldsNames[i])) then
      begin
        clFieldClass := TFieldClass(GetClass(FieldsTypes[i]));
        oField := clFieldClass.Create(DataSet);
        oField.FieldName := FieldsNames[i];
        oField.Calculated := True;
        if oField is TStringField then
          oField.Size := 100; {!!!}
        oField.FieldKind := fkInternalCalc;
        GetFieldInfo(List, oField);
        oField.Free;
      end;
    DataSet.Close;
    SetAllFieldsInfo(List, DataSet);
    ClearAllFieldsInfo(List);
    List.Free;
    DataSet.Open;
  end;
end;

procedure AssignData(List: TList; Dataset: TClientDataSet);
var
  NewDs: TClientDataSet;
begin
  DataSet.DisableControls;
  NewDs := TClientDataSet.Create(nil);
  SetAllFieldsInfo(List, NewDs);
  NewDs.CreateDataSet;
  CopyDatasetData(Dataset, NewDs);
  Dataset.Data := Null;
  SetAllFieldsInfo(List, DataSet);
  Dataset.Data := NewDs.Data;
  NewDs.Data := Null;
  NewDs.Free;
  DataSet.EnableControls;
end;

procedure ClearAllFieldsInfo(List: TList);
var
  i: Integer;
begin
  {Free record in each element of list}
  for i := 0 to List.Count - 1 do
  begin
    TFieldProps(List[i]^).MemoryStream.Free;
    TFieldProps(List[i]^).ClassType := nil;
    TFieldProps(List[i]^).LookUpDataSet := nil;
    Dispose(List[i]);
  end;
  {Clear the List}
  List.Clear;
end;

procedure CopyDatasetData(Source, Target: TDataSet);
type
  TSourceTargetFields = array[0..1] of TField;
var
  i, index: Integer;
  aFields: array of TSourceTargetFields;
  oField: TField;
begin
  if not Source.Active then
    Source.Active := True;
  if not Target.Active then
    Target.Active := True;
  for i := 0 to Source.FieldCount - 1 do
  begin
    oField := Target.FindField(Source.Fields[i].FieldName);
    if oField <> nil then
    begin
      index := High(aFields) + 1;
      SetLength(aFields, index + 1);
      aFields[index][0] := Source.Fields[i];
      aFields[index][1] := oField;
    end;
  end;

  Source.First;
  while not Source.Eof do
  begin
    Target.Insert;
    for i := 0 to High(aFields) do
    begin
      aFields[i][1].Value := aFields[i][0].Value;
    end;
    Target.Post;
    Source.Next;
  end;
end;

procedure DeleteField(List: TList; index: integer);
begin
  if index < List.Count then
  begin
    TFieldProps(List[index]^).MemoryStream.Free;
    TFieldProps(List[index]^).ClassType := nil;
    TFieldProps(List[index]^).LookUpDataSet := nil;
    Dispose(List[index]);
    List.Delete(index);
  end;
end;

procedure GetAllFieldsInfo(List: TList; DataSet: TDataSet);
var
  i: Integer;
  Field: TField;
begin
  for i := 0 to DataSet.Fields.Count - 1 do
  begin
    Field := DataSet.Fields[i];
    {Put Field information into list}
    GetFieldInfo(List, Field)
  end;
end;

procedure GetFieldInfo(List: TList; Field: TField);
var
  FieldProps: PFieldProps;
  i: integer;
begin
  New(FieldProps);

  {FieldName is necesary to compare if exist into the list}
  FieldProps^.FieldName := Field.FieldName;
  FieldProps^.ClassType := TFieldClass(Field.ClassType);
  FieldProps^.MemoryStream := TMemoryStream.Create;
  FieldProps^.MemoryStream.WriteComponent(Field);
  {LookUpDataSet is necesary because is a pointer and WriteComponent do not keep this information}
  FieldProps^.LookUpDataSet := Field.LookupDataSet;

  for i := 0 to List.Count - 1 do
  begin
    if TFieldProps(List[i]^).FieldName = FieldProps^.FieldName then
    begin
      {if exist into list then delete it}
      TFieldProps(List[i]^).MemoryStream.Free;
      TFieldProps(List[i]^).ClassType := nil;
      TFieldProps(List[i]^).LookUpDataSet := nil;
      Dispose(List[i]);
      List.Delete(i);
      Break;
    end;
  end;

  {Add information into the list}
  List.Add(FieldProps);
end;

function GetFieldIndex(List: TList; FieldName: string): integer;
var
  i: integer;
begin
  result := -1;
  for i := 0 to List.Count - 1 do
  begin
    if AnsiCompareText(PFieldProps(List[i]).FieldName, FieldName) = 0 then
    begin
      result := i;
      Break;
    end;
  end;
end;

function GetFieldName(List: TList; index: integer): string;
begin
  if index < List.Count then
    result := PFieldProps(List[index]).FieldName
  else
    result := '';
end;

procedure SetAllFieldsInfo(List: TList; DataSet: TDataSet);
var
  i: Integer;
  LocalField: TField;
  FieldClass: TFieldClass;
  SourceInfo: TMemoryStream;
begin
  if DataSet.Active then
    DataSet.Active := False;

  {se recorre toda la lista de definiciones de campos}
  DataSet.Fields.Clear;
  DataSet.FieldDefs.Clear;

  {Add all List Field definition into List to DataSet}
  for i := 0 to List.Count - 1 do
  begin
    {Get Correct Class Type}
    FieldClass := TFieldProps(List[i]^).ClassType;

    {if Class exists}
    if FieldClass <> nil then
    begin
      {Goto the first position of stream}
      SourceInfo := TFieldProps(List[i]^).MemoryStream;
      SourceInfo.Seek(0, soFromBeginning);

      {Create Field with Dataset}
      LocalField := FieldClass.Create(DataSet);
      {Set Field information}
      LocalField := TField(SourceInfo.ReadComponent(LocalField));
      {Assign DataSet to Field}
      LocalField.DataSet := DataSet;
      LocalField.LookupDataSet := TFieldProps(List[i]^).LookUpDataSet;

      //      if FieldClass=TStringField then LocalField.Size:=100; {!!!}
    end;
  end;
end;

procedure RegClasses;
var
  AFieldClasses: array[0..25] of TPersistentClass;
begin
  AFieldClasses[0] := TADTField;
  AFieldClasses[1] := TAggregateField;
  AFieldClasses[2] := TArrayField;
  AFieldClasses[3] := TAutoIncField;
  AFieldClasses[4] := TBCDField;
  AFieldClasses[5] := TBinaryField;
  AFieldClasses[6] := TBlobField;
  AFieldClasses[7] := TBooleanField;
  AFieldClasses[8] := TBytesField;
  AFieldClasses[9] := TCurrencyField;
  AFieldClasses[10] := TDateField;
  AFieldClasses[11] := TDataSetField;
  AFieldClasses[12] := TDateTimeField;
  AFieldClasses[13] := TFloatField;
  AFieldClasses[14] := TGraphicField;
  AFieldClasses[15] := TIntegerField;
  AFieldClasses[16] := TLargeintField;
  AFieldClasses[17] := TMemoField;
  AFieldClasses[18] := TNumericField;
  AFieldClasses[19] := TObjectField;
  AFieldClasses[20] := TReferenceField;
  AFieldClasses[21] := TSmallintField;
  AFieldClasses[22] := TStringField;
  AFieldClasses[23] := TTimeField;
  AFieldClasses[24] := TVarBytesField;
  AFieldClasses[25] := TWordField;
  RegisterClasses(AFieldClasses);
end;

procedure UnRegClasses;
var
  AFieldClasses: array[0..25] of TPersistentClass;
begin
  AFieldClasses[0] := TADTField;
  AFieldClasses[1] := TAggregateField;
  AFieldClasses[2] := TArrayField;
  AFieldClasses[3] := TAutoIncField;
  AFieldClasses[4] := TBCDField;
  AFieldClasses[5] := TBinaryField;
  AFieldClasses[6] := TBlobField;
  AFieldClasses[7] := TBooleanField;
  AFieldClasses[8] := TBytesField;
  AFieldClasses[9] := TCurrencyField;
  AFieldClasses[10] := TDateField;
  AFieldClasses[11] := TDataSetField;
  AFieldClasses[12] := TDateTimeField;
  AFieldClasses[13] := TFloatField;
  AFieldClasses[14] := TGraphicField;
  AFieldClasses[15] := TIntegerField;
  AFieldClasses[16] := TLargeintField;
  AFieldClasses[17] := TMemoField;
  AFieldClasses[18] := TNumericField;
  AFieldClasses[19] := TObjectField;
  AFieldClasses[20] := TReferenceField;
  AFieldClasses[21] := TSmallintField;
  AFieldClasses[22] := TStringField;
  AFieldClasses[23] := TTimeField;
  AFieldClasses[24] := TVarBytesField;
  AFieldClasses[25] := TWordField;
  UnRegisterClasses(AFieldClasses);
end;

initialization
  RegClasses;

finalization
  UnRegClasses;
end.
11 мар 09, 07:58    [6908517]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Создать поле в открытом TClientDataset ? 
BasilCat
Member

Откуда:
Сообщений: 12
Типа так работает:
+
begin

  CDS2 := TClientDataSet.Create(nil);
// &#231;&#228;&#229;&#241;&#252; &#228;&#238;&#225;&#224;&#226;&#232;&#242;&#252; &#234;&#238;&#228; &#228;&#238;&#225;&#224;&#226;&#235;&#229;&#237;&#232;&#255; &#228;&#240;&#243;&#227;&#232;&#245; &#239;&#238;&#235;&#229;&#233; ...

 With CDS2 do
  begin
// 1
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'NUMBER_LIST';
    end;
// 2
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftString;
     Size:=20;
     Name := 'NUMBER_SAKAS';
    end;
// 3
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'TIPORASMER_H_OCNOVI';
    end;
// 4
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftString;
     Size:=20;
     Name := 'TOLCHINA_NAPLAVKI';
    end;
// 5
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftString;
     Size:=20;
     Name := 'TIP_LENTI';
    end;
// 6
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'DLINA';
    end;
// 7
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'CHIRINA';
    end;
// 8
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftString;
     Size:=20;
     Name := 'MARKA_OCNOVI';
    end;
// 9
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftString;
     Size:=20;
     Name := 'TIP_MARKA_LENTI';
    end;
// 10
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftDate;
     Name := 'DATA_SADANIJA';
    end;
// 11
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftTime;
     Name := 'VREMJA_SADANIJA';
    end;

// 12
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftMemo;
     Size:=240;
     Name := 'OPICANIE';
    end;

// 13
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftGraphic;
     Size:=240;
     Name := 'FOTO';
    end;
// 14
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'USTANOVL_U';
    end;

// 15
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'USTANOVL_A';
    end;
// 16
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'SYPPORT_N';
    end;
// 17
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'Mode_Napl';
    end;
// 18
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'X_L1';
    end;
// 19
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'A_L';
    end;
// 20
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'B_L';
    end;
// 21
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'Y_L1';
    end;
// 22
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'R_R';
    end;
// 23
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'XY_NUMBER';
    end;
// 24
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := '_ZIKL';
    end;
// 25
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'NOMER_MACHINE';
    end;
// 26
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftInteger;
     Name := 'NOMER_MACHINE_VIPOL';
    end;
// 27
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftGraphic;
     Size:=240;
     Name := 'PLAN_LISTA';
    end;
// 28
   With FieldDefs.AddFieldDef do
    begin
     DataType := ftString;
     Size:=20;
     Name := 'CVET';
    end;


   CreateDataSet;
   SaveToFile('C:\CLX_CLIENT_SERVER\csd\SAKAS2.cds');
  end;

end;

Модератор: Пользуйтесь тегом (кнопкой) SRC для оформления кода, пожалуйста.
19 янв 19, 14:43    [21789279]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Delphi Ответить