IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Comportement de WorksheetFunction.Min


Sujet :

Macros et VBA Excel

  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 204
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 204
    Points : 1 768
    Points
    1 768
    Par défaut Comportement de WorksheetFunction.Min
    Bonjour,

    Je doit obtenir le minimum entre plusieurs dates, certaines peuvent être nulle.
    Je passe par la fonction WorksheetFunction.Min, et j'obtiens un comportement étrange:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    cdate(Application.WorksheetFunction.Min(#4/30/2024#, Null))    '// Ok, renvoie 30/04/2024
     
    cdate(Application.WorksheetFunction.Min(#4/30/2024#, Null, #4/26/2024#, #4/20/2024#))    '// Ko, renvoie 00:00:00
                                                                                             '// Je m'attend à 20/04/2024
    A noter que les dates (ici en dur) son contenues dans des variables.

  2. #2
    Membre averti Avatar de Nain porte koi
    Homme Profil pro
    a
    Inscrit en
    Novembre 2023
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : a

    Informations forums :
    Inscription : Novembre 2023
    Messages : 260
    Points : 348
    Points
    348
    Par défaut
    Hello,

    peut-on mettre la valeur "null" dans une cellule du tableur ? (c'est une vraie question)

    Personnellement je ne crois pas, donc je ne suis pas particulièrement étonné si une fonction de calcul du tableur renvoie un résultat erroné si on lui donne un argument qu'elle ne sait pas gérer... C'est juste une supposition.
    JièL
    Membre des AMIS
    Anti Macro Inutilement Superfétatoire

  3. #3
    Membre éprouvé
    Inscrit en
    Décembre 2002
    Messages
    814
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 814
    Points : 1 282
    Points
    1 282
    Par défaut
    Salut, pour contourner le problème, une solution serait d'ajouter les dates non nulles à une liste et ensuite utiliser Application.WorksheetFunction.Min sur cette liste pour obtenir la date minimale.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 204
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 204
    Points : 1 768
    Points
    1 768
    Par défaut
    @Nain porte koi:
    Ca a du sens, et ton raisonnement rejoint l'avis de l'un de mes collègue: Il y a la surcouche Excel qui fait "quelque chose".

    @Franc:
    Construire une liste (tableau dynamique), c'est la croix la bannière.
    J'ai trouvé une fonction qui passe par les arguments dynamiques (ParamArray):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Public Function Minimum(ParamArray Values() As Variant) As Variant
        Dim Lower As Variant
            '// cherche la 1er valeur non null
        Dim Item As Variant
        For Each Item In Values
            If Not (IsNull(Item)) Then
                Lower = Item
                Exit For
            End If
        Next
     
            '// cherche la plus petite valeur
        For Each Item In Values
            If (Item < Lower) Then
                Lower = Item
            End If
        Next
        Minimum = Lower
    End Function

  5. #5
    Membre régulier
    Homme Profil pro
    CIP
    Inscrit en
    Avril 2024
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : CIP
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2024
    Messages : 47
    Points : 82
    Points
    82
    Par défaut re
    rebonjour deedolith

    si vos variables ont été déclarées correctement le vbnull ne devrait pas vous poser problème
    vbnull en numerique(long) vaut 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Sub test()
        Dim dat1&, dat2&, dat3&, dat4&, dat5&
        dat1 = #5/22/2024#
        dat2 = #4/16/2024#
        dat3 = vbNull
        dat4 = #6/24/2024#
        dat5 = #3/18/2024#
     
        MsgBox WorkShootfunction_Min(dat1, dat2, dat3, dat4, dat5)
     
    End Sub
     
    Function WorkShootfunction_Min(ParamArray mesdate())
        Dim Grand&, d
        Grand = 100000000
        For Each d In mesdate
            If d > 1 And d < Grand Then Grand = d
        Next
        WorkShootfunction_Min = CDate(Grand)
    End Function
    on constate quoi
    que mes dates sont des long
    et que par conséquent en sautant les "1" et gardant le plus petit a chaque tours j'obtiens ma plus petite date
    et combien même si les dates avaient été déclarées en date
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     If clng( d )> 1 And clng(d) < Grand Then Grand =clng( d)
    on pourrait même se passer de la condition vbnull en faisant une simple addition booléenne pour l’excepter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     If d + (Grand * Abs(d = 1)) < Grand Then Grand = d

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 204
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 204
    Points : 1 768
    Points
    1 768
    Par défaut
    Je ne peut pas être d'accord.

    Pour la simple raison que l'absence de valeur (Null) ne signifie pas une valeur particulière qui elle est forcément valide.
    Comment ensuite distinguer une valeur absente (donc Null) d'une valeur valide (qui peut être n'importe quoi, y compris une valeur particulière) ?

    Au pire, une classe OptionalDate (ou OptionalValue) fait l'affaire, mais ce exclue également les méthode de WorksheetFunction qui ne travaillent pas avec ce genre d'objets.

  7. #7
    Membre régulier
    Homme Profil pro
    CIP
    Inscrit en
    Avril 2024
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : CIP
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2024
    Messages : 47
    Points : 82
    Points
    82
    Par défaut re
    relis mon message
    je pars de 100000000
    dans la boucle j'ajoute a tous 100000000 * la valeur numérique du booléen Abs(d = 1)

    autrement dit
    la comparaison se fait sur le numérique de la date + grand *le numérique du booléen
    si j'ai une date d sera = a (par exemple pour aujourdhui 45406 + grand* (le abs du boolean) donc date + 0
    donc tout ce qui n'est pas date vaudra 0 + grand* lebouboul donc soit minimum 100000000
    tout ce qui est null vaudra 1+ grand* lebouboul soit 100000001

    tout ce qui est date vaudra xxxxx + grand* lebouboul soit grand*0 soit que la date

    conclusion
    tout ce qui est date sera toujours dans l’opération (avec + grand*....) plus petit

    Addition logique

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 204
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 204
    Points : 1 768
    Points
    1 768
    Par défaut
    Non, tu implémentes un cas particulier,
    Tu peux faire toute la gymnastique que tu veux, ca reste un cas particulier, qui n'aura jamais d'équivalence à une valeur null.

    De plus:
    Cette fonction implique que la fonction appelante doit adapter ses données avant de les donner en argument, s'assurer de la compatibilité de la valeur retournée, ce n'est pas son job.
    Quid des heures (Le type date inclue les heures) ?

    En résumé:
    Violation du SRP (https://en.wikipedia.org/wiki/Single...lity_principle),
    Violation de la concordance des types,
    Ce n'est définitivement pas une solution acceptable.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 15/02/2010, 21h52
  2. open avec comport
    Par Goldocrack dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/04/2009, 08h12
  3. [Sybase] Comportement bizarre d'une table
    Par sdozias dans le forum Sybase
    Réponses: 4
    Dernier message: 03/02/2004, 10h39
  4. [Free Pascal] Comportement de Exec
    Par néo333 dans le forum Free Pascal
    Réponses: 3
    Dernier message: 01/11/2003, 17h46
  5. Réponses: 2
    Dernier message: 22/09/2003, 11h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo