Q:  How do I use a PW byte field to hold arrays of records?

A:

unit ubytefld;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, DB, DBTables;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Table1: TTable;
    ListBox1: TListBox;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

type
  MyStr = string[20];
  pMyRec = ^TMyRec;
  TMyRec = record  //Takes 32 bytes.
    s: string[19]; // 20 bytes used.
    i, j: integer;
    b1, b2: byte;
  end;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  MyArrs: pMyRec;
begin
//  This was written to work with an array of 3 records, but
//  the example uses only one of them.
  MyArrs := AllocMem(SizeOf(TMyRec) * 3);
  try
    with MyArrs^ do begin
      // Fill the array from a memo field.
      s := memo1.lines[0];
      i := StrToInt(memo1.lines[1]);
      j := StrToInt(memo1.lines[2]);
      b1 := StrToInt(memo1.lines[3]);
      b2 := StrToInt(memo1.lines[4]);

      table1.insert;
      table1.FieldByName('f1').SetData(MyArrs);
      table1.post;
    end;
  finally
    FreeMem(MyArrs, SizeOf(TMyRec) * 3);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  MyArrs: pMyRec;
begin
//  This was written to work with an array of 3 records, but
//  the example uses only one of them.
  MyArrs := AllocMem(SizeOf(TMyRec) * 3);
  try
    if table1.FieldByName('f1').GetData(MyArrs) then
      caption := 'true'
    else caption := 'false';

//The list box is to display the data retrieved.
    with listbox1.items do begin  // View the fill-in values
      add(MyArrs^.s);
      add(IntToStr(MyArrs^.i));
      add(IntToStr(MyArrs^.j));
      add(IntToStr(MyArrs^.b1));
      add(IntToStr(MyArrs^.b2));
    end;
  finally
    FreeMem(MyArrs, SizeOf(TMyRec) * 3);
  end;
end;

end.