IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Filtre sur une liste box


Sujet :

Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 137
    Points
    137
    Par défaut Filtre sur une liste box
    bonjour,

    J'aimerai créer un filtre sur une liste box. Je m'explique
    Imaginons que ma liste box contient les lignes suivantes:
    Mr Goss N.
    Mr Dupond O.
    Mr Dupont J.
    Mr Duval R.
    Mr Laport N.
    J'aimerai que si j'ecris dans une text box "Mr Du*" que ma liste box ne contienne plus que:
    Mr Dupond O.
    Mr Dupont J.
    Mr Duval R.
    Je ne sais pas du tout comment faire sanchant qu'il faut que se soit assez optimisé puisque ma liste box contient plusieures dixènes de millier de champs .
    Est ce que la class TlistBox contient une fonction qui permet de faire ca ?

    Merci d'ance pour votre aide.

    Dereck

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 137
    Points
    137
    Par défaut
    J'ai flané sur le forum et j'ai trouvé un truc qui a l'aire de correspondre à ce que je cherche: "DBListBox"

    Dans le form, ils disent:
    il faut relier la DBListBox a un Data Source qui
    lui même est relié a un Querry.
    Ca l'aire vraimant bien. Seul souci, c'est que je ne m'y connait tres moyennement en base de donnée.
    Il en excite plusieur type. la quelle me conseillez ?

  3. #3
    Fxg
    Fxg est déconnecté
    Membre éclairé
    Homme Profil pro
    ingénieur financier
    Inscrit en
    Septembre 2003
    Messages
    510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur financier

    Informations forums :
    Inscription : Septembre 2003
    Messages : 510
    Points : 837
    Points
    837
    Par défaut
    Un début de réflexion Ici avec les différents tuto du site

  4. #4
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Suggestion pour une autre approche : Au lieu de stocker la liste complète des noms dans une ListBox je la plaçerais plutôt dans une TStringList et après avoir écrit dans une text box ou un TEdit "Mr Du" je parcours(*) la StringList pour y rechercher toutes les lignes qui commencent par "Mr Du" pour ne recopier que celles-ci vers la ListBox d'affichage.

    (*) : avant de parcourir la StringList on "clear" bien entendu le contenu de la ListBox pouvant résulter d'une recherche précédente.

    En dissociant ainsi le lieu de "stockage" du lieu d"affichage" on se simplifie la vie, et puisque l'objectif est de n'afficher que les seuls noms qui répondent au critère de recherche, inutile donc d'afficher dans la ListBox les plusieures dixaines de milliers de lignes.

    A l'inverse si tu stockes les plusieures dixaines de milliers de lignes dans la ListBox à chaque recherche il faut de toutes façons sauver (au moins temporairement) tout son contenu ailleurs pendant que la ListBox n'affiche que le résultat extrait par la recherche ... donc autant stocker la liste complète en permance dans une StringList ou un truc équivalent ça évitera d'avoir à gérer la sauvegarde temporaire.

    A+.

  5. #5
    Membre actif

    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2009
    Messages : 128
    Points : 203
    Points
    203
    Par défaut Filtre avec masque
    Bonjour Gilbert, et bonjour aux membres de Dev.net

    Il se trouve qu'avec mon pote Columbo sur un autre forum, nous avons travaillé sur cette fonction de filtre. Il s'agit de comparer une string à un filtre qui utilise les caractères génériques '*' et '?'... J'espère que cela fera ton bonheur. Si tu veux me contacter pour plus amples détails, tu connais la boîte... Mais cela peut intéresser d'autres.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    function Filtre(Mot,Masque: string) : boolean; register
        var R: array of Integer;
            Bon: boolean;
            Total, Etoiles : integer;       //Paramètres de comparaisons
            i,n,Rn : integer;               //compteurs locaux
            Sesi,Sedi,Secx,Sedx,
            SSesi,SSedi,SSecx : integer;    //Save registres
        function Columbo: boolean;
        asm
             jmp     @PeterFalk
        @Sigma: {ebx pointe R}   {routine de calcul des entiers de 1 à eax dans R[]}
             cmp     eax,0
             je      @finSigma
             mov     Secx,ecx             //save ecx
             mov     ecx,eax              //ecx := n
             shl     ecx,2                //ecx:=n*4
             xor     eax,eax              //eax compteur retour
             @calcul:
             add     eax,dword ptr[ebx]+ecx //sommation
             sub     ecx,4                  //terminé ?
             jnz     @calcul
             mov     ecx,Secx             //replace ecx
             @finSigma:
             ret
        @Comparer:   {algorithme de comparaison - ebx pointe R}
             mov    Sesi,esi                  //save pointeurs
             mov    Sedi,edi
             mov    Secx,ecx
             mov    Sedx,edx
             mov    esi,Mot                   //esi pointe Mot
             mov    eax,DWord ptr[esi-4]     //génère Temp aussi longue que Mot
             call   System.@NewAnsiString
             mov    edi,eax                  //edi pointe Temp
             mov    edx,Masque               //edx pointe masque
             xor    ecx,ecx                  //ecx compteur char de Temp et Mot
             mov    i,ecx                    //i=0 compteur Mask
             mov    n,ecx                    //n=0 compteur R
             @Boucle:
             mov    eax,i
             mov    al,Byte ptr[edx]+eax    //Mask[i] en al
             @interro:
             cmp    al,$3F                  //'?' ?
             jne    @etoile                 //non
             mov    al,Byte ptr[esi+ecx]    //oui
             mov    Byte ptr[edi+ecx],al    //Temp:=Temp+Mot[j]
             inc    ecx
             jmp    @FinBoucle
             @etoile:
             cmp    al,$2A                  //'*' ?
             jne    @autre                  //non
             add    n,type integer          //oui
             mov    eax,n
             mov    eax,DWord ptr[ebx+eax]  //Rn:= R[n]
             cmp    eax,0
             je     @FinBoucle
             mov    Rn,eax
             @Betoile:
             mov    al,Byte ptr[esi+ecx]
             mov    Byte ptr[edi+ecx],al
             inc    ecx
             dec    Rn
             jnz    @BEtoile
             jmp    @FinBoucle
             @autre:
             mov    Byte ptr[edi+ecx],al
             inc    ecx
             @FinBoucle:                   //Vérifie que Temp = Début du Mot}
             mov    DWord ptr[edi-4],ecx   //nouvelle longueur Temp
             mov    SSedi,edi              //sauver pointeurs
             mov    SSesi,esi
             mov    SSecx,ecx              //Length(Temp) en ecx
             xor    eax,eax                //result:=false;
             repe   cmpsb
             setz   al
             mov    ecx,SSecx              //replacer les pointeurs
             mov    edi,SSedi
             mov    esi,SSesi
             cmp    eax,0
             je     @finIso
             inc    i
             mov    eax,DWord ptr[edx-4]
             cmp    i,eax
             jne    @Boucle
             @finiso:                       //compare Temp et Mot}
             xor    eax,eax                 //result := false
             mov    ecx,DWord ptr[edi-4]    //ecx =length(Temp)
             cmp    ecx,DWord ptr[esi-4]    //length(Temp)=length(Mot) ?
             jne    @fin                    //non
             repe   cmpsb                   //oui : comparaison byte à byte
             setz   al
             @fin:
             mov    DWord ptr[edi-4],0      //Temp:=''
             mov    edx,Sedx
             mov    ecx,Secx
             mov    edi,Sedi
             mov    esi,Sesi
             ret
        @PeterFalk: {algorithme de traitement du tableau R[]}
             mov    ebx,[R]               //ebx pointe R[]
             cmp    Etoiles,0             //Etoiles=0 ?
             jne    @TotalPositif         //non
             call   @Comparer              //oui
             jmp    @finAlgo              //retour dépendant
             @TotalPositif:
                 cmp    Total,-1
                 jle    @finfalse
                 xor    ecx,ecx             //k:=0
                 mov    DWord ptr[ebx],ecx  //R[0]:=0
                 @repeat:
                    inc    ecx                 //inc(k)
                    cmp    Etoiles,ecx         //k=Etoiles ?
                    jne    @else               //non
                    mov    edx,Total           //oui
                    mov    eax,ecx             //eax:=k-1
                    dec    eax
                    call   @Sigma
                    sub    edx,eax             //edx:=Total-Sigma(k-1)
                    mov    DWord ptr[ebx]+ecx*4,edx  //R[k]:=Total-Sigma(k-1)
                    call   @Comparer
                    cmp    eax,0               //Comparer=false ?
                    jne    @finAlgo            //true=>fin filtre true
                    @while:  {false => while (k>0) and (Sigma(k)>=Total) do dec(k)}
                        cmp    ecx,1
                        jl     @SuiteWhile
                        mov    eax,ecx
                        call   @sigma           //eax:=Sigma(k)
                        cmp    eax,Total
                        jl     @SuiteWhile
                        dec    ecx             //do dec(k)
                        jmp    @while
                    @SuiteWhile:
                    inc    DWord ptr[ebx]+ecx*4   //inc(R[k]);
                    jmp    @until
                    @else:
                    mov   DWord ptr[ebx]+ecx*4,0  // R[k]:=0;
                 @until:
                 cmp   DWord ptr[ebx],0      //(R[0]=0) ?
                 je    @repeat               //oui
             @finfalse:
             mov   eax,0                 //retour false
             @finAlgo:
        end;
    begin
      asm {Vérification des strings - Calculs de Etoiles et Total}
             @init:
             mov    edx,Masque
             cmp    edx,0                    //Masque='' ?
             jne    @SInit1                  //non
             @ExitFalse:
             mov    n,0                      //sortie false
             jmp    @FinInit
             @SInit1:
             mov    eax,Mot
             cmp    eax,0                     //Mot='' ?
             jne    @SInit2                   //non => suite algo
             xor    ecx,ecx                   //i:=0
             @BVerif:                         //boucle de vérification Masque
             cmp    DWord ptr[edx]-4,ecx      // i = length(Masque) ?
             je     @ExitTrue                 // oui, donc que des '*'
             cmp    Byte ptr[edx]+ecx,$2a     //Masque[i]='*'?
             jne    @ExitFalse                //non => retour false
             inc    ecx                       //inc(i)
             jmp    @BVerif
             @ExitTrue:
             mov    n,1                       //Sortie true
             jmp    @FinInit
             @SInit2:
             mov    ecx,DWord Ptr[eax]-4      //ecx = length(Mot)
             mov    eax,DWord ptr[edx]-4      //eax = length(Masque)
             mov    Total,ecx
             sub    Total,eax
             xor    eax,eax                   //compteur occurences en eax
             @Compte:
             cmp    byte ptr[edx],$2a
             jne    @suite
             inc    eax
             @suite:
             inc    edx
             dec    ecx
             jnz    @Compte
             mov    Etoiles,eax
             add    Total,eax
             mov    n,2
             @finInit:
      end;
      case n of
          0: Result:=false;
          1: Result:=true;
          2: begin
             Setlength(R,Etoiles+1);
             Result:=Columbo;
             SetLength(R,0);
             end;
      end;
    end;
     
    procedure TFormMain.Button1Click(Sender: TObject);
    var Masque,Mot,mess : string; i: integer;
    begin
      Masque:= '*s carrées'; Mot:='Parties carrées';
      Mess:='Masque : '+Masque+#10+'Mot       : '+Mot+#10#10;
      if Filtre(Mot,Masque) then ShowMessage(Mess+'Mot conforme au masque')
                            else ShowMessage(Mess+'Mot non conforme au masque');
    end;
    Le noyau asm est une implémentation d'un code génial bâti en Delphi par Columbo. (C'est pour cela que l'on trouve le label PeterFalk... )

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 137
    Points
    137
    Par défaut
    Merci pour toutes vos reponse.

    Et pour ce qui est de relier une DBListBox a un Data Source quelqu'un a deja testé?

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    A Rekin85 : Salut René. Tu dis :
    J'espère que cela fera ton bonheur. ... Mais cela peut intéresser d'autres
    ... merci beaucoup, pour ma part je me suis contenté de mémoriser le lien direct vers cette discussion pour le cas où j'aurais besoin de ton code, et j'espère surtout que le code intéressera Dereck07

    Cordialement, et à +.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 137
    Points
    137
    Par défaut
    Bonjour,

    J'ai testé le code en assembleur. Il filtre bien mais voulant utiliser le programme que je fait sur mon lieu de travail je trouvais un peu dangereux d'utiliser du code que je ne metrise pas. Bien que vous m'avait l'aire tous trés honnète rien ne me garanti qu'un virus ne se cache pas dans le code assembleur.

    J'ai donc recoder la fonction filtre en dephi:
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    function Filtre(mot,filtre: string) : boolean;
    var
    Pm,Pf:integer;
    c:char;
    fini, etoile:integer;
    r:boolean;
    begin
    Pm:=1;
    Pf:=1;
    fini:=0;
    r:=true;
    while((Pf<Length(filtre)+1)and(Pm<Length(mot)+1)and r)do
    begin
     if ((Pf<Length(filtre)+1)and(Pm<Length(mot)+1)) then
        begin
          if ((filtre[Pf]<>'*')and(filtre[Pf]<>'?')and(filtre[Pf]<>mot[Pm])) then r:=false;
        end;
      while (((filtre[Pf]='*')or(filtre[Pf]='?'))and(Pf<Length(filtre)+1)and(Pm<Length(mot)+1)and r) do
      begin
        if filtre[Pf]='?' then Pm:=Pm+1;
        if filtre[Pf]='*' then etoile:=1;
        Pf:=Pf+1;
      end;
      if ((etoile = 1)and (r)) then
        begin
          while ((mot[Pm]<>filtre[Pf])and(Pm<Length(mot)+1))do
            begin
              Pm:=Pm+1;
            end;
          etoile:=0;
        end;
      while((filtre[Pf]=mot[Pm])and(Pf<Length(filtre)+1)and(Pm<Length(mot)+1)and r) do
        begin
          Pm:=Pm+1;
          Pf:=Pf+1;
        end;
    end;
    result:=false;
    while filtre[Pf]='*' do
      begin
        Pf:=Pf+1;
      end;
    if ((Pf=Length(filtre)+1)and(Pm=Length(mot)+1)and r) then
      begin
        result:=true;
      end;
    end;
    Merci a tous pour votre aide ;-)

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 137
    Points
    137
    Par défaut
    Je viens de finir le tout.
    Je donne l'ensemble au cas ou ca intèresse quelqu'un:

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    function Filtre_(mot:string;filtre: string) : boolean;
    var
    Pm,Pf:integer;
    etoile:integer;
    r:boolean;
    begin
    Pm:=1;
    Pf:=1;
    etoile:=0;
    r:=true;
    while((Pf<Length(filtre)+1)and(Pm<Length(mot)+1)and r)do
    begin
     if ((Pf<Length(filtre)+1)and(Pm<Length(mot)+1)) then
        begin
          if ((filtre[Pf]<>'*')and(filtre[Pf]<>'?')and(filtre[Pf]<>mot[Pm])) then r:=false;
        end;
      while (((filtre[Pf]='*')or(filtre[Pf]='?'))and(Pf<Length(filtre)+1)and(Pm<Length(mot)+1)and r) do
      begin
        if filtre[Pf]='?' then Pm:=Pm+1;
        if filtre[Pf]='*' then etoile:=1;
        Pf:=Pf+1;
      end;
      if ((etoile = 1)and (r)) then
        begin
          while ((mot[Pm]<>filtre[Pf])and(Pm<Length(mot)+1))do
            begin
              Pm:=Pm+1;
            end;
          etoile:=0;
        end;
      while((filtre[Pf]=mot[Pm])and(Pf<Length(filtre)+1)and(Pm<Length(mot)+1)and r) do
        begin
          Pm:=Pm+1;
          Pf:=Pf+1;
        end;
    end;
    result:=false;
    while filtre[Pf]='*' do
      begin
        Pf:=Pf+1;
      end;
    if ((Pf=Length(filtre)+1)and(Pm=Length(mot)+1)and r) then
      begin
        result:=true;
      end;
    end;
     
     
     
     
     
    function FiltreListe(L:TstringList;filtre:string):TstringList;
    var
    ListRetour:TstringList;
    i:integer;
    s,s2:string;
    b:boolean;
    begin
    ListRetour:=TstringList.create;
    i:=0;
    Form1.ProgressBar2.Position:=0;
    while(i< L.Count) do
    begin
      s:=Form1.Edit1.Text;
      s2:=L.Strings[i];
      if(Filtre_(L.Strings[i],Form1.Edit1.Text)) then
      begin
        ListRetour.Add(DataPrim.Strings[i]);
      end;
      Form1.ProgressBar2.Position:=trunc(100*i/DataPrim.Count);
      i:=i+1;
    end;
    result:=ListRetour;
    end;
    Utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Liste:TstringList;
    begin
    Liste:=TstringList.create();
    Liste.Add('Nom1');
    Liste.Add('Nom2');
    Liste.Add('Name');
    Liste.Add('Lala1');
     
    Listbox1.Items:=FiltreListe(Liste,Edit1.Text);
    end;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de l'affichage de deux colonnes filtrés dans une liste box
    Par Dr walid dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 09/06/2014, 02h35
  2. [Débutant] gestion d'un clic sur une liste box
    Par claireP23 dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 08/01/2007, 15h34
  3. [Débutant]Changer de page sur un séléction d'une liste box
    Par virgul dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 04/12/2006, 10h26
  4. Recherche sur 2 elements dans une liste box.
    Par molarisapa dans le forum Access
    Réponses: 2
    Dernier message: 29/05/2006, 18h43
  5. Filtre sur une liste de valeurs
    Par Death83 dans le forum Débuter
    Réponses: 3
    Dernier message: 07/05/2006, 00h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo