Aide à compléter code VBA XLS

Résolu/Fermé
Saajo - Modifié le 29 déc. 2020 à 00:11
 Saajo - 4 janv. 2021 à 22:33
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
A voir également:

5 réponses

jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
29 déc. 2020 à 00:43
Bonjour
Tu pourrais utiliser deux boucles imbriquées.
Une première boucle sur les lignes et dedans, une seconde boucle pour les colonnes.
0
Merci Jordane45 pour ton aide.
Etant novice sur le codage, pourrais-tu me donner plus de détails, stp?
Bien à toi
Saajo
0
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650 > Saajo
29 déc. 2020 à 10:39
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
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
29 déc. 2020 à 12:46
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
Saajo > jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024
29 déc. 2020 à 15:57
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650 > Saajo
29 déc. 2020 à 17:02
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
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
29 déc. 2020 à 17:57
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
Saajo > jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024
29 déc. 2020 à 18:26
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650 > Saajo
29 déc. 2020 à 20:35

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
0
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
29 déc. 2020 à 22:48
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

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
A quel endroit je position le Else?
0
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
29 déc. 2020 à 23:06
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650 > jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024
30 déc. 2020 à 00:05
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
Saajo > jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024
30 déc. 2020 à 08:30
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
Saajo > Saajo
4 janv. 2021 à 19:01
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
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650 > Saajo
4 janv. 2021 à 19:14
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