dBase 中有一个复合索引,索引值段可以是一个表达式!那么这种情况如何查询呢?
Here is an example of how to call the generic SearchExpr function:
{current index key expression is 'DTOS(CRT_DATE)+CRT_CODE'}
Table1.SetKey;
Table1.FieldByName('CRT_DATE').AsString := '2/2/94'; {assign search values}
Table1.FieldByName('CRT_CODE').AsString := 'T002'; {assign search values}
if SeekExpr(Table1.Handle, [Table1.FieldByName('CRT_DATE'),
Table1.FieldByName('CRT_CODE')] ) then
ShowMessage('Found!')
else
ShowMessage('Not found!');
{note that the record pointer is now on the record it found, if any}
Here is the code for the generic search function:
function TDBFTest1.SeekExpr(hTable: HDBIcur;
aFlds: array of TField): boolean;
const
KeyBufSize = 250; {maximum size of key}
var
pRecBuf: pByte; {contains a record in memory}
pKeyBuf: pByte; {contains actual key}
TblProps: CURProps; {table properties }
rslt: DBIResult; {result of BDE call}
i: integer; {counter}
tmpPSZ: PCHAR;
tmpDate: LongInt;
begin
{get size of record buffer}
DbiGetCursorProps(hTable, TblProps);
{allocate memory for record buffer}
GetMem(pRecBuf, TblProps.iRecBufSize * sizeof(BYTE));
GetMem(pKeyBuf, KeyBufSize); {allocate mem for key}
{initialize record buffer}
DbiInitRecord(hTable, pRecBuf);
{set search values in record buffer}
for i := 0 to High(aFlds) do
begin
{TStringField}
if (aFlds[i] is TStringField) then
begin
GetMem(tmpPSZ, Length(aFlds[i].AsString)+1);
StrPCopy(tmpPSZ, aFlds[i].AsString);
DbiPutField(hTable, {TTable}
aFlds[i].FieldNo, {TField}
pRecBuf, {pointer to record buffer}
(tmpPSZ)); {pointer to value}
FreeMem(tmpPSZ, Length(aFlds[i].AsString)+1);
end
{TDateField}
else if (aFlds[i] is TDateField) then
begin
tmpDate := Trunc(aFlds[i].AsDateTime);
DbiPutField(hTable, {TTable}
aFlds[i].FieldNo, {TField}
pRecBuf, {pointer to record buffer}
(@tmpDate)); {pointer to value}
end
end;
{create a key for the above values}
DbiExtractKey(hTable, pRecBuf, pKeyBuf);
{search using this key (stored in pKeyBuf)}
table1.updatecursorpos;
rslt := DbiGetRecordForKey(hTable, True, 0, 0, pKeyBuf, nil);
table1.refresh; {update data aware components}
if rslt <> 0 then
Result := False
else
result := True;
ShowRecord; {display new record number -- see below}
{free memory allocated for buffer}
FreeMem(pRecBuf, TblProps.iRecBufSize * sizeof(BYTE));
FreeMem(pKeyBuf, KeyBufSize);
end;
procedure TDBFTest1.ShowRecord;
{Show a dBase record number}
{NOTE: it assumes there is a label component named RecordNo.}
var
myrecprop: RECprops;
recno: integer;
begin
table1.updatecursorpos;
recno := 0;
dbiGetRecord(table1.handle, dbiNOLOCK, nil, @myrecprop);
recno := myrecprop.iPhyRecNum;
RecordNo.Caption := inttostr(recno);
end;