Voir le flux RSS

Blog de Serge Girard (aka SergioMaster)

[FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView

Noter ce billet
par , 15/10/2019 à 17h36 (138 Affichages)
La curiosité est-elle un défaut ? En rédigeant mes diverses interventions sur les TListViews et, en particulier, en liant ces dernières à une source de données la propriété FillBreakGroups du lien (un TLinkFillControlToField) me titillait l'esprit. Je me suis donc penché sur ce point particulier que je n'avais, jusqu'à présent jamais utilisé.

Pour tester ceci je suis parti d'un ensemble de données simple, récupéré à partir d'un fichier fourni dans le répertoire <Embarcadero>\Samples\Data\customers.xml, que j'ai quelque peu condensé pour ne garder que les colonnes CustNo, Country, Company et mis dans un fichier mémoire TFDMemtable.

Après établissement du lien entre mon TListView (apparence ListItemRightDetail) et ma source de données en utilisant le concepteur visuel de liaisons, je suis retourné sur les propriétés du lien ainsi créé pour indiquer le nom de la colonne qui allait être utilisé pour contröler les groupes : propriété FillBreakFieldName. Ensuite, en cliquant sur bouton points de suspension (...) de la propriété FillBreakGroups j'ai ajouté quelques groupes.

Nom : DesignGroupes.PNG
Affichages : 22
Taille : 46,2 Ko

Vous pouvez constater, dès le design, la prise en compte de ces éléments.

Bien sûr, la saisie des groupes étant plutôt rédhibitoire je me suis ensuite posé la question : Est-il possible, à l'exécution, de créer mes groupes en fonction des données ?

J'ai donc ajouté un bouton qui exécutera le processus, découper l'ensemble des données en centaines.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TmainForm.btngrp100Click(Sender: TObject);
var n : integer;
    aGroup : TFillBreakGroupItem;
// min et max qu'il faudrait récupérer via une requête
const min = 1221;
      max = 9841;
begin
LinkListGroups.Active:=false;
LinkListGroups.FillBreakGroups.Clear;
// Créations des divers groupes
for n := (min div 100) to (max div 100) do
  begin
   aGroup := LinkListGroups.FillBreakGroups.AddItem;
   aGroup.MaxValue:=(n*100+99).ToString;
   aGroup.MinValue:=(n*100).ToString;
   aGroup.DisplayText:=format('Centaine %d',[n*100]);
  end;
LinkListGroups.Active:=True;
end;
MinValue et MaxValue attendent des chaines de caractères pas des entiers

Nom : RunGroupes100.PNG
Affichages : 20
Taille : 16,0 Ko

Deux autres questions se sont alors posées :
  1. La récupération des valeurs minimum et maximum, plutôt que l'utilisation de constantes;
  2. Le changement dans l'ordre de la source de données pour la création d'une liste groupée différemment.


Point 1
Table en mémoire oblige, pour obtenir les valeurs minimale et maximale de ma source de données il me faut passer par du SQL Local. Pour cela j'ajoute un TFDConnexion (driver SQLite), un TFDLocalSQL et un TFDQuery . Enfin, je renseigne la propriété LocalSQL de ma table mémoire.

Nom : design.PNG
Affichages : 20
Taille : 17,0 Ko

Il ne reste alors qu'à modifier le code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
procedure TmainForm.btngrp100Click(Sender: TObject);
var n : integer;
    aGroup : TFillBreakGroupItem;
    NoMin, NoMax : Integer;
begin
LinkListGroups.Active:=false;
LinkListGroups.FillBreakGroups.Clear;
{---}
fdCustomers.DisableControls;  // éviter le scintillement
fdCustomers.IndexName:='DEFAULT_ORDER';  // s'assurer de l'ordre (ascendant sur la colonne custno)
FDLocalSQL1.Active:=True; // activer le SQL Local
fdquery1.SQl.text:='SELECT MIN(CUSTNO) AS CMIN,MAX(CUSTNO) AS CMAX FROM fdCustomers';
fdQuery1.Active:=True;
noMin:=fdQuery1.FieldByName('CMin').asInteger div 100;
noMax:=fdQuery1.FieldByName('CMax').asInteger div 100;
FDLocalSQL1.Active:=False;
// Créations des divers groupes
for n := noMin to noMax do{--}
  begin
   aGroup := LinkListGroups.FillBreakGroups.AddItem;
   aGroup.MaxValue:=(n*100+99).ToString;
   aGroup.MinValue:=(n*100).ToString;
   aGroup.DisplayText:=format('Centaine %d',[n*100]);
  end;
LinkListGroups.FillBreakFieldName:='CustNo'; // s'assure que c'est bien que c'est sur la colonne Custno que s'opére la rupture
LinkListGroups.Active:=True;
fdCustomers.EnableControls;  // réactive les contrôles
end;
Point 2
Jusqu'à présent la table était ordonnée (obligatoire) selon le numéro de client (custno), lors des définitions de la table en mémoire, j'avais défini un second index basé sur un ordre alphabétique des colonnes Country et Company. Bien évidemment il faut changer les groupes mais aussi le critère de regroupement .

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
procedure TmainForm.btnPaysNomClick(Sender: TObject);
var aGroup : TFillBreakGroupItem;
begin
fdCustomers.DisableControls;
fdCustomers.IndexName:='PAYS';  // Changement d'ordre
FDLocalSQL1.Active:=True;  
// Récupération des différents pays 
fdquery1.SQl.text:='SELECT DISTINCT COUNTRY FROM fdCustomers ORDER BY COUNTRY';
fdQuery1.Active:=True;

LinkListGroups.Active:=false;
// Création des groupes
LinkListGroups.FillBreakGroups.Clear;
while Not FDQuery1.EOF do
  begin
   aGroup := LinkListGroups.FillBreakGroups.AddItem;
   aGroup.MaxValue:=FDQuery1.FieldByName('COUNTRY').asString;
   aGroup.MinValue:=FDQuery1.FieldByName('COUNTRY').asString;
   aGroup.DisplayText:=FDQuery1.FieldByName('COUNTRY').asString;
   FDQuery1.Next;
  end;
FDLocalSQL1.Active:=False;
LinkListGroups.FillBreakFieldName:='Country';  // Indication du critère de regroupement 
LinkListGroups.Active:=True;
fdCustomers.EnableControls;
end;
Plus une feuille de style pour donner un peu de "peps" au résultat et voilà le résultat

Nom : Groupe100.PNG
Affichages : 20
Taille : 17,2 Ko Nom : Pays.PNG
Affichages : 20
Taille : 16,9 Ko

Voilà ma curiosité satisfaite, j'espère qu'il en sera de même pour vous. Une entrée de plus à mon carnet de plongée qui s'étoffe tant que rien que dans cette petite mer des listes (TListBox, TListView) il y a matière à un livre. Qui sait, peut-être un jour m'y lancerai-je !

En pièce jointe mon petit projet
Miniatures attachées Fichiers attachés

Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Viadeo Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Twitter Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Google Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Facebook Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Digg Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Delicious Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog MySpace Envoyer le billet « [FMX] Utilisation de FillBreakGroups de la liaison des données à un TListView » dans le blog Yahoo

Mis à jour 28/10/2019 à 09h07 par SergioMaster

Tags: fmx, groupes, listview
Catégories
Programmation , Delphi , FMX

Commentaires