Components for Delphi and C++ Builder.

Go to Russian forum
Go to EhLib.com
It is currently 19 Apr 2024, 04:53

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: 15 May 2017, 10:24 
Offline

Joined: 21 Nov 2012, 01:56
Posts: 119
Hi Dear Admin,
I have huge data in the grid, if a field value changes , I have to access several rows by keys and changes some values in them, how do I realize it? sometimes those rows maybe out of view because the filtering feature, so I have to access them behind the view and make use of the internal array of records.

thanks again!


Top
 Profile  
 
PostPosted: 18 May 2017, 20:00 
Offline

Joined: 08 May 2014, 18:06
Posts: 663
Hello

You need to explore the methods of your DataSet.
The DBGrid does not store data. All data is stored in DataSet.
When user filter data, filtering is applied to the DataSet records.

Standard DataSet has next methods to locate records
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; virtual;
function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; virtual;

_________________
Best regards
EhLib Support Team


Top
 Profile  
 
PostPosted: 19 May 2017, 05:13 
Offline

Joined: 21 Nov 2012, 01:56
Posts: 119
EhLibSupport wrote:
Hello

You need to explore the methods of your DataSet.
The DBGrid does not store data. All data is stored in DataSet.
When user filter data, filtering is applied to the DataSet records.

Standard DataSet has next methods to locate records
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; virtual;
function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; virtual;


I knows your meaning. but what I refer to is not the standard datasets, I means the TMemTableEh. Is there a way to locate a TMemoryRecordEh with KeyValues in the internal array of records in the TMemTableEh even under filtering?

Standard datasets don't have this feature.
it is also a reason why we as customers choose TMemTableEh from the excellent Delphi library EHLib, not the standard datasets.


Thanks.


Top
 Profile  
 
PostPosted: 22 May 2017, 11:37 
Offline

Joined: 08 May 2014, 18:06
Posts: 663
Hello

You can use MemTableEh1.RecordsView.MemTableData.RecordsList property to access internal buffer of all records.
The RecordsList does not depend on the filter.

And use similar code to find and change field value in the specified record

Code:
procedure TForm1.Button2Click(Sender: TObject);
var
  AllRecs: TRecordsListEh;
  i: Integer;
  NameIdx: Integer;
  Rec: TMemoryRecordEh;
begin
  AllRecs := MemTableEh1.RecordsView.MemTableData.RecordsList;
  NameIdx := MemTableEh1.RecordsView.MemTableData.DataStruct.FieldIndex('Name');
  for i := 0 to AllRecs.Count-1 do
  begin
    Rec := AllRecs.Rec[i];
    if VarToStr(Rec.Value[NameIdx, dvvValueEh]) = 'Canada' then
    begin
      Rec.Edit;
      Rec.DataValues['Capital', dvvValueEh] := '<<Ottawa>>';
      Rec.Post;
    end;
  end;
end;


Here we change 'Capital' field value for a record with field [Name] = 'Canada'.

The Demo is attached


Attachments:
2017-05-22-FindRecordInMemTableRecords.zip [3 KiB]
Downloaded 174 times

_________________
Best regards
EhLib Support Team
Top
 Profile  
 
PostPosted: 22 May 2017, 14:53 
Offline

Joined: 21 Nov 2012, 01:56
Posts: 119
Thanks for your time.

I got so much out of your reply.
Can I suggest a locate method with multi-keyvalue to search in the internal buffer of all records just like standard datasets?
It will come handy comparing to writing a for-loop statement when coding.

Besides, I am always confused with the 2 properties of MemTableEh.Rec and MemTableEH.RecView, what is the difference between the 2 properties?

Best Regards
Nick.


Top
 Profile  
 
PostPosted: 23 May 2017, 04:22 
Offline

Joined: 08 May 2014, 18:06
Posts: 663
Hello Nick

1.
Quote:
Can I suggest a locate method with multi-keyvalue to search in the internal buffer of all records just like standard datasets?
It will come handy comparing to writing a for-loop statement when coding.

Unfortunately, there is no Locate method in the TRecordsListEh list.
(May be we will add similar method at the next version)
You can use its next counterpart - FindRecInRecordsList.

Code:
function FindRecInRecordsList(RecList: TRecordsListEh; const KeyFields: string;
  const KeyValues: Variant; TryUseIndex: Boolean = True): TMemoryRecordEh;
var
  Fields: TList;
  I, RecIndex: Integer;
  MTIndex: TMTIndexEh;

  procedure GetFieldList(List: TList; const FieldNames: string);
  var
    Pos: Integer;
    Field: TMTDataFieldEh;
    Len: Integer;
  begin
    Len := FieldNames.Length;
    Pos := 1;
    while Pos <= Len do
    begin
      Field := RecList.DataStruct.FieldByName(ExtractFieldName(FieldNames, Pos));
      if Assigned(List) then List.Add(Field);
    end;
  end;

  function CompareRecValues(Rec: TMemoryRecordEh; const VarValues: Variant): Boolean;
  var
    I: Integer;
  begin
    if Fields.Count = 0 then
      Result := False
    else if Fields.Count = 1 then
      Result := VarEquals(Rec.Value[TMTDataFieldEh(Fields.First).Index, dvvValueEh], VarValues)
    else begin
      Result := True;
      for I := 0 to Fields.Count - 1 do
        Result := Result and VarEquals(Rec.Value[TMTDataFieldEh(Fields[I]).Index, dvvValueEh], VarValues[I]);
    end;
  end;

begin
  Result := nil;
  MTIndex := nil;
  Fields := TList.Create;
  try
    GetFieldList(Fields, KeyFields);

    if TryUseIndex then
      MTIndex := RecList.Indexes.GetIndexForFields(KeyFields);

    if MTIndex <> nil then
    begin
      if MTIndex.FindRecordIndexByKey(KeyValues, RecIndex) then
        Result := RecList[RecIndex]
    end else
    begin
      for I := 0 to RecList.Count-1 do
      begin
        if CompareRecValues(RecList.Rec[i], KeyValues) then
        begin
          Result := RecList.Rec[i];
          Break;
        end
      end;
    end;

  finally
    Fields.Free;
  end;
end;


2.
Quote:
Besides, I am always confused with the 2 properties of MemTableEh.Rec and MemTableEH.RecView, what is the difference between the 2 properties?

--
MemTableEh.Rec points to the current record of TMemoryRecordEh type where the data is stored.
--
MemTableEH.RecView points to the TMemRecViewEh object.
   TMemRecViewEh contains a pointer to the data record - Rec: TMemoryRecordEh
    And the properties for creating the tree structure of Child nodes.
    They are used when MemTableEh is in tree mode.

_________________
Best regards
EhLib Support Team


Top
 Profile  
 
PostPosted: 23 May 2017, 06:22 
Offline

Joined: 21 Nov 2012, 01:56
Posts: 119
admin,
Haha, I have to admit that, you are such a genius,and I am a stealer, always stealing from you.
It is really very close to what I want, accessing huge data at the background even under filtering.
Sincerely hope this feature would be added in next version.
As to the buffer of all records, could they be sorted when accessing? For example, when a certain amount is allocated to a range of records in buffer under a certain of sorting even filtering is on.
I know it is too more to ask, just wana know Could or Could not.
And thanks for the help on Rec and RecView properties. too.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group