shell13010
Messages postés73Date d'inscriptionmardi 3 avril 2007StatutMembreDernière intervention12 mai 2013
-
9 avril 2009 à 19:36
shell13010
Messages postés73Date d'inscriptionmardi 3 avril 2007StatutMembreDernière intervention12 mai 2013
-
12 avril 2009 à 00:53
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.
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 10 avril 2009 à 07:44
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.
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202237 10 avril 2009 à 15:07
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.
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 21:29
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.
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 10 avril 2009 à 14:46
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 ...
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 10 avril 2009 à 15:48
@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
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202237 10 avril 2009 à 18:20
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%
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 10 avril 2009 à 21:56
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 ...
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 10 avril 2009 à 22:06
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...
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202237 11 avril 2009 à 01:43
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.
shell13010
Messages postés73Date d'inscriptionmardi 3 avril 2007StatutMembreDernière intervention12 mai 20131 12 avril 2009 à 00:53
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;