Jump to content
markus_ja

Please implement TW3DataSet.Locate

Recommended Posts

Hello,

 

I implemented it myself, see below. It's the same syntax as in Delphi. Maybe you can use my code for the next release?

TW3DatasetLocateOption = (loCaseInsensitive);
TW3DatasetLocateOptions = set of TW3DatasetLocateOption;

function TMyDataSet.Locate(aKeyField: String; aKeyValue: Variant; aOptions: TW3DatasetLocateOptions = []): Boolean;
begin
  Result := Locate([aKeyField], [aKeyValue], aOptions);
end;

function TMyDataSet.Locate(aKeyFields: array of string; aKeyValues: array of variant;
  aOptions: TW3DatasetLocateOptions = []): Boolean;

  function IsMatch(aKeyField: TW3DatasetField; aKeyValue: variant): Boolean;
  begin
    Result := false;
    if (aKeyField.Kind = ftString) and (loCaseInsensitive in aOptions) then
    begin
      if aKeyField.AsString.ToLower = LowerCase(aKeyValue) then
      begin
        Result := true;
      end;
    end
    else
    begin
      if aKeyField.Data = aKeyValue then
      begin
        Result := true;
      end;
    end;
  end;

var
  keyFields: array of TW3DatasetField;
  curPos: Integer;
begin

  if aKeyFields.Count <> aKeyValues.Count then
  begin
    //raise Exception
  end;

  for var i:=0 to aKeyFields.Count - 1 do
  begin
    keyFields.Add(Fields.FieldByName(aKeyFields[i]));
  end;

  curPos := RecNo;
  First;
  while not EOF do
  begin
    Result := true;

    for var i:=0 to keyFields.Count - 1 do
    begin

      if not IsMatch(keyFields[i], aKeyValues[i]) then
      begin
        Result := false;
      end;

    end;

    if Result then
      Exit;

    Next;
  end;

  if not Result then
    MoveTo(curPos);
end;

Share this post


Link to post
Share on other sites

@gabr42:

 

I just recognized, that an overloaded function with optional parameter doesn't work in SmartPascal. Please, remove one of the overloaded function or fix the compiler, in order that function is working properly.

 

The issue occures, when you use the optional parameter in that function.

DataSet.Locate(key, value); //Works fine
DataSet.Locate(key, value, [loCaseInsensitive]); //Won't compile.

See here for more details:

http://forums.smartmobilestudio.com/index.php?/topic/4002-overloaded-function-with-optinal-set-parameter-doesnt-compile/

Share this post


Link to post
Share on other sites

@gabr42:

 

I added a new option to the Locate function, in order I can iterate through all matching records. Please add that as well, it makes the DataSet more powerful.

TW3DatasetLocateOption = (loCaseInsensitive, loStartFromCurrentPos);

loStartFromCurrentPos is used to start searching from the current pos. So, it is possible in while loop do find all matching records.

See example:

aDestDataSet.First;
while aDestDataSet.Locate([keyField], [keyValue], [loStartFromCurrentPos]) do
begin
  //Do something

  aDestDataSet.Next;
end;

Here is the modifed Locate function:

function TMyDataSet.Locate(aKeyFields: array of string; aKeyValues: array of variant;
  aOptions: TW3DatasetLocateOptions = []): Boolean;

  function IsMatch(aKeyField: TW3DatasetField; aKeyValue: variant): Boolean;
  begin
    Result := false;
    if (aKeyField.Kind = ftString) and (loCaseInsensitive in aOptions) then
    begin
      if aKeyField.AsString.ToLower = LowerCase(aKeyValue) then
      begin
        Result := true;
      end;
    end
    else
    begin
      if aKeyField.Data = aKeyValue then
      begin
        Result := true;
      end;
    end;
  end;

var
  keyFields: array of TW3DatasetField;
  curPos: Integer;
begin

  if aKeyFields.Count <> aKeyValues.Count then
  begin
    //raise Exception
  end;

  for var i:=0 to aKeyFields.Count - 1 do
  begin
    keyFields.Add(Fields.FieldByName(aKeyFields[i]));
  end;

  curPos := RecNo;
  if not (loStartFromCurrentPos in aOptions) then
    First;

  while not EOF do
  begin
    Result := true;

    for var i:=0 to keyFields.Count - 1 do
    begin

      if not IsMatch(keyFields[i], aKeyValues[i]) then
      begin
        Result := false;
      end;

    end;

    if Result then
      Exit;

    Next;
  end;

  if not Result then
    MoveTo(curPos);
end;

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×