Aide à compléter code VBA XLS [Résolu]

Signaler
-
 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

Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139
Bonjour
Tu pourrais utiliser deux boucles imbriquées.
Une première boucle sur les lignes et dedans, une seconde boucle pour les colonnes.
Merci Jordane45 pour ton aide.
Etant novice sur le codage, pourrais-tu me donner plus de détails, stp?
Bien à toi
Saajo
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139 > 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

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
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139
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

>
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021

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
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139 > 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
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
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139
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


>
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021

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

Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139 > Saajo

1/ si je souhaite qu'il m'identifient les cellules vides en rouge => comment faire?

https://www.excel-pratique.com/fr/vba/couleurs


2/ Une fois renseigner comment rendre leur format d'origine ?

https://www.excel-pratique.com/fr/vba/evenements_feuille
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
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139
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
A quel endroit je position le Else?
>
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021

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
> 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
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139 > 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))
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021
3 139 >
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021

PS: Pour toute nouvelle question, merci de créer une nouvelle discussion propre à ton nouveau "souci"
et n'oublie pas de mettre cette discussion en RESOLUE.
>
Messages postés
30842
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
5 janvier 2021

Bonsoir Jordane45,
Pour pour ta réponse. C'est RESOLUE
Bien à toi
Saajo