Hi

i need to read the last 14 Entries made into a typed file and then list the entries in a StringGrid so i can copy them to label captions later.

I am a little unsure how to write the Code to loop for the last 14 Entries.

the current code i have is this

if SysUtils.FileExists(ShiftFile) then
  begin
    // Reopen the file in read only mode
    AssignFile(F, ShiftFile);
    Reset(F);
    try
      // Display the file contents
    while Not Eof(F) do
      Read(F, shift);
      // Here i need to find the last 14 Entries
    finally
      CloseFile(F);
    end;

i know that the While Not EoF will just read the entire file until it reaches the end.

How could i make it Read only the last 14 Entries and then list each one in a StringGrid so i can use them later.

thank you for your time.

Dani AI

Generated

A concise, robust approach is to determine how many records are in the typed file, compute the safe start index for the last N entries, Seek to that index and then Read exactly that many records into the StringGrid. pointed in the right direction with FileSize/Seek; the only arithmetic needed is to clamp the start index so it never goes negative (no accidental off‑by‑one).

Key points:

  • FileSize(fileVar) returns the total record count; valid record indices are 0..FileSize-1.
  • Let ToRead := Min(14, FileSize). StartIndex := FileSize - ToRead.
  • Seek(fileVar, StartIndex) then loop ToRead times calling Read(fileVar, Rec) and fill the grid rows.
  • Always use try...finally to CloseFile and guard against empty files.

Example (illustrative):

var
  ShiftF: file of TShiftRec;
  Total, ToRead, Start, I: Integer;
  R: TShiftRec;
begin
  AssignFile(ShiftF, ShiftFileName);
  Reset(ShiftF);
  try
    Total := FileSize(ShiftF);
    if Total = 0 then Exit;            // nothing to show
    ToRead := Total;
    if ToRead > 14 then ToRead := 14;
    Start := Total - ToRead;          // 0-based safe start
    Seek(ShiftF, Start);
    StringGrid1.RowCount := ToRead + 1; // row 0 = headers
    for I := 0 to ToRead - 1 do
    begin
      Read(ShiftF, R);
      StringGrid1.Cells[0, I + 1] := R.SomeTextField;
      StringGrid1.Cells[1, I + 1] := IntToStr(R.SomeNumberField);
      // map remaining fields as needed
    end;
  finally
    CloseFile(ShiftF);
  end;
end;

Troubleshooting and cautions:

  • If the record contains managed types (AnsiString/UnicodeString, dynamic arrays), typed files may not be safe across runs. Use fixed-length fields (ShortString/array[0..N] of Char) or switch to TFileStream and explicit serialization.
  • If data looks garbled, check record packing/alignment or compiler differences; packed record or explicit field sizes fixes that.
  • To avoid UI flicker, set grid row count once and fill cells, and validate column count before assigning cells.

I'll just give you a few more commands to play with :-)

On a typed file, you just use the command FileSize(Type).
It gives you the exact number of records in the file.
:icon_exclaim: just remember that 0 is also a record.

Now for the coding:

VAR
  TheStart, TheEnd:INTEGER;
BEGIN
.... ... ..
  TheEnd:=FileSize(YourAssignedFileType);
  TheStart:=FileSize-14;
  DEC(TheStart); // We need to decrease this value by one because we count Zero too.
  Seek(YourAssignedFileType,TheStart);// Jumps to the correct location of data.
  REPEAT
    .... read the data
    INC(TheStart);
  UNTIL TheStart=TheEnd;
.. ... ....
END;

I am sure you figure the rest out.
If you have less than 14 records, you need to make some code to avoid error there too.

Best regards.
Morten, Norway.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.