Nombre de cellules vides dans plusieurs plages
Bonjour,
Je dispose d'un onglet avec 10 plages ("C8:N32"), ("C38:N62"), ("C68:N92"), ("C98:N122"), ("C128:N152"), ("R8:AD32"), ("R38:AD62"), ("R68:AD92"), ("R98:AD122"), ("R128:AD152"). Chaque plage compte 300 cellules vides ou non.
Le code ci-dessous permet de savoir si la plage C8:N32 est vide ou non par comparaison entre les 300 cellules totales (Variable Z) et le nombre de cellules vides (Variable Total).
Si Total < Z alors je suis en mesure de dire que la plage C8:N32 est non vide
Si Total >= Z alors la plage n'est pas utilisée
Je comptais appliquer ce raisonnement sur les 10 plages, et additionner les variables io pour connaître le nombre de plages utilisées sur ma feuille. Je reporte ensuite ce chiffre sur une autre feuille.
Je m'exerce sur 1 onglet mais à terme il y aura plusieurs onglets similaires et cela évitera de devoir compter les plages utilisées par onglet manuellement.
'Option Explicit
Sub CountBlanks()
Dim rng As Range
Dim WorkRng As Range
Dim Total As Integer
On Error Resume Next
Set WorkRng = Range("C8:N32")
For Each rng In WorkRng
If IsEmpty(rng.Value) Then
Total = Total + 1
End If
Next
MsgBox "Il y a " & Total & " cellules vides dans cette plage."
'Z = le nombre de cellules totales dans la plage C8:N32
Dim Z As Integer
Z = 300
'Variable io = 1 si Total < Z OU 0 si Total >= Z
Dim io As Byte
If Total < Z Then
io = 1
Else
io = 0
End If
MsgBox io & " plage(s) utilisée(s)"
End Sub
Je cherche un moyen d'optimiser au mieux ce code plutôt que de le coller 10 fois puis d'additionner les variables "1 ou 0" mais je ne sais pas trop comment m'y prendre..
Toute piste / solution est la bienvenue
Merci d'avance
Bonjour,
Je pense qu'en passant par un Array pour les plages et la méthode find de la plage associé à une boucle ça me paraît plus concis et clair :
Sub COMPTAGE()
Dim PLAGE As Variant, P%, TROUVE As Variant, RESULTAT%
PLAGE = Array(("C8:N32"), ("C38:N62"), ("C68:N92"), ("C98:N122"), ("C128:N152"), ("R8:AD32"), ("R38:AD62"), ("R68:AD92"), ("R98:AD122"), ("R128:AD152"))
For P = 0 To UBound(PLAGE) 'On boucle pour chaque plage du tableau PLAGE
Set TROUVE = Range(PLAGE(P)).Find("*") 'On cherche une valeur dans la plage P
If TROUVE Is Nothing Then RESULTAT = RESULTAT + 1 'Si le résultat est rien (donc si rien n'est trouvé) alors on incrémente
Next P 'On passe à la prochaine plage
MsgBox "Il y a " & RESULTAT & " plages utilisée"
End Sub
Cdlt,
Bonjour,
Avec votre code et un tableau, ca donne ça.
(J'ai pas bien compris la plage utilisée ou pas donc j'ai laissé en std by)
Sub CountBlanks()
Dim rng As Range
Dim WorkRng As Range
Dim Total As Integer
Dim Z, nbplages As Integer
nbplages = 2 ' a modifier
ReDim tablo(nbplages)
tablo(0) = "C8:N32"
tablo(1) = "C38:N62"
For i = 0 To nbplages - 1
Total = 0
On Error Resume Next
Set WorkRng = Range(tablo(i))
For Each rng In WorkRng
If IsEmpty(rng.Value) Then
Total = Total + 1
End If
Next
msg = msg & "Il y a " & Total & " cellules vides dans la plage " & tablo(i) & " " & Chr(10)
'Z = le nombre de cellules totales dans la plage C8:N32
Z = 300
'Variable io = 1 si Total < Z OU 0 si Total >= Z
Dim io As Byte
If Total < Z Then
io = 1
Else
io = 0
End If
MsgBox io & " plage(s) utilisée(s)"
Next
MsgBox msg
End Sub
Cdlt
Bonjour à tous,
merci pour votre réactivité !
@Ergotamine , "il y a 0 plages utilisées" malgré certaines cellules remplies avec du texte dans différentes plages. Ta partie
Set TROUVE = Range(PLAGE(P)).Find("*")
équivaut à la partie du code ci-dessous ? Elle cherche dans la plage si une cellule contient du contenu ?
For Each rng In WorkRng
If IsEmpty(rng.Value)
[...]
Next
(Les cellules contiendront exclusivement du texte pour info)
@fg2b , ton aperçu marche très bien, je n'ai plus qu'à adapter puis additionner le nombre de plages utilisées, je devrais m'en dépatouiller sans problème, merci !
Pour l'histoire des plages utilisées, si dans C8:N32 j'ai 1 cellule d'utilisée, dans R68:AD92 j'ai 5 cellules avec du texte, et dans R98:AD122 3 cellules utilisées, je veux pouvoir dire "on utilise 3 plages sur 10". Qu'il y ait 1 ou 20 cellules utilisées dans les plages, leur contenu est négligeable
Bonjour,
Étonnant car avec mon fichier test où j'avais bien testé du texte j'ai le bon résultat (cf. fichier joint). Ici vous devriez obtenir 8. Si vous effacez les données d'une plage, alors le résultat sera 9, etc ...
Pour la question c'est ça en effet, sauf qu'elle ne s'arrête qu'à la première cellule non vide rencontrée, ça évite des boucles trop longues vu qu'on ne veut connaître que le nombre de plages utilisées et non de cellules.
Dans l'attente de votre retour car j'aimerai savoir ce qui ne fonctionne pas. Si vous pouvez éventuellement joindre votre fichier ..
Cdlt,
Bonjour,
Un essai dérivé du code d'Ergotamine (non testé) :
Sub COMPTAGE()
Dim PLAGE As Variant, P As Variant, RESULTAT%
PLAGE = Array("C8:N32", "C38:N62", "C68:N92", "C98:N122", "C128:N152", "R8:AD32", "R38:AD62", "R68:AD92", "R98:AD122", "R128:AD152")
For Each P In PLAGE 'On boucle pour chaque plage du tableau PLAGE
RESULTAT = RESULTAT + CInt(Application.CountA(Sheets("NomFeuille").Range(P)) > 0)
Next P 'On passe à la prochaine plage
MsgBox "Il y a " & RESULTAT & " plages utilisées"
End Sub
@Ergotamine
La tête dans le guidon, j'avais mal interprété votre code, il fonctionne à merveille...
En revanche, lorsque seul 2 plages sur 10 sont vides de contenu, on récupère le chiffre 2 au niveau du MsgBox final, ce qui correspond au nombre de plages vides or j'aurais besoin du nombre de plages utilisée : 8 dans l'exemple ci-dessus
MsgBox "Il y a " & 10 - RESULTAT & " plages utilisée"
J'ai rajouté " 10 - " à votre code pour obtenir 8, est-ce acceptable ? En tout cas cette "bidouille" fonctionne
Merci d'avoir pris le temps de vous pencher sur mon cas, je vais en tirer une bonne leçon lorsque j'aurai tout compris
@Pedro22
Merci d'avoir jeté un oeil ! On obtient " -8 " lorsque 8 plages sur 10 sont remplies
Bonjour,
Oui tout à fait ça fonctionne. On peut aussi fonctionner par le raisonnement inverse : on n'ajoute 1 que si quelque chose est trouvé ce qui donne via 3 lettres "Not" sur la condition IF :
Sub COMPTAGE()
Dim PLAGE As Variant, P%, TROUVE As Variant, RESULTAT%
PLAGE = Array(("C8:N32"), ("C38:N62"), ("C68:N92"), ("C98:N122"), ("C128:N152"), ("R8:AD32"), ("R38:AD62"), ("R68:AD92"), ("R98:AD122"), ("R128:AD152"))
For P = 0 To UBound(PLAGE) 'On boucle pour chaque plage du tableau PLAGE
Set TROUVE = Range(PLAGE(P)).Find("*") 'On cherche une valeur dans la plage P
If Not TROUVE Is Nothing Then RESULTAT = RESULTAT + 1 'Si le résultat n'est pas rien (donc si quelque chose est trouvé) alors on incrémente
Next P 'On passe à la prochaine plage
MsgBox "Il y a " & RESULTAT & " plages utilisées"
End Sub
En tout cas je suis rassuré que ça fonctionne. N'hésitez pas à passer votre sujet en résolu si la solution vous convient pour améliorer la lisibilité du forum.
Cdlt,
Edit : Pedro22 merci pour le CountA il faudra que je m'en souvienne si je veux à l'occasion comptabiliser les cellules sans les tester une à une !
Pour éviter le -8
, il faut utiliser un Abs
quelque part, j'ai tendance à oublier que VBA ne converti pas True
en 1
lors du passage en numérique.
Concernant ta modification sur le code de Ergotamine, je te conseille de remplacer ton 10
par UBound(PLAGE) + 1
(qui évoluera en même temps que le nombre de plages).
@Pedro22
J'ai testé en plaçant Abs(RESULTAT) dans le MsgBox de ton code et ça fonctionne !
Merci pour l'astuce, il y a des chances que la version finale comporte 15 plages, ça me fera 1 chose à modifier en moins...