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

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
franco
Niveau 7
Niveau 7
Messages : 343
Enregistré le : lun. 03 oct. 2011 22:37
Localisation : Liévin
Status : Hors ligne

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

#1

Message 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
Modifié en dernier par franco le jeu. 08 mai 2014 19:48, modifié 1 fois.
L'entraide, c'est mon dada ;)
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2515
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

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

#2

Message 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
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

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

#3

Message 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:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
franco
Niveau 7
Niveau 7
Messages : 343
Enregistré le : lun. 03 oct. 2011 22:37
Localisation : Liévin
Status : Hors ligne

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

#4

Message 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.
L'entraide, c'est mon dada ;)
Avatar du membre
TommyDDR
Modérateur
Modérateur
Messages : 2128
Enregistré le : mar. 22 juil. 2008 21:55
Localisation : Nantes
Status : Hors ligne

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

#5

Message 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
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2515
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

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

#6

Message par jguinch »

@TommyDDR : je me disais aussi que c'était pas très propre le truc que j'avais proposé... :?
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

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

#7

Message 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
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
franco
Niveau 7
Niveau 7
Messages : 343
Enregistré le : lun. 03 oct. 2011 22:37
Localisation : Liévin
Status : Hors ligne

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

#8

Message par franco »

Salut à tous :D

Merci pour vos éclaircissements. 8)

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

@+
L'entraide, c'est mon dada ;)
Répondre