Tdbf/tdataset sorting multiple fields in delphi

1.6k views Asked by At

I have a delphi application that uses tdbf which is based on tdataset with the advantage of not requiring bde engine. I needed the table to be sorted and I did this one a single field by adding an indexdef and then specifying the indexfieldnames.

I am trying to now get it to sort on 2 fields ie group men together and then women together and then have each group sorted on salary so that we see females from lowest earner to highest earner followed by men in the same way.

I have read every piece of material stating that you simply specify sortfield of the indexdef as 'gender+salary'. When I try use the index I get told that '+' is not a valid fieldname. I have tried every delimeter from '.'. ','. '&' and ';'. Every delimeter gets picked up as a field that doesn't exist. What is the correct way to sort a table on multiple fields?

Thanks in advance Clinton Brits

2

There are 2 answers

0
Ken White On BEST ANSWER

xBASE (dBASE and it's derivatives) requires that fields in an index all be converted to the same data type, typically strings. To do that typically requires some common functions:

  • DTOS() - Converts an xBASE date to the format CCYYMMDD as a string
  • STR() - Converts a numeric to a string, with an optional width specifier (default 10) and number of digits to the right of the decimal point. Specifically, the syntax is specified as STR(<numeric> [, <width> [, <decimaldigits>] ]).
  • SUBSTR() - Extracts a portion of a string from another, with a specified starting position and number of characters
  • IIF() - Immediate IF, used to convert logicals (eg., IIF(Married = .T., 'Y', 'N')

Index expressions are indeed combined with the + operator. The error you're receiving is probably because you haven't converted to a common data type.

As you've specified the Gender column (probably defined as CHAR 1) and Salary column (probably a NUMERIC of some size), you can use something like

Dbf1.AddIndex('GENDER_SAL', 'GENDER + STR(SALARY, 10, 0)', []);

This creates a index on an expression like F 10000, F 200000, M 12000, where SALARY is converted to the default width of 10 characters (left padded with spaces) and no decimal digits. This should work for you.

0
jrodenhi On

I have not used the component, but it looks like they want to use index expressions that are similar to what we used to use in dBase III. On page 7 in the PDF version of the documentation, they offer an example under the Expressions topic:

Dbf1. AddIndex('INDEX1 ', 'DTOS( DATEFIELD)+ SUBSTR ( LONGFIELD ,1 ,10)+ SUBSTR
( LONGFIELD2 ,1 ,20)', []);

You could try their SubStr function on your fields with parameters that would include the whole string and see if that at least gets you a result.