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 :

Double soucis avec NETWORKDAYS [Toutes versions]


Sujet :

Macros et VBA Excel

  1. #1
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut Double soucis avec NETWORKDAYS
    Bonjour,
    Un petit bonjour après une longue absence

    Comme indiqué dans le titre, j'ai un double soucis avec la fonction NetWorkDays utilisée sous VBA.

    La première question :
    je cherche à utiliser cette fonction en ajoutant le paramétrage JoursFériés sous forme d'un tableau à la place d'un range sans y parvenir
    et utiliser une feuille cachée n'est pas une solution très heureuse.
    Si les interactions croisés Array <> Range fonctionnent très bien dans les 2 sens dans la plupart des cas sous VBA,
    ce n'est pas le cas avec NetWorkDays : une idée de contournement sans passer par une feuille cachée ?

    Le second soucis est le paramétrage générique des jours fériés à la fonction NETWORKDAYS que je compte utiliser sur plusieurs années.
    Comment contourner le problème de façon à ce que tous les 01Janvier, ..., 25Décembre de ma liste de jours fériés
    soient pris en compte sans avoir à détailler cette liste pour chaque année ?
    Une idée ?

    Merci pour vos réflexions.

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

    Informations professionnelles :
    Activité : peu importe

    Informations forums :
    Inscription : Novembre 2023
    Messages : 1 536
    Par défaut
    Citation Envoyé par DarkVader Voir le message
    Bonjour,
    Un petit bonjour après une longue absence
    Hello,

    Citation Envoyé par DarkVader Voir le message
    je cherche à utiliser cette fonction en ajoutant le paramétrage JoursFériés sous forme d'un tableau à la place d'un range sans y parvenir
    Après quelques recherche j'ai trouvé ça, je cite "L’argument jours_fériés doit être une plage de cellules contenant les dates ou une constante de matrice des valeurs sérielles qui représentent ces dates." ici : https://support.microsoft.com/fr-fr/...8-4e925bfd5e28
    Outre le fait que la phrase est assez incompréhensible, après quelques autres recherche il semblerait que la 3ème argument serait une matrice. Exemple ici : https://www.techonthenet.com/excel/f...etworkdays.php et là https://excelcorpo.com/la-fonction-n...s-networkdays/
    Mais je ne vois pas comment un array pourrait être transformé en matrice ni comment on peut générer une matrice en VBA

    Citation Envoyé par DarkVader Voir le message
    et utiliser une feuille cachée n'est pas une solution très heureuse.
    C'est pourtant une solution simple et ça résoudrait le second soucis

    Citation Envoyé par DarkVader Voir le message
    Le second soucis est le paramétrage générique des jours fériés à la fonction NETWORKDAYS que je compte utiliser sur plusieurs années.
    Comment contourner le problème de façon à ce que tous les 01Janvier, ..., 25Décembre de ma liste de jours fériés soient pris en compte sans avoir à détailler cette liste pour chaque année ?
    En PJ un feuille avec un exemple des jours fériés calculés en fonction de l'année.
    Fichiers attachés Fichiers attachés
    JièL
    Membre des AMIS
    Anti Macro Inutilement Superfétatoire

  3. #3
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    En fait, NetworkDays attendait un tableau à 1 dimension et non à 2 comme l'opère un tranfert range vers array.
    Donc 1 simple split de la liste des jours fériés fait l'affaire pour le 3ème argument.

    Concernant la liste des jours fériés à date fixe ou non,
    le fait de pouvoir transmettre à la volée le paramètre sous forme de tableau
    résout le problème.


    Encore merci - c'est résolu.

  4. #4
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    Je ne comprends plus : le code suivant était fonctionnel d'où ma précédente réponse
    et depuis, il génère une erreur 1004 sur l'appel de Networkdays.

    J'en suis même venu à réinstaller Excel mais rien n'y fait !

    Bref, retour à la case départ

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
            ' Nombre de jours ouvrés       
        Public Function Count_OpenDays(ByVal dateBegin As Date, ByVal dateEnd As Date) As Long
                Dim tmpDate  As Date
                Dim sHollidays As String, param
     
     
    'On Error Resume Next
     
     
                ' Ne pas obtenir un éventuel décompte négatif
                If dateBegin > dateEnd Then tmpDate = dateBegin: dateBegin = dateEnd: dateEnd = tmpDate
     
                ' Liste des jours fériés à décompter
                sHollidays = get_Holidays(dateBegin, dateEnd)
     
                param = Split(sHollidays, ";")
     
                Count_OpenDays = Application.WorksheetFunction.NetworkDays(dateBegin, dateEnd, param)
            End Function
     
            ' Liste des jours fériés
            Public Function get_Holidays(dateBegin As Date, dateEnd As Date, Optional zone As String = "FR") As String
                Dim a As Long, sFeries As String, b As Boolean
                Dim p As Date, tmpDate As Date, sDate As String
     
     
                'Etablir la liste des jours fériés
                For a = Year(dateBegin) To Year(dateEnd)
                    p = EasterMonday(a)
     
                    'Common
                    sDate = "01/01/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                                 ' Jour de l'an
                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
                    sDate = Format(p - 3, "dd/mm/yyyy"): b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                  ' Vendredi Saint
                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
                    sDate = "25/12/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                                 ' Noel
                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
     
                    'FR
                    If zone = "FR" Then
                        sDate = Format(p, "dd/mm/yyyy"): b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                  ' Lundi de Paques
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
                        sDate = "01/05/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 1er mai
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
    '                    sDate = "08/05/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' Victoire 45
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate                          '
    '                    sDate = "14/07/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 14 Juillet
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
    '                    sDate = "15/08/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' Assomption
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
    '                    sDate = "11/11/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 11 Novembre
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
    '                    sDate = "26/12/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 2ème Noel
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
     
                    'US
                    ElseIf zone = "US" Then
                        tmpDate = nDayOfMonth(CDate("01/01/" & a), 3): b = tmpDate >= dateBegin And tmpDate <= dateEnd                                      ' 19/01 : Martin Luther King Junior Day (3ème Lundi de Janvier)
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & tmpDate
                        tmpDate = nDayOfMonth(CDate("01/02/" & a), 3): b = tmpDate >= dateBegin And tmpDate <= dateEnd                                      ' 16/02 : President’s Day (3ème Lundi de Février)
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & tmpDate
                        tmpDate = nDayOfMonth(CDate("01/06/" & a), 1) - 7: b = tmpDate >= dateBegin And tmpDate <= dateEnd                                  ' 25 mai Memorial Day (Dernier Lundi de Mai)
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & tmpDate
                        sDate = "19/06/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 19 Juin Juneteenth
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
                        sDate = "04/07/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 04 Juillet : Independance Day
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
                        sDate = "07/09/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 7 septembre : Labor Day
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
    '                    tmpDate = nDayOfMonth(CDate("01/10/" & a), 2, vbFriday): b = tmpDate >= dateBegin And tmpDate <= dateEnd                            ' 12 Octobre : Columbus Day (2ème lundi d’octobre)
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & tmpDate
    '                    sDate = "11/11/" & a: b = DateValue(sDate) >= dateBegin And DateValue(sDate) <= dateEnd                                             ' 11 Novembre Veteran's Day
    '                        If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & sDate
                        tmpDate = nDayOfMonth(CDate("01/11/" & a), 4, vbThursday):  b = tmpDate >= dateBegin And tmpDate <= dateEnd                         ' 26 Novembre : Thanksgiving Day (4ème jeudi de novembre)
                            If b Then sFeries = sFeries & IIf(sFeries <> "", ";", "") & tmpDate
                    End If
                Next
     
                get_Holidays = sFeries
            End Function
     
            ' Lundi de Paques
            Public Function EasterMonday(a As Long) As Date
                Dim NbO As Long, Epacte As Long
                Dim PLune As Date
     
                NbO = ((a - 532) Mod 19) + 1
     
                Epacte = (11 * NbO - (3 + Int(2 + Int(a / 100)) * 3 / 7)) Mod 30
                PLune = DateSerial(a, 4, 19) - ((Epacte + 6) Mod 30)
                If Epacte = 24 Or Epacte = 25 Then PLune = PLune - 1
     
                '   Lundi de Pâques
                EasterMonday = PLune - Weekday(PLune) + vbMonday + 7
     
            End Function
     
     
            ' nième jour du mois
            Public Function nDayOfMonth(firstDayOfMonth As Date, n As Long, Optional wd As VbDayOfWeek = vbMonday) As Date
                Dim w As Long, fd As Date, f As Date, x As Long
     
                ' Jour demandé base Monday =1
                wd = wd + 6
     
                ' 1 jour du mois : des fois que firstDayOfMonth <> 1er du mois
                fd = DateValue("01/" & Month(firstDayOfMonth) & "/" & Year(firstDayOfMonth))
                w = Weekday(fd, vbMonday)
     
                ' Uniquement une date du mois concerné
                For x = n To 1 Step -1
                    f = fd + ((wd - w) Mod 7) + ((x - 1) * 7)
                    If Month(f) = Month(firstDayOfMonth) Then Exit For
                Next
     
                nDayOfMonth = f
            End Function

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

    Informations professionnelles :
    Activité : peu importe

    Informations forums :
    Inscription : Novembre 2023
    Messages : 1 536
    Par défaut
    Bizarre

    chez moi le code fonctionne très bien (Excel 365 version 2601)
    Nom : 2026-03-16_19-32-08.png
Affichages : 101
Taille : 5,9 Ko
    JièL
    Membre des AMIS
    Anti Macro Inutilement Superfétatoire

  6. #6
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    Tu viens de mettre le doigt sur un truc :
    Effectivement le code marche
    ... mais uniquement sur cette période (01/01/26 - 16/03/26)
    Cela viens donc du format du tableau puisqu'avec 1 seul jour férié défini, cela fonctionne.

    J'y retournerai demain.

    Bonne soirée.

  7. #7
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 444
    Billets dans le blog
    3
    Par défaut
    Bonjour,

    Avec 2 jours ça a l'air de passer aussi

    en O5 : 1/1/2026
    en P5 : 5/5/2026

    La fonction suivante appliquée à ces 2 cellules renvoie le même résultat que NB.Jours.ouvres avec la liste des 1/1/2026 et 1/5/2026 en jours fériés

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Function TestNetworkDays(DateDeb As Date, DateFin As Date) As Long
    Dim Tablo
        Tablo = Array(#1/1/2026#, #5/1/2026#)
        TestNetworkDays = Application.WorksheetFunction.NetworkDays(DateDeb, DateFin, Tablo)
    End Function

  8. #8
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    la fonction tableur NB.JOURS.OUVRE fonctionne dans tous les cas
    alors que Networkdays pose soucis quand la plage de date s'étend sur plus d'une année
    ET que des jours fériés existent sur les 2 années !!!

  9. #9
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 444
    Billets dans le blog
    3
    Par défaut
    Re,

    Peut-être essayer NetworkDays_Intl ? (NB.JOURS.OUVRES.INTL)

    Ne fonctionne que depuis Excel 2016 (d'après l'aide MS qui raconte souvent n'importe quoi)

  10. #10
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    J'ai déjà essayé sans résultat mais j'ai une petite idée du problème.
    Il est probable que les dates soient interprêtées au format "mm/dd/yyyy" d'où le rejet du 25/12/2025.

    A vérifier ... ultérieurement

  11. #11
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 444
    Billets dans le blog
    3
    Par défaut
    Re,

    Sinon, si c'est bien limité à une année, il ne reste plus qu'à découper les dates par année... ou à ne pas utiliser NetworkDays et recoder la fonction, à ce stade

  12. #12
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 444
    Billets dans le blog
    3
    Par défaut
    Re,

    Euh... je ne comprend pas bien
    ai essayé sur 2 années, avec comme liste de jours fériés juste : 1/1/2026, 1/5/2026, 1/1/2027, 1/5/2027

    du 1/1/2026 au 5/5/2027

    NB.JOURS.OUVRES renvoie 347
    la fonction suivante renvoie 346

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Function TestNetworkDays(DateDeb As Date, DateFin As Date) As Long
    Dim Tablo
        Tablo = Array(#1/1/2026#, #5/1/2026#, #1/1/2027#, #5/1/2027#)
        TestNetworkDays = Application.WorksheetFunction.NetworkDays(DateDeb, DateFin, Tablo)
    End Function
    pas compris pourquoi

  13. #13
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 444
    Billets dans le blog
    3
    Par défaut
    Re,

    par contre la fonction là renvoie 347

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Function TestNetworkDays(DateDeb As Date, DateFin As Date) As Long
    Dim Tablo
        Tablo = Array(CLng(#1/1/2026#), CLng(#5/1/2026#), CLng(#1/1/2027#), CLng(#5/1/2027#))
        TestNetworkDays = Application.WorksheetFunction.NetworkDays(DateDeb, DateFin, Tablo)
    End Function
    en espérant que ces tests donnent des pistes, je m'arrête là pour aujourd'hui

  14. #14
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    La gestion des dates s'effectue différemment sous classeur excel et sous vba (sic Microsoft !)
    l'un tenant compte de la version locale (ici française) alors que l'autre, uniquement de la version anglaise.
    Le fait d'utiliser Worksheetfunction qui interfère entre les 2 est-il la cause du problème ?

    Une chose est sure : il existe un système de correction des dates de type Date et String
    (exemple "25/12/xxxx" et "12/25/xxxx" interprêtés comme la même valeur afin de ne pas générer d'erreur
    et ce, quelquesoit le paramètrage locale du format date).

    Il faut donc de préférence utiliser des Long et les n° de série des dates
    d'où le code modifié suivant qui lui est fonctionnel.

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
            ' Retourne le nombre de jours ouvrés                               
    '        ' =================================================================='
            ' Nombre de jours ouvrés
            Public Function Count_OpenDays(ByVal dateBegin As Date, ByVal dateEnd As Date, Optional sCountry As String = "FR") As Long
                Dim tmpDate  As Date
                Dim sHollidays As String, param() As Long
     
     
                ' Ne pas obtenir un éventuel décompte négatif
                If dateBegin > dateEnd Then tmpDate = dateBegin: dateBegin = dateEnd: dateEnd = tmpDate
     
                ' Liste des jours fériés à décompter
                param() = get_Holidays(dateBegin, dateEnd, sCountry)
     
                Count_OpenDays = Application.WorksheetFunction.NetworkDays(dateBegin, dateEnd, param)
            End Function
     
            ' Liste des jours fériés
            Public Function get_Holidays(dateBegin As Date, dateEnd As Date, Optional zone As String = "FR") As Long()
                Dim a As Integer, p As Date, b As Boolean
                Dim dDate As Long, dDates() As Long, i As Long
     
                ReDim dDates(0 To 0)
     
                'Etablir la liste des jours fériés
                For a = Year(dateBegin) To Year(dateEnd)
                    p = EasterMonday(a)
     
                    'Common
                    dDate = DateSerial2Long(a, 1, 1): b = dDate >= dateBegin And dDate <= dateEnd                                                               ' Jour de l'an
                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                    dDate = CLng(p) - 3: b = dDate >= dateBegin And dDate <= dateEnd                                                                            ' Vendredi Saint
                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                    dDate = DateSerial2Long(a, 12, 25): b = dDate >= dateBegin And dDate <= dateEnd                                                             ' Noel
                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
     
                    'FR
                    If zone = "FR" Then
                        dDate = CLng(p): b = dDate >= dateBegin And dDate <= dateEnd                                                                            ' Lundi de Paques
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                        dDate = DateSerial2Long(a, 5, 1): b = dDate >= dateBegin And dDate <= dateEnd                                                           ' 1er mai
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = DateSerial2Long(a, 5, 8): b = dDate >= dateBegin And dDate <= dateEnd                                                           ' Victoire 45
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = DateSerial2Long(a, 7, 14): b = dDate >= dateBegin And dDate <= dateEnd                                                          ' 14 Juillet
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = DateSerial2Long(a, 8, 15): b = dDate >= dateBegin And dDate <= dateEnd                                                          ' Assomption
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = DateSerial2Long(a, 11, 11): b = dDate >= dateBegin And dDate <= dateEnd                                                         ' 11 Novembre
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = DateSerial2Long(a, 12, 26): b = dDate >= dateBegin And dDate <= dateEnd                                                         ' 2ème Noel
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1                     '
     
     
     
                    'US
                    ElseIf zone = "US" Then
                        dDate = nDayOfMonth(a, 1, 1, 3): b = dDate >= dateBegin And dDate <= dateEnd                                                            ' 19/01 : Martin Luther King Junior Day (3ème Lundi de Janvier)
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                        dDate = nDayOfMonth(a, 2, 1, 3): b = dDate >= dateBegin And dDate <= dateEnd                                                            ' 16/02 : President’s Day (3ème Lundi de Février)
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                        dDate = nDayOfMonth(a, 6, 1, 1) - 7: b = dDate >= dateBegin And dDate <= dateEnd                                                        ' 25 mai Memorial Day (Dernier Lundi de Mai)
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                        dDate = DateSerial2Long(a, 6, 9): b = dDate >= dateBegin And dDate <= dateEnd                                                           ' 19 Juin Juneteenth
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                        dDate = DateSerial2Long(a, 7, 4): b = dDate >= dateBegin And dDate <= dateEnd                                                           ' 04 Juillet : Independance Day
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                        dDate = DateSerial2Long(a, 9, 7): b = dDate >= dateBegin And dDate <= dateEnd                                                           ' 7 septembre : Labor Day
                            If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = nDayOfMonth(a, 10, 1, 2, vbFriday): b = dDate >= dateBegin And dDate <= dateEnd                                                 ' 12 Octobre : Columbus Day (2ème lundi d’octobre)
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = DateSerial2Long(a, 11, 11): b = dDate >= dateBegin And dDate <= dateEnd                                                         ' 11 Novembre Veteran's Day
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
    '                    dDate = nDayOfMonth(a, 11, 1, 4, vbThursday): b = dDate >= dateBegin And dDate <= dateEnd                                               ' 26 Novembre : Thanksgiving Day (4ème jeudi de novembre)
    '                        If b Then ReDim Preserve dDates(LBound(dDates) To i): dDates(i) = dDate: i = i + 1
                    End If
                Next
     
                get_Holidays = dDates()
            End Function
     
            ' Date qualifiée par son n° de série
            Public Function DateSerial2Long(a As Integer, m As Integer, j As Integer) As Long
                DateSerial2Long = CLng(DateSerial(a, m, j))
            End Function
     
            ' Lundi de Paques
            Public Function EasterMonday(a As Integer) As Date
                Dim NbO As Long, Epacte As Long
                Dim PLune As Date
     
                NbO = ((a - 532) Mod 19) + 1
     
                Epacte = (11 * NbO - (3 + Int(2 + Int(a / 100)) * 3 / 7)) Mod 30
                PLune = DateSerial(a, 4, 19) - ((Epacte + 6) Mod 30)
                If Epacte = 24 Or Epacte = 25 Then PLune = PLune - 1
     
                '   Lundi de Pâques
                EasterMonday = PLune - Weekday(PLune) + vbMonday + 7
     
            End Function
     
     
            ' nième jour du mois
            Public Function nDayOfMonth(a As Integer, m As Integer, j As Integer, n As Long, Optional wd As VbDayOfWeek = vbMonday) As Date
                Dim firstDayOfMonth As Long
                Dim w As Long, fd As Long, f As Long, x As Long
     
                firstDayOfMonth = DateSerial2Long(a, m, j)
     
                ' Jour demandé base Monday =1
                wd = wd + 6
     
                ' 1 jour du mois : des fois que firstDayOfMonth <> 1er du mois
                fd = DateSerial2Long(a, m, 1)
                w = Weekday(fd, vbMonday)
     
                ' Uniquement une date du mois concerné
                For x = n To 1 Step -1
                    f = fd + ((wd - w) Mod 7) + ((x - 1) * 7)
                    If Month(f) = Month(firstDayOfMonth) Then Exit For
                Next
     
                nDayOfMonth = f
            End Function
    Merci à toto pour sa participation

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 574
    Par défaut
    Hello,

    Si je puis apporter mon grain de sel:
    Ne fesant que peut confiance aux notations de dates genre #5/1/2026#, du a la confusion récurrente entre les format de dates françaises et américaines,
    je préfère passer par les fonctions de gestion des dates, comme DateSerial:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim Dt As Date
    Dt = DateSerial(2026, 5, 1)    '// 1er Mai 2026
    Et avec un tableau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim Table As Variant
    Table = Array(DateSerial(2026, 1, 1), DateSerial(2026, 5, 1))

  16. #16
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 444
    Billets dans le blog
    3
    Par défaut
    Bonjour,

    bonne remarque mais je viens de tester et la fonction suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Function TestNetworkDays(DateDeb As Date, DateFin As Date) As Long
    Dim Tablo
        Tablo = Array(DateSerial(2026, 1, 1), DateSerial(2026, 5, 1), DateSerial(2027, 1, 1), DateSerial(2027, 5, 1))
        TestNetworkDays = Application.WorksheetFunction.NetworkDays(DateDeb, DateFin, Tablo)
    End Function
    renvoie 346 du 1/1/2026 au 5/5/2027
    comme renvoyait celle-ci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Function TestNetworkDays(DateDeb As Date, DateFin As Date) As Long
    Dim Tablo
        Tablo = Array(#1/1/2026#, #5/1/2026#, #1/1/2027#, #5/1/2027#)
        TestNetworkDays = Application.WorksheetFunction.NetworkDays(DateDeb, DateFin, Tablo)
    End Function
    en désaccord avec nb.jours.ouvres qui trouve 347 entre ces 2 dates avec les mêmes jours fériés fournis
    ou celle-ci qui trouve 347 aussi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Function TestNetworkDays(DateDeb As Date, DateFin As Date) As Long
    Dim Tablo
        Tablo = Array(CLng(#1/1/2026#), CLng(#5/1/2026#), CLng(#1/1/2027#), CLng(#5/1/2027#))
        TestNetworkDays = Application.WorksheetFunction.NetworkDays(DateDeb, DateFin, Tablo)
    End Function
    Toujours pas bien compris pourquoi d'ailleurs, mais ça ne résoud pas le désaccord

  17. #17
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 149
    Par défaut
    Citation Envoyé par deedolith Voir le message
    Hello,

    Si je puis apporter mon grain de sel:
    Ne fesant que peut confiance aux notations de dates genre #5/1/2026#, du a la confusion récurrente entre les format de dates françaises et américaines,
    je préfère passer par les fonctions de gestion des dates, comme DateSerial:
    deedolith a tout dit

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

Discussions similaires

  1. Souci avec double clic
    Par AnthonyBon dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 16/10/2018, 12h12
  2. [PHP 5.3] Soucis avec le résultat d'une requête (double boucles while)
    Par beegees dans le forum Langage
    Réponses: 7
    Dernier message: 31/05/2010, 22h26
  3. Souci avec un double switch
    Par Olivier Regnier dans le forum Langage
    Réponses: 1
    Dernier message: 25/08/2009, 18h53
  4. Petit soucis avec les doubles
    Par yakamoneye dans le forum Débuter
    Réponses: 30
    Dernier message: 08/06/2008, 11h04
  5. Réponses: 4
    Dernier message: 16/02/2003, 12h16

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