How to change the data type of a clientdataset field at run time

For Delphi ClientDataSets, where fields were defined at design time, is there a way at runtime to change a particular field data type (change cds.Fields [n] .DataType)?

I have an outdated Delphi 7 program with the SQLDataSet and ClientDataSet fields set at design time (to override various properties).

They are connected to a third-party Sybase SQL Anywhere 11 database.

Recently, the seller changed all the Description fields from VarChar (128) to a long varchar, but only for some of his customers. Therefore, my code should support both types of fields when I request these Description fields.

I was hoping to set up conditional compilation in the field types of the class (then add the fields before opening the SQL / CLient dataset), but the compiler ignores the conditional expressions {$ IFDEF} in the class component definition section (which, I think more, makes sense)!

There are dozens of modules in which hundreds of fields are affected, so understanding is evaluated.

Thank.

Cheers, EdB

+4
source share
1 answer

I also came across this problem before, not with CDS, but with TADODataSet, using constant fields during development. I think the code below will help you understand how to fix / fix your CDS datasets.

, ; ; "" , DataSet :

// TData class    
procedure TData.DataModuleCreate(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ComponentCount - 1 do
    if (Components[I] is TCustomADODataSet) then
      DataSetPrepareMemoFields(TDataSet(Components[I]));
end;

procedure TData.DataSetPrepareMemoFields(DataSet: TDataSet);
var
  Fld: TField;
  I: Integer;
  FldName, CompName: string;
  AOwner: TComponent;
begin
  // Here you need to query the actual table schema from the database 
  // e.g. ADOConnection.GetFieldNames and act accordingly

  // check which DataSet you need to change
  // if (DataSet = dsOrders) or ... then... 

  if DataSet.FieldList.Count > 0 then
    for I := DataSet.FieldList.Count - 1 downto 0 do 
    begin
      if DataSet.FieldList.Fields[I].ClassNameIs('TMemoField') and (DataSet.FieldList.Fields[I].FieldKind = fkData) then 
      begin
        // save TMemoField properties
        AOwner := DataSet.FieldList[I].Owner;
        CompName := DataSet.FieldList[I].Name;
        FldName := DataSet.FieldList.Fields[I].FieldName;
        // dispose of TMemoField
        DataSet.FieldList[I].DataSet := nil; // Un-Attach it from the DataSet
        // create TWideADOMemoField instead
        Fld := TWideADOMemoField.Create(AOwner); // Create new persistent Filed instead 
        Fld.Name := CompName + '_W';
        Fld.FieldName := FldName;
        Fld.DataSet := DataSet;
      end;
    end;
end;

, , , . . // .

+1

All Articles