Adding a field to TDbf at runtime lazarus / 16-Databases ---------------------------------------------------------------------- maurobio · 2021-12-09 21:53 Dear ALL, I have a Dbase file with the following structure: QuoteField   Type   Field Size   Decimal C_REG   C   10   0 N_DISP   N   1   0 N_TIPO   N   2   0 N_ESPE   N   5   0 N_SEXO   N   2   0 C_CAMP   C   16   0 N_PROJ   N   3   0 N_AMBI   N   2   0 D_DETE   C   10   0 N_ENTR   N   1   0 D_ENTR   C   10   0 N_SECO   N   4   0 N_LIQI   N   4   0 N_LAMI   N   4   0 N_TCOL   N   3   0 N_REGI   N   2   0 N_SIGLA   N   2   0 I would like to add a new integer field ('N_NOME') to this file at runtime. Here is my code (partially adapted from https://forum.lazarus.freepascal.org/index.php?topic=21006.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 program SGCFix; {$mode objfpc}{$H+} uses  Classes, SysUtils, Dbf, db, Dbf_Common;  var  ADbf: TDbf;  //AField: TField;  AFields: array of TField;  Temf: TIntegerField;  i: integer;  begin  ADbf := TDbf.Create(nil);  ADbf.FilePath := 'data' + DirectorySeparator;   ADbf.Exclusive := True;  ADbf.TableName := 'DADOS.dbf';  ADbf.Open;  ADbf.Close;      SetLength(AFields, ADbf.FieldDefs.Count);  for i:=0 to ADbf.FieldDefs.Count - 1 do        AFields[i] := ADbf.FieldDefs[i].CreateField(ADbf);  Temf := TIntegerField.Create(nil);  Temf.FieldKind := fkCalculated;  Temf.FieldName := 'N_NOME';  Temf.DataSet := ADbf;  ADbf.Open;  ADbf.Edit;  ADbf.Post;  for i := Low(AFields) to High(AFields) do      AFields[i].Free;  SetLength(AFields, 0);  Temf.Free;  ADbf.Close;  WriteLn('-- done -- ');       end.   It compiles without errors, but it does nothing: the new field is not added and the file is not modified. Could anyone out there give a hand? Thanks in advance! With best wishes, ---------------------------------------------------------------------- korba812 · 2021-12-09 23:05 Do you want to change dbf file structure or add a calculated field? The post you are referring to is for a calculated field. If you want to change dbf file structure then use TDbf.RestructureTable method. Here's an example (it is about deleting a field, but it should be helpful): https://forum.lazarus.freepascal.org/index.php?topic=8567.0 ---------------------------------------------------------------------- maurobio · 2021-12-09 23:36 Hi, @korba512! Thanks a lot for your reply! I rewrote my code according to the example you pointed out: 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 program SGCFix; {$mode objfpc}{$H+} uses  Classes, SysUtils, Dbf, db, Dbf_Common;  var  SGCDbf: TDbf;  FieldDefs: TDbfFieldDefs;  begin  SGCDbf := TDbf.Create(nil);  SGCDbf.FilePath := 'data' + DirectorySeparator;   SGCDbf.Exclusive := True;  SGCDbf.TableName := 'DADOS.dbf';  SGCDbf.Open;  FieldDefs := TDbfFieldDefs.Create(nil);  FieldDefs.Assign(SGCDbf.DbfFieldDefs);  FieldDefs.Close;  FieldDefs.Add('N_NOME', ftInteger, 0, True);  SGCDbf.RestructureTable(FieldDefs, False);    SGCDbf.Close;  SGCDbf.Free;  FieldDefs.Free;  WriteLn('-- done -- ');       end.  ... but it still does not work. Now, the compiler returns several error messages, apparently related to the TDbfFieldDefs type which seems not to be recognized: QuoteFree Pascal Compiler version 3.2.0 [2021/02/21] for i386 Copyright (c) 1993-2020 by Florian Klaempfl and others Target OS: Win32 for i386 Compiling SGCfix.lpr SGCfix.lpr(10,14) Error: Identifier not found "TDbfFieldDefs" SGCfix.lpr(10,27) Error: Error in type definition SGCfix.lpr(18,16) Error: Identifier not found "TDbfFieldDefs" SGCfix.lpr(19,13) Error: Illegal qualifier SGCfix.lpr(20,13) Error: Illegal qualifier SGCfix.lpr(21,13) Error: Illegal qualifier SGCfix.lpr(22,36) Error: Incompatible type for arg no. 1: Got "", expected "TDbfFieldDefs" SGCfix.lpr(25,13) Error: Illegal qualifier SGCfix.lpr(29) Fatal: There were 8 errors compiling module, stopping Fatal: Compilation aborted Error: C:\lazarus\fpc\3.2.0\bin\i386-win32\ppc386.exe returned an error exitcode Any hints? With best wishes, ---------------------------------------------------------------------- wp · 2021-12-09 23:45 If you want to add a calculated field you must provide a handler for the Dataset's OnCalcFields event which has the purpose the calculate the value(s) for the calculated field(s). Note that the "normal" fields are not accessible here, only those that you recreated yourself for the AFields array. The attached sample contains two "regular" fields, "A" and "B". At runtime a third field "C" is created as calculated field which calculates the sum of A and B. ---------------------------------------------------------------------- maurobio · 2021-12-10 00:04 Hi, @wp! Thanks for your reply. In fact, I do not want a 'calculated field' - this was mistakenly taken from an example I found here on the forum. I just want to add a field at runtime. The example pointed out by @korba512 seems to be similar to what I need, but as I wrote in my previous reply, I got compiler errors because of a seemingly unrecognized type. With best wishes, ---------------------------------------------------------------------- Handoko · 2021-12-10 02:19 Maybe: 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 program Test; uses  Classes, SysUtils, Dbf, db, dbf_fields; var  SGCDbf: Tdbf;  FieldDefs: TDbfFieldDefs;  NewFieldDef: TDbfFieldDef; begin  SGCDbf := TDbf.Create(nil);  SGCDbf.FilePath := 'data' + DirectorySeparator;  SGCDbf.Exclusive := True;  SGCDbf.TableName := 'DADOS.dbf';  SGCDbf.Open;  FieldDefs := TDbfFieldDefs.Create(nil);  FieldDefs.Assign(SGCDbf.DbfFieldDefs);  NewFieldDef := FieldDefs.AddFieldDef;  NewFieldDef.FieldName := 'N_NOME';  NewFieldDef.FieldType := ftInteger;  NewFieldDef.Required := True;  SGCDbf.RestructureTable(FieldDefs, True);  FieldDefs.Free;  SGCDbf.Close;  SGCDbf.Free end. ---------------------------------------------------------------------- maurobio · 2021-12-10 11:58 Hi, @Handoku! Thanks a lot, not only for your reply, but for your post at another thread (https://forum.lazarus.freepascal.org/index.php/topic,8567.0.html), which has been pointed out to me by @korba512 and that effectively provided a working solution to my problem. I was sure that some unit was missing where TDbfFieldDefs was declared, but I could not find out which one. The TDbf tutorial does not mention the dbf_fields unit in the section "What to put in in your uses section"(https://wiki.lazarus.freepascal.org/Lazarus_Tdbf_Tutoria l#What_to_put_in_your_uses_section) and so I got lost. With best wishes, ---------------------------------------------------------------------- Handoko · 2021-12-10 15:19 The problem has been reported: https://forum.lazarus.freepascal.org/index.php/topic,35480.msg234567.h tml#msg234567