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

VB 6 et antérieur Discussion :

[Runtime Error 381 sur VB6] Problème avec une boucle For et une liste


Sujet :

VB 6 et antérieur

  1. #1
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut [Runtime Error 381 sur VB6] Problème avec une boucle For et une liste
    Bonjour,

    Ça fait maintenant un bon bout de temps que je n'ai pas fait de Visual Basic, et j'ai décidé de faire un petit programme pour mon plaisir.


    Malgré la facilité du projet, je me retrouve quand même avec certaines erreurs, dont une où je ne suis pas capable de trouver une solution.

    L'erreur Runtime 381 : Invalid Property Array Index.
    Si j'ai bien compris, cette erreur est due au fait que je ne suis plus dans l'array avec ma boucle.

    Le problème, c'est que je ne comprends pas pourquoi. Voici mon bout de compte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Private Sub cmdRemove_Click()
        Dim i As Integer, strFiles As String
     
        For i = 0 To lstExe.ListCount - 1
            If (lstExe.Selected(i) = True) Then
                lstExe.RemoveItem (i)
                strFiles = strFiles & lstExe.List(i) & vbCrLf
            End If
        Next i
     
        If (Len(strFiles) > 0) Then MsgBox "The following file(s) has (have) been removed : " & vbCrLf & strFiles, vbOKOnly, "Removing Files"
    End Sub
    J'avais pensé que puisque j'efface un item dans ma boucle, le .ListCount diminue, ce qui fait que i devient trop grand.

    Je tiens à préciser que ça n'arrive pas lorsque je choisis seulement le dernier item de ma liste, ce qui renforce ma théorie.

    J'essaie toujours d'arranger ça le plus proprement possible pour éviter un code laid et illisible :p

    Merdi d'avance,

    Jihnn

  2. #2
    Expert éminent sénior


    Profil pro
    Inscrit en
    Juin 2003
    Messages
    14 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 14 008
    Points : 20 038
    Points
    20 038
    Par défaut
    Citation Envoyé par Jihnn Voir le message
    ....J'avais pensé que puisque j'efface un item dans ma boucle, le .ListCount diminue, ...
    cela à bien l'air d'être ton problème, en VB les limites d'une boucle FOR ne sont pas ré-évalués durant la boucle .. elles sont calculées à la première iteration .. puis conservés jusqu'à la fin de la boucle .. ainsi le fait que ton .ListCount diminue durant la "rotation" dans la boucle n'influence pas la fin de celle-ci.... dans ton cas un débordement...

  3. #3
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    Merci de cette réponse.

    Dans ce cas, quel est mon problème ? Sachant que si seulement le dernier item est sélectionné (et donc supprimé), aucune erreur ne se produit ?

    Edit: Pendant que j'y pense, la ligne qui produit l'erreur est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If (lstExe.Selected(i) = True) Then

  4. #4
    Membre expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Points : 3 696
    Points
    3 696
    Par défaut
    Et si tu faisais une boucle do while ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Sub cmdRemove_Click()
        Dim i As Integer, strFiles As String
        i= 0
        Do while i <=lstExe.ListCount - 1
            If (lstExe.Selected(i) = True) Then
                lstExe.RemoveItem (i)
                strFiles = strFiles & lstExe.List(i) & vbCrLf
            End If
            i = i+1
        loop 
     
        If (Len(strFiles) > 0) Then MsgBox "The following file(s) has (have) been removed : " & vbCrLf & strFiles, vbOKOnly, "Removing Files"
    End Sub
    En général, on ne demande de conseils que pour ne pas les suivre ou, si on les a suivis, reprocher à quelqu'un de les avoir donnés
    (ALEXANDRE DUMAS)

    N'hésitez pas à visiter ma page de contributions

  5. #5
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    Merci

    Ça marche, mais moyennement :/

    Je n'ai plus d'erreur, mais si je supprime le dernier fichier (avec ou sans un autre), il va marcher bizarrement.

    Si seulement le dernier fichier est sélectionné, ça ne marche pas (Ça l'enlève de la liste, mais pas du fichier où il est écrit).
    Si je prend le dernier et un autre, le troisième sera supprimé au lieu des deux autres dans le fichier, mais les deux sélectionnés seront supprimés de la liste

    Bref, un peu compliqué... Voici le code de cette procédure, le reste marche bien toutefois :

    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
    Private Sub cmdRemove_Click()
        Dim i As Integer, j As Integer, k As Integer, l As Integer, strFiles As String, arrLines() As String
     
        Open App.Path & "\exeloader.txt" For Input As #1
            i = 0
            While Not EOF(1)
                i = i + 1
                ReDim Preserve arrLines(i)
                Line Input #1, arrLines(i)
            Wend
        Close #1
     
     
        j = 0
        Do While j <= lstExe.ListCount - 1
            If (lstExe.Selected(j) = True) Then
                lstExe.RemoveItem (j)
                strFiles = strFiles & lstExe.List(j) & vbCrLf
                For k = 0 To UBound(arrLines)
                    If arrLines(k) = LCase(lstExe.List(j)) Then arrLines(k) = vbNullString
                Next k
            End If
            j = j + 1
        Loop
     
        Open App.Path & "\exeloader.txt" For Output As #2
            For l = 0 To UBound(arrLines)
                If arrLines(l) <> vbNullString Then Print #2, arrLines(l)
            Next l
        Close #2
     
        If (Len(strFiles) > 0) Then MsgBox "The following file(s) has (have) been removed : " & vbCrLf & strFiles, vbOKOnly, "Removing Files"
    End Sub

  6. #6
    Expert éminent sénior


    Profil pro
    Inscrit en
    Juin 2003
    Messages
    14 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 14 008
    Points : 20 038
    Points
    20 038
    Par défaut
    ne doit tu pas inverser l'ordre de ces 2 lignes...? tu enlève "l'item" de ta liste puis tu l'utilise (donc c'est plus lui mais le suivant..) pour ta concaténation..:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
                lstExe.RemoveItem (j)
                strFiles = strFiles & lstExe.List(j) & vbCrLf

    sinon la solution pour ta boucle est peu-être de l'effectuer en sens inverse...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     For i =  lstExe.ListCount - 1 TO 0  step -1
    ainsi le fait de supprimer un 'item' .. ne provoque pas de décalage dans les 'items' restant à traiter ...

  7. #7
    Expert confirmé
    Avatar de zazaraignée
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    3 174
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 3 174
    Points : 4 085
    Points
    4 085
    Par défaut
    Salut

    Je viens de tester ceci avec une liste dont la propriété Multiselect = 2 pour Extended.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Private Sub cmdSupprimerItem_Click()
        Dim i As Integer
        i = 0
        Do While i < List1.ListCount
            ' code pour supprimer le fichier...
            If List1.Selected(i) Then List1.RemoveItem i
            i = i + 1
        Loop
    End Sub
    Ça fonctionne bien

    Ceci dit, pour une liste à sélection simple, pas la peine de se fatiguer, une seule ligne suffit.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        List1.RemoveItem List1.ListIndex
    [Edit] Avant que j'oublie, puisque la liste contient des noms de fichiers, pour pouvoir effacer le fichier à partir de son nom complet (avec le chemin), il vaut mieux procéder à l'effacement du fichier avant de supprimer son nom de la liste. Ou encore mettre temporairement ce nom dans une variable.

Discussions similaires

  1. Problèmes avec inputdlg à l'intérieur d'une boucle
    Par laulau301090 dans le forum MATLAB
    Réponses: 3
    Dernier message: 26/04/2013, 20h25
  2. Réponses: 3
    Dernier message: 24/05/2007, 17h56
  3. Réponses: 2
    Dernier message: 29/08/2006, 13h59
  4. Réponses: 12
    Dernier message: 11/04/2006, 11h41
  5. [VB6] Problème avec la touche 0 dans une MaskEdBox
    Par bb62 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 02/03/2006, 09h47

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