{ prdxsort.pas } program PrdxSort; {$IfDef VER80} uses SnipTool, SnipData, SysUtils, WinTypes, WinProcs, DbiProcs, DbiTypes, DbiErrs; {$Else} uses WinTypes, WinCrt, Strings, DbiProcs, DbiTypes, DbiErrs, SnipTool, SnipData; {$EndIf} const NAMELEN = 30; { Default length of the mapped fields } szTblName = 'vendors'; szSortedTblName = 'SortVend'; szTblType = 'PARADOX'; { Field Descriptor used in mapping the fields of the table Used in order to display the fields in the order that they are sorted: 'State/Prov' and 'Street'. The 'Vendor Name' is included as additional information. See the fieldmap.c file for a description of field mapping } fldDes: array[0..2] of FLDDesc = ( ( iFldNum: 1; { Field Number } szName: 'State/Prov'; { Field Name } iFldType: fldZSTRING; { Field Type } iSubType: fldUNKNOWN; { Field Subtype } iUnits1: NAMELEN; { Field Size ( 1 or 0 ) } iUnits2: 0; { Decimal places ( 0 ) } iOffset: 0; { Offset in record ( 0 ) } iLen: 0; { Length in Bytes ( 0 ) } iNullOffset: 0; { For Null Bits ( 0 ) } efldvVchk: fldvNOCHECKS; { Validiy checks ( 0 ) } efldrRights: fldrREADWRITE { Rights } ), ( iFldNum: 2; szName: 'Street'; iFldType: fldZSTRING; iSubType: fldUNKNOWN; iUnits1: NAMELEN; iUnits2: 0; iOffset: 0; iLen: 0; iNullOffset: 0; efldvVchk: fldvNOCHECKS; efldrRights: fldrREADWRITE ), ( iFldNum: 3; szName: 'Vendor Name'; iFldType: fldZSTRING; iSubType: fldUNKNOWN; iUnits1: NAMELEN; iUnits2: 0; iOffset: 0; iLen: 0; iNullOffset: 0; efldvVchk: fldvNOCHECKS; efldrRights: fldrREADWRITE ) ); { FldDescs1 } {===================================================================== Code: FindFirstChar(); Input: const char * - the string to search Return: Pointer to the location in the string after the House number Description: This function is used to skip the house number part of the street address when sorting the table. This allows the 'Street' field to be sorted according to the street name. ===================================================================== } function FindFirstChar (const szString: pchar): pCHAR {DBIFN}; var uWhere: UINT16; { Counter to keep track of the current character within the string } begin uWhere := 0; { Search for the first blank as part of the string - This should be the start of the street name. } while ((szString[uWhere] <> '') and (szString[uWhere] <> ' ')) do begin uWhere := uWhere + 1; end; { return the character after the space } FindFirstChar := pCHAR((szString[uWhere+1])) ; end; {===================================================================== Code: StreetCompare(); Input: pVOID pLdObj - Language driver, not used pVOID pValue1 - First value to compare pVOID pValue2 - Second value to compare INT16 iLen - Length, not used Return: -1 if (pValue1 < pValue2) 0 if (pValue1 = pValue2) 1 if (pValue1 > pValue2) Description: This function is used in comparing the 'Street' field of the vendor table. This function will sort according to the street name, not the address. ===================================================================== } function StreetCompare (pLdObj: pointer; pValue1: pointer; pValue2: pointer; iLen: INT16): INT16; var rslt: INT16; { Value returned from IDAPI functions } szOne: pCHAR; { First value to compare } szTwo: pCHAR; { Second value to compare } begin { Dummy assignments to avoid warnings } iLen := iLen; pLdObj := pLdObj; { Skip leading numeric values - used to skip the House Number portion of the street address. } szOne := FindFirstChar( pValue1); szTwo := FindFirstChar( pValue2); { Compare the values in the 'Street' field, starting the strings at the first non-numeric character - sort on Street name, not the house number on a given street. } rslt := StrComp(szOne, szTwo); { If on the same street (pValue1 = pValue2), compare House Number on the street } if (rslt = 0) then rslt := StrComp(pCHAR(pValue1), pCHAR(pValue2)); if (0 < rslt) then rslt := 1; if (rslt < 0) then rslt := -1; StreetCompare := rslt; end; {===================================================================== Code: ParadoxSort(); Input: None. Return: None. Description: This example shows how to sort on a field in a PARADOX table. The example will use the DbiSortTable() function. ===================================================================== } var hDb: hDBIDb; { Handle to the Database } hCur: hDBICur; { Handle to the table } hSortCur: hDBICur; { Handle to the sorted table } NOSRTFLDS: UINT16; uNumFields: UINT16; const uSortFields: array[0..1] of UINT16 = ( 5, 3 ); bCaseIns: array[0..1] of BOOL = ( FALSE, FALSE); SortOrd: array[0..1] of SORTOrder = ( sortASCEND, sortASCEND ); pfSortFn: array[0..1] of pfSORTCompFn = ( nil, nil ); uNumToSort: UINT32 = 10; begin Screen('*** Sorting Example ***'); Screen(' Initializing IDAPI...'); if (InitAndConnect(hDb) <> DBIERR_NONE) then { Terminate example if } begin { Initialization fails } Screen(''); Screen('*** End of Example ***'); exit; end; Screen(' Setting the default Database directory...'); ChkRslt(DbiSetDirectory(hDb, pCHAR(szTblDirectory)), DBIERR_NONE, ' Error - SetDirectory.'); Screen(' Open the '+szTblName+' table...'); if (ChkRslt(DbiOpenTable(hDb, pCHAR(szTblName), pCHAR(szTblType), nil, nil, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, nil, hCur), DBIERR_NONE, ' Error - OpenTable.') <> DBIERR_NONE) then begin CloseDbAndExit(hDb); Screen(''); Screen('*** End of Example ***'); exit; end; ChkRslt(DbiSetToBegin(hCur), DBIERR_NONE, ' Error - SetToBegin.'); Screen(' Display the unsorted '+szTblName+' table...'); ChkRslt(DisplayTable(hCur, uNumToSort), DBIERR_NONE, ' Error - DisplayTable.'); Screen(' '); Screen(' Sort the '+szTblName+' table, using first the "State/Prov"'+ ' field,'); Screen(' and then the "Street" field. The sorted'+ ' records are saved in the '+szSortedTblName+' table'); { Determine the number of fields in the sorted table } NOSRTFLDS := trunc(sizeof(uSortFields) / sizeof(uSortFields[0])); if (ChkRslt(DbiSortTable(hDb, pCHAR(szTblName), pCHAR(szTblType), nil, pCHAR(szSortedTblName), nil, nil, NOSRTFLDS, @uSortFields, @bCaseIns, @SortOrd, @pfSortFn, FALSE, nil, uNumToSort), DBIERR_NONE, ' Error - SortTable.')<> DBIERR_NONE) then begin ChkRslt(DbiDeleteTable(hDb, pCHAR(szSortedTblName), pCHAR(szTblType)), DBIERR_NONE, ' Error - DeleteTable.'); CloseDbAndExit(hDb); Screen(''); Screen('*** End of Example ***'); exit; end; Screen(' Open the sorted table ('+szSortedTblName+')....'); if (ChkRslt(DbiOpenTable(hDb, pCHAR(szSortedTblName), pCHAR(szTblType), nil, nil, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, nil, hSortCur), DBIERR_NONE, ' Error - OpenTable.') <> DBIERR_NONE) then begin ChkRslt(DbiDeleteTable(hDb, pCHAR(szSortedTblName), pCHAR(szTblType)), DBIERR_NONE, ' Error - DeleteTable.'); Screen(' Clean up IDAPI...'); CloseDbAndExit(hDb); Screen(''); Screen('*** End of Example ***'); exit; end; Screen(' Change which fields of the table are displayed:'); Screen(' State/Prov, Street, and Vendor Name.'); { Determine the number of fields that are part of the descriptor } uNumFields := trunc(sizeof(FldDes) / sizeof (FldDes[0])); { Set the field mapping. } ChkRslt(DbiSetFieldMap(hSortCur, uNumFields, @FldDes), DBIERR_NONE, ' Error - SetFieldMap.'); ChkRslt(DbiSetToBegin(hSortCur), DBIERR_NONE, ' Error - SetToBegin.'); Screen(' Display the sorted table ('+szSortedTblName+')...'); ChkRslt(DisplayTable(hSortCur, uNumToSort), DBIERR_NONE, ' Error - DisplayTable.'); Screen(' '); Screen(' Close the origional table ('+szTblName+')...'); ChkRslt(DbiCloseCursor(hCur), DBIERR_NONE, ' Error - CloseCursor.'); Screen(' Close the sorted table ('+szSortedTblName+')...'); ChkRslt(DbiCloseCursor(hSortCur), DBIERR_NONE, ' Error - CloseCursor.'); Screen(' Delete the sorted table ('+szSortedTblName+')...'); ChkRslt(DbiDeleteTable(hDb, pCHAR(szSortedTblName), pCHAR(szTblType)), DBIERR_NONE, ' Error - DeleteTable.'); Screen(' Close the Database and exit IDAPI...'); CloseDbAndExit(hDb); Screen('*** End of Example ***'); end.