Listbox et savoir si il y a une items qui est vide alors supprime.. [Résolu]

Signaler
Messages postés
73
Date d'inscription
mardi 3 avril 2007
Statut
Membre
Dernière intervention
12 mai 2013
-
Messages postés
73
Date d'inscription
mardi 3 avril 2007
Statut
Membre
Dernière intervention
12 mai 2013
-
Bonsoir a tous,

J'aimerais savoir si dans un listbox il y a des items qui son vide alors on les supprimes... exemple

cooooo
      //ici c'est vide alors on supprime..
ooo
      //ici c'est vide alors on supprime..
ool.

auriez vous une idée?

merci d'avance.

15 réponses

Messages postés
2226
Date d'inscription
dimanche 5 octobre 2003
Statut
Modérateur
Dernière intervention
18 novembre 2010
13
salut

for i:= ListBox.Count-1 downto 0 do
  if ListBox.Items[i]='' then
    ListBox.Items.Delete(i);

a+
Messages postés
2226
Date d'inscription
dimanche 5 octobre 2003
Statut
Modérateur
Dernière intervention
18 novembre 2010
13
Ok alors je la fait dans le "bon" sens :

procedure TForm1.Button1Click(Sender: TObject);
var i, j, nb: integer;
begin
  nb:= ListBox1.Count-1;
  i:= 0;
  while i < nb do
  begin
    if ListBox1.Items[i]='' then
    begin
      ListBox1.Items.Delete(i);
      Dec(nb);
    end
    else
      Inc(i);
  end;
end;

On comprends surement mieux le problème de le faire comme ça.
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
30
parcourt la listbox à l'envers car quand on supprime un élément de la
liste avec Delete, tous les éléments <strike>"descendent"</strike> d'un rang



remonte d'un rang ...
si je supprime index 10, alors index 11, 12... remonte de 1 donc deviennent 10 et 11

la premiere solution de JulioDelphi est la bonne methode, ont pourrait y ajouter pour plus de performance :

ListBox1.Items.BeginUpdate;
try
  for I := ListBox1.Count-1 downto 0 do
    if ListBox1.Items[I] = EmptyStr then
      ListBox1.Items.Deletes(I);
finally
  ListBox1.Items.EndUpdate;
end;

cela empeche les appels inutiles a la methode OnChange de TListBox, pendant le traitement, les gains sont assé important et peuvent aller de plusieurs secondes a quelques minutes.

<hr size="2" width="100%" />
Messages postés
73
Date d'inscription
mardi 3 avril 2007
Statut
Membre
Dernière intervention
12 mai 2013

merci bien[../auteur/JULIODELPHI/174597.aspx JulioDelphi]  c'etais tout bete mais fallais le savoir

bonne fin de soirée..
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Ouais, je tiens à indiquer que JulioDelphi parcourt la listbox à l'envers car quand on supprime un élément de la liste avec Delete, tous les éléments "descendent" d'un rang, pour évider qu'il y ait un trou. Donc, dans ce sens, on s'adapte automatiquement au décalage. Alors que si l'on fait de 0 à ListBox.Count - 1, on accentuera le décalage, ce qui pose des problèmes.

Voilà ...

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Mais ta première solution est la meilleure ;)
Sinon tu peux le faire avec une boucle for..do aussi :

procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to ListBox1.Items.Count - 1 do
if ListBox1.Items[I] = '' then
begin
ListBox1.Items.Delete(I);
asm DEC I; end;
end;
end;

Tu utilises l'asm car Delphi veut pas que tu touche à la variable de contrôle de boucle ...

Cordialement, Bacterius !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Oui mais je voulais dire descendent vers le début de la liste ^^ mais je n'étais pas clair.

Cordialement, Bacterius !
Messages postés
2226
Date d'inscription
dimanche 5 octobre 2003
Statut
Modérateur
Dernière intervention
18 novembre 2010
13
@foxy : très bonne idée que je connaissais pas !
@bacterius : oui mais ASM quoi ... lol faut connaitre :] c'est presque de la triche ^^ mais tant que ça marche et que ça compile :p
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
30
oui c'est trés important de placer le beginupdate et endupdate, attention ce dernier utilise TOUJOURS un bloc try finally!

chaque appel a Add, Insert, Exchange, Delete, Move, Remove etc declanche l'evenement Change des objets liste (TStrings), evenement qui peut declancher a son tour le rafraichissement du dessins de l'objet sur la fiche et cela ralentit enormenent les traitements.
pour 1000 entrées et selon le traitement, on peu gagner ~50% du temps.
pour 10000 ~70%
pour 100000 ~90%
 

<hr size="2" width="100%" />
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
13
Salut,



Puisqu'on parle 'perfs' et qu'on fait la course, dans la rubrique coupage-de-cheveu-en-quatre je signale que :
 
if ListBox1.Items[I] = '' then...

est de 8 à 9 fois plus rapide que :

if ListBox1.Items[I] = EmptyStr then...
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Mais peut-être que EmptyStr a un avantage caché ? (genre il s'adapte automatiquement à une certaine variable d'environnement de l'OS) ? Je dis ça au hasard mais on sait jamais ...

Cordialement, Bacterius !
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
13
Ouais... P'têt bien...
J'ai pas trouvé bcp de tuyaux sur EmptyStr et ça m'étonnerait que f0xi utilise un truc qui ne lui permette pas d'avoir fini avant les autres...
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
8
Voilà c'est ce que je pensais aussi :)

Cordialement, Bacterius !
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
30
declaration de EmptyStr :

const
  EmptyStr = '';

mais il est vrai qu'il est peut etre plus performant d'utiliser :

S = ''
ou
S = #0
que
S = EmptyStr

tout depend des optim que fait le compilo, de D5 a D7, D2005 a D2009 les compilos font du plus ou moins bon travail.
Le compilateur de D2009 fait un excelent travail comparé a celui de D7 par exemple.

on pourait egalement utiliser :

Length(S) = 0

ce qui ne serait pas forcement plus rapide.

<hr size="2" width="100%" />
Messages postés
73
Date d'inscription
mardi 3 avril 2007
Statut
Membre
Dernière intervention
12 mai 2013

petite erreur dans le code de f0xy,biensur c'est juste une erreur de frappe

ListBox1.Items.BeginUpdate;
try
  for I := ListBox1.Count-1 downto 0 do
    if ListBox1.Items[I] = EmptyStr then
      ListBox1.Items.Delete(I);
finally
  ListBox1.Items.EndUpdate;
end;