Jump to content

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;
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/

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;
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...