Field-Type TDbf ftFloat seems not workly correct lazarus / 16-Databases ---------------------------------------------------------------------- PascalGuru · 2017-04-26 20:46 Field-Type  TDbf ftFloat  seems not workly correct.   The result on a create Table with this Fieldtype,   we get a Fieldtype  'Numerical' respective  'ftInteger   and there a no possibility to perform decimal places in it.       MyDbf.FieldDefs.Add('ZAHL_FLOAT', ftFloat, 10, true).      Now I have the Piece of Code:     procedure TForm1.DBF_Datei_Neu(sender : TObject);     begin     MyDbf := TDbf.Create(nil);     try              (* Now we use an absolute Path to "DATA"-Directory *)       MyDbf.FilePathFull := 'C:\PROJEKTE\PASCAL\DBA\DATA' + DirectorySeparator;             (* Wir want to create an compatible DBASE4 Table *)       MyDbf.TableLevel := 4;       MyDbf.Exclusive := true;       MyDbf.TableName := 'testpasc.dbf';       (* For this wie need the Unit DB *)       with MyDbf.FieldDefs do         begin                                    // Here are my own- named DBASE-Fieldtypes         Add('ID',         ftInteger,  3, true);  // N  3,0  NoIdx         Add('NAME',       ftString,  20, true);  // C  2    NoIdx                 Add('ZAHL_BYTE',  ftSmallInt, 3, true);  // N  3    NoIdx         Add('ZAHL_INT',   ftInteger,  6, true);  // N  6    NoIdx         ...                 Add('ZAHL_FLOAT', ftFloat,   10, true);  // G 10,3  NoIdx          ...                end; (* of with MyDbf.FieldDefs *)               MyDbf.CreateTable;       MyDbf.Open;       MyDbf.AddIndex('id', 'ID', [ixPrimary, ixUnique]);         (* We fill the first Record *)       MyDbf.Append;     // Create an Record             MyDbf.FieldByName('ID').AsInteger        :=  1;       MyDbf.FieldByName('NAME').AsString       := 'Jesus Christ';       MyDbf.FieldByName('ZAHL_BYTE').AsInteger :=  255;       MyDbf.FieldByName('ZAHL_INT').AsInteger  :=  32767;             MyDbf.FieldByName('ZAHL_FLOAT').AsFloat  :=  3.14159;       MyDbf.Post;       // Important for Store of the Record and Continuing        end; (* of with MyDbf.FieldDefs *)         ...     finally       MyDbf.Free;     end; (* of try-finally *)   end; (* of procedure TForm1.DBF_Datei_Neu *)         If we later load the Table in originally DBASE 4 , which we created with Component  TDbf ,   we see that the field 'ZAHL_FLOAT' is always of Type 'Numerical', not of Type 'Gleitkomma'   (it's a german DBASE, i don't know the correct english naming of this type).   And we see in Field ZAHL_FLOAT only the Number  3 - without decimal places.     What should I do?   Is it really a bug in the Component TDbf ?   Thanks for your help and answers,   PascalGuru ---------------------------------------------------------------------- GAN · 2017-04-26 21:41 From the only official guide of TDBF : https://sourceforge.net/project s/tdbf/files/TDbf%20documentation/TDbf%20documentation%201.1/ Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i NewFieldDefs: TDbfFieldDefs ;NewFieldDef: TDbfFieldDef;Dbf1 : TDbf ;...// create new field listNewFieldDefs := TDbfFieldDefs. Create ( Self );// assign current listNewFieldDefs. Assign ( Dbf1 . DbfFieldDefs);// assume first field is string , 20 wide , make larger to 40NewFieldDefs. Items [0]. Size := 40;// rename second field to ’ RENAMED ’NewFieldDefs. Items [1]. FieldName := ’ RENAMED ’;// add a float fieldNewFieldDef := NewFieldDefs. AddFieldDef;NewFieldDef. FieldName := ’ NEW_FLOAT ’;NewFieldDef. FieldType := ftFloat;NewFieldDef. Size := 10;NewFieldDef. Precision := 3;// restructure table and packDbf1 . Restructure( NewFieldDefs , true );// restructure table and not pack// Dbf1 . Restructure( NewFieldDefs , false );// free memNewFieldDefs. Free ; What you need: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i NewFieldDef := NewFieldDefs. AddFieldDef;NewFieldDef. FieldName := ’ NEW_FLOAT ’;NewFieldDef. FieldType := ftFloat;NewFieldDef. Size := 10;NewFieldDef. Precision := 3; // <--------- Or you can try: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  Add('ZAHL_FLOAT', ftFloat,   10,  3, true);  // G 10,3  NoIdx Regards. ---------------------------------------------------------------------- PascalGuru · 2017-05-03 13:03 Thank you very much for your Help.   I had search and search and search again - but nothing find anywhere.   Beside: The Link of the official Guide works - obviously the Website "Sourcefourge"   are in most Cases does not work in Case of slower (and very slower) Connections.     The official Guide is from 2004 and does not contain all relevant Points for Newbies.   They should be stand in:   Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     uses db, dbf, dbf_fields, dbf_common;     var      NewFieldDefs : TDbfFieldDefs;      NewFieldDef  : TDbfFieldDef;      Dbf1         : TDbf;    begin    ...    // Create new Field-List    NewFieldDefs := TDbfFieldDefs.Create (Self);    // Assign current List    NewFieldDefs.Assign ( Dbf1.DbfFieldDefs);    // Assume first Field is string, 20 wide , make larger to 40    NewFieldDefs. Items [0].Size := 40;    // Rename second field to ’ RENAMED ’    NewFieldDefs. Items [1].FieldName := ’ RENAMED ’;    // Add a Float Field    NewFieldDef := NewFieldDefs.AddFieldDef;    NewFieldDef.FieldName := 'ZAHLFLOAT';    NewFieldDef.FieldType := ftFloat;    NewFieldDef.Size      := 10;  NewFieldDef.Precision := 3;    // Restructure Table and pack    Dbf1.Restructure(NewFieldDefs, true);    // Restructure Table and not pack    // Dbf1.Restructure(NewFieldDefs, false);    // Free mem    NewFieldDefs.Free;       Not all is good - the Command  Dbf1.Restructure  is not accepted.   Which Unit for Restructure is needed ?   I had try all: dbf_common, fpdbexport, fpdbfexport, fpfixedexport   but nothing works!   Like I said before - the Official Guide could be a Step better.     The third suggestion with Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     Dbf1.Add('ZAHL_FLOAT', ftFloat, 10, 3, true);   is not accepted without any more things. (This I had try as First.)       The Single Apostroph on the Documentation is a wrong Sign -   it doesn't accepted from LAZARUS/FREE-PASCAL/TURBO PASCAL/...  (only ' works!)     Thank you for your Help again!   PascalGuru ---------------------------------------------------------------------- PascalGuru · 2017-05-11 14:49 Thank you, People, for your Helps. The Code above is not correct.   1. Instead of  "Restructure"  you must take the correct  "RestructureTable"       In full Description is the correct Writing:          // Restructure Table and not pack         Dbf1.RestructureTable(NewFieldDefs, false);     2. After the Commands         Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i         //Create new Field-List         Dbf1FieldDefs := tDbfFieldDefs.Create(Self);          // Assign current List         Dbf1FieldDefs.Assign(Dbf1.DbfFieldDefs);                  // Assume first Field is String, 20 wide, make larger to 40         Dbf1FieldDefs.Items[0].Size := 40;         // Rename second Field to 'ZAHLFLOAT'         Dbf1FieldDefs.Items[1].FieldName := 'ZAHLFLOAT';            The first Command behind  Assign I get an Runtime-Error:    Projekt XXX has an Exception of "EConvertError"    with the Message.  "Cannot assign a Nil to a TDbfFieldDefs"    at Adress  43A177  There are any Comments, Hints or Suggests ?  Thank you for your Helping. PascalGuru ---------------------------------------------------------------------- Handoko · 2017-06-16 15:40 I think you need this below before you can use the items because Items.Count = 0. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i      NewFieldDef := Dbf1FieldDefs.AddFieldDef; ---------------------------------------------------------------------- PascalGuru · 2018-11-22 16:47 Are there no any Comments or Suggestions ?    (Or is the offical Guide would be a little Bit more helpful or better ?    ) PascalGuru ---------------------------------------------------------------------- wp · 2018-11-22 23:14 I tested your code and it works correctly if I assign the precision to the float flield in the table-creation step or set the Size parameter to 0. The following code uses four methods to add a float field def: your method - does not workuse function AddFieldDef (as proposed by others above) - this gives access to all elements of TFieldDef, in particular to the property Precisionuse procedure Add and extract the added FieldDef from the list of all FieldDefs as being the last item. Then you have access to property Precision again.use procedure Add, but set the Size parameter to zero. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button1Click(Sender: TObject);var  MyDbf: TDbf;  fd: TFieldDef;  i: Integer;begin  MyDbf := TDbf.Create(nil);  try     MyDbf.FilepathFull := ExtractFilePath(Application.ExeName);//    MyDbf.FilePathFull := 'C:\PROJEKTE\PASCAL\DBA\DATA' + DirectorySeparator;     (* Wir want to create an compatible DBASE4 Table *)    MyDbf.TableLevel := 4;     MyDbf.Exclusive := true;    DeleteFile('testpasc.dbf');    MyDbf.TableName := 'testpasc.dbf';     (* For this wie need the Unit DB *)    with MyDbf.FieldDefs do      begin                                    // Here are my own-named DBASE-Fieldtypes      Add('ID',         ftInteger,  3, true);  // N  3,0  NoIdx      Add('NAME',       ftString,  20, true);  // C  2    NoIdx       Add('ZAHL_BYTE',  ftSmallInt, 3, true);  // N  3    NoIdx      Add('ZAHL_INT',   ftInteger,  6, true);  // N  6    NoIdx       // Method #1      Add('ZAHL_FLOAT', ftFloat,   10, true);  // G 10,3  NoIdx       // Method #2      with AddFieldDef do begin      Name := 'ZAHL_FLOAT2';        Datatype := ftFloat;        Size := 10;        Precision := 4;      end;       // Method #3      Add('ZAHL_FLOAT3', ftFloat,   10, true);      fd := Items[Count-1];    fd.Precision := 4;       // Method #4      Add('ZAHL_FLOAT4', ftFloat,   0, true);  // G 10,3  NoIdx    end; (* of with MyDbf.FieldDefs *)     MyDbf.CreateTable;    MyDbf.Open;     for i:=0 to MyDbf.FieldCount-1 do      Memo1.Lines.Add(MyDbf.fields[i].FieldName);     MyDbf.AddIndex('id', 'ID', [ixPrimary, ixUnique]);     (* We fill the first Record *)    MyDbf.Append;     // Create an Record     MyDbf.FieldByName('ID').AsInteger        :=  1;    MyDbf.FieldByName('NAME').AsString       := 'Jesus Christ';    MyDbf.FieldByName('ZAHL_BYTE').AsInteger :=  255;    MyDbf.FieldByName('ZAHL_INT').AsInteger  :=  32767;     MyDbf.FieldByName('ZAHL_FLOAT').AsFloat  := 3.141592;    MyDbf.FieldByName('ZAHL_FLOAT2').AsFloat := 3.141592;    MyDbf.FieldByName('ZAHL_FLOAT3').AsFloat := 3.141592;    MyDbf.FieldByName('ZAHL_FLOAT4').AsFloat := 3.141592;    MyDbf.Post;     // Important for Store of the Record and Continuing  finally    MyDbf.Free;  end; (* of try-finally *)end; (* of procedure TForm1.DBF_Datei_Neu *) The attached screenshot of the LazDataDesktop shows that Method 1 adds the field def as an integer field while the other three methods are correct. I don't know if the behavior in method 1 (your method) is a bug. The conversion from float to integer field is probably made on the assumption that if Precision is zero the float effectively is an integer. On the other hand, you requested a float field, not an integer field. The problem maybe is in the default value of the Precision which should not be 0 (well, I assume that) but maybe 2 or 3. As for the documentation: What you call "official documentation" seems to be the documentation of the Delphi version. Here you have the Lazarus port, which may be different or not - I don't know. When reading Delphi documentation in connection with Lazarus you should always be careful and should not take the text too literal - the basic idea usually is correct, but there are differences in details here and there. A better documentation is our wiki: http://wiki.freepascal.org/Lazarus_Tdbf_Tutorial. I did not read it, but it looks fairly competent when I scrolled through it. And it has the advantage: if there is something wrong we can change it - we cannot change Delphi-related documentation, in particular when it is on a site we don't have access to.