Microsoft 365 somme.si en excluant les doublons

sebsti34

XLDnaute Nouveau
Bonjour,

après des heures à chercher et à faire des tests j'en appel aux pros

J'ai un fichier (celui que j'ai mis en exemple contient des données bidons car l'autre est une usine à gaz avec 700 lignes qui évoluent plusieurs fois par jour)

Je souhaiterais donc faire une somme de la colonne B, seulement si il y a une date en colonne D sans prendre en compte le doublon en colonne A. Dans mon tableau le bon résultat est donc 1400 et avec mes formules que j'ai testé je tombe toujours sur 1600 car je n'arrive pas à éliminer le doublon en A. Le chiffre en B sera toujours le même par rapport à la donnée en A donc peut importe quelle ligne est choisi pour la somme.
Je sais supprimer les doublons avec l'onglet données, mais je ne veux pas les supprimer, simplement ne pas les prendre en compte dans mon somme.si.
J'ai aussi essayé une formule avec SI(NB.SI afin d'afficher des 0 ou des 1 dans une colonne ajoutée à la fin mais le 1 s'ajoute bien sur le derniere doublon de la liste et c est pas forcément celui qui a une date en colonne D

quelqu'un pourrait me donner une piste?

Merci d'avance, bonne journée à tous.
 

Pièces jointes

  • exemple.xlsx
    9 KB · Affichages: 19
Solution
allez, pour aller encore un peu plus loin ... si je veux ajouter un critère de date pour que ça comptabilise uniquement entre telle date et telle date ou après telle date.
Voyez ce fichier (2) et la fonction VBA complétée avec 2 arguments supplémentaires facultatifs :
VB:
Function MaSomme#(plage As Range, colNom%, colDate%, colSomme%, Optional dat1 As Date, Optional dat2 As Date)
Dim d As Object, tablo, i&, dat, test As Boolean
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
tablo = plage 'matrice, plus rapide
For i = 1 To UBound(tablo)
    dat = tablo(i, colDate)
    test = IIf(dat1 And dat2, dat >= dat1 And dat <= dat2, True)
    If IsDate(tablo(i, colDate)) Then If test Then...

sebsti34

XLDnaute Nouveau
Bonjour sebsti34, le forum,

Ne pas touchze au code VBA.

Les modifs sont à faire éventuellement dans la formule de la feuille de calcul :

- 1er argument => référence de la plage contenant les données à traiter

- 2ème argument => n° de colonne des noms dans cette plage

- 3ème argument => n° de colonne des dates dans cette plage

- 4ème argument => n° de la colonne des nombres à sommer.

Vous devez absolument comprendre pourquoi j'ai mis 1;4;2 dans la formule en G6.

A+

J'ai bien compris à quoi correspondent les données dans G6 et donc j'ai modifié avec les numéros des colonnes correspondante et la plage correspondante, j'ai mis le code dans un module standard , mais j'ai #VALEUR qui s'affiche à la place de mon résultat
 

sebsti34

XLDnaute Nouveau
Si je souhaite faire la même chose sauf que ce n'est pas une somme d'une colonne avec des nombres que je veux mais plutot l'équivalent d'un nb.si pour connaitre le nb de case qui contiennent du texte tout en ne prenant pas en compte les fameux doublons, la modif se fait cette fois dans le code vb?
 

job75

XLDnaute Barbatruc
le nb de case qui contiennent du texte tout en ne prenant pas en compte les fameux doublons, la modif se fait cette fois dans le code vb?
Oui, utilisez cette fonction VBA :
VB:
Function MonNombre&(plage As Range, colNom%, colDate%)
Dim d As Object, tablo, i&
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
tablo = plage 'matrice, plus rapide
For i = 1 To UBound(tablo)
    If IsDate(tablo(i, colDate)) Then If tablo(i, colNom) <> "" Then d(tablo(i, colNom)) = ""
Next
MonNombre = d.Count
End Function
3 arguments suffisent.

Edit : code simplifié.
 

Pièces jointes

  • MonNombre(1).xlsm
    47.6 KB · Affichages: 3
Dernière édition:

sebsti34

XLDnaute Nouveau
Oui, utilisez cette fonction VBA :
VB:
Function MonNombre&(plage As Range, colNom%, colDate%)
Dim d As Object, tablo, i&
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
tablo = plage 'matrice, plus rapide
For i = 1 To UBound(tablo)
    If IsDate(tablo(i, colDate)) Then If Not d.exists(tablo(i, colNom)) Then _
        MonNombre = MonNombre + 1: d(tablo(i, colNom)) = ""
Next
End Function
3 arguments suffisent.

Au Top!! ça fonctionne! un grand merci!
 

sebsti34

XLDnaute Nouveau
allez, pour aller encore un peu plus loin ... si je veux ajouter un critère de date pour que ça comptabilise uniquement entre telle date et telle date ou après telle date. J'ai essayé de bricoler des trucs mais le vba c est vraiment pas mon truc. j'en suis aux formules simples dans excel ;)
A la base je ne pensais pas aller aussi loin mais du coup ça m'aide énormément.
 

sebsti34

XLDnaute Nouveau
Bonjour sebsti34,
Puis-je avoir un retour sur ma proposition sur un autre forum, avec les fonctions UNIQUE() et FILTRE() ?
Cdlt.

En fait ça fonctionnait sur le petit tableau d'exemple mais après ça ne fonctionnait plus suivant certains cas. si c'est le dernier doublon qui possède une date en principe ça allait, mais si c'est un doublon au milieux (par exemple le V3 et qu il y a en dessous un V4 et V5 etc) ça ne fonctionnait plus.
 

Jean-Eric

XLDnaute Occasionnel
Re,
Bonjour à tous,
Il faut passer par XLD pour avoir un retour ! :mad:
Sinon, la même réponse avec ton fichier sur XLD.
Cdlt.

iso4219.png
 

Pièces jointes

  • reel2.xlsx
    41.5 KB · Affichages: 2

job75

XLDnaute Barbatruc
allez, pour aller encore un peu plus loin ... si je veux ajouter un critère de date pour que ça comptabilise uniquement entre telle date et telle date ou après telle date.
Voyez ce fichier (2) et la fonction VBA complétée avec 2 arguments supplémentaires facultatifs :
VB:
Function MaSomme#(plage As Range, colNom%, colDate%, colSomme%, Optional dat1 As Date, Optional dat2 As Date)
Dim d As Object, tablo, i&, dat, test As Boolean
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
tablo = plage 'matrice, plus rapide
For i = 1 To UBound(tablo)
    dat = tablo(i, colDate)
    test = IIf(dat1 And dat2, dat >= dat1 And dat <= dat2, True)
    If IsDate(tablo(i, colDate)) Then If test Then If Not d.exists(tablo(i, colNom)) _
        Then MaSomme = MaSomme + tablo(i, colSomme): d(tablo(i, colNom)) = ""
Next
End Function
Si l'on veut traiter toutes les dates après Date 1 donner une date éloignée à Date 2 (01/01/2030).
 

Pièces jointes

  • MaSomme(2).xlsm
    47.6 KB · Affichages: 4

sebsti34

XLDnaute Nouveau
Voyez ce fichier (2) et la fonction VBA complétée avec 2 arguments supplémentaires facultatifs :
VB:
Function MaSomme#(plage As Range, colNom%, colDate%, colSomme%, Optional dat1 As Date, Optional dat2 As Date)
Dim d As Object, tablo, i&, dat, test As Boolean
Set d = CreateObject("Scripting.Dictionary")
d.CompareMode = vbTextCompare 'la casse est ignorée
tablo = plage 'matrice, plus rapide
For i = 1 To UBound(tablo)
    dat = tablo(i, colDate)
    test = IIf(dat1 And dat2, dat >= dat1 And dat <= dat2, True)
    If IsDate(tablo(i, colDate)) Then If test Then If Not d.exists(tablo(i, colNom)) _
        Then MaSomme = MaSomme + tablo(i, colSomme): d(tablo(i, colNom)) = ""
Next
End Function
Si l'on veut traiter toutes les dates après Date 1 donner une date éloignée à Date 2 (01/01/2030).
nikel, ça fonctionne parfaitement. merci beaucoup
 

Membres actuellement en ligne

Statistiques des forums

Discussions
315 097
Messages
2 116 186
Membres
112 679
dernier inscrit
Yupanki