Конвертировать тип данных ftFloat в ftBCD

Как я могу преобразовать тип поля из ftFloat в ftBCD;

Я старался

for i := 0 to FDataSet.FieldCount - 1 do begin
      if FDataSet.Fields.Fields[i].DataType = ftFloat then begin
           FDataSet.Fields.Fields[i].DataType := ftBCD;
      end;
end;

Но я получаю ошибку

[DCC Error]  E2129 Cannot assign to a read-only property

Есть ли способ, которым я могу преобразовать все поля набора данных, что ftFloat в ftBCD?

3 ответа

Решение

DataType является только для чтения Свойством Tfield, созданным для DataType. Это делается из Fielddefs с использованием DefaultFieldClasses: array[TFieldType] для TFieldClass из DB. Если вам нужно изменить тип данных, вам нужно освободить поле и создать еще один, соответствующий вашим потребностям. Ниже показан пример того, как это можно сделать.

type
  TMyFieldInfo = Record
    FieldName: String;
    Size: Integer;
    DataType: TFieldType;
    FieldKind: TFieldKind;
  end;

type
  TFA= Array of TMyFieldInfo;

 Procedure GetFields(DS:Tdataset;var FA:TFA);
  var
    I: Integer;
  begin
    SetLength(FA, DS.FieldCount);
    for I := 0 to DS.FieldCount - 1 do
    begin
      FA[I].FieldName := DS.Fields[I].FieldName;
      FA[I].DataType := DS.Fields[I].DataType;
      FA[I].Size := DS.Fields[I].Size;
      FA[I].FieldKind := fkdata;
    end;
  end;

  Procedure SetFields(DS:Tdataset;var FA:TFA);
  var
    I: Integer;
    F:TField;
  begin
    DS.Fields.Clear;
    for I := Low(FA) to High(FA) do
    begin
      F := DefaultFieldClasses[FA[I].DataType].Create(DS);
      With F do
      begin
        FieldName := FA[I].FieldName;
        FieldKind := FA[I].FieldKind;
        Size := FA[I].Size;
        DataSet := DS;
      end;
    end;

  end;


procedure TForm6.Button1Click(Sender: TObject);
var
   L_FA: TFA;
   I:Integer;
begin
    MyDS.Open;  // open to get the Fielddefs.
    GetFields(MyDS,L_FA);
    MyDS.Close;  // close to be able to change the fields
    for I := Low(L_FA) to High(L_FA) do
      begin
         if L_FA[i].DataType = ftFloat then
            L_FA[i].DataType := ftBCD;
      end;
    SetFields(MyDS,L_FA);
    MyDS.Open;
end;

Вот еще один способ:

Во-первых, вам нужно сбросить таблицу в файл, подобный этому

ADOQuery.SaveToFile('C:\1.xml');

тогда найдите в нем описание вашего поля, допустим, оно будет таким:

<s:datatype dt:type='float' dt:maxLength='8' rs:fixedlength='true' rs:maybenull='true'/>

и замените его другим описанием типа, например так:

<s:datatype dt:type='number' rs:dbtype='currency' dt:maxLength='25' rs:precision='25' rs:fixedlength='true' rs:maybenull='true'/>

Теперь вам нужно загрузить этот файл обратно, вот так:

ADOQuery.LoadFromFile('C:\1.xml');

НЕТ! После того как вы создадите поле данных, вы не сможете его изменить! Это потому, что назначение Filedtype - это гораздо больше, чем просто изменение свойства типа enum. Каждый тип поля - это определенный класс: TintegerField и т. Д.

Таким образом, вы не можете изменить FieldType по той же причине, что не можете сделать TList в строку

Точно, что вы пытаетесь?

Йенс Борришольт

Другие вопросы по тегам