Jump to content


Photo

Please implement TW3DataSet.Locate


  • Please log in to reply
5 replies to this topic

#1 markus_ja

markus_ja
  • Members
  • 319 posts
  • LocationAustria

Posted 10 March 2016 - 03:30 PM

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;

  • Nico Wouterse likes this

#2 gabr42

gabr42

    Boss

  • Administrators
  • 192 posts

Posted 16 March 2016 - 11:35 PM

If you give the code to the Smart project and revoke your rights to it, we can definitely include it in the 2.2 release. I'll make sure it makes it into 2.2 RC2.



#3 markus_ja

markus_ja
  • Members
  • 319 posts
  • LocationAustria

Posted 17 March 2016 - 09:26 AM

You can use it and modify/improve it, as you want. I don't need any rights on that.

If you need some other wording, to revoke my rights just let me know.



#4 markus_ja

markus_ja
  • Members
  • 319 posts
  • LocationAustria

Posted 24 March 2016 - 02:44 PM

@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.smartm...doesnt-compile/



#5 markus_ja

markus_ja
  • Members
  • 319 posts
  • LocationAustria

Posted 24 March 2016 - 02:53 PM

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

  • Dany likes this

#6 gabr42

gabr42

    Boss

  • Administrators
  • 192 posts

Posted 24 March 2016 - 07:39 PM

Added, thanks! Will be included in 2.2RC2.

 

As for the 'overload+optional' problem, we'll take a look at that.






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

IPB Skin By Virteq