XL 2019 Age sur deux siècles

Caninge

XLDnaute Accro
Bonjour à tous,

j'ai réussi à calculer le nombre d'années entre deux dates, mais seulement s'ils sont sur un même siècle.
Mais deux dates sur deux siècles je n'arrive pas.
Pouvez-vous m'aider s'il vous plait.
CANINGE
 

Pièces jointes

  • Age sur deux siècles.xlsx
    9 KB · Affichages: 28

patricktoulon

XLDnaute Barbatruc
re
d'accords c'est une erreur de ma part avec mes grande manières à la con
de donner des noms avec des maj et des min
donc maintenant elle est tout en majuscule et si tu la tape en min elle passe quand même

j'ai ajouté un argument bouleen "JustYear"si tu veux juste les années
donc dans la formule si tu veux que les "ans" tu ajoute ";1" a la formule
démonstration
demo7.gif


la fonction au propre
VB:
Function DATEDIFFAMJ4$(ByVal dat1 As Date, ByVal dat2 As Date, Optional JustYear As Boolean = False)
  '**************************************
'fonction DateDiffAMJ V°4
'auteur:patricktoulon sur Exceldownloads
'date de mise en jour V°4   :    04/07/2021
' mise a jour supplémentaire
' ajout de l'argument boolean "JustYear" en optional pour ne récupérer que les années
'*************************************
  Dim A$, M$, J$, Dtemp$, et$, yeardécalée&, y
    If dat1 > dat2 Then Dtemp = dat2: dat2 = dat1: dat1 = Dtemp
    If Year(dat1) < 1904 Then If Year(dat1) Mod 4 <> 0 Or Year(dat1) Mod 400 <> 0 Then y = 2020 Else y = 1904
    If Year(dat1) < y Then
        'on decale la date la plus ancienne (Dat1)à l'année 1904
        yeardécalée = Abs((Year(dat1) - y))
        dat1 = DateSerial(Year(dat1) + yeardécalée, Month(dat1), Day(dat1))
        dat2 = DateSerial(Year(dat2) + yeardécalée, Month(dat2), Day(dat2))
    End If
    A = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""y"")")
    M = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""ym"")")
    J = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""md"")")
    A = IIf(A = 0, "", IIf(A = 1, A & " an", A & " ans"))
    M = IIf(M = 0, "", IIf(M = 1, M & " mois", M & " mois"))
    J = IIf(J = 0, "", IIf(J = 1, "1  jour", J & " jours"))
    et = IIf(Val(A) > 0 Or Val(M) > 0, IIf(Val(J) > 0, " et ", " "), "")
    DATEDIFFAMJ4 = Application.Trim(A & IIf(Not JustYear, " " & M & " " & et & J, ""))
End Function
voila maintenant c'est nickel
 

Caninge

XLDnaute Accro
avec mes grande manières à la con : faut pas dire ça tu n'es pas un con !!!!
Tu t'insultes. Si tu étais un con comme tu dis tu serais incapable de faire ça !
Ca marche, Je te remercie !
Pour la petite anecdote, j'ai fait mon service militaire à la BAN Cuers Pierrefeu en 1977.
Ca ne doit pas être loin de chez toi non ?
A plus
 

patricktoulon

XLDnaute Barbatruc
re
oui c'est a moins de 40 km
c'est une mauvaise manie que j'ai pris en apprenant le JS il y a quelques années
en JS et même dans le DOM ,très souvent les fonctions ou constantes sont plusieurs mots accrochés et chaque mot a sa première lettre en MAJ
j'ai gardé cette manie
avec 2007 il n'y avait pas de problème lors de la rédaction de la formule mais depuis 2013 j'ai constaté l'obligation de sélectionner la fonction dans la liste proposée lors que je la tape sans respect de la casse sinon elle est considérée comme du texte pourtant il y a bien le "=" devant

je suis content j'ai ajouté deux options aujourd'hui
entre deux siècles
2° "JustYear"'pour ne récupérer que les années

et tout ça avec la gueule de bois 🤣 🤣 🤣
 

patricktoulon

XLDnaute Barbatruc
Bonjour @eriiic
Tu peux expliquer pourquoi 1904 et 2020 ? Je ne vois pas trop la raison de devoir utiliser une 2nde année.
eric

si l'année de la date la plus ancienne(date 1) est une année bissextile(29 février) je la décale en 2020 qui l'est aussi et le même prorata a date 2

si l'année date1 ne l'ai pas je la met a 1904 qui elle ne l'est pas
alors oui !!!! c'est utile que si la date1 est courant février après le 1 er du mois et que l'ecart entre les deux dates est supreieur d'au moins 1 mois
mais j'ai simplifié la démarche je le fait donc systématiquement

pour la date en l'an 20219 j'avais pas prévu de monté aussi haut car vba ne gère pas des dates aussi loin il est donc inutile d'essayer
VB:
Sub test2()
MsgBox CDate("03/03/20219")
End Sub

donc ma fonction va jusqu'en l'an 9999 et c'est déjà pas mal je crois ;)

et puis si en l'an 9999 +1 un utilisateur a un problème avec ma fonction rien a fout' je serais plus là 🤣;)
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Bonjour,

erreur de frappe lire "2 jours du 28/02/2019 au 01/03/2019"
Mais je devais être sur une autre version car ça ne le fait plus, tu ne touches plus aux dates >=1904.

Ceci dit, c'est bien ce qu'il me semblait...
1904 est bissextile. Donc aucune différence que de la mettre en 2020. Toutes les années <1904 passées en paramètre deviennent bissextiles avec toi (y compris les siècles multiples de 400 donc).
Par exemple on obtient 2 jours du 28/02/1903 au 01/03/1903.

De toute façon, décaler sur une année fixe ne peut pas être la solution.
Tu ne peux pas décaler l'année suivant une année bissextile ailleurs que sur une autre année suivant une année bissextile sans introduire d'erreurs potentielles.
Tu ferais mieux de considérer la proposition de faire +400 ans comme correcte et la plus simple (ou + 800, ou +2000 si tu veux tailler plus large mais il faudra traiter la réforme Grégorienne).
On le fait d'office sur toutes les dates sans se poser de question, sans ajouter de tests pour éliminer les cas particuliers que tu introduits.
Et toutes les dates seront correctement décalées, avec les bissextiles à leur place.
eric
 

patricktoulon

XLDnaute Barbatruc
Ah !!... ben je me disais aussi
en effet 1904 est bissextile donc je change ça et c'est bon je vais mettre 1905 a la place
Merci Eriic

oui pour la réforme grégorienne, j'y ai pensé, j'en parle d'ailleurs dans le topic dans le forum fonctions personnalisées
- 11 jour en dessous 9 décembre 1760

le plus 2000 est une bonne idée aussi finalement c'est plus simple
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
@Eriic tu me diras ce que tu en pense
VB:
Function DATEDIFF_AMJ4$(ByVal dat1 As Date, Optional ByVal dat2 As Date = 0, Optional JustYear As Boolean = False)
  '**************************************
'fonction DateDiffAMJ V°4
'auteur:patricktoulon sur Exceldownloads
'date de mise en jour V°4:04/07/2021
' mise a jour supplementaire
' ajout de l'argument boolean "JustYear" pour ne récuprérer que les années
'*************************************
  Dim A$, M$, J$, Dtemp$, et$, yeardécalée&, y
    If dat2 = 0 Then dat2 = Date
    If dat1 > dat2 Then Dtemp = dat2: dat2 = dat1: dat1 = Dtemp
    If Year(dat2) > 9999 Or Year(dat1) < 1700 Then DATEDIFF_AMJ4$ = "yearLimite!!": Exit Function
    'If Year(dat1) < 1900 Then If Year(dat1) Mod 400 = 0 Then y = 2020 Else y = 1905
    'If Year(dat1) < y Then
     If Year(dat1) < 1900 Then
      if dat1< cdate("09/12/1760") then dat1=dat1-11
  'on decale la date la plus ancienne (Dat1)à l'année +2000
        yeardécalée = 2000 'Abs((Year(dat1) - y))
        dat1 = DateSerial(Year(dat1) + yeardécalée, Month(dat1), Day(dat1))
        dat2 = DateSerial(Year(dat2) + yeardécalée, Month(dat2), Day(dat2))
    End If
    A = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""y"")")
    M = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""ym"")")
    J = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""md"")")
    A = IIf(A = 0, "", IIf(A = 1, A & " an", A & " ans"))
    M = IIf(M = 0, "", IIf(M >= 1, IIf(Val(J) = 0, " et ", "") & M & " mois", M & " mois"))
    J = IIf(J = 0, "", IIf(J = 1, "1  jour", J & " jours"))
    et = IIf(Val(A) > 0 Or Val(M) > 0, IIf(Val(J) > 0, " et ", " "), "")
    DATEDIFF_AMJ4 = Application.Trim(A & IIf(Not JustYear, " " & M & " " & et & J, ""))
End Function
 

Discussions similaires

Réponses
93
Affichages
2 K
  • Résolu(e)
Microsoft 365 =somme.si
Réponses
4
Affichages
88