Gérer les messages "Debug.Print" d'une fonction depuis une Sub

Re,

@Jean-Paul

Je me rends compte que si je veux réellement suivre votre conseil (penser Excel avant de penser VBA) toutes les vérifications de validité sur les mois 1 à 12 et 31 ou 30 jours… , devraient pouvoir être géré par des fonctions Excel ?

Je suis un peu dans l'inconnue.

Si votre temps le permet, pourrai-je avoir des pistes ou exemples supplémentaires ?

Re,

Quand tu te lance comme cela tu dois connaître le problème à résoudre.

Tester une date en chaine de caractères comme ceci "240200"
On a vu que l'on pouvais tester le jour avec la fonction IsDayValid par exemple

Public Function IsDayValid(ByVal Value As String) As Variant
    Dim localYear As Integer
    localYear = CInt(Left$(Value, 2))

    Dim LocalMonth As Integer
    LocalMonth = CInt(Mid$(Value, 3, 2))

    Dim testedDay As Long
    testedDay = CLng(Right$(Value, 2))

    Dim resultDay As Long
    If testedDay = 0 Then
        resultDay = Day(Application.WorksheetFunction.EoMonth(DateSerial(localYear, LocalMonth, 1), 0))
    Else
        If testedDay <= Day(Application.WorksheetFunction.EoMonth(DateSerial(localYear, LocalMonth, 1), 0)) Then
            resultDay = testedDay
        Else
            resultDay = -1
        End If
    End If
    IsDayValid = resultDay
End Function

Elle renvoie :

  • Le dernier jour du mois si le jour et à 0
  • False si le jour est en dehors des limites 1 - dernier jour du mois exemple "240256"

Pour le mois c'est plus simple avec la fonction IsValidMonth

Public Function IsValidMonth(ByVal Value As String) As Boolean
    Dim LocalMonth As Long
    LocalMonth = CLng(Mid$(Value, 3, 2))
        IsValidMonth = (LocalMonth >= 1 And LocalMonth <= 12)
End Function

Elle renvoie

  • True si le mois est dans la plage 1 -12
  • False autrement

Pour l'année cela devient plus compliqué avec une année sur deux chiffres avec tes recommendations. Imaginons cette date "740201"

Doit-on considérer que c'est 1974 et là on est dans les clous, ou bien 2074 qui est au delà de l'année en cours plus 50 ans ?

On doit entrer dans des considérations, par exemple une date de péremption ne peux pas être inférieure à la date du jour sinon pas bon, et ne doit pas être supérieure à la date du jour de plus de quelques années, OK. Mais qu'en est-il pour la date de fabrication d'une pièce ou autre, cela change la donne.

Tout cela pour dire que l'on doit bien connaître le contexte, avant de se lancer.

Concernant la mise en place de ce petit monde voici une procédure de test, c'est minimaliste, on pourrait renvoyer la chaine MaDate reformatée par exemple.

Public Sub TestDate()
    Dim Madate As String
    Madate = "240200"
    Dim ValidString as String
    ' // test sur les jours
    If IsDayValid(Madate) = -1 Then
        MsgBox "Le jour renseigné n'est pas dans la plage autorisée !"
    Else
        If IsValidMonth(Madate) = -1 Then
            MsgBox "Le mois renseigné n'est pas dans la plage autorisée !"
        Else
            ' Todo "A faire test sur l'année
            'If IsValidYear = -1 Then
                MsgBox "L'année renseignée n'est pas dans la plage autorisée !"
            'Else
            'End If
        End If
    End If
End Sub

Voilà reste à poser le problème des années. Affaire à suivre...

Bonjour,

@Jean-Paul,

Tous vos exemples m'ont aidé pour comprendre la logique vers laquelle vous vouliez me guider !

De petites choses font que me vieux cerveau me dit stop quand je ne comprends pas, comme par exemple :

Dans la 1er fonction, vous déclarez IsDayValid As Variant

Dans la 2ème fonction, vous déclarez IsValidMonth As Boolean

Pour moi Is quelque chose attend une réponse vraie ou fausse, c'est donc un Boolean ?

Même chose pour :

 Dim LocalMonth As Integer

LocalMonth = CInt(Mid$(Value, 3, 2))

Dim testedDay As Long

testedDay = CLng(Right$(Value, 2))

Veuillez m 'excuser, mais je ne comprends plus dans quel cas utiliser Integer ou Long ?

Je n'ai même pas su mettre en application la fonction IsValidMonth comme pour IsDayValid !

-

Concernant les années pour "740201" la fonction SetYear est faite pour ça et donne 01/02/1974

Soit 2023 - 49.

Pour 730201 la fonction SetYear donne 01/02/2073

Soit 2023 + 50.

Pour ce qui est des dates de péremption, fabrication … Je ne pensais pas aller plus loin que la vérification d'une date valide, car ces dates sont imposées par les fabricants et donc pas de réel action possible.

bonjour,

le debug.print fourni des informations intéressantes mais il ne faut pas crouler sous le nombres.

je te suggère d'utiliser l'espion avec arrêt de la macro selon critères.

si nom tu peux Numéroter tes lignes de code et envoyer les informations dans un fichier de log. Cette méthode te donnera des informations plus précises.

  • .la date et heure
  • Le Nº ligne de code
  • Valeur d'une ou plusieurs variables
  • Etc.

Salut,

Dans la 1er fonction, vous déclarez IsDayValid As Variant

Très bonne question, Jai modifier la fonction et oublié de changer cela, elle peut être de Type Long ou Boolean, dans la première version elle renvoyait, soit le jour qui était de Type Long, soit la Date, qui était je vous le donne en Mille Emile, de Type Date. Donc dans ce cas, ne pouvant pas choisir, c'est le Type Variant qui l'emporte.

Le Type Boolean correspond = 0 pour False et -1 pour True le Type Long va de -2 147 483 648 à 2 147 483 647 donc dans ce cas particulier les deux peuvent convenir.

Veuillez m 'excuser, mais je ne comprends plus dans quel cas utiliser Integer ou Long ?

Avant, il était très important d'économiser de la mémoire sur les anciens PC, donc, on utilisait les Type au plus prés des besoins, le type long prends 32 bits le type Integer 16bits deux fois moins. Maintenant les PC ont plus de mémoire et l'architecture des processeur et en 32 ou 64bits. Ils auront plus de facilité pour travailler avec du 32bits.

Voilà, part sur du type Long pour tout, et cela ira très bien.

Concernant les années pour "740201" la fonction SetYear est faite pour ça et donne 01/02/1974

je n'ai pas approfondi mais si elle te convient garde la..

Edit : Je viens de tester et ce n'est pas le résultat attendu je pense, c'est toi qui décide que cela correspond à 1974...

000326

Je n'ai même pas su mettre en application la fonction IsValidMonth comme pour IsDayValid !

Comme celle des jour si le mois n'est pas compris entre 1 et 12 elle renvoie Faux

000325

Bonjour,

@Jean-Paul, merci pour ces explications

Je regarde pour mettre tous cela en place dès que possible.

Concernant les années pour "740201" la fonction SetYear est faite pour ça et donne 01/02/1974

Edit : Je viens de tester et ce n'est pas le résultat attendu je pense, c'est toi qui décide que cela correspond à 1974...

56213 657c8bc841ae1746053372

Comme je l'ai expliqué dans l'un des messages précédents, la fonction SetYear traite la date de telle sorte que La chaîne "YY" ne peut spécifier qu'une date comprise entre 49 ans dans le passé et 50 ans dans le futur avec comme pivot, l'année en cours.

L'année en cours c'est "Year(Now)" soit 2023.

Dans la fonction CheckDate, je déclare:

YY = SetYear(YY, Year(Now))

Soit:

capture2 capture

Re,

Je comprends bien, et je me suis mal expliqué, la fatigue peut-être, mais je reste sur ma position c'est toi, ou plutôt le code qui décide de la plage de date et cela n'est pas normal.

A part être un devin, et encore, personne ne peut trouver une date si elle est codée sur deux chiffres, c'est toi avec les calculs (compliqués je trouve pour arriver à ce résultat) qui détermine, quel plage de date va être appliquée.

Mais je le redis ci cela te convient c'est le principal.

Salut Jean-Paul, Léo39,

Si on réfléchi en terme de logistique, "40" pour l'année ne pourras être que 2040 et pas 1940

Je dis ça, je dis rien

Bon week-end

Re,

Si on réfléchi en terme de logistique, "40" pour l'année ne pourras être que 2040 et pas 1940

Je dis ça, je dis rien

Oui, C'est ce que je dis, on peut débattre des heures sur le sujet, si l'on entre 21 dans une cellule formatée en date elle est convertie en 2021, Ha bon pourquoi pas 1921, ou 2121, parce que c'est le plus logique bien évidemment, mais cela étant dit, Excel à fait un choix.

Bonjour,

Je comprends qu'un peu plus d'explication s'impose :

La fonction SetYear a été développée dans le but d'essayer de respecter les critères du standard GS1.

GS1 (abréviation de Global Standards 1) organisme mondial actif dans le domaine de la normalisation des méthodes de codage utilisées dans la chaîne logistique, notamment le code-barres.

Les dates sont toujours représentées dans le format YYMMDD, où le siècle de l'année est déterminé par les spécifications GS1. Seules les dates situées entre 49 ans dans le passé et 50 ans dans le futur (par rapport à l'année en cours) peuvent être représentées.

Un cas concret :

Le fabricant d'une machine, garantie la disponibilité des pièces de rechange pendant 40 ans.

Cette machine a été acquise il y a 30 ans donc en 1993.

Les pièces de rechange seront donc disponibles jusqu'en 2033.

Cette machine en obsolescence en 2034 sera remplacée, la disponibilité des pièces pour cette nouvelle machine suivra le même schéma ou l'année en cours sera 2034.

bonjour le fil,

une correction éventuelle

Public Function IsDayValid(ByVal Valeur As String)
     Dim MaDate, Delta

     IsDayValid = -1                         'on commence avec cette valeur et on la corrige éventuellement

     If Len(Valeur) <> 6 Or Not IsNumeric(Valeur) Then Exit Function     'mauvaise longueur ou contenu

     MaDate = DateSerial(Mid(Valeur, 1, 2), Mid(Valeur, 3, 2), 1)
     If Format(MaDate, "yymm") <> Left(Valeur, 4) Then Exit Function     'problème avec le mois

     Delta = Sgn((Year(MaDate) - Year(Now)) \ 50)
     If Delta <> 0 Then MaDate = WorksheetFunction.EDate(MaDate, -Delta * 1200)     'GS1-correction

     If Right(Valeur, 2) = "00" Then
          IsDayValid = Day(WorksheetFunction.EoMonth(MaDate, 0))
     Else
          If Format(MaDate + Right(Valeur, 2) - 1, "yymmdd") = Valeur Then IsDayValid = --Right(Valeur, 2)
     End If
End Function

Bonjour BsAlv,

Une correction? pouvez-vous m'en dire un peux plus?

Bien cordialement

je n'ai pas lu tout le topic, mais je crois que vous voulez le dernier jour ou un jour du mois quand vous donnez un string de 6 chiffres et puis on a ce GS1-standard.

Bon, quand vous donnez "000200", donc pour l'année 2000, le mois février, le dernier jour est le 29.

Si votre question était différent, je l'ai pas bien compris.

Rechercher des sujets similaires à "gerer messages debug print fonction sub"