Page 1 sur 1

[R] Supprimer des entrées d'une listview avec checkbox

Posté : mar. 06 mai 2014 22:11
par franco
Bonjour ;)

Je suis en train de coder un outil qui me liste les dossiers vides à partir d'un chemin donné.
Cette partie fonctionne.

J'affiche donc le résultat dans une listview avec checkbox (case à cocher). J'affiche aussi résultat par résultat dans une barre d'état. A la fin dans la barre d'état, j'affiche le nombre de dossiers vides.
Cette partie fonctionne.

Donc, je coche les items, donc des dossiers vides.
Je décide donc de les supprimer, en actualisation le nombre de dossiers vides dans la barre d'état.
==> C'est cette partie qui beugue.

En effet, si j'en coche plusieurs et que je choisis de les supprimer, plusieurs sont supprimés mais pas la totalité.

Exemple :
Je trouve 22 dossiers vides.
J'en coches 12 dossiers et je choisis de les supprimer : seuls 6 sont supprimés.
Le reste reste coché...


Etant donné que je supprime l'entrée dans la listview, les entrées des dossiers non supprimés ne sont pas effacés.


Voici le code :
► Afficher le textecode
Pouvez-vous m'aider ?
Merci ;)

@plusche

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mar. 06 mai 2014 22:47
par jguinch
Quand tu supprimes un item de la listview, les index se décalent :
Si tu as ça au départ :
- [x] c:\tmp\folder1 : Index 0
- [x] c:\tmp\folder2 : Index 1
- [x] c:\tmp\folder3 : Index 2

Tu te retrouves avec ça dès la suppression du premier dossier :
- [x] c:\tmp\folder2 : Index 0
- [x] c:\tmp\folder3 : Index 1


Donc ta boucle saute un item à chaque fois.

Ce que tu peux faire, c'est soit décrément de $i de 1 à chaque suppression, soit refaire ta boucle autrement... :(

Code : Tout sélectionner

If Not FileExists(_GUICtrlListView_GetItemTextString($ListDesktopLV, $i - 1)) Then
  _GUICtrlListView_DeleteItem($ListDesktopLV, $i - 1)
  $i -= 1
EndIf

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mar. 06 mai 2014 23:14
par mikell
Démonstration :mrgreen:
Lance ce script et coche les 3 ou 4 derniers
► Afficher le texte
C'est la bonne vieille blague de _ArrayDelete ...
Je suis sûr que tu vas trouver la seule ligne à modifier :wink:

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mer. 07 mai 2014 12:03
par franco
Salut ;)

Et merci pour l'aide apportée :D

« Je suis sûr que tu vas trouver la seule ligne à modifier »
En fait, j'ai juste rajouté une ligne grâce aux indications donné par toi-même et par jguinch.

Par rapport au fait du décalage des index et la décrémentation (je ne sais pas si je l'ai bien écrit :P )


Voici ce que j'ai comme code pour le bouton DelThisDir

Code : Tout sélectionner

Case $DelThisDir
            For $i = 1 To _GUICtrlListView_GetItemCount($ListDesktopLV)
                Sleep(10)
                If _GUICtrlListView_GetItemChecked($ListDesktopLV, $i - 1) Then
                    DirRemove(_GUICtrlListView_GetItemTextString($ListDesktopLV, $i - 1))
                    If Not FileExists(_GUICtrlListView_GetItemTextString($ListDesktopLV, $i - 1)) Then _GUICtrlListView_DeleteItem($ListDesktopLV, $i - 1)
                EndIf
            Next
            _GUICtrlStatusBar_SetText($hStatus, "dossiers vides : " & _GUICtrlListView_GetItemCount($ListDesktopLV))
Je rajoute donc la décrémentation, c'est à dire $i -= 1

Code : Tout sélectionner

        Case $DelThisDir
            For $i = 1 To _GUICtrlListView_GetItemCount($ListDesktopLV)
                Sleep(10)
                If _GUICtrlListView_GetItemChecked($ListDesktopLV, $i - 1) Then
                    DirRemove(_GUICtrlListView_GetItemTextString($ListDesktopLV, $i - 1))
                    If Not FileExists(_GUICtrlListView_GetItemTextString($ListDesktopLV, $i - 1)) Then _GUICtrlListView_DeleteItem($ListDesktopLV, $i - 1)
                    [b][u]$i -= 1[/u][/b]
                EndIf
            Next
            _GUICtrlStatusBar_SetText($hStatus, "dossiers vides : " & _GUICtrlListView_GetItemCount($ListDesktopLV))
Cela fonctionne.

Mais vu que tu as parlé de "modification de ligne", peut-être que j'ai tort, dans le sens que l'ajout de cette ligne n'était pas nécessaire.

Quoiqu'il en soit, voici le code complet, si ça peut servir à d'autres.
► Afficher le textecode
@+ et merci :D
Je passe en résolu.

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mer. 07 mai 2014 14:05
par TommyDDR
Une chose à savoir sur les boucles for (en AutoIt, en java par exemple, ça n'est pas le même fonctionnement -> à investiguer) :

Code : Tout sélectionner

For $i = 0 To XXX
XXX ne sera calculé UNE SEULE ET UNIQUE FOIS à l'entrée de la boucle, donc votre

Code : Tout sélectionner

_GUICtrlListView_GetItemCount($ListDesktopLV)
ne sera pas recalculé entre chaque tour de boucle.

C'est pour ça qu'en général, lorsque l'on veut supprimer un élément se situant dans "l'objet" où l'on itère, il est préférable de le faire en commençant par la fin.

Il est aussi fortement déconseillé de modifier la variable de la boucle For (ici : $i), si vous avez besoin de modifier $i, c'est que vous n'avez pas choisi la bonne boucle. Évitez les $i -= 1, votre code n'en sera que meilleur ;)

Code : Tout sélectionner

For $i = _GUICtrlListView_GetItemCount($ListDesktopLV) To 1 Step -1

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mer. 07 mai 2014 16:14
par jguinch
@TommyDDR : je me disais aussi que c'était pas très propre le truc que j'avais proposé... :?

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mer. 07 mai 2014 16:55
par mikell
TommyDDR a écrit :lorsque l'on veut supprimer un élément se situant dans "l'objet" où l'on itère, il est préférable de le faire en commençant par la fin.

Code : Tout sélectionner

For $i = _GUICtrlListView_GetItemCount($ListDesktopLV) To 1 Step -1
Ben oui c'était ça la ligne à modifier :wink:

Le cas d'école c'est _ArrayDelete, comme par exemple dans ce code si on veut éliminer les index impairs :
► Afficher le texte

Re: [..] Supprimer des entrées d'une listview avec checkbox

Posté : mer. 07 mai 2014 17:02
par franco
Salut à tous :D

Merci pour vos éclaircissements. 8)

Je vais pouvoir l'améliorer.
Encore merci. ;)

@+