VBA : Compter les cellules vides entre deux valeurs

Fenriz

XLDnaute Nouveau
Bonsoir,

Je m'adresse à vous ce soir, car j'ai une petite question :

Dans le fichier exemple en pièce jointe, j'aimerais savoir s'il était possible de créer une macro pouvant calculer le nombre de cellules vides et des les coller dans une colonne à coté.

Cette liste de 1 et de "vide" est amenée à sans cesse évoluer (je parle en nombre de lignes sur la colonne A).

J'aimerais aussi, dans le cas où deux "1" se suivent, coller la valeur 1 dans une colonne différente de la premère (cf exemple si je ne suis pas suffisament clair).

Regarde la pièce jointe Forum Excel.xlsx

Dans l'attente d'une réponse de votre part, je vous souhaite de passer une bonne soirée.

Fenriz
 

Pièces jointes

  • Forum Excel.xlsx
    11.6 KB · Affichages: 56
  • Forum Excel.xlsx
    11.6 KB · Affichages: 54

Robert

XLDnaute Barbatruc
Repose en paix
Re : VBA : Compter les cellules vides entre deux valeurs

Bonjour Fenriz et bienvenu, bonjour le forum,

Peut-être comme ça :
Code:
Sub Macro1()
Dim O As Object 'déclare la variable O (Onglet)
Dim DL As Long 'déclare la variable DL (Dernière Ligne)
Dim PL As Range 'déclare la variable PL (PLage)
Dim CEL As Range 'déclare la variable CEL (CELlule)
Dim V As Long 'déclare la variable V (nombre de cellules Vides)
Dim U As Long 'déclare la variable U (Nombre de cellules égales à Un)

Set O = Sheets("Sheet1") 'définit l'onglet O
DL = O.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée DL de l'onglet O
Set PL = O.Range("A2:A" & DL) 'définit la plage PL
For Each CEL In PL 'boucle sur toutes les cellules CEL de la plage PL
    Select Case CStr(CEL.Value) 'agit en fonction de la valeur de la cellule convertie en lettre
        Case "1" 'cas "1"
            U = U + 1 'incrément U
            If V > 0 Then CEL.Offset(-1, 1).Value = V 'si V est supérieur à 0, place dans la cellule au dessus en colonne B le nombe de cellules vides V
            V = 0 'réinitialise V
        Case Else 'autre cas
            V = V + 1 'incrémente U
            If U > 1 Then CEL.Offset(-1, 2).Value = U - 1 'si U est supérieur à 1, place dans la cellule au dessus en colonne C le nombre de cellule égales à "1" moins 1
            U = 0 'réinitialise U
    End Select 'fin de l'action en fonction de
Next CEL 'prochaine cellule de la boucle
End Sub
 

Fenriz

XLDnaute Nouveau
Re : VBA : Compter les cellules vides entre deux valeurs

Bonjour,

Un grand merci à vous de m'avoir répondu si vite et si bien ! c'est bien ce que je voulais.

J'aurais encore deux petite demande :
- Est-il possible de déterminer la plage de valeur à prendre en compte dans le calcul des cases vides ?
- Est-il possible de mettre les valeurs calculées dans une autre feuille en supprimant les cases vides entre chaque valeur ?
Cf. fichier joint. une fois celà terminé, je n'aurais plus de question à poser.

Un grand merci encore.
Regarde la pièce jointe Forum Excel.xlsx
 

Pièces jointes

  • Forum Excel.xlsx
    13.1 KB · Affichages: 40
  • Forum Excel.xlsx
    13.1 KB · Affichages: 36
Dernière édition:

Robert

XLDnaute Barbatruc
Repose en paix
Re : VBA : Compter les cellules vides entre deux valeurs

Bonsoir Fenriz, bonsoir le forum,

Ce qui est pénible c'est le changement de requête qui n'a rien à voir avec la précédente. Chaque macro se prépare, s'étudie stratégiquement (p... je me prends pour Napoléon maintenant ! Faut que j'arrête de boire...) pour être le plus efficace. Ta modification m'oblige soit à tout repenser soit à bidouiller la première pour que ça fonctionne...
Par manque de neurones ou par flemme j'ai choisi de bidouiller. C'est pas terrible mais ça semble fonctionner.
Tu demandes de n'utiliser que la plage A2:A48 pour le calcul des cellules vides. Mais tu n'as pas précisé si c'était aussi pour le calcul des 1 adjacents ? Le code ci-dessous ne fait le calcul pour les deux données que sur la plage A2:A48 j'espère que c'est bien ça que tu voulais.
Le code :
Code:
Sub Macro1()
Dim A49 As String 'déclare la variable A49 (Contenu de la cellule A49)
Dim O1 As Object 'déclare la variable O1 (Onglet 1)
Dim O2 As Object 'déclare la variable O2 (Onglet 2)
Dim PL As Range 'déclare la variable PL (PLage)
Dim CEL As Range 'déclare la variable CEL (CELlule)
Dim V As Long 'déclare la variable V (nombre de cellules Vides)
Dim U As Long 'déclare la variable U (Nombre de cellules égales à Un)
Dim Dest As Range 'décalre la variable Dest (cellule de Destination)

Set O1 = Sheets("Sheet1") 'définit l'onglet O1
Set O2 = Sheets("Sheet2") 'définit l'onglet O2
'la cellule A49 permet d'afficher la dernière valeur V ou U
Set PL = O1.Range("A2:A49") 'définit la plage PL
A49 = CStr(O1.Range("A49").Value) 'définit la variable A49
O1.Range("A49").Value = "" 'vide le contenue de la cellule A49 (pour le besoin de la boucle)
For Each CEL In PL 'boucle sur toutes les cellules CEL de la plage PL
    Set Dest = Nothing 'réinitalise la variable Dest
    Select Case CStr(CEL.Value) 'agit en fonction de la valeur de la cellule convertie en lettre
        Case "1" 'cas "1"
            U = U + 1 'incrément U
            If V > 0 Then 'condition : si V est positif
                'définit la variable dest (si la ligne de la première cellule vide de la colonne B est supérieure à la ligne 1,
                'Dest est la première cellule vide de la colonne A, sinon
                'Dest est la première cellule vide de la colonne B, décalée d'une colonne vers la gauche à gauche)
                Set Dest = IIf(O2.Cells(Application.Rows.Count, 2).End(xlUp).Row > 1, _
                   O2.Cells(Application.Rows.Count, 2).End(xlUp).Offset(1, -1), _
                   O2.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0))
                Dest.Value = V ' place dans la cellule de destination Dest le nombe de cellules vides V
            End If 'fin de la condition
            V = 0 'réinitialise V
        Case Else 'autre cas
            V = V + 1 'incrémente U
            If U > 1 Then 'condition : si U est supérieur à 1
                'définit la variable dest (première cellule vide de la colonne A décalée d'une colonne vers la droite)
                Set Dest = O2.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 1)
                Dest.Value = U - 1 'place dans la cellule de destination Dest, le nombe de cellules contenant un, qui se suivent, moins 1
            End If 'fin de la condition
            U = 0 'réinitialise U
    End Select 'fin de l'action en fonction de
Next CEL 'prochaine cellule de la boucle
O1.Range("A49").Value = A49 'récupère la valeur de la cellule A49
End Sub
 

Fenriz

XLDnaute Nouveau
Re : VBA : Compter les cellules vides entre deux valeurs

Bonsoir Robert,

Mille pardons pour mon changement, je ne pensais pas que celà en engendrerait autant de changements dans la macro...
Je suis désolé mais je vais encore être curieux.
En pièce jointe, mon fichier qui me sert tous les jours. J'ai modifié la plage de A2 à A49 en A2 à A306, la macro s'arrête et ne donne pas les bons résultats... (idem quand la plage était de A2 à A49) je ne sais pas pourquoi, le savez-vous ?

Regarde la pièce jointe Forum excel.xlsm

Dans tous les cas, je vous remercie beaucoup et encore désolé de vous embêter avec mon problème.

Bonne soirée.
 

Pièces jointes

  • Forum excel.xlsm
    24 KB · Affichages: 50
  • Forum excel.xlsm
    24 KB · Affichages: 47

Robert

XLDnaute Barbatruc
Repose en paix
Re : VBA : Compter les cellules vides entre deux valeurs

Bonjour Fenriz, bonjour le forum,

La condition qui définissait la cellule de destination Dest était erronée. Certaines valeurs venaient écraser des valeurs précédentes. Le code modifié :
Code:
Sub Test()
Dim BE As Variant 'décalre la variable BE (Boîte d'Entrée)
Dim PL As Range 'déclare la variable PL (PLage)
Dim CF As String 'déclare la variable CF (contenu de la Cellule de Fin)
Dim O1 As Object 'déclare la variable O1 (Onglet 1)
Dim O2 As Object 'déclare la variable O2 (Onglet 2)
Dim CEL As Range 'déclare la variable CEL (CELlule)
Dim V As Long 'déclare la variable V (nombre de cellules Vides)
Dim U As Long 'déclare la variable U (Nombre de cellules égales à Un)
Dim Dest As Range 'décalre la variable Dest (cellule de Destination)

'définit la boite d'entrée BE
Set O2 = Sheets("Sheet2") 'définit l'onglet O2
O2.Range("A1").CurrentRegion.Offset(1, 0).ClearContents 'efface les anciennes données de comptage
debut: 'étiquette
BE = Application.InputBox("Tapez le numéro de ligne de la dernière cellule de la plage à compter.", "DERNIÈRE CELLULE", Type:=1)
If BE = False Then Exit Sub 'si bouton "Annuler", sort de la procédure
If BE > Application.Rows.Count Then GoTo debut 'si le numéro de ligne est supérieur au nombre de lignes de l'application retourne à la boîte d'entrée via l'étiquette "debut"
Set O1 = Sheets("Sheet1") 'définit l'onglet O1
Set PL = O1.Range("A2:A" & BE + 1) 'définit la plage PL (avec uen cellule en plus (vide) pour finaliser le comptage
CF = CStr(O1.Range("A" & BE + 1).Value) 'définit la variable CF
O1.Range("A" & BE + 1).Value = "" 'vide le contenue de la cellule de fin (pour le besoin de la boucle)
For Each CEL In PL 'boucle sur toutes les cellules CEL de la plage PL
    Set Dest = Nothing 'réinitalise la variable Dest
    Select Case CStr(CEL.Value) 'agit en fonction de la valeur de la cellule convertie en lettre
        Case "1" 'cas "1"
            U = U + 1 'incrément U
            If V > 0 Then 'condition : si V est positif
                'définit la variable dest (si la ligne de la première cellule vide de la colonne B est supérieure à la ligne
                'de la première cellule vide de la colonne A, Dest est la première cellule vide de la colonne A, sinon
                'Dest est la première cellule vide de la colonne B, décalée d'une colonne vers la gauche à gauche)
                Set Dest = IIf(O2.Cells(Application.Rows.Count, 2).End(xlUp).Row > O2.Cells(Application.Rows.Count, 1).End(xlUp).Row, _
                   O2.Cells(Application.Rows.Count, 2).End(xlUp).Offset(1, -1), _
                   O2.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0))
                Dest.Value = V ' place dans la cellule de destination Dest le nombe de cellules vides V
            End If 'fin de la condition
            V = 0 'réinitialise V
        Case Else 'autre cas
            V = V + 1 'incrémente U
            If U > 1 Then 'condition : si U est supérieur à 1
                'définit la variable dest (première cellule vide de la colonne A décalée d'une colonne vers la droite)
                Set Dest = O2.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 1)
                Dest.Value = U - 1 'place dans la cellule de destination Dest, le nombe de cellules contenant un, qui se suivent, moins 1
            End If 'fin de la condition
            U = 0 'réinitialise U
    End Select 'fin de l'action en fonction de
Next CEL 'prochaine cellule de la boucle
O1.Range("A" & BE + 1).Value = CF 'récupère la valeur de la cellule de fin
O2.Activate 'active l'oglet O2
End Sub
J'ai rajouté un bouton pour lancer la macro dans ton fichier modifié en pièce jointe :
 

Pièces jointes

  • Fenriz_v01.xlsm
    31.3 KB · Affichages: 40

job75

XLDnaute Barbatruc
Re : VBA : Compter les cellules vides entre deux valeurs

Bonjour Fenriz, Robert,

En analysant les zones c'est simple :

Code:
Sub Analyse_zones()
Dim F1 As Worksheet, F2 As Worksheet, source As Range
Dim dest As Range, a As Range, b As Range, ac&, bc&, i&, j&
Set F1 = Sheet1: Set F2 = Sheet2 'CodeNames à adapter
Set source = F1.[A2:A306] 'plage à adapter
Set dest = F2.[A2] '1ère cellule
dest.Resize(F2.Rows.Count - dest.Row + 1, 2).ClearContents 'RAZ
On Error Resume Next 'si les SpecialCells n'existent pas
source.SpecialCells(xlCellTypeConstants, 2).ClearContents 'vide les ""
Set a = source.SpecialCells(xlCellTypeBlanks) 'vides
Set b = source.SpecialCells(xlCellTypeConstants, 1) 'nombres
ac = a.Areas.Count: bc = b.Areas.Count
For i = 1 To Application.Max(ac, bc)
  j = j + 1
  If i <= ac Then dest(j) = a.Areas(i).Count
  If i <= bc Then If b.Areas(i).Count > 1 Then _
    j = j + 1: dest(j, 2) = b.Areas(i).Count - 1
Next
End Sub
La 9ème ligne du code supprime préalablement les textes vides "" de la plage source.

Fichier joint.

A+
 

Pièces jointes

  • Analyse zones(1).xls
    58 KB · Affichages: 44
Dernière édition:

Fenriz

XLDnaute Nouveau
Re : VBA : Compter les cellules vides entre deux valeurs

Job75, Robert, je vous remercie, c'est tout à fait çà !!!!!!!!!

MERCI à vous deux ! Et en prime, il y à le bouton pour faire fonctionner la macro, c'est le top !!!!!!!!!!!

Je vous souhaite une bonne fin de journée !!!!!
 

job75

XLDnaute Barbatruc
Re : VBA : Compter les cellules vides entre deux valeurs

Re,

En toute rigueur il faut tester la 1ère zone de la plage source :

Code:
Sub Analyse_zones()
Dim F1 As Worksheet, F2 As Worksheet, source As Range
Dim dest As Range, a As Range, b As Range, test As Boolean, i&, j&
Set F1 = Sheet1: Set F2 = Sheet2 'CodeNames à adapter
Set source = F1.[A2:A306] 'plage à adapter
Set dest = F2.[A2] '1ère cellule
dest.Resize(F2.Rows.Count - dest.Row + 1, 2).ClearContents 'RAZ
On Error Resume Next 'si les SpecialCells n'existent pas
source.SpecialCells(xlCellTypeConstants, 2).ClearContents 'vide les ""
Set a = source.SpecialCells(xlCellTypeBlanks) 'vides
Set b = source.SpecialCells(xlCellTypeConstants, 1) 'nombres
test = source(1) = "" 'teste la 1ère zone
For i = 1 To Application.Max(a.Areas.Count, b.Areas.Count)
  j = j + 1
  If test Then
    dest(j) = a.Areas(i).Count
    If b.Areas(i).Count > 1 Then _
      j = j + 1: dest(j, 2) = b.Areas(i).Count - 1
  Else
    If b.Areas(i).Count > 1 Then _
      dest(j, 2) = b.Areas(i).Count - 1: j = j + 1
    dest(j) = a.Areas(i).Count
  End If
Next
End Sub
Fichier (2) où j'ai ajouté 1 en A2 et A3 de Sheet1.

Edit : avec On Error Resume Next pas besoin des tests If i <= ac et If i <= bc...

A+
 

Pièces jointes

  • Analyse zones(2).xls
    58.5 KB · Affichages: 47
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 294
Messages
2 086 891
Membres
103 404
dernier inscrit
sultan87