Date et heure EcartDate

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous,

Beaucoup de question sur comment calculer l'âge d'une personne à partir de sa date de naissance ou bien le nombre d'année, de mois et de jour entre deux dates.

J'ai repris une fonction de @ROGER2327🙂 qui l'avait lui-même reprise de JP Mesters et j'ai ajouté quelques options.

La fonction : EcartDate(Debut As Date, Fin As Date, Optional Quoi As String = "", Optional Langue As String = ".fr")

Debut est la date de début de la période (c'est une vraie date au sens d'Excel pas du texte)
Fin est la date de début de la période (c'est une vraie date au sens d'Excel pas du texte)
Quoi est ce qu'on désire en sortie :
  • ce paramètre est facultatif
  • si quoi = 1 ou "a" ou "y" alors on retourne un nombre qui est le nombre d'année entre le Debut et la Fin
  • si quoi = 2 ou "m" alors on retourne un nombre qui est le nombre de mois entre le Debut et la Fin
  • si quoi = 3 ou "j" ou "d" alors on retourne un nombre qui est le nombre de jour entre le Debut et la Fin
  • si quoi est omis ou différent des valeurs ci-dessus alors on retourne la durée (âge) en texte sous la forme texte : n an m mois j jour
  • on adapte le texte de sortie avec les singuliers ou pluriels requis.
Langue est un texte indiquant la langue à utiliser :
  • ce paramètre est facultatif
  • cet argument sera égal un court texte commençant par un point et suivi du suffixe internet (pour site du pays de la langue désirée)
  • exemple de texte : .fr (français), .gb (anglais), .uk (anglais), .usa (américain), .de (allemand), .es (espagnol), .it (italien), .pt (portugais), .cor (corse)
  • si Langue est omis ou bien ne correspond pas à une des traductions alors la langue sera le français
Pour ajouter une langue dans le code :
  • dupliquer la dernière ligne de type texte = texte & "," & ".cor,annu,anni,m...
  • remplacer cor par le code du pays parlant la langue désirée
  • puis, séparées par des virgules, indiquer les traductions de an (au singulier puis au pluriel), de mois (au singulier puis au pluriel) et enfin de jour (au singulier puis au pluriel).

Vos avis, critiques et suggestions sont les bienvenues. Il faudrait aboutir à une fonction personnalisée avec un consensus "presque général".
Si c'est une mauvaise idée ou bien redondant alors je retirerai la fonction sans en être marri en aucune manière.:)

Le code est dans module1:
VB:
Function EcartDate(Debut As Date, Fin As Date, Optional Quoi As String = "", Optional Langue As String = ".fr")
' adapté d'un code de -> JP Mesters
Const defaut = ".fr"

Dim texte$, Nba&, Nbm&, Nbj&, Retenue&, s$, t, i&
   If Debut > Fin Then EcartDate = "#CHRONOLOGIE!": Exit Function
   texte = ".fr,an,ans,mois,mois,jour,jours"                         'français (.fr)
   texte = texte & "," & ".gb,year,years,month,months,day,days"      'anglais (.gb)
   texte = texte & "," & ".uk,year,years,month,months,day,days"      'anglais (.uk)
   texte = texte & "," & ".usa,year,years,month,months,day,days"     'américain (.usa)
   texte = texte & "," & ".de,Jahr,Jahre,Monat,Monate,Tag,Tage"      'allemand (.de)
   texte = texte & "," & ".es,año,años,mes,meses,día,días"           'espagnol (.es)
   texte = texte & "," & ".it,anno,anni,mese,mesi,giorno,giorni"     'italien (.it)
   texte = texte & "," & ".pt,ano,anos,mês,meses,dia,dias"           'portugais (.pt)
   texte = texte & "," & ".cor,annu,anni,mese,mesi,ghjornu,ghjorni"  'corse (.cor)
 
   Nba = Year(Fin) - Year(Debut)
   Nbm = Month(Fin) - Month(Debut)
   Nbj = Day(Fin) - Day(Debut)
   Retenue = Day(DateSerial(Year(Fin), Month(Fin), 0))
   If Nbj < 0 Then Nbm = Nbm - 1: Nbj = Nbj + Retenue
   If Nbm < 0 Then Nba = Nba - 1: Nbm = Nbm + 12

   Select Case Left(LCase(Quoi), 1)
      Case "a", "y", "1"
         EcartDate = Nba: Exit Function
      Case "m", "2"
         EcartDate = Nbm: Exit Function
      Case "j", "d", "3"
         EcartDate = Nbj: Exit Function
      Case Else
         Quoi = LCase(Quoi): Langue = LCase(Langue): t = Split(LCase(texte), ",")
         If Left(Langue, 1) <> "." Then Langue = defaut
         For i = 0 To UBound(t)
            If Langue = t(i) Then Exit For
         Next i
         If i > UBound(t) Then i = 1
         s = IIf(Nba = 0, "", IIf(Nba = 1, "1 " & t(i + 1), Nba & " " & t(i + 2)))
         s = Trim(s & " " & IIf(Nbm = 0, "", IIf(Nbm = 1, "1 " & t(i + 3), Nbm & " " & t(i + 4))))
         s = Trim(s & " " & IIf(Nbj = 0, "", IIf(Nbj = 1, "1 " & t(i + 5), Nbj & " " & t(i + 6))))
   End Select
   EcartDate = s
End Function
 

Pièces jointes

  • calcul âge-v1.xlsm
    25.7 KB · Affichages: 23
Dernière édition:

patricktoulon

XLDnaute Barbatruc
Bonjour Etoto
déjà perso j'ai ajouté case "mj",4 qui donne la différence en mois et jour
alors que la fonction d'origine donne le même chose que la fonction native datedif et qui n'a donc aucun intérêt selon moi

le calcul en jour n'a aucun intérêt non plus ;sachant que date1- date2 te donne la différence en jour (donc pas besoins de fonction pour ça )

en heure est vraiment utile? tel est la question
si @mapomme est d’accord je donne ma version
 

Etoto

XLDnaute Barbatruc
Bonjour Etoto
déjà perso j'ai ajouté case "mj",4 qui donne la différence en mois et jour
alors que la fonction d'origine donne le même chose que la fonction native datedif et qui n'a donc aucun intérêt selon moi

le calcul en jour n'a aucun intérêt non plus ;sachant que date1- date2 te donne la différence en jour (donc pas besoins de fonction pour ça )

en heure est vraiment utile? tel est la question
si @mapomme est d’accord je donne ma version
Re,
Les heures pour moi c'est pas vraiment utile, mais je vois que dans le forum certains essaient de calculer les écarts en heures (je comprend pas trop pourquoi) et je me suis donc dit que ce serait une bonne idée de voir s'il est possible de rajouter cette option à cette fonction pour aider ceux qui en ont besoin. Mais moi j'en ai pas besoin du tout, je pensais juste aux autres. Je m'y connait pas en VBA mais pour rajouter les heures, il suffirait de faire comme les jours mais de multiplier le résultat par 24.
 

patricktoulon

XLDnaute Barbatruc
re
ma version
VB:
'*****************************************
'Fonction ecartDate
'auteur @mapomme sur exceldownloads (forum des fonctions personalisées vba)
'version:1.0 du 22/05/2021
'mises a jour
'23/05/2021: remplacement du principe split texte par un case langue(par patricktoulon sur exeldownload)
'23/05/2021:ajout de la date fin optionel pour l'age (par patricktoulon sur exeldownload)
'23/05/2021:ajout de la detection de langue system automatique (argument omis)(par patricktoulon sur exeldownload)
'23/05/2021:ajout de l'intitulés optionnel pour tout les cases (par patricktoulon sur exeldownload)
'23/05/2021:modification du case "m",2 qui donnait une réponse éronnée(par patricktoulon sur exeldownload)
'24/05/2021:ajout du case "mj",4 qui donne la difference en mois et en jour(par patricktoulon sur exeldownload)
'24/05/2021:ajout de langue (par patricktoulon sur exeldownload)
Option Explicit

Function EcartDate(Debut As Date, Optional Fin As Date = 0, Optional Quoi As String = "", Optional Langue As String = "")
' adapté d'un code de -> JP Mesters

    If Fin = 0 Then Fin = Date
    If Debut > Fin Then EcartDate = "#CHRONOLOGIE!": Exit Function
    Dim Nba&, Nbm&, Nbmx&, Nbj&, Retenue&, s$, t, i&, withlang
    withlang = Langue <> ""
    If Langue = "" Then Langue = Application.International(xlCountrySetting)

    Select Case LCase(Langue)
    Case ".cor": t = Array("annu", "anni", "mese", "mesi", "ghjornu", "ghjorni")    'corse
    Case 33, ".fr": t = Array("an", "ans", "mois", "mois", "jour", "jours")    'french
    Case 49, ".de": t = Array("Jahr", "Jahre", "Monat", "Monate", "Tag", "Tage")    'allemand
    Case 34, ".es": t = Array("año", "años", "mes", "meses", "día", "días")    'spanich
    Case 1, 44, ".uk", ".gb", ".us": t = Array("year", "years", "month", "months", "day", "days")    'english/US UK GB
    Case 36, ".it": t = Array("anno", "anni", "mese", "mesi", "giorno", "giorni")   'italian
    Case 351, ".pt": t = Array("ano", "anos", "mês", "meses", "dia", "dias")   'portugesh
    Case 90, ".sw": t = Array("år", "år", "månad", "månad", "dag", "dagar")    'Swedish suede
    Case 31, ".pb", ".du": t = Array("jaar", "jaar", "maand", "maand", "dag", "dagen")   'dutch nertherland (pays bas)
    Case 358, ".fi": t = Array("vuosi", "vuotta", "kuukausi", "kuukausi", "päivä", "päivät")   'finnich finland(finlande)
    Case 45, ".da": t = Array("år", "år", "måned", "måned", "dag", "dage")    'canemark,dannois
        'etc...etc...(possible d'en rajouter)
    Case Else: t = Array("year", "years", "month", "months", "day", "days")   ' on le met par defaut en anglais (langue universelle) au cas ou la langue n'est pas retrouvée
    End Select

    Nba = Year(Fin) - Year(Debut)
    Nbm = Month(Fin) - Month(Debut)
    Nbj = Day(Fin) - Day(Debut)
    Retenue = Day(DateSerial(Year(Fin), Month(Fin), 0))
    If Nbj < 0 Then Nbm = Nbm - 1: Nbj = Nbj + Retenue
    If Nbm < 0 Then Nba = Nba - 1: Nbm = Nbm + 12
    Nbmx = Nbm + (Nba * 12)    'ajout patricktoulon
    Select Case Left(LCase(Quoi), 1)
        'ajout  des intitulés an/mois/jour pour tout les cases(par patricktoulon sur exeldownload)
    Case "a", "y", "1": EcartDate = Nba & IIf(withlang, IIf(Nba <= 1, " " & t(0), " " & t(1)), ""): Exit Function
        ' modif  le cas "m" ou 2 donne maintenant le rel ecart en mois(par patricktoulon sur exeldownload)
    Case "m", "2": EcartDate = Nbmx & IIf(withlang, IIf(Nbmx <= 1, " " & t(2), " " & t(3)), ""): Exit Function
        'ajout  ecartdate en  mois et jours(par patricktoulon sur exeldownload)
    Case "mj", "4": EcartDate = Nbmx & IIf(withlang, IIf(Nbmx <= 1, " " & t(2), " " & t(3)), "") & " " & _
                                Nbj & IIf(Nbj <= 1, " " & t(4), " " & t(5)): Exit Function
        'le case "j" je le laisse mais c'est sans intéret(par patricktoulon sur exeldownload)
    Case "j", "d", "3": EcartDate = Nbj & IIf(withlang, IIf(Nbj <= 1, " " & t(4), " " & t(5)), ""): Exit Function
    Case Else
        s = IIf(Nba = 0, "", IIf(Nba = 1, "1 " & t(0), Nba & " " & t(1)))
        s = Trim(s & " " & IIf(Nbm = 0, "", IIf(Nbm = 1, "1 " & t(2), Nbm & " " & t(3))))
        s = Trim(s & " " & IIf(Nbj = 0, "", IIf(Nbj = 1, "1 " & t(4), Nbj & " " & t(5))))
    End Select
    EcartDate = s
End Function

'sub de test
Sub test()
    Dim date1 As Date, date2 As Date
    date2 = CDate("20/06/2021")
    date1 = CDate("12/03/2019")

    MsgBox " age " & EcartDate(CDate("04/03/1970"))    'mettre  une date de naissance uniquement

    MsgBox EcartDate(date1, date2, 4, 33)        'en mois et jour(s) +langue francais forcée

    MsgBox EcartDate(date1, date2, 1, ".es")    'nombre d'année +langue
    MsgBox EcartDate(date1, date2, 1)           'nombre d'année

    MsgBox EcartDate(date1, date2, 2, ".uk")    'nombre de mois  +langue
    MsgBox EcartDate(date1, date2, 2)           'nombre de mois

    MsgBox EcartDate(date1, date2, 3, ".es")    'nombre de jours  +langue
    MsgBox EcartDate(date1, date2, 3)           'nombre de jour

    MsgBox EcartDate(date1, date2)              'langue par defaut du system WINDOWS(et non celui de excel)
    MsgBox EcartDate(date1, date2, , 33)        'langue francais forcée
    MsgBox EcartDate(date1, date2, , ".fr")     'langue francais forcée
    MsgBox EcartDate(date1, date2, , ".uk")     'langue valable pour  anglais uk/ us /gb  forcée
    MsgBox EcartDate(date1, date2, , 49)        'langue allemand forcée
    MsgBox EcartDate(date1, date2, , ".es")     'langue espagnol forcée

End Sub
 

Discussions similaires

Statistiques des forums

Discussions
312 103
Messages
2 085 312
Membres
102 860
dernier inscrit
fredo67