Aide à compléter code VBA XLS

Résolu
Saajo -  
 Saajo -
Bonsoir à tous,

Je cherche à simplifier mon code mais également à l'optimiser. Je m'explique.
L'objectif ici est d'identifier les cellules vides afin d'informer l'utilisateur qu'il à omis de renseigner ces cellules. Si sur une ligne j'ai 2 cellules saisie sur 6 cellules, je pars du principe qu'il n'a pas compléter sa ligne, et donc je dois le notifier.

D'autre part, si une ligne est totalement vide, je peux considérer que il n'y a pas eu de saisie et que je peux donc considérer de ne pas le notifier.

base de principe:
1/ Il y 14 ligne à vérifier si les cellules sont vides (A7:F20)
2/ si cellule E7:E20 non vide, le code doit contrôler que les cellules A7:F20 sont non vides, sinon cas de cellule vide message avec cellule identifier a renseigner.
3/ si une ligne A7:F20 est vide alors je considère qu'il n'y pas de saisie donc pas de notification

Problématiques:
1/ J'ai utilisé le code FOR EACH, mais je ne peux que l'utiliser un nbre de fois limiter x5, alors que j'ai que 14 lignes.
2/ Comment optimiser ce code pour intégrer ces 14 lignes?
3/ comment ne pas intégrer dans le message box les cellules vide d'une ligne considérer non saisie?

Merci à la communauté pour tous conseils que vous voudrez bien me donner.

Bonne soirée.

Ci dessous le code à compléter :


Public Sub CheckEntries()
Dim c As Range
Dim message As String
message = "Cellules non renseignées :"


For Each c In Range("a7:F7")
If c = "" Then message = message & vbCrLf & c.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next

For Each c In Range("a8:F8")
If c = "" Then message = message & vbCrLf & c.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next

For Each c In Range("a9:F9")
If c = "" Then message = message & vbCrLf & c.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next

For Each c In Range("a10:F10")
If c = "" Then message = message & vbCrLf & c.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next

For Each c In Range("a11:F11")
If c = "" Then message = message & vbCrLf & c.Address(RowAbsolute:=False, ColumnAbsolute:=False)


Next c
MsgBox message

End Sub

5 réponses

  1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
     
    Bonjour
    Tu pourrais utiliser deux boucles imbriquées.
    Une première boucle sur les lignes et dedans, une seconde boucle pour les colonnes.
    0
    1. Saajo
       
      Merci Jordane45 pour ton aide.
      Etant novice sur le codage, pourrais-tu me donner plus de détails, stp?
      Bien à toi
      Saajo
      0
      1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830 > Saajo
         
        Pour faire des boucles
        https://silkyroad.developpez.com/vba/boucles/#LIII

        Normalement... je me serai arrêté là ... n'ayant pas pour habitude de donner le code tout cuit ... et t'aurai laissé cherché un minimum avant de te donner la réponse.

        Mais bon, c'est tellement simple que... ben.. voila
        Sub exemple()
        Dim valCel As Range
        Dim message As String
        message = "Cellules non renseignées :"
        
        'boucle sur les lignes 7 à 20
        For l = 7 To 20
            'boucle sur les colonnes 1 à 6 ( A à F )
            For c = 1 To 6
                Set valCel = Cells(l, c)
                If IsEmpty(valCel) Or valCel.Value = "" Then
                    message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
                End If
            Next
        Next
        MsgBox message
        
        End Sub
        
        
        0
  2. Saajo
     
    Genial !!
    Merci Jordane45 ça fonctionne parfaitement bien!

    Cependant, il reste le point n°3 que je souhaiterais ajouter:
    3/ comment ne pas intégrer dans le message box les cellules vide d'une ligne considérer non saisie?
    => je sais j'abuse un peu ! Mais cela serait TOP.

    Pour être plus précis:
    Imaginons que il n'y a plus de saisie sur les lignes 17, 18, 19 et 20, je souhaiterais que dans le message les cellules des lignes 17,18,19 et 20 n'apparaissent pas. Attention, cela sera aléatoire en terme de ligne, il se pourrait bien que se soit à partir de la ligne 11 ou 14, etc...

    Donc logique du code:
    => si 2 cellules vides colonne B et E sur la même ligne 17, alors ne pas afficher les cellules vide de ces lignes, sinon afficher.

    Je te remercie pour l'aide précieuse déjà donnée.
    Bien à toi,
    Saajo
    0
    1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
       
      Tu ajoutes un IF qui fait cette vérification entre les deux boucles
      For l = 7 To 20
          'boucle sur les colonnes 1 à 6 ( A à F )
          ' ICI .. tu écris le IF qui va faire la vérification ....
          If  jetelaissecompleter Then
            For c = 1 To 6
              '...
             Next
         End if
        Next
      
      
      0
      1. Saajo > jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Je ne trouve pas la logique. Car pour moi, le code devrait remonter la colonne B20 et E20 jusqu'à une cellule renseignée. Et si renseigné alors vérifier si les cellules des lignes sont vides. Si conditions vrai alors envoyer message des cellules non renseignées de ces lignes.

        Si une ligne est entièrement vide, le message box ne devrai pas faire apparaitre ces cellules comme non renseignés , car volontairement non saisie.

        Voila ce que j'ai mis, mais le code ne fonctionne pas :



        Sub CheckEntries()
        Dim valCel As Range
        Dim message As String
        message = "Cellules non renseignées :"

        'boucle sur les lignes 7 à 20
        For l = 7 To 20


        'condition si colonne B et F contient un nombre alors aller à la boucle colonnes continuer le traitement
        If IsNumeric(valCel(2)) And IsNumeric(valCel(5)) Then GoTo MSG
        End If

        'boucle sur les colonnes 1 à 6 ( A à F )
        MSG: For c = 1 To 6
        Set valCel = Cells(l, c)
        If IsEmpty(valCel) Or valCel.Value = "" Then
        message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
        End If
        Next
        Next
        MsgBox message

        End Sub



        Merci pour ton aide.

        Bien à toi
        Saajo
        0
      2. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830 > Saajo
         
        If IsNumeric(valCel(2)) And IsNumeric(valCel(5)) Then GoTo MSG
        End If
        </block>
        valCel n'existe pas ... là où tu as mis ta ligne de code ....
        
        A la place,   écris
        <code basic>
        If IsNumeric(cells(l,2)) And IsNumeric(cells(l,5)) Then GoTo MSG
        End If
        


        En plus.. pourquoi utiliser un GOTO ??
        Il suffit de faire comme je te l'avais écrit dans mon exemple ..
        Un truc du genre :
        'boucle sur les lignes 7 à 20
        For l = 7 To 20
        
        
        'condition si colonne B et F contient un nombre alors aller à la boucle colonnes continuer le traitement
        If IsNumeric(cells(l,2)) And IsNumeric(cells(l,5)) Then
            'boucle sur les colonnes 1 à 6 ( A à F )
             For c = 1 To 6
                Set valCel = Cells(l, c)
                If IsEmpty(valCel) Or valCel.Value = "" Then
                    message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
                End If
            Next
          End If
        Next
        MsgBox message
        


        NB: Remarques tu que le code que je te poste est en couleur et affiche le numéro des lignes ?? .. c'est par-ce que j'utilise correctement les balises de code en y précisant le LANGAGE.
        Merci d'y faire attention désormais toi aussi.
        Pour rappel, explications ( à lire ENTIEREMENT ) disponibles ici : https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
        0
  3. Saajo
     
    Merci Jordane45 !

    Compris pour les balises de codage.

    C'est pas tout à fait ça. je m'explique:

    1/ la boite de dialogue affiche les cellules vides lignes par lignes avec obligation de cliquer sur ok pour que la macro s'exécute jusqu'à la dernière ligne. => comment faire pour qu'il ne fasse apparaitre qu'un seul message avec les cellules vides? sans devoir cliquer sur OK à chaque ligne traité.

    2/ La boite de dialogue fait ressortir les cellules vides pour les lignes vides. Hors, la condition serait celle-ci: si cellules vides sur l'ensemble de la lignes alors ne pas mentionner dans la boite de dialogue. => Comment faire pour qu'il considère cette condition?

    
    Sub CheckEntries()
    Dim valCel As Range
    Dim message As String
    message = "Cellules non renseignées :"
    
    'boucle sur les lignes 7 à 20
    For l = 7 To 20
    
    
    'condition si colonne B et F contient un nombre alors aller à la boucle colonnes
    If IsNumeric(Cells(l, 2)) And IsNumeric(Cells(l, 5)) Then
    
    
        'boucle sur les colonnes 1 à 6 ( A à F )
    MSG:    For c = 1 To 6
            Set valCel = Cells(l, c)
            If IsEmpty(valCel) Or valCel.Value = "" Then
                message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
            End If
        Next
    
    MsgBox message
    
    End If
    
    Next
    
    End Sub
    
    
    


    Note perso:
    Je me demandais ce qui te motive à apporter ton aide sur les demandes comme les miennes? Quels sont tes intérêts ou satisfaction à aider les cas désespérer comme le mien?

    De mon côté, ton aide m'ai très utile puisque une fois le codage parfait trouvé, je gagnerais un temps précieux dans l'exercice de mes fonctions/job.

    Bien à toi,
    Saajo
    0
    1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
       
      Pour ce qui est d'apporter de l'aide, et bien, disons que lorsque j'ai débuté on est venu m'aider... maintenant j'en fais autant pour les autres lorsque je le peux.
      En plus, je ne peux pas rester sans réflechir... donc aider les autres ça m'aide à occuper mon esprit.

      Pour en revenir à ton souci, (désolé ça ne va pas être très agréable... ) ... je ne comprends pas comment tu fais pour ne pas réussir à copier/coller le code que je t'ai donné....


      Pour ce qui est de vérifier si une ligne entière et entièrement vide, tu dois pouvoir utiliser un IF de ce genre
       If WorksheetFunction.CountA(ActiveSheet.Rows(l)) = 0 Then
      


      Et si non vide.. il suffit de voir si elle est > 0
      Donc, dans ton code ça pourrait se traduire comme ça
      'boucle sur les lignes 7 à 20
      For l = 7 To 20
        ' Si la ligne entière n'est pas vide :
        If WorksheetFunction.CountA(ActiveSheet.Rows(l)) > 0 Then
           'condition si colonne B et F contient un nombre alors aller à la boucle colonnes continuer le traitement
           If IsNumeric(cells(l,2)) And IsNumeric(cells(l,5)) Then
             'boucle sur les colonnes 1 à 6 ( A à F )
              For c = 1 To 6
                 Set valCel = Cells(l, c)
                 If IsEmpty(valCel) Or valCel.Value = "" Then
                     message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
                 End If
             Next
           End if
        End If
      Next
      
      'On affiche la messagebox qu'une fois les boucles terminées
      MsgBox message
      
      
      
      0
      1. Saajo > jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Merci Jordane45. Tu dégaines plus vite que ton ombre :-)

        Effectivement pouvoir aider et rendre service dans la mesure du possible est toujours bienveillant. C'est sympa.

        Je pense qu'il y mauvaise compréhension concernant le copier/coller => il me semble avoir pu copié selon tes reco ?!

        Concernant le code, il fonctionne et même très bien.

        Allez, petite dernière ! => uniquement si tu as du temps

        1/ si je souhaite qu'il m'identifient les cellules vides en rouge => comment faire?
        2/ Une fois renseigner comment rendre leur format d'origine ?
        3/ Ne pas sauvegarder si les corrections sont non faites

        L'objectif : identifier rapidement les problématiques via un visuelle percutant et forcer à saisir l'information sur l'instant T

        Merci Jordane45

        Code ci-*dessous:

        Sub CheckEntries()
        Dim valCel As Range
        Dim message As String
        message = "Cellules non renseignées :"
        
        'boucle sur les lignes 7 à 20
        For l = 7 To 20
        
        
        ' Si la ligne entière n'est pas vide :
        If WorksheetFunction.CountA(ActiveSheet.Rows(l)) > 0 Then
        
        'condition si colonne B et F contient un nombre alors aller à la boucle colonnes
        If IsNumeric(Cells(l, 2)) And IsNumeric(Cells(l, 5)) Then
        
        
            'boucle sur les colonnes 1 à 6 ( A à F )
        MSG:    For c = 1 To 6
                Set valCel = Cells(l, c)
                If IsEmpty(valCel) Or valCel.Value = "" Then
                    message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
                End If
            Next
        
        End If
        
        End If
        
        Next
        
        
        'On affiche la messagebox qu'une fois les boucles terminées
        
        MsgBox message
        
        
        End Sub
        
        
        0
  4. Saajo
     
    Sincèrement merci Jordane45.

    C'est super, j'ai réussi à intégrer grace à ton lien le format couleur rouge:

    Sub CheckEntries()
    Dim valCel As Range
    Dim message As String
    message = "Veuillez corriger les cellules suivantes :"
    
    'boucle sur les lignes 7 à 20
    For l = 7 To 20
    
    
    ' Si la ligne entière n'est pas vide :
    If WorksheetFunction.CountA(ActiveSheet.Rows(l)) > 0 Then
    
    'condition si colonne B et F contient un nombre alors aller à la boucle colonnes
    If IsNumeric(Cells(l, 2)) And IsNumeric(Cells(l, 5)) Then
    
    
        'boucle sur les colonnes 1 à 6 ( A à F )
      For c = 1 To 6
            Set valCel = Cells(l, c)
            If IsEmpty(valCel) Or valCel.Value = "" Then
                message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
            End If
            
            'si ensemble cellule vide alors surbrillance rouge
            If IsEmpty(valCel) Or valCel.Value = "" Then
                valCel.Interior.Color = RGB(255, 0, 0)
            End If
           
        Next
    
    End If
    
    End If
    
    Next
    
    'On affiche la messagebox qu'une fois les boucles terminées
    
    MsgBox message
    
    End Sub
    


    Maintenant, je suis bloquer pour remettre le format cellule en mode original lorsqu'on confirme le OK de la boîte de dialogue. Peux tu me dire ou je le place?
    J'imagine qu'il faut remettre la même formule juste avant le End Sub, mais cela ne fonctionne pas.

    Bien à toi,
    Saajo
    0
    1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
       
      Deja, tu pourrais l'utiliser qu'un seul œuf dedans tu y fais le message et puis change la couleur.
      ensuite pour remettre le format d'origine tu peux simplement faire un else et y remettre la ligne de code adéquate dedans.

      Si tu ne sais pas ce qu'est un Else, je t'invite tu as regarder sur internet comment on fait des tests conditionnels en VBA
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Saajo
     
    A quel endroit je position le Else?
    0
    1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
       
      Dans le if ....
      Mais j'insiste, regarde comment on écrit un if else en VBA... C'est le minimum à connaître quand on fait de la programmation.
      0
    2. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830 > jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Sub CheckEntries()
        Dim valCel As Range
        Dim message As String
        message = "Veuillez corriger les cellules suivantes :"
      
        'boucle sur les lignes 7 à 20
        For l = 7 To 20
          ' Si la ligne entière n'est pas vide :
          If WorksheetFunction.CountA(ActiveSheet.Rows(l)) > 0 Then
            'condition si colonne B et F contient un nombre alors aller à la boucle colonnes
            If IsNumeric(Cells(l, 2)) And IsNumeric(Cells(l, 5)) Then
                'boucle sur les colonnes 1 à 6 ( A à F )
              For c = 1 To 6
                Set valCel = Cells(l, c)
                If IsEmpty(valCel) Or valCel.Value = "" Then
                  message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
                  valCel.Interior.Color = RGB(255, 0, 0) 'si ensemble cellule vide alors surbrillance rouge
                Else
                  valCel.Interior.Color = RGB(0, 0, 0) 
                End If
               Next
            End If
          End If
      
        Next
        'On affiche la messagebox qu'une fois les boucles terminées
        MsgBox message
      
      End Sub
      
      0
    3. Saajo > jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Merci pour ta réponse.

      Ca ne répond pas exactement a ce que je souhaite. Néanmoins j'ai trouvé la solution. Je l'ai positionné juste avant le END SUB, cela permet lorsque je ferme la boite de dialogue d'annuler les fonds en surbrillance.

      Sub CheckEntries()
      Dim valCel As Range
      Dim message As String
      message = "Veuillez corriger les cellules suivantes :"
      
      'boucle sur les lignes 7 à 20
      For l = 7 To 20
      
      
      ' Si la ligne entière n'est pas vide :
      If WorksheetFunction.CountA(ActiveSheet.Rows(l)) > 0 Then
      
      'condition si colonne B et F contient un nombre alors aller à la boucle colonnes
      If IsNumeric(Cells(l, 2)) And IsNumeric(Cells(l, 5)) Then
      
      
          'boucle sur les colonnes 1 à 6 ( A à F )
        For c = 1 To 6
              Set valCel = Cells(l, c)
              If IsEmpty(valCel) Or valCel.Value = "" Then
                  message = message & vbCrLf & valCel.Address(RowAbsolute:=False, ColumnAbsolute:=False)
              End If
              
              'si ensemble cellule vide alors surbrillance rouge
              If IsEmpty(valCel) Or valCel.Value = "" Then
                  valCel.Interior.Color = RGB(255, 0, 0)
              Else
                  valCel.Interior.Color = RGB(255, 255, 255)
              End If
             
          Next
      
      End If
      
      End If
      
      Next
      
      'On affiche la messagebox qu'une fois les boucles terminées
      
      MsgBox message
      
      For l = 7 To 20
          'boucle sur les colonnes 1 à 6 ( A à F )
          For c = 1 To 6
              Set valCel = Cells(l, c)
                      'si ensemble cellule vide alors surbrillance rouge
              If valCel.Interior.Color = RGB(255, 0, 0) Then
                  valCel.Interior.Color = RGB(255, 255, 255)
              End If
          Next
      Next
      
      End Sub
      



      que veut dire: "tu pourrais l'utiliser qu'un seul œuf dedans"


      Merci pour ton aide Jordane45
      Sans toi j'aurai mis des heures carrés à chercher.

      Je n'ai pas encore parfaitement fini mon fichier => je reviendrai bientôt pour compléter ma macro avec plus d'éléments

      Je te souhaite un bon réveillon de fin d'année

      Bien à toi,
      Saajo
      0
    4. Saajo > Saajo
       
      Hello !
      Tous mes vœux pour cette nouvelle année .

      Je souhaiterais rajouter une conditions sur mon code ci-dessus:

      je souhaiterais lui dire si ligne pas vide de la colonne A à F et non toute la ligne. comment l'écrire?
      ci-dessous le bout de code que je souhaiterais modifier

      
      
      ' Si la ligne entière n'est pas vide :
      If WorksheetFunction.CountA(ActiveSheet.Rows(l)) > 0 Then
      
      
      




      Merci
      Bonne soirée
      Saajo
      0
    5. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830 > Saajo
       
      Et bien, au lieu de cibler la ligne entière, tu dois pouvoir spécifier la plage de cellule à traiter
      https://docs.microsoft.com/fr-fr/office/vba/api/excel.range.cells

      Donc, remplacer
      ActiveSheet.Rows(l)
      

      par un truc du genre
      ActiveSheet.Range(cells(l,1),cells(l,6))
      
      0