Signaler

Fonction COUNTIF [Résolu]

Posez votre question camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - Dernière réponse le 17 févr. 2017 à 09:40 par camcam1404
Bonjour,

J'ai besoin d'aide pour une code qui est peut-être un peu compliqué.

J'ai plusieurs feuilles de calcul:
Un feuille appelé "REF"
D'autres feuilles appelés "RES_XX.XX.XXXX" où XX.XX.XXXX correspond à une date que l'on peut retrouver dans la colonne A de la feuille nommé "REF"

Si un feuille "RES_XX.XX.XXXX" contient la date inscrit en colonne A de la feuille appelé "REF", je veux savoir si le contenu de la colonne B de la feuille concernée "RES_XX.XX.XXXX" est contenu dans la colonne C de la feuille nommé "REF". Si oui la colonne C de la feuille "RES_XX.XX.XXXX" contient un 1, si non un 0.
(J’espère avoir bien expliqué le code que je souhaite mettre en place).

Voilà le code que j’ai écrit. Il me semble que la fonction COUNTIF est adapté À ma situation, cependant son utlisation n’est pas très clair pour moi.


Sub pairing()

Dim f As Worksheet
Dim e As Worksheet
Dim lastrow As Long
Dim i As Long

For Each f In ActiveWorkbook.Worksheets

If UCase(f.Name) Like "*REF*" Then
       e = f.Name
       End If

If UCase(f.Name) Like "*RES_*" Then 

lastrow = f.Range("A" & Application.Rows.Count).End(xlUp).Row

For i = 2 To lastrow

While f.Range("A:A") Like f.Name Then 

If   ActiveCell.FormulaR1C1 = "=COUNTIF(RES_310117!C[-3],REF!RC[-2])" Then                                      
                        Colums(i,3)=1 
                Else   Colums(i,3)=0
                 End if

Wend
         Next i

End If

Next f

End Sub



ActiveCell.FormulaR1C1 = "=COUNTIF(RES_310117!C[-3],REF!RC[-2])" (C´est ce que j'obtient avec l'enregistreur de macro mais je vois pas trop comment adapté cette formule a mon cas)
J´ai essayé ceci sans succés: countif(f.Cells(i,2),e.Cells (i,3)
Afficher la suite 
Utile
+0
moins plus
Bonjour Camcam, bonjour le forum,

Les explications sont claires ! Mais un petit fichier exemple viendrait illuminer encore plus cette clarté (obscure) car même ton code est confus pour moi...
camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 8 févr. 2017 à 11:45
Comment joindre un fichier À la conversation ?
Répondre
ThauTheme 4086Messages postés mardi 21 octobre 2014Date d'inscription 23 février 2017 Dernière intervention - 8 févr. 2017 à 12:05
Re,

Par exemple : http://www.cjoint.com/
mais il y a en plein d'autres...
Répondre
camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 8 févr. 2017 à 17:41
Merci ! Voilà il est là le fichier: http://www.cjoint.com/c/GBiqOQnaQaM
Répondre
Donnez votre avis
Utile
+0
moins plus
Re,

Le fichier c'est bien mais tes explications sont toujours confuses pour moi. Pourquoi seules 3 cellules sont colorées de jaunes ?
Pourrais-tu rajouter un onglet dans ton fichier en montrant ce que tu désires avoir après le traitement par la macro. Peut-être réussirai-je à mieux comprendre...
camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 9 févr. 2017 à 18:21
Bonsoir,
Voilà ce que je veux obtenir: http://www.cjoint.com/c/GBjrsWnYNev
J'espère que c 'est plus clair maintenant.
J'ai coloré certain cellule de la colonne A dans la feuille REF pour mettre en valeur le changement de date. Les dates correspondent au jour de la création du numéro de série.
Le mesures (j'ai pas donné les valeurs des mesures) sont toujours effectués (feuille RES) le même jour ou le numéro de série a été affecté au produit (feuille REF)

Il faut savoir aussi que plusieurs produit peuvent avoir le même numéro de série uniquement si ils n'ont pas été mesurés à la même date...
Répondre
Donnez votre avis
Utile
+0
moins plus
Re,

Essaie comme ça :

Sub Macro2()
Dim R As Worksheet 'déclare la variable R (onglet REF)
Dim TR As Variant 'déclare la variable TR (Tableau des Références)
Dim O As Worksheet 'déclare la variable O (Onglets)
Dim TD As Variant 'déclare la variable TD (Tableau des Dates)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)

'***************
'les onglet RES_
'***************
Set R = Worksheets("REF") 'définit l'onglet R
TR = R.Range("A1").CurrentRegion 'définit le tableau des références TR
For Each O In Worksheets 'boucle 1 : sur tous les onglets O du classeur
    If O.Name <> R.Name Then 'condition 1 : si le nom de l'onglet O est différent du nom de l'onglet R
        TD = O.Range("A1").CurrentRegion 'définit le tableau des dates TD
        For I = 2 To UBound(TD, 1) 'boucle 2 sur toutes les lignes I du tableau des dates TD (en partant de la seconde)
            For J = 2 To UBound(TR, 1) 'boucle 3 : sur les lignes J du tableau des référence TR (en partant de la seconde)
                'condition 2 :  si la donnée ligne J colonne 1 de TR est égale aux derniers caractères, après le quatrième,
                'du nom de l'onglet O et si les numéros de série sont identiques (en colonne 2 pour TD et en colonne 3 pour TR)
                If TR(J, 1) = Mid(O.Name, 5) And TD(I, 2) = TR(J, 3) Then
                    TD(I, 3) = 1: Exit For 'la donnée ligne I colonne 3 de TD est égale à 1, sort de la boucle 2
                Else 'sinon (condition 2)
                    TD(I, 3) = 0 'la donnée ligne I colonne 3 de TD est égale à 0
                End If 'fin de la condition 2
            Next J 'prochaine ligne de la boucle 2
        Next I 'prochaine ligne de la boucle 1
        'renvoie le tableau TD dans la cellule A1 redimensionnée de l'onglet O
        O.Range("A1").Resize(UBound(TD, 1), UBound(TD, 2)).Value = TD
        Erase TD 'efface le tableau TD
    End If 'fin de la condition 1
Next O 'prochain onglet de la boucle 1

'************
'l'onglet REF
'************
For I = 2 To UBound(TR, 1) 'boucle 1 : sur toutes les lignes I du tableau des références TR (en partant de la seconde)
    With Sheets("RES_" & TR(I, 1)) 'prend en compte l'onglet correspondant à la date de la données ligne I colonne 1 de TR
        TD = .Range("A1").CurrentRegion 'définit la tableau des dates TD
    End With 'fin de la prise en compte l'onglet correspondant à la date de la données ligne I colonne 1 de TR
    For J = 2 To UBound(TD, 1) 'boucle 2 : sur toutes les lignes J du tableau des dates TD (en partant de la seconde)
        'si les numéros de série sont identiques (en colonne 3 pour TR et en colonne 2 pour TD),
        'renvoie 1 dans la cellule ligne I colonne 4 de l'onglet R, va à l'étiquette "suite"
        If TR(I, 3) = TD(J, 2) Then R.Cells(I, 4).Value = 1: GoTo suite
    Next J 'prochaine ligne de la boucle 2
    R.Cells(I, 4).Value = 0 'renvoie 0 dans la cellule ligne I colonne 4 de l'onglet R
suite: 'étiquette
Next I 'prochaien ligne de la boucle 1
End Sub

camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 16 févr. 2017 à 13:15
Re,

- Quand jèxécute ton code j'ai toujours une erreur du type suivant qui apparait:
"Erreur d'exécution 9, l'indice n'appartient pas à la sélection"


-Je n'ai pas déclaré certaines variables car je pensais que j'en avais pas besoin vu que j'utilisais un "Set".


-Oui je sais que c'est plus rapide de travailler avec des tableaux. Je vais pas tarder à m'y mettre.
Répondre
ThauTheme 4086Messages postés mardi 21 octobre 2014Date d'inscription 23 février 2017 Dernière intervention - 16 févr. 2017 à 14:05
Re,

Erreur 9 est souvent le cas quand le nom d'un onglet est différent du nom utilisé dans le code pour y faire référence. Tu m'aurais aussi écrit la ligne surlignée de jaune quand le code plante, j'aurais pu être plus précis...

Set permet de définir une variable objet, mais cela ne la déclare pas !... Toutefois, la déclarations des variable n'est pas obligatoire mais je la recommande toujours pour éviter les erreurs...

• Les variables tableau... J'ai mis du temps à m'y mettre car au début je n'y comprenais que dalle et ça me paraissait trop compliqué. Mais maintenant je n'en démords plus.
Répondre
camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 16 févr. 2017 à 15:39
Re,

C'est la ligne là qui plante:

TD(I, 3) = 1: Exit For pour les onglets RES_
Répondre
ThauTheme 4086Messages postés mardi 21 octobre 2014Date d'inscription 23 février 2017 Dernière intervention - 16 févr. 2017 à 20:14
Re,

Je t'ai proposé un code en utilisant le second fichier que tu as fourni et tu l'as copié/collé dans le premier fichier que tu as fourni...
Dans ce cas, en effet, le CurrentRegion ne dimensionne TD qu'avec deux colonnes seulement. Par conséquent, TD(I, 3) provoque une erreur. il fallait une étiquette ligne 1 pour la colonne C des onglets RES_ et une étiquette ligne 1 colonne D pour l'onglet REF.

J'étais très étonné quand tu m'as dit dans le post #12 que ça ne fonctionnait pas car je teste pratiquement toujours mes codes avant de les proposer...

Revoici donc une version corrigée et fonctionnelle pour les deux fichiers :

Sub Macro2()
Dim R As Worksheet 'déclare la variable R (onglet REF)
Dim TR As Variant 'déclare la variable TR (Tableau des Références)
Dim O As Worksheet 'déclare la variable O (Onglets)
Dim TD As Variant 'déclare la variable TD (Tableau des Dates)
Dim I As Integer 'déclare la variable I (Incrément)
Dim J As Integer 'déclare la variable J (incrément)

'***************
'les onglet RES_
'***************
Set R = Worksheets("REF") 'définit l'onglet R
R.Range("D1").Value = "RES" 'écrit "RES" dans la cellule D1 (la fameuse étiquette manquante)
TR = R.Range("A1").CurrentRegion 'définit le tableau des références TR
For Each O In Worksheets 'boucle 1 : sur tous les onglets O du classeur
    If O.Name <> R.Name Then 'condition 1 : si le nom de l'onglet O est différent du nom de l'onglet R
        O.Range("C1").Value = "RES" 'écrit "RES" dans la cellule C1 (l fameuse étiquette manquante)
        TD = O.Range("A1").CurrentRegion 'définit le tableau des dates TD
        For I = 2 To UBound(TD, 1) 'boucle 2 sur toutes les lignes I du tableau des dates TD (en partant de la seconde)
            For J = 2 To UBound(TR, 1) 'boucle 3 : sur les lignes J du tableau des référence TR (en partant de la seconde)
                'condition 2 :  si la donnée ligne J colonne 1 de TR est égale aux derniers caractères, après le quatrième,
                'du nom de l'onglet O et si les numéros de série sont identiques (en colonne 2 pour TD et en colonne 3 pour TR)
                If TR(J, 1) = Mid(O.Name, 5) And TD(I, 2) = TR(J, 3) Then
                    TD(I, 3) = 1: Exit For 'la donnée ligne I colonne 3 de TD est égale à 1, sort de la boucle 2
                Else 'sinon (condition 2)
                    TD(I, 3) = 0 'la donnée ligne I colonne 3 de TD est égale à 0
                End If 'fin de la condition 2
            Next J 'prochaine ligne de la boucle 2
        Next I 'prochaine ligne de la boucle 1
        'renvoie le tableau TD dans la cellule A1 redimensionnée de l'onglet O
        O.Range("A1").Resize(UBound(TD, 1), UBound(TD, 2)).Value = TD
        Erase TD 'efface le tableau TD
    End If 'fin de la condition 1
Next O 'prochain onglet de la boucle 1

'************
'l'onglet REF
'************
For I = 2 To UBound(TR, 1) 'boucle 1 : sur toutes les lignes I du tableau des références TR (en partant de la seconde)
    With Sheets("RES_" & TR(I, 1)) 'prend en compte l'onglet correspondant à la date de la données ligne I colonne 1 de TR
        TD = .Range("A1").CurrentRegion 'définit la tableau des dates TD
    End With 'fin de la prise en compte l'onglet correspondant à la date de la données ligne I colonne 1 de TR
    For J = 2 To UBound(TD, 1) 'boucle 2 : sur toutes les lignes J du tableau des dates TD (en partant de la seconde)
        'si les numéros de série sont identiques (en colonne 3 pour TR et en colonne 2 pour TD),
        'renvoie 1 dans la cellule ligne I colonne 4 de l'onglet R, va à l'étiquette "suite"
        If TR(I, 3) = TD(J, 2) Then R.Cells(I, 4).Value = 1: GoTo suite
    Next J 'prochaine ligne de la boucle 2
    R.Cells(I, 4).Value = 0 'renvoie 0 dans la cellule ligne I colonne 4 de l'onglet R
suite: 'étiquette
Next I 'prochaien ligne de la boucle 1
End Sub
Répondre
camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 17 févr. 2017 à 09:40
aaaaaaah. Je vois déjà un peu mieux comment les tableaux fonctionnenent avec cette remarque,

Merci encore !

Bonne journée :)
Répondre
Donnez votre avis
Utile
+0
moins plus
Re,

Quand les numéros de série sont identiques, on écrit "1" et il n'y a plus nécessité de continuer la boucle. En revanche, si ils ne sont pas identiques, il faut boucler jusqu'à ce que que l'on trouve (ou pas) la correspondance.
Le Goto permet deux choses : sortir de la boucle (un Exit For aurais pu faire l'affaire) et sauter la ligne qui écrit "0" (le Exit For ne pouvait pas faire ça)...

j'appelle étiquette mais je ne suis pas sur que ce soit le terme exact. GoTo permet de faire continuer le code à un endroit précis. On peut utiliser n'importe quel mot (sauf les mots-clé VBA) suivi de deux points (:) pour définir la ligne où repart le code.
On pourrait écrire par exemple :

If TR(I, 3) = TD(J, 2) Then R.Cells(I, 4).Value = 1: GoTo Camcam
R.Cells(I, 4).Value = 0 'renvoie 0 dans la cellule ligne I colonne 4 de l'onglet R
Camcam: 'étiquette
MsgBox "La Ligne R.Cells(I,4).Value = 0 a été sautée"


J'espère que mes explications sont claires mais si, malgré le code complètement commenté, je dois passer mon temps à expliquer je ne vais pas y arriver. Utilise l'aide VBA avant de poser tes questions...
camcam1404 44Messages postés mardi 13 décembre 2016Date d'inscription 17 février 2017 Dernière intervention - 10 févr. 2017 à 13:15
Compris !
Je me suis aussi renseigné de mon cote À ce sujet , je te rassure.
Parmis tout ce que j'ai lu ton explication est la plus claire, encore meci :)
Répondre
pijaku 12158Messages postés jeudi 15 mai 2008Date d'inscription ModérateurStatut 17 février 2017 Dernière intervention - 16 févr. 2017 à 10:13
Bonjour tous les deux,

Le GoTo, dans ce cas, permet de faire gagner une ligne de code (indiquée ci-dessous).
En effet, une autre solution serait de se servir d'un boolean (ici Test) :
Dim Test As Boolean
For I = 2 To UBound(TR, 1) 
    Test = False 'Unique ligne de code ajoutée
    With Sheets("RES_" & TR(I, 1)) 
        TD = .Range("A1").CurrentRegion 
    End With
    For J = 2 To UBound(TD, 1) 
       If TR(I, 3) = TD(J, 2) Then Test = True: Exit For 
    Next J 
 'Si Test = True, CInt(Test) * - 1 = 1 Si Test = False, CInt(Test) * - 1 = 0
    R.Cells(I, 4).Value = CInt(Test) * -1 
Next I 
End Sub
Répondre
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !