Blog

All Blog Posts  |  Next Post  |  Previous Post

Filtering in Delphi: From Strings to Structured Logic

Today

TMS Software Delphi  Components


Filtering data is something we all do.

Whether it’s a grid, a dataset, or a list of objects—at some point, users want to narrow things down.

In Delphi, the most common starting point is still the Filter property on a TDataSet.

DataSet.Filter := 'Age > 18 AND Country = ''BE''';
DataSet.Filtered := True;

It works.
But once you go beyond simple cases, it quickly becomes harder to manage.

Where It Starts to Break Down

The main issue is that filtering is just… a string.

That means:

  • No structure
  • No validation before execution
  • No guidance while building it

And as developers, we might get away with that.
But even then, it’s not always pleasant to work with.

A slightly more complex example:

([YearOfBirth] < 2008 AND [Subscription Country] = 'BE') OR ([YearOfBirth] < 2005 AND [Subscription Country] = 'US')

Now imagine:

  • Typing this manually
  • Making sure field names are correct
  • Keeping brackets balanced
  • Debugging when something doesn’t work

There’s no help.
You only find out something is wrong after applying the filter.

What About End Users?

This is where things really fall apart.

We can’t realistically expect users to write expressions like that.

Even if we wrap it in a UI:

  • They still need to understand field names
  • They still need to understand operators
  • They still need to think in syntax

That’s not how users think about filtering.

They think in terms of:

  • “Show me adults”
  • “Only items from Belgium”
  • “Orders after this date”

Not:

(Age > 18 AND Country = 'BE')

The Core Problem

If you look at it from a bit of distance, the issue is not filtering itself.

It’s how we represent it.

Right now:

  • We store logic as a string
  • We build it manually
  • We validate it too late

What we’re missing is:

  • A structured way to define filters
  • Something that reflects actual logic (not just text)
  • A way to validate before applying

A Different Approach

Instead of thinking in strings, you can break a filter down into smaller parts:

  • A field (what are we filtering on?)
  • An operator (how do we compare?)
  • A value (what are we comparing against?)

Something like:

Age > 18

Becomes:

  • Field: Age
  • Operator: >
  • Value: 18

And once you have that, you can start combining them:

  • With AND / OR
  • In groups
  • Even nested if needed

At that point, you’re no longer dealing with a string.
You’re working with a model of your filter logic.

And that opens the door to:

  • Validation before execution
  • Reusable logic across controls
  • And eventually… user-friendly ways to build filters

Where This Leads

Once filtering is structured instead of string-based, a few things become possible:

  • You can generate different output formats (DataSet, SQL, OData, …)
  • You can validate filters safely before applying them
  • You can build UI on top of the logic, instead of parsing text afterward

That’s the direction we started exploring.

Not by replacing filtering entirely,
but by putting a layer in between:
something that understands filter logic
and can translate it where needed

Next Step

In the next post, we’ll look at how this structured approach can be implemented in practice:

  • how filters are built internally
  • how grouping and nesting works
  • and how this solves a lot of the issues mentioned here


Gjalt Vanhouwaert




This blog post has not received any comments yet.



Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post