Compter le nombre de cellules sans les doublons

Moonshine33

XLDnaute Nouveau
Bonjour,
Dans une base de données, je souhaite compter le nombre de cellules d'une colonne sans compter les doublons, sous condition d'une date située dans une autre colonne. Ci-joint un fichier exemple pour mieux comprendre ma demande.
Ma demande est de calculer par exemple pour le mois de janvier 2017 situé en colonne A, le nombre de cellules différentes situées en colonne B, mais sans compter les récurrences.
En gros, je souhaite pouvoir compléter le tableau que j'ai mis sur la page (où ma valeur sera toujours 4 pour cet exemple, car je n'ai que 4 produits A-B-C-D), mais avec une formule excel ou une macro.
J'ai vu la formule : {=SOMME(SI(PLAGE<>"";1/NB.SI(PLAGE;PLAGE))), mais ça ne fonctionne pas comme je souhaite...
Merci d'avance à ceux qui prendront le temps de m'aider !
Moonshine.
 

Pièces jointes

  • Exemple1.xlsx
    9.5 KB · Affichages: 72

zebanx

XLDnaute Accro
Bonjour à tous,

@job75 quel acharnement - merci !:)

J'ai tenté de repatir du (très bon) code VBA de Pierre-Jean pour KIM (#5)
Ca donnerait ça en prenant une correction sur le "-1" et réglé par une formule car je n'arrive pas à coller une instruction dans la fonction pour la faire passer de -1 à 0 s'il n'y a pas d'occurences.

Cdlt
zebanx

------
Function nb_sp2(zone, ref, ref2)
tablo = zone
For n = LBound(tablo) To UBound(tablo)
If CStr((tablo(n, 1)) & "-" & (tablo(n, 2))) = CStr((ref) & "-" & (ref2)) Then
If InStr(dif, tablo(n, 3)) = 0 Then dif = dif & tablo(n, 3) & ";"
End If
Next
nb_sp2 = UBound(Split(dif, ";"))
If np_sp2 < 0 Then
np_sp2 = 0
End If
End Function
 

Pièces jointes

  • pj-fonction-valDiff 2.xls
    62.5 KB · Affichages: 51

job75

XLDnaute Barbatruc
Bonjour le fil, bonjour Nicole,

Pour le problème de KIM voici 2 fonctions VBA utilisant le Dictionary.

1) Sans feuille "Produits", fichier (3) :
Code:
Dim d As Object 'mémorise pour gagner du temps sur la création

Function nb_sp1&(zone, texte$)
Dim n&
zone = zone 'matrice, plus rapide
If d Is Nothing Then Set d = CreateObject("Scripting.Dictionary") Else d.RemoveAll
For n = 1 To UBound(zone)
  If zone(n, 1) & zone(n, 2) = texte Then d(zone(n, 3)) = ""
Next
nb_sp1 = d.Count
End Function
2) Avec feuille "Produits", fichier (3 bis) :
Code:
Dim d As Object 'mémorise pour gagner du temps sur la création

Function nb_sp2&(zone1, zone2, texte$)
Dim n&
zone1 = zone1.Resize(, 2): zone2 = zone2 'matrices, plus rapides (au moins 2 éléments)
If d Is Nothing Then Set d = CreateObject("Scripting.Dictionary") Else d.RemoveAll
For n = 1 To UBound(zone1): d(zone1(n, 1)) = "": Next
For n = 1 To UBound(zone2)
  If zone2(n, 1) & zone2(n, 2) = texte Then _
    If d.exists(zone2(n, 3)) Then nb_sp2 = nb_sp2 + 1: d.Remove zone2(n, 3)
Next
End Function
Durées des recalculs chez moi :

- fichier Compter sans doublons(2).xlsx => 0,29 [Edit : corrigé 0,19] millième de seconde

- fichier Compter sans doublons(3).xlsm => 1,02 [Edit : corrigé 0,92] millième de seconde

- fichier Compter sans doublons(3 bis).xlsm => 1,15 [Edit : corrigé 1,05] millième de seconde

A+
 

Pièces jointes

  • Compter sans doublons(3).xlsm
    22.9 KB · Affichages: 59
  • Compter sans doublons(3 bis).xlsm
    25.5 KB · Affichages: 56
Dernière édition:

KIM

XLDnaute Accro
Bonjour le fil,
@job75, Merci pour ces 2 macros, une autre façon de déclarer les données. J'en profite pour apprendre à optimiser le code utilisé et à résoudre ses problèmes.
Surpris de remarquer qu'une formule est plus rapide qu'un tableau Dictionnary!

Merci encore
Amitiés
KIM
 
Dernière édition:

Moonshine33

XLDnaute Nouveau
Bonjour à tous,
Merci pour vos nombreuses réponses, je vais tester ça. Juste une précision, mais je vois que quelqu'un a soulevé le point, sur mon exemple A-B-C-D ne seront pas connus, je souhaite uniquement que les cellules différentes soient comptées dans un intervalle de temps donné, mais je ne pourrais pas rentrer leur nom dans la formule / macro.
Merci encore,
Moonshine
 

job75

XLDnaute Barbatruc
Re,
Juste une précision, mais je vois que quelqu'un a soulevé le point, sur mon exemple A-B-C-D ne seront pas connus
Dans ce cas il vaut mieux utiliser une fonction VBA, voici la mienne :
Code:
Dim d As Object 'mémorise pour gagner du temps sur la création

Function nb_sp&(zone, ref)
Dim m, y, n&
zone = zone 'matrice, plus rapide
m = Month(ref): y = Year(ref)
If d Is Nothing Then Set d = CreateObject("Scripting.Dictionary") Else d.RemoveAll
For n = 1 To UBound(zone)
  If Month(zone(n, 1)) = m And Year(zone(n, 1)) = y Then d(zone(n, 2)) = ""
Next
nb_sp = d.Count
End Function
Fichier (4).

Edit : le recalcul des formules prend 0,51 millième de seconde.

A+
 

Pièces jointes

  • Exemple(4).xlsm
    23.7 KB · Affichages: 46
Dernière édition:

Moonshine33

XLDnaute Nouveau
Merci pour ta dernière macro Job75, c'est effectivement exactement ce dont j'ai besoin :).
Par contre j'ai du mal à comprendre comment tu définis l'emplacement d'écriture de la macro (mon tableau à droite) et l'emplacement de prise des données, pourrais-tu m'expliquer un peu les lignes de ta macro, pour que je puisse l'adapter à mon vrai fichier (le tableau en question est sur une autre feuille dans mon vrai fichier)? De ce que j'en comprend ce serait "zone" qui définit un emplacement, mais à quoi correspond t-il exactement ?
Je ne suis malheureusement que débutante en VBA :(...
Merci d'avance !
Moonshine
 
Dernière édition:

job75

XLDnaute Barbatruc
Bonjour Moonshine33,

Comme toutes les fonctions VBA le code de la fonction doit être placé dans un module standard.

Pour les données sources il s'agit d'un tableau Excel nommé Tableau1.

Ce tableau peut-être mis n'importe où.

Si vous ne connaissez pas renseignez-vous.

A+