Microsoft 365 Convertir en VBA

BrunoM45

XLDnaute Barbatruc
Re,

Une solution via une fonction
VB:
Sub Test()
  Dim zv_debut As Date, zv_fin As Date
  zv_debut = #4/16/2019#
  zv_fin = Date
  nbre_mois = EvaluateDateDif(zv_debut, zv_fin, "m") + (EvaluateDateDif(zv_debut, zv_fin, "md") / Day(DateSerial(Year(zv_fin), Month(zv_fin) + 1, 1) - 1))
  Debug.Print nbre_mois
End Sub

Function EvaluateDateDif(DateDeb As Date, DateFin As Date, Quoi As String)
  Dim sDateDeb As String, sDateFin As String
  Dim sForm As String
  ' Convertir la date au format américain + texte
  sDateDeb = Format(DateDeb, "mm/dd/yyyy")
  ' Convertir la date au format américain + texte
  sDateFin = Format(DateFin, "mm/dd/yyyy")
  ' Inclure la transformation en date des dates texte... et oui ça marche comme ça ;-)
  sForm = "datedif(" & "datevalue(""" & sDateDeb & """)" & ",datevalue(""" & sDateFin & """),""" & Quoi & """)"
  EvaluateDateDif = Application.Evaluate(sForm)
End Function
@+
 

Dranreb

XLDnaute Barbatruc
Pourtant:
Entre la date du jour et la date de naissance, 19 mois sont couverts.
Le nombre de jours séparant la fin du mois en cours du 1er du mois de naissance est de :
31/10/2020 - 01/04/2019 = 579 jours.
Le nombre de jours séparant la date du jour de la date de naissance n'est que de :
17/10/2020 - 16/04/2019 = 550 jours
Il ne faut donc prendre que 550 / 579 soit 94,9914 % de ces 19 mois, ce qui fait bien 18,0483592 mois, soit, arrondi à 2 décimales 18,05 et non 18,03
Me suis-je planté quelque part ?
 

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonsoir Dranreb,
Pas d'accord. XL répond 18.03 car il travaille en unités : année, mois, jours.
Un an c'est 1, que cette année ait eu 365 ou 366 jours.
Un mois c'est 1/12, que ce mois ait eu 28,29,30 ou 31 jours.
Heureusement, sinon quelle galère pour vous souhaiter votre anniversaire. :)
 

Dranreb

XLDnaute Barbatruc
Pour obtenir ce que vous dites j'aurais simplement divisé le nombre de jours qui sépare celle du jour de naissance par 30,436875
Là oui, on a une durée indépendante des dates.
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous,

Un essai pour ce que j'en ai compris.

Deux fonctions : nbMois(ddn As Date) et nbJour(ddn As Date)
  • la première donne le nombre de mois complet depuis la date de départ ddn et aujourd’hui. Les mois complets sont les dates anniversaire inférieures ou égales à aujourd'hui
  • la deuxième donne le nombre de jour depuis le lendemain de la dernière date anniversaire de ddn (inférieure ou égale à aujourd'hui) et aujourd’hui
VB:
Function nbMois(ddn As Date)
Dim i&, d As Date
   For i = 0 To 2400
      d = DateSerial(Year(ddn), Month(ddn) + i, Day(ddn))
      If d > Date Then Exit For
   Next
   nbMois = i - 1
   If nbMois < 0 Then nbMois = CVErr(xlErrNA)
End Function

Function nbJour(ddn As Date)
Dim i
   i = nbMois(ddn)
   If IsError(i) Then
      nbJour = CVErr(xlErrNA)
   Else
      nbJour = Date - DateSerial(Year(ddn), Month(ddn) + i, Day(ddn))
   End If
End Function
Ceci n'est qu'une approximation puisque ni l'année, ni le mois ne sont des unités. Seul le jour peut être considéré comme une unité.

Si quelqu'un est né le 31 janvier. A quelle date aura-t-il un mois ? (personnellement, je ne sais pas)
Un nouveau-né né le 01 janvier aura 1 mois le 01/02. Un nouveau-né né le 01 février aura 1 mois le 01/03. le premier aura vécu 31 jours, le second 28 jours (29 les années bissextiles). A un mois chacun, ils auront une différence d'âge égale à 3 jours (soit #10%) !
 

Fichiers joints

Dernière édition:

Dranreb

XLDnaute Barbatruc
Même en faisant le calcul un peu autrement, je trouve à peu près la même chose :
VB:
Function AgeEnMois(ByVal D1 As Date, Optional ByVal D2 As Date = 0) As Double
   Dim J1&, M1&, A1&, NbJrM1&, J2&, M2&, A2&, NbJrM2
   If D2 = 0 Then D2 = Date
   J1 = Day(D1): M1 = Month(D1): A1 = Year(D1): NbJrM1 = Day(DateSerial(A1, M1 + 1, 0))
   J2 = Day(D2): M2 = Month(D2): A2 = Year(D2): NbJrM2 = Day(DateSerial(A2, M2 + 1, 0))
   AgeEnMois = (NbJrM1 + 1 - J1) / NbJrM1 + 12 * (A2 - A1) + M2 - M1 - 1 + J2 / NbJrM2
   AgeEnMois = Int(AgeEnMois * 100 + 0.5) / 100
   End Function
Je n'ai jamais eu et n'aurai jamais aucune confiance dans le DATEDIF.
 

PORCHER

XLDnaute Junior
Bonjour du Dimanche à tous,
Merci infiniment à tous ceux qui ont apportés des réponses au sujet.
La solution de Daniel
[AA10].Formula = "=DATEDIF(""" & Format(zv_Debut, "d/m/yyyy") & """,""" & Format(zv_Fin, "d/m/yyyy") & """,""md"")"
nbre_mois = DateDiff("m", zv_Debut, zv_Fin) + ([AA10] / Day(DateSerial(Year(zv_Fin), Month(zv_Fin) + 1, 0)))
Le résultat : 19,8709677419355 pour zv_fin = 23/03/2019
ET...
Formule excel : DATEDIF(E28;$C$1;"m")+(DATEDIF(E28;$C$1;"md")/JOUR(FIN.MOIS($C$1;0)))
[E28] = zv_debut
[$C$1] = zv_fin
Le résultat: 18,871
OU EST L'ERREUR!
Merci encore
Amicalement
Jean-Yves
 

danielco

XLDnaute Accro
Bonjour @PORCHER , bonjour à tous,

J'ai bâti ma solution sur DATEDIF. Il s'avère que cette fonction est buggée. Il ne faut donc pas la prendre en considération. Il y a eu plusieurs autres réponses à ta question au cours de cette discussion. A toi de choisir.

Daniel
 

danielco

XLDnaute Accro
Je ne comprends pas pourquoi tu utilises la valeur "18,01" dans tes tests. Apparemment, avec l'exemple initial, toutes les réponses proposées (à l'exception de la mienne (tant pis pour la "gloire" sic) donnent un résultat supérieur à 18 (et même apparemment à 18,01).

Daniel
 

PORCHER

XLDnaute Junior
Explication ;
Si un enfant de 0 à 18 mois et un jour, recois un repas Enfant
Si un enfant de 18 mois et deux jours recois un repas Adulte
Donc pour moi le jour doit etre pris en compte !
 

BrunoM45

XLDnaute Barbatruc
Re,

Pourquoi ne pas afficher le résultat en clair : 18 mois et 1 jour, plutôt qu'un chiffre à virgule ?

@+
 
Dernière édition:

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous,

@danielco,
Je ne pense pas que la fonction DateDif soit bugguée. C'est simplement sa méthode de calcul qui n'est pas basée sur un nombre de jours écoulés mais sur des unités de temps ( année, mois, jour )
Ainsi 1.5 mois peut vouloir dire 43 jours ou 46 jours. ( 28+15 ou 31+15 )

C'est pour cela qu'un calcul en jours écoulés et par DateDif donneront des résultats différent.
A noter que d'un point de vue administratif ou du sens commun, c'est cette fonction qui est utilisée.
Vous obtenez la majorité à 18 ans date anniversaire quelle que soit le nombre d'années bissextiles que vous ayez vécu.
 

PORCHER

XLDnaute Junior
Bien raisonné Daniel mais alors que peut on faire pour répondre à mon problème.
J'ai envoyé un fichier sans mot de passe, peut tu corriger à ta convenance
je t'en remercie
amicalement
Jean-Yves
 

Dranreb

XLDnaute Barbatruc
Bonjour.
DATEDIF(E28;$C$1;"m")+(DATEDIF(E28;$C$1;"md")/JOUR(FIN.MOIS($C$1;0)))
Que le DATEDIF soit bogué ou non, cette formule ne me semble pas correcte dans la mesure où le nombre excédentaire de jours trouvé sur le nombre de mois est répartit seulement sur le mois en cours, ce qui est faux si on est justement au dernier jour du mois, alors que les jours en excédent sont dûs à ce que la naissance est vers la fin de son mois, et que c'est donc celui-ci qui n'est pas complet.
 

sylvanu

XLDnaute Barbatruc
Supporter XLD
Re le fil,
Si le problème à l'origine est simplement :
Si un enfant de 0 à 18 mois et un jour, reçois un repas Enfant
Si un enfant de 18 mois et deux jours reçois un repas Adulte
Alors pourquoi ne pas utiliser cette simple formule :
Code:
=SI(MOIS.DECALER(C9;18)+1<AUJOURDHUI();"Repas Adulte";"Repas Enfant")
 

Fichiers joints

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous,

Des unités de Temps : Seul le jour peut être une unité mais certainement pas le mois ou l'année.
Donc pour le mois ou l'année, seul l'usage courant et populaire peut être pris en compte (voir une tentative dans mon post #25).
D'ailleurs à chaque question sur les durées en mois ou années, la discussion se transforme en roman fleuve toujours sans conclusion claire et tranchée.

C'est surprenant qu'une organisation aussi caritative (et combien utile) se transforme en établissement de clercs comptables (c'est de la provocation amicale) . Un petit, à un jour près, va manger comme un enfant et soudain le lendemain prendra une ration d'adulte ? Certes non ! Alors faisons un calcul simple, on n'est pas à un jour près. Voir la proposition de @sylvanu (que je salue :) ) juste ci-dessus.
 
Dernière édition:

Créez un compte ou connectez vous pour répondre

Vous devez être membre afin de pouvoir répondre ici

Créer un compte

Créez un compte Excel Downloads. C'est simple!

Connexion

Vous avez déjà un compte? Connectez vous ici.

Haut Bas