IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Syntaxe variables avec CountIf [XL-2013]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2017
    Messages : 30
    Par défaut Syntaxe variables avec CountIf
    Bonjour le forum,

    Je viens solliciter votre aide.

    Mon classeur Excel est organisé de la manière suivante:
    - Colonne 1: Nom des tâches
    - Colonne 2: Date de début
    - Colonne 3: Date de fin
    - Colonne 4 : Code permettant de différencier les différentes tâches.

    Mon but c'est d'ajouter des valeurs aux colonnes 2 et 3 de mes tâches en fonction du code qu'elles contiennent (colonne 4).

    Je suis donc parti sur un Userform dans lequel je définis dans un Textbox la valeur que je souhaite ajouter à mes colonnes. Ci-dessous mon code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Private Sub CommandButton3_Click()  'Bouton Valider
     
    Dim S As Integer, derLig As Integer, i As Integer, f As Worksheet, a As Integer, b As Integer
     
        'modif_duree
        If TextBox1 = "" Then
            Exit Sub
        End If
     
        Set f = Sheets("Feuil1")
        With f
        DerniereLigne = Feuil1.Range("A300").End(xlUp).Address
        L = Range(DerniereLigne).Row
     
    'Compte le nombre total de tâches avec le code Super
     
        For i = 2 To L
        S = WorksheetFunction.CountIf(.Range(.Cells(2, 4), .Cells(i, 4)), "Super")
     
        Next i
     
    'Ajout des valeurs
     
        For i = 2 To L
     
        'Condition uniquement pour la première ligne de Super
        If S = 1 Then
        .Cells(i, 3) = .Cells(i, 3) + ((1 / (S * 3)) * Val(TextBox1))
     
     
        'Condition sur toutes les autres ligne de Super (de la 2èeme à la dernière)
        ElseIf S > 1 Then
                    .Cells(i, 2) = .Cells(i, 2) + ((a - 1 / (S * 3)) * Val(TextBox1))
                    .Cells(i, 3) = .Cells(i, 3) + ((a / (S * 3)) * Val(TextBox1))
        End If
     
        Next i
     
        End With
     
       Set f = Nothing
     
        TextBox1 = ""
    repartition.Hide
    End Sub
    Le principe est le suivant:

    1 - Compter le nombre total de tâches (ou lignes) portant le code Super dans la colonne 4
    2 - Appliquer une première condition Uniquement sur la première tâche avec le code Super
    2 - Appliquer une deuxième condition sur toutes les autres lignes (de la 2 ème à la dernière) portant le code Super.

    La partie du code suivante me permet de déterminer à l'aide de la fonction CountIf le nombre total de lignes avec le code Super:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    'Compte le nombre total de tâches avec le code Super
     
        For i = 2 To L
        S = WorksheetFunction.CountIf(.Range(.Cells(2, 4), .Cells(i, 4)), "Super")
     
        Next i
    Mon problème vient dans la suite du code. Je n'arrive pas à trouver la bonne syntaxe pour définir ma variable a ni à appliquer les conditions Uniquement sur la première ligne de Super dans un premier temps puis sur toutes les autres lignes de Super dans un deuxième temps dans la partie suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    For i = 2 To L
     
        'Condition uniquement pour la première ligne de Super
        If S = 1 Then
        .Cells(i, 3) = .Cells(i, 3) + ((1 / (S * 3)) * Val(TextBox1))
     
     
        'Condition sur toutes les autres ligne de Super (de la 2èeme à la dernière)
        ElseIf S > 1 Then
                    .Cells(i, 2) = .Cells(i, 2) + ((a - 1 / (S * 3)) * Val(TextBox1))
                    .Cells(i, 3) = .Cells(i, 3) + ((a / (S * 3)) * Val(TextBox1))
        End If
     
        Next i
    Je voudrais ajouter dans la colonne 3 de la première ligne portant le code "Super" la valeur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    + ((1 / (S * 3)) * Val(TextBox1))
    Avec S = le nombre total de ligne portant le code Super

    Puis sur toutes les autres lignes toujours avec le code Super en colonne 4 (de la 2 ème à la dernière ligne), ajouter la valeur suivante:

    -Dans la colonne 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    + ((a - 1 / (S * 3)) * Val(TextBox1))
    avec a -1 = le numéro de ligne Super précédent. Si on est à la troisième ligne de Super, a-1 = 2

    -Dans la colonne 3 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    + ((a / (S * 3)) * Val(TextBox1))
    avec a = le numéro de ligne Super actuel Si on est à la troisième ligne de Super, a =3

    Toujours avec S = le nombre total de lignes de Super.

    Pouvez-vous m'orienter dans ma démarche?

    Je vous remercie d'avance pour votre aide !

    Ci-joint mon classeur Excel.
    Fichiers attachés Fichiers attachés

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Déjà, commençons par compter le nombre "Super" présent dans ta colonne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Dim nbOccurence As Variant
    Dim derLig As Integer
     
        'Récupère le nombre de ligne de ton fichier
        derLig = .Cells(Rows.Count, 4).End(xlUp).Row
        'Calcul le nombre de fois que "Super" est présent dans ta colonne
        nbOccurence = Evaluate("COUNTIF(D2:D" & derLig & ",""Super"")")
    Ensuite, on va utiliser un Find pour trouver les lignes comprenant le mot "Super" en colonne 4 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim r As Range
    Dim f As WorkSheet
     
        With f
               'On récupère la première ligne comportant "Super"
               Set r = .Range("D2:D"  & derLig).Find("Super")
    Ensuite, on applique ton calcul sur la première ligne trouvé et on passe à la ligne suivant (en gardant le numéro de la ligne précédente pour tes futurs calculs) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim lignePrec As Integer
     
          'On applique ton calcul
         .Cells(r.Row, 3) = .Cells(r.Row, 3) + ((1 / (nbOccurence - 3)) - Val(TextBox1))
     
         'On garde en mémoire le numéro de la ligne
         lignePrec = r.Row
     
         'On passe à la ligne suivante
         Set r = .Range("D2:D" & derLig).FindNext(r)
    Et enfin, on applique les autres calculs à toutes les autres lignes trouvés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Dim address As String
     
    If Not r Is Nothing Then
     
                'On garde en mémoire l'adresse de la ligne actuelle
                address = r.address
     
                Do
     
                    'On applique tes calculs
                    .Cells(r.Row, 2) = .Cells(r.Row, 2) + ((lignePrec / (nbOccurence * 3)) * Val(TextBox1))
                    .Cells(r.Row, 3) = .Cells(r.Row, 3) + ((r.Row / (nbOccurence * 3)) * Val(TextBox1))
     
                    'On récupère le numéro de la ligne actuel
                    lignePrec = r.Row
                    'On passe à la ligne suivante
                    Set r = .Range("D2:D" & derLig).FindNext(r)
     
                'Et on fait ceci tant que l'on a des ligne a étudié ou tant que l'on est pas retourné à la première ligne étudiée
                Loop While Not r Is Nothing And r.address <> address
     
        End If
    Voilà, avec ceci tu as toute les cartes en main pour résoudre ton problème, si tu as des question hésite pas.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2017
    Messages : 30
    Par défaut
    Bonjour Oudouner,

    Merci beaucoup pour ton aide, j'ai complété ta macro en rajoutant "Feuil1" avant les et afin qu'elle fonctionne sur mon classeur .

    J'ai fait un test et la macro fonctionne très bien. Il y a juste un petit soucis:

    - La macro commence à s’exécuter à partir de la ligne 4 de mon classeur (soit à la 2 ème tâche avec le code "Super") plutôt qu'à partir de la ligne 2 (première tâche avec le code super) comment y remédier?

    J'ai également une deuxième question à te poser parce que je pense que je me suis un peu mal exprimé .

    Est-il possible de remplacer par le numéro de Super actuel et par le numéro de Super précédent dans la partie du code suivante?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    + ((lignePrec / (nbOccurence * 3)) * Val(TextBox1))
    + ((r.Row / (nbOccurence * 3)) * Val(TextBox1))
    Par exemple dans cette illustration,

    Nom : 3.PNG
Affichages : 938
Taille : 13,0 Ko

    la ligne 2 contient la 1ère tâche super
    la ligne 4 la 2ème tâche super
    la ligne 6 la 3ème tâche super
    etc...

    Ainsi en prenant la ligne 8 de cet exemple, celle-ci contient la 4 ème tache de super, on aurait donc le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    .Cells(8, 2) = .Cells(8, 2) + (( 3 / (nbOccurence * 3)) * Val(TextBox1))
    .Cells(8, 3) = .Cells(8, 3) + ((4 / (nbOccurence * 3)) * Val(TextBox1))
    puis pour on aurait Je sais pas si j'ai été un peu plus clair.

    Je te remercie d'avance

  4. #4
    Invité
    Invité(e)
    Par défaut
    Si j'ai bien compris, essaye avec sa (à intégrer dans tout ton code bien sur) :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Public Sub barrym()
     
    Dim S As Integer, derLig As Integer, i As Integer, f As Worksheet, a As Integer, r As Range, nbOccurence As Variant, address As String, lignePrec As Integer
     
        Set f = ActiveWorkbook.Sheets("Feuil1")
     
        With f
     
            derLig = .Cells(Rows.Count, 4).End(xlUp).Row
            nbOccurence = Evaluate("COUNTIF(D2:D" & derLig & ",""Super"")")
        'Compte le nombre total de tâches avec le code Super
     
            Set r = .Range("D1:D" & derLig).Find("Super")
     
            .Cells(r.Row, 3) = .Cells(r.Row, 3) + ((1 / (nbOccurence - 3)) - Val(TextBox1))
     
            lignePrec = 1
            Set r = .Range("D1:D" & derLig).FindNext(r)
     
             If Not r Is Nothing Then
     
                    'On garde en mémoire l'adresse de la première ligne
                    address = r.address
     
                    Do
     
                        .Cells(r.Row, 2) = .Cells(r.Row, 2) + ((lignePrec / (nbOccurence * 3)) * Val(TextBox1))
                        .Cells(r.Row, 3) = .Cells(r.Row, 3) + ((lignePrec + 1 / (nbOccurence * 3)) * Val(TextBox1))
     
                        'On récupère le numéro de la ligne actuel
                        lignePrec = lignePrec + 1
                        'On passe à la ligne suivante
                        Set r = .Range("D1:D" & derLig).FindNext(r)
     
                    'Et on fait ceci tant que l'on a des ligne a étudié ou tant que l'on est pas retourné à la première ligne étudiée
                    Loop While Not r Is Nothing And r.address <> address
     
            End If
        End With
     
    End Sub

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2017
    Messages : 30
    Par défaut
    Parfait, c'est exactement ce qu'il me fallait, tu m'enlèves une épine du pied. Merci beaucoup !

    Un dernier point, dans la deuxième partie de la macro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     Set r = f.Range("D1:D" & derLig).FindNext(r)
     
             If Not r Is Nothing Then
     
                    'On garde en mémoire l'adresse de la première ligne
                    address = r.address
     
                    Do
     
                        f.Cells(r.Row, 2) = f.Cells(r.Row, 2) + ((lignePrec / (nbOccurence * 3)) * Val(TextBox1))
                        f.Cells(r.Row, 3) = f.Cells(r.Row, 3) + (((lignePrec + 1) / (nbOccurence * 3)) * Val(TextBox1))
     
                        'On récupère le numéro de la ligne actuel
                        lignePrec = lignePrec + 1
                        'On passe à la ligne suivante
                        Set r = f.Range("D1:D" & derLig).FindNext(r)
     
                    'Et on fait ceci tant que l'on a des ligne a étudié ou tant que l'on est pas retourné à la première ligne étudiée
                    Loop While Not r Is Nothing And r.address <> address
     
            End If
    La boucle tourne jusqu'à revenir sur la première tâche Super et applique de nouveau l'ajout des valeurs. Peut-on rajouter une condition pour qu'une fois de retour sur la première ligne, qu'il n'y ait pas de nouvelle fois un ajout de valeur?

    La première tâche Super est actuellement affectée dans un premier temps par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Set r = f.Range("D1:D" & derLig).Find("Super")
     
     f.Cells(r.Row, 3) = f.Cells(r.Row, 3) + ((1 / (nbOccurence * 3)) * Val(TextBox1))
     
     lignePrec = 1
    Puis un fin de macro lorsque la boucle revient à la première tache Super par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f.Cells(r.Row, 2) = f.Cells(r.Row, 2) + ((lignePrec / (nbOccurence * 3)) * Val(TextBox1))
     f.Cells(r.Row, 3) = f.Cells(r.Row, 3) + (((lignePrec + 1) / (nbOccurence * 3)) * Val(TextBox1))
    Hors logiquement avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Loop While Not r Is Nothing And r.address <> address
    La macro est censée s'arrêter une fois de retour à la première tâche. (Elle s'arrête bien à la première tâche mais après avoir rajouté les valeurs).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Ah oui ! Excuse moi c'est une erreur de ma part, il faut conserver l'adresse de la première ligne avant de rencontrer dans le If !
    De cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Public Sub barrym()
     
    Dim S As Integer, derLig As Integer, i As Integer, f As Worksheet, a As Integer, r As Range, nbOccurence As Variant, address As String, lignePrec As Integer
     
        Set f = ActiveWorkbook.Sheets("Feuil1")
     
        With f
     
            derLig = .Cells(Rows.Count, 4).End(xlUp).Row
            nbOccurence = Evaluate("COUNTIF(D2:D" & derLig & ",""Super"")")
        'Compte le nombre total de tâches avec le code Super
     
            Set r = .Range("D1:D" & derLig).Find("Super")
     
            .Cells(r.Row, 3) = .Cells(r.Row, 3) + ((1 / (nbOccurence - 3)) - Val(TextBox1))
     
            lignePrec = 1
            address = r.address
            Set r = .Range("D1:D" & derLig).FindNext(r)
     
             If Not r Is Nothing Then
     
                    'On garde en mémoire l'adresse de la première ligne
     
                    Do
     
                        .Cells(r.Row, 2) = .Cells(r.Row, 2) + ((lignePrec / (nbOccurence * 3)) * Val(TextBox1))
                        .Cells(r.Row, 3) = .Cells(r.Row, 3) + ((lignePrec + 1 / (nbOccurence * 3)) * Val(TextBox1))
     
                        'On récupère le numéro de la ligne actuel
                        lignePrec = lignePrec + 1
                        'On passe à la ligne suivante
                        Set r = .Range("D1:D" & derLig).FindNext(r)
     
                    'Et on fait ceci tant que l'on a des ligne a étudié ou tant que l'on est pas retourné à la première ligne étudiée
                    Loop While Not r Is Nothing And r.address <> address
     
            End If
        End With
     
    End Sub

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Syntax setTimeout avec variable.
    Par defacta dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 19/08/2009, 15h14
  2. syntaxe like avec variable
    Par xirom dans le forum Requêtes
    Réponses: 3
    Dernier message: 23/09/2008, 22h56
  3. Syntaxe Range avec une variable pour la colonne
    Par Spykerman dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 25/06/2008, 13h50
  4. vba syntaxe dlookup avec 2 variables
    Par Chris 81 dans le forum VBA Access
    Réponses: 2
    Dernier message: 26/11/2007, 16h30
  5. erreur syntaxe variable avec un caractère ":"
    Par wiss20000 dans le forum JDBC
    Réponses: 15
    Dernier message: 19/03/2007, 15h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo