Getting float field precision runtime

Posted on 2004-08-04
Last Modified: 2010-04-04
I have the following problem.

 I use TTable component to connect to dbf file, previously created with Database Desktop (thus I consider it correct). I have a float-type field in the table and I need to get the precision of the field runtime. Whatever I do I don't receive the expected result:

1. Precision := TFloatField(Table.Fields.FindField('smth')).Precision
Returns default precision value (15) but not the one I specified in the dbf file.

2. table1.FieldDefs.Items[0].Precision
Returns 0.

How should I get the precision (and size) values for table fields?

Thanks in advance!
Question by:vk33
LVL 17

Accepted Solution

geobul earned 100 total points
ID: 11714395

Add a memo, a button and a table on a form. Set the table DatabaseName and TableName properties to point to your dbf and add the code below. Pressing the button will fill the memo with fields descriptions. Precision is the length of the field and Scale is the decimal part, Field.iUnits1 and Field.iUnits2 respectively:

  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Table1: TTable;
    procedure Button1Click(Sender: TObject);
    { Private declarations }
    { Public declarations }

  Form1: TForm1;


{$R *.DFM}

uses bde;

procedure fDbiOpenFieldList(Table: TTable; Physical: Boolean; List: TStrings);

function BDEFieldIntToStr(FieldType: Word): string;

  case FieldType of
    fldUNKNOWN: result := 'unknown';
    fldZSTRING: result := 'string';               { Null terminated string }
    fldDATE: result := 'date';                    { Date     (32 bit) }
    fldBLOB: result := 'BLOb';                    { Blob }
    fldBOOL: result := 'boolean';                 { Boolean  (16 bit) }
    fldINT16: result := 'integer';                { 16 bit signed number }
    fldINT32: result := 'long integer';           { 32 bit signed number }

    fldFLOAT: result := 'float';                  { 64 bit floating point }
    fldBCD: result := 'BCD';                      { BCD }
    fldBYTES: result := 'bytes';                  { Fixed number of bytes }
    fldTIME: result := 'time';                    { Time        (32 bit) }
    fldTIMESTAMP: result := 'timestamp';          { Time-stamp  (64 bit) }
    fldUINT16: result := 'unsigned int';          { Unsigned 16 bit integer }
    fldUINT32: result := 'unsigned long int';     { Unsigned 32 bit integer }

    fldFLOATIEEE: result := 'float IEEE';         { 80-bit IEEE float }
    fldVARBYTES: result := 'varbytes';            { Length prefixed var bytes }
    fldLOCKINFO: result := 'lockinfo';            { Look for LOCKINFO typedef }
    fldCURSOR: result := 'Oracle cursor';         { For Oracle Cursor type }

    { Paradox types (Physical) }
    fldPDXCHAR: result := 'alpha';                { Alpha    (string) }
    fldPDXNUM: result := 'numeric';               { Numeric }

    fldPDXMONEY: result := 'money';               { Money }
    fldPDXDATE: result := 'date';                 { Date }
    fldPDXSHORT: result := 'smallint';            { Short }
    fldPDXMEMO: result := 'Memo BLOb';            { Text Memo       (blob) }
    fldPDXBINARYBLOB: result := 'Binary BLOb';    { Binary data     (blob) }
    fldPDXFMTMEMO: result := 'formatted BLOb';    { Formatted text  (blob) }
    fldPDXOLEBLOB: result := 'OLE BLOb';          { OLE object      (blob) }

    fldPDXGRAPHIC: result := 'Graphic BLOb';      { Graphics object (blob) }
    fldPDXLONG: result := 'long integer';         { Long }
    fldPDXTIME: result := 'time';                 { Time }
    fldPDXDATETIME: result := 'date time';        { Time Stamp }
    fldPDXBOOL: result := 'boolean';              { Logical }
    fldPDXAUTOINC: result := 'auto increment';    { Auto increment (long) }
    fldPDXBYTES: result := 'bytes';               { Fixed number of bytes }

    fldPDXBCD: result := 'BCD';                   { BCD (32 digits) }

    { xBASE types (Physical) }
    fldDBCHAR: result := 'character';             { Char string }
    fldDBNUM: result := 'number';                 { Number }
    fldDBMEMO: result := 'Memo BLOb';             { Memo          (blob) }
    fldDBBOOL: result := 'logical';               { Logical }
    fldDBDATE: result := 'date';                  { Date }
    fldDBFLOAT: result := 'float';                { Float }

    fldDBLOCK: result := 'LOCKINFO';              { Logical type is LOCKINFO }
    fldDBOLEBLOB: result := 'OLE BLOb';           { OLE object    (blob) }
    fldDBBINARY: result := 'Binary BLOb';         { Binary data   (blob) }
    fldDBBYTES: result := 'bytes';                { Only for TEMPORARY tables }
    fldDBLONG: result := 'long integer';          { Long (Integer) }
    fldDBDATETIME: result := 'date time';         { Time Stamp }
    fldDBDOUBLE: result := 'double';              { Double }

    fldDBAUTOINC: result := 'aut increment';      { Auto increment (long) }
    Result := 'not found';

  hFieldCur: hDBICur;
  rslt: DBIResult;
  Field: FLDDesc;
  Check(DbiOpenFieldList(Table.DBHandle, PChar(Table.TableName), nil,
    Physical, hFieldCur));
    rslt := DbiGetNextRecord(hFieldCur, dbiNOLOCK, @Field, nil);
    if (rslt = DBIERR_NONE) then begin

      List.Add(Format('Field Name:%s Type:%s, Precision:%d, Scale:%d', [Field.szName, BDEFieldIntToStr(Field.iFldType), Field.iUnits1, Field.iUnits2]));
  until (rslt <> DBIERR_NONE);

procedure TForm1.Button1Click(Sender: TObject);
  fDbiOpenFieldList(Table1, True, Memo1.Lines);

Regards, Geo

Author Comment

ID: 11716286
It's from the help. ;) Thanks a lot!!!

Just for the reference of the others, here's the function for resolving field precision:

uses BDE;
function ResolvePrecision(Table: TTable; FieldName: string): integer;
  hFieldCur: hDBICur;
  rslt: DBIResult;
  Field: FLDDesc;
  Check(DbiOpenFieldList(Table.DBHandle, PChar(Table.TableName), nil,
    true, hFieldCur));
    rslt := DbiGetNextRecord(hFieldCur, dbiNOLOCK, @Field, nil);
    if (rslt = DBIERR_NONE) then
      if (Field.szName = FieldName) then begin
         Result := Field.iUnits2;
  until (rslt <> DBIERR_NONE);
  raise Exception.Create('Field ' + FieldName + ' not found!');

Note: This function is used with dbase tables and unlike the source code posted before I used Field.iUnits2 instead of Field.iUnits1. I guess it's specific for dbase tables.

Best regards!

Featured Post

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to define IfThen functions in one common unit? 4 54
Performance of SQL statement 37 112
Unique identifier on a terminal server (rdp) 4 55
Wincontrol not (correctly) drawn 15 38
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question