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

Macros et VBA Excel Discussion :

Utiliser une boucle "For" dans un" Select Case"


Sujet :

Macros et VBA Excel

  1. #1
    Membre du Club
    Inscrit en
    Juin 2013
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Juin 2013
    Messages : 81
    Points : 45
    Points
    45
    Par défaut Utiliser une boucle "For" dans un" Select Case"
    Bonjour,

    Je tente d'utiliser une boucle For dans un Select, et le message d'erreur suivant apparait : "Statements and labels invalid between Select Case and First Case".

    Or, j'aimerais bien écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Select Case Attribut
           For i = 1 To 20
                Case Range("Index").Offset(i, 0)
                Lin = i
            Next i
     
           Case Else
          MsgBox "Attention, les attributs rentrés ne correspondent pas à l'index !"
           End
    End Select
    En effet, j'ai placé dans ma feuille excel une place de cellules correspondants à l'ensemble des valeurs que peut prendre "Attribut". Toutes ces valeurs se trouvent sur la même colonne et se suivent ligne par ligne. Je trouve cela à la fois plus élégant et plus efficient d'utiliser alors une boucle for.

    Savez-vous pourquoi cela ne marche pas ?
    J'envisage d'utiliser une boucle if à la place, mais cela ne serait pas non plus ni très élégant, ni très efficient.

    Merci d'avance,
    Novic_vba

  2. #2
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 058
    Points
    32 058
    Par défaut
    Le problème est que ton code n'est pas cohérent. Select case choisit une fois entre plusieurs possibilités. Le for, soit doit être à l'interieur du case, soit à l'extérieur du bloc select case complet.

    Dis-moi si je comprends bien ta demande : tu veux vérifier si l'Attribut est bien dans une des cases Case Range("Index").Offset(i, 0)?

    Si oui, je te propose de faire de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Lin = 0
    For i = 1 To 20
        If Attribut = Range("Index").Offset(i, 0) Then
            Lin = i
            Exit For
        End If
    Next i
    If Lin = 0 Then
        MsgBox "Attention, les attributs rentrés ne correspondent pas à l'index !"
    End If
    le Exit For est pour éviter de boucler alors qu'on a déjà trouvé la valeur de Lin. Et, si on n'en a trouvé aucune(Lin est resté à zéro), alors on sort le message d'alerte.

    Evidemment, si c'est autre chose que tu veux, ça ne te conviendra pas(mais alors dis-nous quoi).
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  3. #3
    Membre du Club
    Inscrit en
    Juin 2013
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Juin 2013
    Messages : 81
    Points : 45
    Points
    45
    Par défaut
    Bonjour el_slapper,

    L'attribut recherché existe nécessairement. Le message d'erreur n'a été placé que si quelque chose se passe mal.

    Ce code vise en réalité à remplir une matrice constituée de deux attributs (l'un en abscisse, l'autre en ordonnée), grâce à deux fonctions : l'une renvoie le numéro de la ligne de l'attribut en question, et l'autre renvoie le numéro de la colonne lié à l'attribut.
    Le code posté est ainsi simplifié (en réalité, il existe plusieurs attributs, qui ne sont pas nécessairement sous la cellule "Index"
    Quand le code a récupéré la valeur correspondant à une valeur correspondant au croisement de l'attribut 1 et une valeur de l'attribut 2, il suffit d'écrire : Range("Cellule_En_Haut_A_Gauche").Offset(lin(Attribut(Numero),Col(Attribut(Numero)) = ...
    Je ne suis pas certain que mon explication suffise, mais malheureusement la sécurité de mon ordinateur ne me laisse pas poster des fichiers sur des forums.

    Finalement, j'ai effectivement opté pour votresolution avec une boucle for et un "If"
    Malheureusement mon code est soudain beaucoup plus lent. Alors si cette solution suffit, je serais heureux s'il existait une solution alternative.

    Novice_vba

  4. #4
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 058
    Points
    32 058
    Par défaut
    Ah, alors c'est plus compliqué, en effet. Si tu as des problèmes de performance, c'est que tu dois avoir plein de recherches à faire. Une solution est de chercher durectement la case via la fonction Find.

    D'abord, il faut déterminer ton périmètre de recherche (ça sera un range). Si je garde les 20 cases que tu avais dans ton premier exemple, ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        Dim MyRange As Range
        Set MyRange = Range(Cells(Range("Index").Row + 1, Range("Index").Column), Cells(Range("Index").Row + 20, Range("Index").Column))
    un peu bourrin, mais tu as tes 20 cases à droite de "index". A adapter évidemment.

    ensuite, il faut faire le find proprement dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        Dim MyCell As Variant
        Set MyCell = MyRange.Find(What:=Attribut, LookAt:=xlWhole)
            If MyCell Is Nothing Then
            MsgBox "Attention, les attributs rentrés ne correspondent pas à l'index !"
        Else
            Lin = MyCell.Row
            Col = MyCell.Column
        End If
    MyCell possède et la ligne, et la colonne que tu cherches. Donc, tu ne fais la recherche qu'une fois, et normalement, les fonctions intrinsèques sont plus rapides que des boucles "manuelles" comme ma première solution(à vérifier avec tes données). A noter que si tu recherches ton attribut un certain nombre de fois, tu n'as pas besoin de redéfinir MyRange à chaque fois. Une seule fois suffit(c'est plus rapide).
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

Discussions similaires

  1. Utiliser une boucle for avec un pas de 2
    Par ayari.zohra dans le forum Langage
    Réponses: 39
    Dernier message: 27/05/2012, 19h21
  2. Réponses: 2
    Dernier message: 17/05/2012, 01h18
  3. [Débutant] utiliser une boucle for avec la fonction wavread()
    Par alimo44 dans le forum Signal
    Réponses: 1
    Dernier message: 21/06/2010, 08h08
  4. utiliser une boucle 'for' in JAsperReport
    Par Javix dans le forum Jasper
    Réponses: 6
    Dernier message: 13/12/2007, 10h05
  5. [Tableaux] Utiliser une boucle for dans un echo
    Par maoboy dans le forum Langage
    Réponses: 7
    Dernier message: 18/06/2007, 13h55

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