Microsoft 365 trouver la date la plus récente (uniquement sur le jour) contenue dans ma cellule :

Usine à gaz

XLDnaute Barbatruc
Supporter XLD
Bonjour à toutes et à tous,
Je vous souhaite une belle journée :)

Je me permets de revenir vers nos chers ténors en vba pour un besoin particulier qui, selon mes recherche n'a jamais été traité, ni sur le forum, ni sur internet.

Il m'est très difficile d'expliquer mon besoin dans le post. Il est, je crois, clairement montré dans le fichier test que je joins à ma demande.

Si vous aviez la solution vba, ça m'arrangerait bien lol :)
En espérant que ce sera pas trop ch..t à lire.
Je vous remercie vivement,
Amicalement,
lionel,
 

Pièces jointes

  • test_uf_comment.xlsm
    206.5 KB · Affichages: 49
Dernière édition:
Solution
Bonjour Lionel, soan, Yeahou,

Cette solution impose le minimum de contraintes aux dates dans la cellule active :
VB:
Sub DerniereDate()
Dim x$, i%, y$, a(), n%
x = Application.Trim(ActiveCell) 'SUPPRESPACE
For i = 1 To Len(x)
    y = Mid(x, i, 14)
    If y Like "##?##?## ##:##" And IsDate(y) Then ReDim Preserve a(n): a(n) = CDbl(CDate(y)): n = n + 1
Next
If n Then MsgBox "Dernière date " & Format(Application.Max(a), "dd-mm-yy hh:mm")
End Sub
Les renvois à la ligne ne sont pas indispensables.

Il suffit que les dates soient bien des dates formatées "jj-mm-aa hh:mm", le tiret pouvant être un slash /.

A+

soan

XLDnaute Barbatruc
Inactif
@Yeahou

tu as écrit : « Et en plus t'es miro, j'ai fait la même ! 🥴 »

c'est pas que j'suis miro mais diplomate ! 😂 🤣 j'avais bien vu qu't'avais fait la même erreur que moi, mais j'ai fait semblant d'pas m'en apercevoir, et surtout, d'pas mettre le doigt dessus : j'voulais pas risquer d'te froisser ! depuis qu't'as assassiné le Docteur Lenoir dans la Bibliothèque en l'faisant trébucher dans l'escalier qui mène au donjon du Manoir (car il avait juste oublié d'te donner ton whiskas), j'ai trop peur de tes réactions quand tu t'vexes ! :p 😁 🤣 comment ? l'escalier qui mène au donjon n'est pas dans la Bibliothèque ? t'es bien sûr ? il est même pas accessible par un passage secret dissimulé dans une alcôve ? 🤪 😄 à tout hasard : est-ce que t'as bien sondé tous les murs de la Bibliothèque ? 😁

@Usine à gaz

après mon post, j'étais sûr que tu verrais bien par toi-même que seule la solution de job75 prend aussi l'heure en compte ; normal : c'est lui le meilleur ! 😜 en plus, il ne se trompe jamais, et il n'hésite pas à qualifier mes explications de vaseuses même si elles sont claires mais que la qualité conceptuelle d'un compilateur performant est hors de sa portée ! 😭 tiens, j'suis surpris qu'il n'aie pas jeté l'anathème sur mon erreur d'avoir oublié de prendre l'heure en compte ! sans doute ai-je dû bénéficier, tout à fait fortuitement, d'un de ses trop rares moments de clémence envers moi... 😁 😄 🤣 il devait sans doute être occupé à siroter son Whisky ! 🥃 ou p't'être qu'il était trop absorbé par son feuilleton télévisé ? 📺

mébon, si le début d'une ligne est toujours une date valide et que pour toi ça change rien si les heures sont différentes, alors ma solution du post #3 est quand même valable ! :) c'est p't'être pour ça que l'épée de Damoclès Job75 ne s'est pas abattue sur moi ? :rolleyes: il va p't'être me répondre que j'me suis encore enlisé dans des explications vaseuses ? 😁 😂 🤣 à croire que mes posts sont comme des sables mouvants, où celui qui s'y aventure risque de ne pas en ressortir ! 😭



pour info : du coup, j'suis sorti d'ma caverne et d'mon hibernation ; Yeahou, tu peux aller continuer à vaquer à tes affaires : t'as plus besoin d'venir papoter avec moi (que j'sois miro ou non ! 😁).

soan
 

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Re bonjour le fil, le forum
des dates qui sont le même jour, mais à des heures différentes !" = pas de souci pour moi,
mais pas pour moi !
voici mon code modifié
VB:
Sub Trouver_Date_Max()
    Dim Tableau_en_Cours, Date_Max As Date, Date_en_Cours As Date, Compteur% 'définition des variables
    On Error Resume Next 'désactivation des erreurs de chaîne non date/heure
    Tableau_en_Cours = Split(ActiveCell.Value, vbLf) 'création du tableau de données
    For Compteur = LBound(Tableau_en_Cours, 1) To UBound(Tableau_en_Cours, 1) 'boucle sur tableau
        Date_en_Cours = Left(Tableau_en_Cours(Compteur), 14) 'transformation chaîne texte en date heure par intégration, longueur de la chaine à modifier si format date heure différent en nombre de caractères
        If Date_en_Cours > Date_Max Then Date_Max = Date_en_Cours 'mise à jour date max
    Next Compteur
    On Error GoTo 0
    If Date_Max = 0 Then MsgBox "Pas de date trouvée", vbOKOnly + vbInformation Else _
        MsgBox "La date la plus récente est le " & Format(Date_Max, "DDDD DD MMMM YYYY " & Chr(34) & "à" & _
            Chr(34) & " HH" & Chr(34) & "h" & Chr(34) & "MM") & ".", vbOKOnly + vbInformation  'test retour
End Sub

@soan , c'est vrai que je ne suis pas venu discuter mais il est connu que les 🐱 ont peur des 🐻 !
tu ne t'imagines quand même pas que je passe ma vie devant mon écran ?
En fait si, mais pas forcément sur internet et sur XLD
ma « solution » plante carrément si le début d'une ligne n'est pas une date valide, et sous la forme jj-mm-aa !
"j'avais bien vu qu't'avais fait" cette erreur, mais sans être diplomate, je sais être indulgent et compréhensif envers les petits jeunes.😼
[édition: une ligne vide ou un retour chariot à la fin plantent aussi d'ailleurs]

Bien amicalement, @+
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous,

Un autre essai avec une fonction personnalisée utilisable sur la feuille ou en VBA.

Cette fonction devrait ne pas prendre en compte les dates erronées du type "29/2/25" qui sont traitées par les fonctions CDATE ou DateSerial sans broncher!
  • Cdate transforme la date "29/2/25" en 25/02/2029 ==> Cdate("29/2/25") = 25/02/2029
  • Dateserial transforme la date "29/2/25" en 01/03/2025 ==> DateSerial(25, 2, 29) donne 01/03/2025)

La seule contrainte sur les dates est que les séparateurs entre le jour et le mois et le mois et l'année doivent être identiques et différents des deux-points qui correspondent aux écritures des heures (bien sûr, ils doivent aussi être différents de l'espace qui est le séparateur de mots).
Les dates peuvent être situées n'importe où dans le texte. Les jours et mois sont à un ou deux chiffres. Les années sont à deux ou quatre chiffres.

Le code de la fonction :
VB:
Function DateRecente(x As String)
Dim AA$, t, d, y As Date, max
Dim an&, mois&, jour&
   DateRecente = "": AA = Left(Year(Date), 2)
   t = Split(Replace(Replace(x, Chr(10), " "), Chr(13), " "))
   If LBound(t) < 0 Then Exit Function
   For Each d In t
      y = 0
      If d Like "#?#?##" And Mid(d, 2, 1) = Mid(d, 4, 1) And Mid(d, 2, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = AA & Right(d, 2): mois = Mid(d, 3, 1): jour = Left(d, 1)
      ElseIf d Like "##?#?##" And Mid(d, 3, 1) = Mid(d, 5, 1) And Mid(d, 3#, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = AA & Right(d, 2): mois = Mid(d, 4, 1): jour = Left(d, 2)
      ElseIf d Like "#?##?##" And Mid(d, 2, 1) = Mid(d, 5, 1) And Mid(d, 2, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = AA & Right(d, 2): mois = Mid(d, 3, 2): jour = Left(d, 1)
      ElseIf d Like "##?##?##" And Mid(d, 3, 1) = Mid(d, 6, 1) And Mid(d, 3, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = AA & Right(d, 2): mois = Mid(d, 4, 2): jour = Left(d, 2)
      ElseIf d Like "#?#?####" And Mid(d, 2, 1) = Mid(d, 4, 1) And Mid(d, 2, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = Right(d, 4): mois = Mid(d, 3, 1): jour = Left(d, 1)
      ElseIf d Like "##?#?####" And Mid(d, 3, 1) = Mid(d, 5, 1) And Mid(d, 3#, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = Right(d, 4): mois = Mid(d, 4, 1): jour = Left(d, 2)
      ElseIf d Like "#?##?####" And Mid(d, 2, 1) = Mid(d, 5, 1) And Mid(d, 2, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = Right(d, 4): mois = Mid(d, 3, 2): jour = Left(d, 1)
      ElseIf d Like "##?##?####" And Mid(d, 3, 1) = Mid(d, 6, 1) And Mid(d, 3, 1) <> ":" And Mid(d, 2, 1) <> " " Then
         an = Right(d, 4): mois = Mid(d, 4, 2): jour = Left(d, 2)
      End If
      y = DateSerial(an, mois, jour)
      If Year(y) = an And Month(y) = mois And Day(y) = jour Then If y > 1 Then If y > max Then max = y
   Next d
   If max > 0 Then DateRecente = max Else DateRecente = ""
End Function
 

Pièces jointes

  • Usine à gaz- date la plus récente- v1.xlsm
    22.1 KB · Affichages: 8
Dernière édition:

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Bonsoir le fil, le forum

Pour le fun, une modification pour gérer le cas du 29/02 en année non bissextile évoqué par @mapomme , avec une fonction personnalisée. C'est assez rapide pour être utilisé au besoin sur de grands ensembles de données.

Bien cordialement
VB:
Sub Trouver_Date_Max()
    Dim Tableau_en_Cours, Date_Max As Date, Date_en_Cours As Date, Compteur% 'définition des variables
    On Error Resume Next 'désactivation des erreurs de chaîne non date/heure
    Tableau_en_Cours = Split(ActiveCell.Value, vbLf) 'création du tableau de données
    For Compteur = LBound(Tableau_en_Cours, 1) To UBound(Tableau_en_Cours, 1) 'boucle sur tableau
        If Not Test_Date(Left(LTrim(Tableau_en_Cours(Compteur)), 8)) Then Date_en_Cours = Left(LTrim(Tableau_en_Cours(Compteur)), 14) Else _
            MsgBox Left(Tableau_en_Cours(Compteur), 8) & " n'est pas une date valide", vbOKOnly + vbCritical 'transformation chaîne texte en date heure par intégration
        If Date_en_Cours > Date_Max Then Date_Max = Date_en_Cours 'mise à jour date max
    Next Compteur
    On Error GoTo 0
    If Date_Max = 0 Then MsgBox "Pas de date trouvée", vbOKOnly + vbInformation Else _
        MsgBox "La dernière date saisie est le " & Format(Date_Max, "DDDD DD MMMM YYYY " & Chr(34) & "à" & Chr(34) & " HH" & Chr(34) & "h" & Chr(34) & "MM") & ".", vbOKOnly + vbInformation             'retour
End Sub
Function Test_Date(Date_Val$) As Boolean
    If Not Mid(Date_Val, 1, 2) = 29 Or Not Mid(Date_Val, 4, 2) = 2 Then Exit Function
    If Day(DateSerial(Day:=Mid(Date_Val, 1, 2), Month:=Mid(Date_Val, 4, 2), Year:=Mid(Date_Val, 7, 2))) < Mid(Date_Val, 1, 2) / 1 Then Test_Date = True
End Function
 

Pièces jointes

  • Date_Max_UsineaGaz_Gestion_29-02.xlsm
    21.5 KB · Affichages: 3

mapomme

XLDnaute Barbatruc
Supporter XLD
Pour le fun, une modification pour gérer le cas du 29/02 en année non bissextile évoqué par @mapomme , avec une fonction personnalisée.
Avant d'aller dormir : il n'y a pas que le 29/02, il y a aussi les 31/04, 31/06...

Excel est besogneux et cherche toujours une solution...
Ma fonction traite théoriquement tous les cas où Cdate ou Dateserial transformerait une date erronée en une date valide (mais fantaisiste).
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir @job75 ;),

Excel est besogneux et cherche toujours une solution...

Je n'ai jamais compris cet acharnement de VBA à vouloir interpréter (via Cdate et DateSerial) coûte que coûte comme date une expression qui manifestement n'est pas une date (au sens commun du terme). Cela peut induire des effets très néfastes.
 
Dernière édition:

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Bonjour le fil, le forum
Avant d'aller dormir : il n'y a pas que le 29/02, il y a aussi les 31/04, 31/06...
@job75 ,pas d'accord avec toi, comme a dit @mapomme , seul les 29/02 des années non bissextiles sont validés par Vba, un 31/04 ne peut pas poser problème car il est très facilement détecté et éliminé comme date.
C'est ce qui se passait dans mon code et c'est pourquoi je l'ai repris.
Je n'ai jamais compris cet acharnement de VBA à vouloir interpréter coûte que coûte comme date une expression qui manifestement n'est pas une date (au sens commun du terme). Cela peut induire des effets très néfastes.
@mapomme , je pense à un bug lié au calcul d'heure sur plus de 24h00 qui ne prend pas en compte ce cas particulier dans VBA et à la façon dont Excel gère le lien jour/heures.
Image5.png

Sans doute une brique trop profonde dans les fondations d'Excel.

Bien cordialement, @+
 

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Re Bonjour @Usine à gaz , @job75 , @mapomme ,@Marcel32 , le forum

ne te froisse surtout pas, Job75, mais j'ai bien aimé ta proc alors je l'ai modifié pour l'accélérer un peu et intégrer la gestion des 29/02 cités par mapomme. Malgré cet ajout, elle est encore deux fois plus rapide sur un grand ensemble de données à analyser. Je la garde dans ma besace, ça peut servir.

Bien amicalement
[édition: modif de la fonction Test_Date, on gagne encore en temps]
[édition: correction du code au post 38]
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour @Yeahou ;),

je pense à un bug lié au calcul d'heure sur plus de 24h00 qui ne prend pas en compte ce cas particulier dans VBA et à la façon dont Excel gère le lien jour/heures.
Image5.png

Sans doute une brique trop profonde dans les fondations d'Excel.

Je dois être mal réveillé (chez moi, ça dure jusqu'à très tard dans la matinée) mais je ne vois pas d'incohérence dans ton tableau Excel...
D'ailleurs, je n'évoquais pas le comportement d'Excel (qui ne me pose pas de problème particulier quant aux dates) mais celui de VBA via ses fonctions Cdate() et DateSerial().
 
Dernière édition:

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Bonjour @mapomme

Il n'y a pas d'incohérence dans le tableau, c'est juste pour illustrer pourquoi dateserial (ou les données jour/mois/année sont paramètrées indépendamment) renvoie le 01/03/25 qui correspond au 28/02/25 + 1 jour dans le cas de 29/02/25, j'ai basé ma fonction de test la dessus. Dans une feuille de calcul, xlvalidatedate fait bien la différence et ne reconnait pas une entrée 29/02/25 en date.
d'ailleurs une commande Vba du type DateSerial(2025, 2, 40) renverra le 12 mars 2025
on est bien 40 jours après le début du mois 02 après le début de l'année 2025.
Dateserial fait bien le boulot.
[édition: mais bon, je me suis peut être mal exprimé pour expliquer la façon dont Excel traite les dates et le lien fort date/heure dans les calculs d'excel qui explique aussi le non affichage des heures négatives dans excel (hors calendrier 1904) car sans précision de jour, excel considère l'heure comme étant du premier jour du calendrier ce qui plante l'affichage (et non le calcul qui est bien géré) en cas d'heure négative]
[édition2: pour Cdate, je pense à un évaluate qui fait trop bien son boulot
CDateDateToute expression de date valide.
29/02/25 au format anglais remplit bien la condition]

Bien cordialement
 
Dernière édition:

Discussions similaires