clientdataset persistent fields property

TeeGrid VCL / FMX for Embarcadero RAD Studio, Delphi, C++ Builder and Lazarus Free Pascal.
Post Reply
rbarone
Newbie
Newbie
Posts: 26
Joined: Thu May 18, 2023 12:00 am

clientdataset persistent fields property

Post by rbarone » Fri Jul 05, 2024 9:08 am

HI
if I connect a Tgrid to a Delphi 12.1 clientdataset, the grid is fed with all the persistent fields of the query
But if I act for example on the visible true/false property in the object inspector of persistent fields, this is not reflected on the Tgrid but I am forced to modify the Tgrid field by field to make what I want invisible or visible
Am I doing something wrong or is this how it works?
field_property.png
example problem
field_property.png (111.9 KiB) Viewed 26619 times

rbarone
Newbie
Newbie
Posts: 26
Joined: Thu May 18, 2023 12:00 am

Re: clientdataset persistent fields property

Post by rbarone » Fri Jul 05, 2024 9:28 am

HI
I just discovered that to resolve this you need to unlink the clientdataset to the Tgrid with the object inspector, modify the persistent fields and then reconnect the clientdataset to the TGrid
This causes the components to lose some dynamism. Check how it behaves at runtime.
Maybe this could be an interesting fix?
Ciao

Marc
Site Admin
Site Admin
Posts: 1272
Joined: Thu Oct 16, 2003 4:00 am
Location: Girona
Contact:

Re: clientdataset persistent fields property

Post by Marc » Fri Jul 05, 2024 10:04 am

Hello,

Thanks for the follow-up, we'll take a look,

Regards,
Marc Meumann
Steema Support

rbarone
Newbie
Newbie
Posts: 26
Joined: Thu May 18, 2023 12:00 am

Re: clientdataset persistent fields property

Post by rbarone » Mon Jul 08, 2024 9:39 am

hi
still pertaining to the visible issue of persistent fields, I tried to make some code by adapting one of your examples to manage the expander
visible property at runtime doesn't work, the rest of the code works great
furthermore, changing the display label on the persistent field has no effect on the column title of the grid and this is a big problem, is there some instruction that I haven't found?
Help me please!
Am I doing something wrong?

Code: Select all

/*********************************/
  My_Ctgrid_class := C_TeeGrid_Class.Create;
  // Initialize "Expander"
  My_Ctgrid_class.max_col_footer := 4;

  My_Ctgrid_class.Params_matrix[1].field_name := 'pk_progressivo';
  My_Ctgrid_class.Params_matrix[1].position := 0;
  My_Ctgrid_class.Params_matrix[1].type_function := 'count';

  My_Ctgrid_class.Params_matrix[2].field_name := 'budget';
  My_Ctgrid_class.Params_matrix[2].position := 5;
  My_Ctgrid_class.Params_matrix[2].type_function := 'sum';

  My_Ctgrid_class.Params_matrix[3].field_name := 'budget_utilizzato';
  My_Ctgrid_class.Params_matrix[3].position := 6;
  My_Ctgrid_class.Params_matrix[3].type_function := 'sum';

  My_Ctgrid_class.Params_matrix[4].field_name := 'quota_detraibile';
  My_Ctgrid_class.Params_matrix[4].position := 8;
  My_Ctgrid_class.Params_matrix[4].type_function := 'average';

  TeeGrid1 := My_Ctgrid_class.tgrid_expander(TeeGrid1, Cds_ListView, [b]cds_detail[/b], true, true);
(cds_detail is dataset in attach image)

Code: Select all

/*********************************/
 


type
  TParams = Record
    field_name: string;
    position: smallint;
    type_function: string;
  End;

  C_TeeGrid_Class = class(TObject)

    procedure CBEnabledChange(Sender: TObject);
  private
    { Private declarations }
  protected
  public
    { Public declarations }
    mydataset1_tmp, mydataset2_tmp: TclientDataSet;
    Expander: TExpanderRender;
    function tgrid_expander(mytgrid: tteegrid; mydataset1_in: TclientDataSet;
      mydataset2_in: TclientDataSet; open_expander: boolean;
      footer_calc: boolean): tteegrid;
    procedure GetMyDati(const Sender: TExpanderRender; const ARow: Integer;
      out AData: TObject);
    function read_mydata(const ARecNo: Integer; mydataset1: TclientDataSet;
      mydataset2: TclientDataSet): TclientDataSet;
    function CloneData(const ADataSet: TclientDataSet): TclientDataSet;
    // procedure DetailNewGroup(const Sender, NewGroup: TRowGroup; field_name1 :string; field_name2 : string);
    procedure DetailNewGroup(const Sender, NewGroup: TRowGroup);

    constructor Create;

  var
    max_col_footer: smallint;
    Params_matrix: array [1 .. 10] of TParams;
{ I use the array to manage the totals row of the expander grid
 I pass to the function the fields I want to be used, their position as columns and the type of
 aggregation (this only at text level and then I manage with if se sum count etc)
 }
  end;

--------------------------
procedure C_TeeGrid_Class.CBEnabledChange(Sender: TObject);
begin
  //
end;

// Return a new clone copy of ADataSet data, all rows
function C_TeeGrid_Class.CloneData(const ADataSet: TclientDataSet)
  : TclientDataSet;
var
  tmp: TMemoryStream;
begin
  tmp := TMemoryStream.Create;
  try
    ADataSet.SaveToStream(tmp);
    tmp.position := 0;

    result := TclientDataSet.Create(nil);
    TclientDataSet(result).LoadFromStream(tmp);
  finally
    tmp.Free;
  end;

end;

procedure C_TeeGrid_Class.DetailNewGroup(const Sender, NewGroup: TRowGroup);
var
  tmpTot: TColumnTotals;
  i: smallint;
begin

  // Create a Totals band
  tmpTot := TColumnTotals.Create(NewGroup.Footer); // <--- set to Footer

  // Add some calculations

  for i := 1 to max_col_footer do
  begin
    if Params_matrix[i].type_function = 'count' then
    begin
      tmpTot.Calculation.Add(NewGroup.Columns[Params_matrix[i].position],
        TColumnCalculation.Count);
      tmpTot.Calculation.Add(Params_matrix[i].field_name,
        TColumnCalculation.Count);
    end;
    if Params_matrix[i].type_function = 'sum' then
    begin
      tmpTot.Calculation.Add(NewGroup.Columns[Params_matrix[i].position],
        TColumnCalculation.Sum);
      tmpTot.Calculation.Add(Params_matrix[i].field_name,
        TColumnCalculation.Sum);
    end;
    if Params_matrix[i].type_function = 'min' then
    begin
      tmpTot.Calculation.Add(NewGroup.Columns[Params_matrix[i].position],
        TColumnCalculation.Min);
      tmpTot.Calculation.Add(Params_matrix[i].field_name,
        TColumnCalculation.Min);
    end;
    if Params_matrix[i].type_function = 'max' then
    begin
      tmpTot.Calculation.Add(NewGroup.Columns[Params_matrix[i].position],
        TColumnCalculation.Max);
      tmpTot.Calculation.Add(Params_matrix[i].field_name,
        TColumnCalculation.Max);
    end;
    if Params_matrix[i].type_function = 'average' then
    begin
      tmpTot.Calculation.Add(NewGroup.Columns[Params_matrix[i].position],
        TColumnCalculation.Average);
      tmpTot.Calculation.Add(Params_matrix[i].field_name,
        TColumnCalculation.Average);
    end;
  end;
  // Add a Totals header:
  TTotalsHeader.CreateTotals(NewGroup.Footer, tmpTot);

end;

procedure C_TeeGrid_Class.GetMyDati(const Sender: TExpanderRender;
  const ARow: Integer; out AData: TObject);
begin

  AData := TVirtualDBData.From(read_mydata(ARow + 1, mydataset1_tmp,
    mydataset2_tmp));
end;

function C_TeeGrid_Class.read_mydata(const ARecNo: Integer;
  mydataset1: TclientDataSet; mydataset2: TclientDataSet): TclientDataSet;
// Return the CustomerID for row: ARow
  function key_ricerca: Integer;
  begin
    mydataset1.RecNo := ARecNo;
    result := mydataset1.FieldByName('pk_progressivo').AsInteger;
  end;

// Execute OrdersTable query for a given CustomerID
  procedure FiltroDati(const key_ricerca: Integer);
  begin
    mydataset2.active := False;
    mydataset2.ParamByName('pk_progressivo').AsInteger := key_ricerca;
    mydataset2.active := True;
  end;

begin
  FiltroDati(key_ricerca);
  result := CloneData(mydataset2);
end;

function C_TeeGrid_Class.tgrid_expander(mytgrid: tteegrid;
  mydataset1_in: TclientDataSet; mydataset2_in: TclientDataSet;
  open_expander: boolean; footer_calc: boolean): tteegrid;
begin
  mydataset1_tmp := mydataset1_in;
  mydataset2_tmp := mydataset2_in;

  // Create "Expander"
  Expander := mytgrid.grid.Current.NewExpander;

  // Setup event
  Expander.OnGetData := GetMyDati;

  // We don't know in advance if a row can be expanded or not, so set Always
  // Expander.AlwaysExpand := True;

  // Set to first Column
  mytgrid.Columns[0].Render := Expander;

  // Optional:
  if footer_calc = True then
    mytgrid.grid.Current.OnNewDetail := DetailNewGroup;

  if not open_expander then
  Begin
    mytgrid.grid.Current.ShowHideAllDetail(0, False);
    Open := False;
  End
  else
  Begin
    mytgrid.grid.Current.ShowHideAllDetail(0, True);
    Open := True;
  End;

  result := mytgrid;
end;

constructor C_TeeGrid_Class.Create;
begin
  //
end;

end.
Attachments
field_property_expander.png
persistent field property visible
field_property_expander.png (133.49 KiB) Viewed 26547 times

Marc
Site Admin
Site Admin
Posts: 1272
Joined: Thu Oct 16, 2003 4:00 am
Location: Girona
Contact:

Re: clientdataset persistent fields property

Post by Marc » Mon Jul 08, 2024 3:33 pm

Hello,

We'll run some checks for suggestions.

Regards,
Marc Meumann
Steema Support

Marc
Site Admin
Site Admin
Posts: 1272
Joined: Thu Oct 16, 2003 4:00 am
Location: Girona
Contact:

Re: clientdataset persistent fields property

Post by Marc » Mon Jul 08, 2024 5:05 pm

Hello,

The refreshing of the grid content should be done by modifying the source, as you observed in your earlier post. In addition to that your could modify the columns (hiding them) in relation to any particular fields that you may not wish to include at any time.

eg.

Code: Select all

  TeeGrid1.Columns.Items[3].Visible := not TeeGrid1.Columns.Items[3].Visible;
  TeeGrid1.Columns.Items[3].Header.Text := 'my col header text';
The best example, I think, that covers the use of expander is this one:

https://github.com/Steema/TeeGrid-VCL-F ... il_FireDAC

It is likely that you've seen it already. It includes methods to show/hide the expander and to implement it by code. Have you seen that code?

I'm sure this answer doesn't go into the detail you're looking for so please let us know what it's missing, I haven't been able to pick out all of the details from your code sample.

With thanks.
Regards,
Marc
Steema Support

rbarone
Newbie
Newbie
Posts: 26
Joined: Thu May 18, 2023 12:00 am

Re: clientdataset persistent fields property

Post by rbarone » Tue Jul 09, 2024 8:43 am

Hi Marc
Thank you for your always prompt response

I used all the code you provided and improved it
I also solved the problems I reported to you and which I will try to explain better here
If anything you could create a small demo or a note for those who use your wonderful component whose wide possibilities I appreciate every day
The underlying issue is managing the runtime dataset that powers the expander
during the clone phase via the SaveToStream / LoadFromStream cycle the resulting dataset loses all the properties set in the original clientdataset
Example
ClientDataSet: My_dataset_input_for_clone
Persistent field: field_1, field_2,
Sets the object inspector properties
1) Field_1.visible = False
2) Field_1.displaylabel = 'field_1'
3) Field_1.displaywith = 30
4) Field_2.visible = True
5) Field_2.displaylabel = 'My_name_for_label_header' (modify from field_2)
6) Field_2.displaywith = 10 (change from 30)

the result is that
1 = true
5 = field_2
6=30
in practice it loses these properties
the solution is that when I exit the loadfromstream code I make the settings I need but this is inconvenient, very inconvenient.

Sorry for my english
Ciao
Raffaele

Marc
Site Admin
Site Admin
Posts: 1272
Joined: Thu Oct 16, 2003 4:00 am
Location: Girona
Contact:

Re: clientdataset persistent fields property

Post by Marc » Mon Jul 15, 2024 8:13 am

Hello Raffaele,

We're taking a look to see what improvements can be made. Thanks for the detailed information.

Regards,
Marc
Steema Support

Post Reply