Recent

Author Topic: [Solved] Lazreport. Sorting.  (Read 664 times)

Petrus Vorster

  • Full Member
  • ***
  • Posts: 222
[Solved] Lazreport. Sorting.
« on: January 20, 2026, 01:24:22 pm »
Hi All

Can one sort a dataset in Lazreport before the report prints?
I have a simple DBF with tracking numbers, and they all look like this: 2 alphabetical characters + 9 numbers + 2 Alphabetical characters.
Those front characters can vary wildly.

So first one need to sort according to the last two characters, that will put each country together, then simply add every same type of front digits together, RC, RA, PB, PC .... Alphabetical order not really required.
Lastly I need to count each type, but I wont know what the user is going to scan that day... :D
My output should look like this:

001 | Rx952800068ZA
002 | Rx854658956ZA
003 | LM756478001CN
004 | LA456784456CN
----------------------------
RX : 2     LA: 1
Lm: 1
TOTAL : 4
(But it will be WAY more)

I have the counters on the output working that does the line counts, but sorting those in country first and then by first digits is surprisingly difficult.
AI gives garbage answers.  :D

Thank you all for you patience.

-Peter

 
« Last Edit: January 21, 2026, 11:39:26 am by Petrus Vorster »

andersonscinfo

  • Full Member
  • ***
  • Posts: 156
Re: Lazreport. Sorting.
« Reply #1 on: January 20, 2026, 01:25:23 pm »
Hello Peter,

The short answer is: **LazReport cannot sort data on its own.** It iterates through the dataset strictly in the order provided by the dataset itself. Therefore, if you use Group Headers/Footers based on Country or Prefix, the underlying data must be pre-sorted, otherwise, the report will create a new group every time the value changes (which explains your difficulty).

Since you are using a simple DBF, creating complex indexes involving substrings (like `SUBSTR`) directly on the DBF file can sometimes be fragile or limited by the DBase level.

The most robust and "classic" solution in Lazarus—without altering your original DBF structure—is to use a temporary in-memory dataset (`TBufDataset`). This allows you to parse the tracking number into distinct fields (`Country`, `Prefix`) and utilize standard indexing features reliably.

Here is a solution using `TBufDataset` (available in the standard `BufDataset` unit):

1. **Read** from your DBF.
2. **Parse** the string into a temporary memory dataset with separate columns for sorting.
3. **Index** the memory dataset.
4. **Print** from the memory dataset.

Here is a working example:

```pascal
uses
  ..., db, BufDataset; // Make sure BufDataset is in your uses clause

procedure TForm1.PrintSortedReport;
var
  TempDS: TBufDataset;
  FullCode, Country, Prefix: String;
begin
  // 1. Setup the temporary in-memory dataset
  TempDS := TBufDataset.Create(nil);
  try
    TempDS.FieldDefs.Add('TrackCode', ftString, 20);
    TempDS.FieldDefs.Add('SortCountry', ftString, 2); // For the last 2 chars
    TempDS.FieldDefs.Add('SortPrefix', ftString, 2);  // For the first 2 chars
    TempDS.CreateDataset;

    // 2. Iterate your source DBF and populate the TempDS
    SourceDBF.First;
    while not SourceDBF.EOF do
    begin
      FullCode := SourceDBF.FieldByName('TRACKING_NO').AsString;
     
      // Basic validation to avoid errors on empty/short strings
      if Length(FullCode) >= 13 then
      begin
        // Extract Country (Last 2) and Prefix (First 2)
        // Using standard Pascal 'Copy' function
        Country := Copy(FullCode, Length(FullCode) - 1, 2);
        Prefix := Copy(FullCode, 1, 2);

        TempDS.Append;
        TempDS.FieldByName('TrackCode').AsString := FullCode;
        TempDS.FieldByName('SortCountry').AsString := Country;
        TempDS.FieldByName('SortPrefix').AsString := Prefix;
        TempDS.Post;
      end;
      SourceDBF.Next;
    end;

    // 3. Apply the Sort Order
    // We create an ephemeral index on the memory data
    TempDS.AddIndex('ByCountryPrefix', 'SortCountry;SortPrefix', [ixCaseInsensitive]);
    TempDS.IndexName := 'ByCountryPrefix';

    // 4. Link to LazReport
    // Assuming frReport1 is your TfrReport and frDBDataSet1 is your TfrDBDataSet
    frDBDataSet1.DataSet := TempDS;
   
    // Now the report will receive data sorted by Country first, then Prefix.
    // In LazReport designer:
    // - Create a Group Header with condition: [frDBDataSet1."SortCountry"]
    // - Inside that, you can have a Master Data band.
   
    frReport1.LoadFromFile('YourReport.lrf');
    frReport1.ShowReport;

  finally
    TempDS.Free;
  end;
end;

```

**Why this approach?**
According to the `TBufDataset` documentation, it provides a strictly local, buffered dataset that mimics standard TDataSet behavior. By separating the logic (parsing the string) from the storage (the DBF), you gain full control over the sort order without fighting DBase expression syntax.

This ensures your "Total" and grouping logic in LazReport works perfectly because the data is guaranteed to be contiguous.

Best regards.
« Last Edit: January 20, 2026, 03:14:59 pm by andersonscinfo »

Petrus Vorster

  • Full Member
  • ***
  • Posts: 222
Re: Lazreport. Sorting.
« Reply #2 on: January 20, 2026, 01:53:49 pm »
Ok, go slow there mate.
This is still legacy DBF.

I am an absolute bummer on Sqlite. Pawel is busy teaching me how to work that.
Heavens, I still have soooo much to learn.

-Peter

Thausand

  • Sr. Member
  • ****
  • Posts: 458
Re: Lazreport. Sorting.
« Reply #3 on: January 20, 2026, 02:01:42 pm »
warning, is clanker.

CharlyTango

  • Full Member
  • ***
  • Posts: 177
Re: Lazreport. Sorting.
« Reply #4 on: January 20, 2026, 02:15:56 pm »
Pawel is busy teaching me how to work that.

You've been refusing for quite some time now, putting it off again and again instead of finally saying goodbye to the dbf problems.
Lazarus stable, Win32/64

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Lazreport. Sorting.
« Reply #5 on: January 20, 2026, 02:37:08 pm »
Pawel is busy teaching me how to work that.

You've been refusing for quite some time now, putting it off again and again instead of finally saying goodbye to the dbf problems.
I agree with you but @Petrus Vorster needs to understand that the "dbf format" as such does not exist, because there are so many variants.
The closest thing you can get is using the ms ODBC driver, that supports most - but not all!!!! - of the index formats and headers.
If the original dbf's are really standard dbf, that is not a problem, but please, please do not use that format unless you know all the details. Simply use Sqlite instead.
The reason I mention the index formats are two way:
1. You can't even do lookups fast without a proper index
2. A proper index needs to be of a known type (dBase111, dBasIV, dBase7, Foxpro, Clipper, PerfectView? I smell you have no clue)
3. It also needs to be properly encoded in the header of the table

If you do NOT know any about the above three it is futeless to use "dbf format" because that is futile.

In summary I DO understand @CharlyTango's frustration. He is right.

If @Paweld (I assume) helps you, that is probably your best guess, but even he will run into your problems if the EXACT format for both the table and the index are not known or spoofed or simply incorrect.

The component is usually sufficient to read all entries seuentially and create a better format by reading all records sequentially and store it in a better format.
« Last Edit: January 20, 2026, 02:43:28 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

cdbc

  • Hero Member
  • *****
  • Posts: 2611
    • http://www.cdbc.dk
Re: Lazreport. Sorting.
« Reply #6 on: January 20, 2026, 02:42:06 pm »
Hi
@Thausand:
Quote
warning, is clanker.
I think you have a typo, shouldn't that be:
Warning, is Wanker.  :P  (I honestly didn't know, that AI could do that)  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Thausand

  • Sr. Member
  • ****
  • Posts: 458
Re: Lazreport. Sorting.
« Reply #7 on: January 20, 2026, 02:51:00 pm »
I think you have a typo, shouldn't that be:
Warning, is Wanker.  :P  (I honestly didn't know, that AI could do that)  :D
LOL

yes, maybe you right. When wank enough hard then come out slop  :D

PascalDragon

  • Hero Member
  • *****
  • Posts: 6315
  • Compiler Developer
Re: Lazreport. Sorting.
« Reply #8 on: January 20, 2026, 09:34:15 pm »
Hello Peter,

The forum software does not support MarkDown. You need to use its BBCodes instead for formatting.

Petrus Vorster

  • Full Member
  • ***
  • Posts: 222
Re: Lazreport. Sorting.
« Reply #9 on: January 21, 2026, 11:39:09 am »
You fellows are right. I have been putting if off too long.
Tell you what, I am not going to expand that project any further until i have done this Sqlite thing.

On the other side of the coin, for my use DBF work great. It runs without issues and it was a huge change from Power & Freebasic flat files I had. My sqlite experience over there was terribly limited.

I am now busy with some personal examples from an expert here.

Let me bury the old stuff.

-Peter

 

TinyPortal © 2005-2018