某些TDataSet,对于已按某字段排序的DataSet,在进行Locate时并没有使用二分查询、线性插值查找等高效查找算法。因为程序需要,所以自己写了一个,愿与大家一起分享。本函数只能完全等值匹配,不支持部分匹配、忽略大小写匹配,如果需要这两种模式,还是调用TdataSet.Locate。function DataSetLocateEx(ADataSet: TDataSet; AFieldNames: string; vals: Variant; IsAsc: boolean): boolean;
label
  JumpoutMainLoop;
var
  top, bottom: int64;
  ccc: int64;
  Find: boolean;
  Index: integer;
  ControlsDisabled: boolean;
  Fields: TList;
  val: Variant;
  OldRecNO: integer;
  i: integer;
  Matched: boolean;
begin
  try
    ADataSet.CheckBrowseMode;
    Fields := TList.Create;
    ADataSet.GetFieldList(Fields, AFieldNames);
    ControlsDisabled := ADataSet.ControlsDisabled;
    if not ControlsDisabled then
      ADataSet.DisableControls;    Index := ADataSet.fieldbyname(TField(Fields[0]).FieldName).Index;
    if VarIsArray(vals) then
      val := vals[0]
    else
      val := vals;
    ADataSet.First;
    top := ADataSet.RecNo;
    ADataSet.Last;
    bottom := ADataSet.RecNo;
    FInd := false;
    while top <= bottom do
    begin
      ccc := (top + bottom) div 2;
      ADataSet.RecNo := ccc;
      if IsAsc then
      begin
        if ADataSet.Fields[Index].AsVariant > val then
        begin
          Bottom := ccc - 1;
        end
        else
          if ADataSet.Fields[Index].AsVariant < val then
          begin
            Top := ccc + 1;
          end
          else
          begin
            while (ADataSet.Fields[Index].AsVariant = val) and (not ADataSet.Bof) do
              ADataSet.Prior;
            if (ADataSet.Bof) and (ADataSet.Fields[Index].AsVariant = val) then
            else
              ADataSet.Next;
            if Fields.Count > 1 then
            begin
              Matched := false;
              while (not Matched) and (ADataSet.Fields[Index].AsVariant = val) and (not ADataSet.Eof) do
              begin
                Matched := true;
                for i := 1 to Fields.Count - 1 do
                begin
                  if TField(Fields[i]).AsVariant <> vals[i] then
                  begin
                    Matched := false;
                    break;
                  end;
                end;
                if Matched then
                begin
                  Find := true;
                  goto JumpoutMainLoop;
                end
                else
                  ADataSet.Next;
              end;
            end;
            if Fields.Count = 1 then
            begin
              Find := true;
              break;
            end
            else
            begin
              Find := false;
              break;
            end;          end;
      end
      else
      begin
        if ADataSet.Fields[Index].AsVariant < val then
        begin
          Bottom := ccc - 1;
        end
        else
          if ADataSet.Fields[Index].AsVariant > val then
          begin
            Top := ccc + 1;
          end
          else
          begin
            while (ADataSet.Fields[Index].AsVariant = val) and (not ADataSet.Bof) do
              ADataSet.Prior;
            if (ADataSet.Bof) and (ADataSet.Fields[Index].AsVariant = val) then
            else
              ADataSet.Next;
            if Fields.Count > 1 then
            begin
              Matched := false;
              while (not Matched) and (ADataSet.Fields[Index].AsVariant = val) and (not ADataSet.Eof) do
              begin
                Matched := true;
                for i := 1 to Fields.Count - 1 do
                begin
                  if TField(Fields[i]).AsVariant <> vals[i] then
                  begin
                    Matched := false;
                    break;
                  end;
                end;
                if Matched then
                begin
                  Find := true;
                  goto JumpoutMainLoop;
                end
                else
                  ADataSet.Next;
              end;
            end;
            if Fields.Count = 1 then
            begin
              Find := true;
              break;
            end
            else
            begin
              Find := false;
              break;
            end;          end;
      end;
      continue;
      JumpoutMainLoop:
      break;
    end;
  finally
    if not ControlsDisabled then
      ADataSet.EnableControls;
    Fields.Free;
  end;
  result := Find;
end;