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 :

[VBA EXCEL] - Boucles et UserForm


Sujet :

Macros et VBA Excel

  1. #1
    Membre habitué Avatar de ancel17
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Mars 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Mars 2007
    Messages : 312
    Points : 178
    Points
    178
    Par défaut [VBA EXCEL] - Boucles et UserForm
    Bonjour le Forum,

    Mon UserForm2 lance une procédure lorsqu'il est activé.
    Dans cette procédure, j'ai une boucle For Each... Next qui demande l'ouverture d'un UserForm4.

    Mon problème est le suivant :
    Le UserForm4 est montré lors de la première itération de la boucle, je ne peux plus l'afficher...
    L'erreur renvoyé est :
    Erreur d'exécution '400':
    Feuille déjà affichée ; affichage modal impossible
    J'ai donc tenté le coup en passant la propriété ShowModal du UserForm4 de True à False.

    Je n'ai alors effectivement plus de message d'erreur, mais mon UserForm4 n'est plus "prioritaire" sur ma procédure, c'est-à-dire qu'il est bien affiché mais la procédure continue de dérouler...

    Résultat, lorsque j'accède au UserForm4, il n'est plus utile car la procédure est terminée. Mon UserForm4 ne renvoie donc pas les valeurs rentrées et n'étant plus dans la boucle (dans le sens où j'y accède une fois la procédure terminée), il n'apparait qu'une fois...

    Voici le code utilisé pour le UserForm2 :
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Private Sub UserForm_Activate()
     
    UserForm2.Repaint
    DoEvents
     
    Dim Fl1 As Worksheet, Fl2 As Worksheet
    Dim Ctrl As Control
    Dim n As Integer
    Dim Fichier As String
    Dim c As Range
     
    Application.ScreenUpdating = False
     
    Set Fl1 = ThisWorkbook.Worksheets(1)
    Set Fl2 = ThisWorkbook.Worksheets(5)
     
    ...
     
    'finalise le classement par ordre alphabétique (positionne "101 - AMP" après "16 - Développement" par exemple)
    i = 0
    For Each c In Fl1.Range("IV1:IV" & Fl1.Range("IV65536").End(xlUp).Row).Cells
        If c.Value Like "10*" Then
            Fl1.Range("IV" & Fl1.Range("IV65536").End(xlUp).Row + 1).Value = c.Value
            i = i + 1
        End If
    Next c
    If Not i = 0 Then
        If i > 1 Then
            Fl1.Range("IV1:IV" & i).Delete (xlShiftUp)
        Else
            Fl1.Range("IV1").Delete (xlShiftUp)
        End If
    End If
     
    n = 0
    'la boucle qui pose problème, mais est-ce vraiment la boucle...
    For Each c In Fl1.Range("IV1:IV" & Fl1.Range("IV65536").End(xlUp).Row).Cells
        Fl1.Range("A" & 7 + n * 34) = c.Value
        Application.ScreenUpdating = True
        UserForm4.Label14 = c.Value
        UserForm4.Label15 = Fl1.Range("A" & 7 + n * 24).Address
        UserForm4.Show
        Application.ScreenUpdating = False
        n = n + 1
    Next c
    Code du UserForm4 :
    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
    Private Sub CommandButton1_Click()
     
    Dim Fl1 As Worksheet
    Dim c As Range
    Dim ld As Integer, cd As Integer
     
    Set Fl1 = ThisWorkbook.Worksheets(1)
     
    ld = Fl1.Range(UserForm4.Label15).Row
    cd = Fl1.Range(UserForm4.Label15).Column
     
    Fl1.Cells(ld + 4, cd + 83).Value = UserForm4.TextBox1
    Fl1.Cells(ld + 7, cd + 83).Value = UserForm4.TextBox2
    Fl1.Cells(ld + 10, cd + 83).Value = UserForm4.TextBox3
    Fl1.Cells(ld + 13, cd + 83).Value = UserForm4.TextBox4
    Fl1.Cells(ld + 16, cd + 83).Value = UserForm4.TextBox5
    Fl1.Cells(ld + 19, cd + 83).Value = UserForm4.TextBox6
     
    UserForm4.Hide
     
    End Sub
    Quelqu'un a-t-il une suggestion ?
    Sigue soñando

  2. #2
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 543
    Points
    15 543
    Par défaut
    Tu pourrais utiliser Application.screenUpDating = false avant de mettre à jour ta feuille de calculs
    Tu peux surtout ajouter DoEvents après UserForm4.Show et avant UserForm4.Hide

    dans Usf3
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        '...
        UserForm4.Label15 = Fl1.Range("A" & 7 + n * 24).Address
        DoEvents
        UserForm4.Show
    Dans Usf4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    '...
    Fl1.Cells(ld + 19, cd + 83).Value = UserForm4.TextBox6
    DoEvents
    UserForm4.Hide
    Teste déjà ça.
    Tu nous dis

  3. #3
    Membre habitué Avatar de ancel17
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Mars 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Mars 2007
    Messages : 312
    Points : 178
    Points
    178
    Par défaut
    salut Ouskel'n'or,

    ça a l'air de fonctionner pour ce qui est du message d'erreur mais j'ai l'impression que ta solution, ré-active l'USF2 en fin d'itération, du coup la procédure est relancé systématiquement...

    je suis donc coincé sur la première itération !

    Vérification faite,

    On active bien à chaque fois USF2...
    Donc bloqué à la première itération qui est relancé à chaque fois (tout comme la procédure jusqu'à cette itération)...
    Sigue soñando

  4. #4
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 543
    Points
    15 543
    Par défaut
    En tout cas, ce n'est pas là qu'il faut chercher.
    DoEvents sert à donner au système le temps pour mettre à jour les données dans ta feuille, afficher ceci ou cela, pas à activer quoi que ce soit.
    Je ne sais pas ce que tu as comme code, ailleurs que dans le bouton, dans usf4, mais c'est là qu'il faut chercher.
    Tu es sûr que tu n'as pas un usf2.show quelque part ? Si tu en as un, tu dois le supprimer.
    A+

  5. #5
    Membre habitué Avatar de ancel17
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Mars 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Mars 2007
    Messages : 312
    Points : 178
    Points
    178
    Par défaut
    Je n'en ai pas l'impression...

    Voici l'ensemble de mon "oeuvre" :

    Mon USF1 s'ouvre à l'ouverture du fichier en fonction du titre du fichier.
    Soit je clique sur Annuler et je ferme le USF1 (et par la suite qd mon fichier sera opérationnel, le fichier, d'où l'apostrophe devant Thisworkbook.Close), soit je renseigne les données et je clique sur Ok :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Private Sub CommandButton1_Click()    'Bouton OK
     
    UserForm1.Hide
    UserForm2.Label1.Caption = "Votre fichier " & UserForm1.TextBox1.Value & " - Suivi Affaire.xls est en cours de création." & vbCrLf & vbCrLf & "Veuillez patienter..."
    UserForm3.Show
     
    End Sub
     
    Private Sub CommandButton2_Click()             'Bouton Annuler
    UserForm1.Hide
    'ThisWorkbook.Close SaveChanges:=False
    End Sub
    Si je clique sur Ok, mon USF3 s'affiche, je remplis mes taux horaires (TextBox1 à 12) et je clique sur Ok :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub CommandButton1_Click()
    UserForm3.Hide
    UserForm2.Show                                       'USF2.Show, le seul et unique...
    End Sub
    Mon USF2 s'affiche et lance la procédure :
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    Private Sub UserForm_Activate()
     
    UserForm2.Repaint
    DoEvents
     
    Dim Fl1 As Worksheet, Fl2 As Worksheet
    Dim Ctrl As Control
    Dim n As Integer
    Dim Fichier As String
    Dim c As Range
     
    Application.ScreenUpdating = False
     
    Set Fl1 = ThisWorkbook.Worksheets(1)
    Set Fl2 = ThisWorkbook.Worksheets(5)
     
    Fl1.Range("A1") = UserForm1.TextBox1.Value & " - " & UserForm1.TextBox2.Value
    Fl1.Range("B3") = DateSerial(Year(UserForm1.TextBox6.Value), Month(UserForm1.TextBox6.Value), Day(UserForm1.TextBox6.Value))
    Fl1.Range("E3") = DateSerial(Year(UserForm1.TextBox5.Value), Month(UserForm1.TextBox5.Value), Day(UserForm1.TextBox5.Value))
    Fl1.Range("B4") = UserForm1.TextBox3.Value
    Fl1.Range("E4") = UserForm1.TextBox4.Value
     
    n = 0
    For Each c In Fl1.Range("F6:CD6").Cells
        If Not c.Value Like "Total*" Then
            c.Value = DateSerial(Year(UserForm1.TextBox6.Value), 1 + n, 1)
            n = n + 1
        End If
    Next c
     
    Fl2.Range("AH67") = Val(UserForm3.TextBox1)
    Fl2.Range("AH68") = Val(UserForm3.TextBox2)
    Fl2.Range("AH69") = Val(UserForm3.TextBox3)
    Fl2.Range("AH70") = Val(UserForm3.TextBox4)
    Fl2.Range("AH71") = Val(UserForm3.TextBox5)
    Fl2.Range("AH72") = Val(UserForm3.TextBox6)
     
    Fl2.Range("AI67") = Val(UserForm3.TextBox7)
    Fl2.Range("AI68") = Val(UserForm3.TextBox8)
    Fl2.Range("AI69") = Val(UserForm3.TextBox9)
    Fl2.Range("AI70") = Val(UserForm3.TextBox10)
    Fl2.Range("AI71") = Val(UserForm3.TextBox11)
    Fl2.Range("AI72") = Val(UserForm3.TextBox12)
     
    n = 0
    For Each Ctrl In UserForm1.Controls
        If TypeOf Ctrl Is MSForms.CheckBox And Ctrl = True Then
            n = n + 1
            If n <= 2 Then
                Fl1.Range("IV" & n) = Ctrl.Caption
            Else
                Fl1.Range("A41:CF74").Copy
                Fl1.Range("A41").Insert (xlShiftDown)
                Fl1.Range("IV" & n) = Ctrl.Caption
            End If
        End If
    Next Ctrl
     
    Fl1.Range("IV1:IV" & Fl1.Range("IV65536").End(xlUp).Row).Sort Key1:=Fl1.Range("IV1")
     
    i = 0
    For Each c In Fl1.Range("IV1:IV" & Fl1.Range("IV65536").End(xlUp).Row).Cells
        If c.Value Like "10*" Then
            Fl1.Range("IV" & Fl1.Range("IV65536").End(xlUp).Row + 1).Value = c.Value
            i = i + 1
        End If
    Next c
    If Not i = 0 Then
        If i > 1 Then
            Fl1.Range("IV1:IV" & i).Delete (xlShiftUp)
        Else
            Fl1.Range("IV1").Delete (xlShiftUp)
        End If
    End If
     
    n = 0
    For Each c In Fl1.Range("IV1:IV" & Fl1.Range("IV65536").End(xlUp).Row).Cells
        Fl1.Range("A" & 7 + n * 34) = c.Value
        UserForm4.Label14 = c.Value
        UserForm4.Label15 = Fl1.Range("A" & 7 + n * 34).Address
        n = n + 1
        Application.ScreenUpdating = True
        UserForm4.Show
        DoEvents
        Application.ScreenUpdating = False
    Next c
     
    Fl1.Range("CG1:IV65536").Delete (xlShiftToLeft)
     
    Set Fl1 = Nothing
    Set c = Nothing
     
    MàJ
     
    Fichier = Application.GetSaveAsFilename(UserForm1.TextBox1.Value & " - Suivi Affaire.xls")
    ThisWorkbook.SaveAs Fichier
     
    UserForm2.Hide
     
    Application.ScreenUpdating = True
     
    End Sub
    Le code du USF2 n'était pas entier dans le premier post car je ne pensais pas que l'erreur puisse se situer ailleurs que dans ma fameuse boucle...
    A chaque itération, USF4 est sensé s'affiché avec le nom du métier correspondant (Label14), et permettre la saisie des heures prévue (TextBox1 à 6).
    Je peux alors choisir de saisir les valeurs et cliquer sur Ok, ou de quitter l'assitant :
    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
    Private Sub CommandButton1_Click()      'Bouton Ok
     
    Dim Fl1 As Worksheet
    Dim c As Range
    Dim ld As Integer, cd As Integer
     
    Set Fl1 = ThisWorkbook.Worksheets(1)
     
    ld = Fl1.Range(UserForm4.Label15).Row
    cd = Fl1.Range(UserForm4.Label15).Column
     
    Fl1.Cells(ld + 4, cd + 83).Value = Val(UserForm4.TextBox1)
    Fl1.Cells(ld + 7, cd + 83).Value = Val(UserForm4.TextBox2)
    Fl1.Cells(ld + 10, cd + 83).Value = Val(UserForm4.TextBox3)
    Fl1.Cells(ld + 13, cd + 83).Value = Val(UserForm4.TextBox4)
    Fl1.Cells(ld + 16, cd + 83).Value = Val(UserForm4.TextBox5)
    Fl1.Cells(ld + 19, cd + 83).Value = Val(UserForm4.TextBox6)
     
    DoEvents
    UserForm4.Hide
     
    End Sub
     
    Private Sub CommandButton2_Click()        'Bouton Quitter Assistant
    UserForm5.Show
    End Sub
    En cliquant sur Ok, je devrait continuer la procédure et parcourir la boucle normalement mais ce n'est pas le cas, je repars systématiquement du début de la Sub USF2_Activate...

    En cliquant sur Quitter Assitant, j'affiche le USF5, demandant confirmation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Sub CommandButton1_Click()          'Bouton Ok (on quitte l'assistant)
    UserForm5.Hide
    UserForm4.Hide
    End Sub
     
    Private Sub CommandButton2_Click()                    'Bouton Annuler (on revient au USF4)
    UserForm5.Hide
    End Sub
    Notons qu'avant l'insertion des DoEvents, on pouvait quitter l'assistant, ce qui n'est plus le cas...
    Après avoir cliquer sur Ok, le USF2 est ré-activé... Mais je pense qu'un petit USF2.Hide devrait faire l'affaire pour ce problème précis...
    Sigue soñando

  6. #6
    Membre habitué Avatar de ancel17
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Mars 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Mars 2007
    Messages : 312
    Points : 178
    Points
    178
    Par défaut
    problème résolu,

    en ajoutant USF2.Hide juste avant la fameuse boucle, la boucle se passe correctement...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    n = 0
    UserForm2.Hide
    For Each c In Fl1.Range("IV1:IV" & Fl1.Range("IV65536").End(xlUp).Row).Cells
        Fl1.Range("A" & 7 + n * 34) = c.Value
        UserForm4.Label14 = c.Value
        UserForm4.Label15 = Fl1.Range("A" & 7 + n * 34).Address
        n = n + 1
        Application.ScreenUpdating = True
        UserForm4.Show
        DoEvents
        Application.ScreenUpdating = False
    Next c
     
    Fl1.Range("CG1:IV65536").Delete (xlShiftToLeft)
    En tout cas merci de t'etre penché sur mon problème...
    Ceci dit, si tu as une explication à ce qui reste pour moi un mystère, n'hésite pas !

    Idem pour l'optimisation du code...
    Sigue soñando

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [vba excel] boucle et controle
    Par CIBOOX dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 23/07/2007, 09h13
  2. vba[Excel 2003]Problème userform
    Par stargates dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 07/07/2007, 15h15
  3. VBA EXCEL : boucle, recherche ligne
    Par sebi78 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 03/04/2007, 13h02
  4. [VBA Excel] Lien entre userforms
    Par violette_china dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 27/11/2006, 02h21
  5. [VBA EXCEL] Réduire/Agrandir UserForms
    Par Fench dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 06/11/2003, 16h02

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