TL;DR —
Year(d),Month(d),Day(d),Hour(t),Minute(t),Second(t)renvoient chacun un entier tiré d'une date — simple et sans ambiguïté.Weekday(d)est le piège : il renvoie 1 à 7, mais la numérotation dépend d'un second argument qui vautvbSunday(1) par défaut, si bien que par défaut lundi vaut 2, pas 1. PassezvbMonday(ou comparez aux constantesvb*) et la logique de week-end cesse d'être discrètement fausse.
Sub PartsDemo()
Dim d As Date: d = #2026-08-26# ' un mercredi
Debug.Print Year(d), Month(d), Day(d) ' 2026 8 26
Debug.Print Weekday(d) ' 4 - dimanche=1 par defaut, donc mer=4
Debug.Print Weekday(d, vbMonday) ' 3 - lundi=1, donc mer=3
Debug.Print DatePart("ww", d) ' 35 - numero de semaine (pas de fonction dediee)
End Sub
Extraire les parties, c'est l'inverse de construire une date à partir de ses
éléments : vous avez le Double, et vous voulez l'année, le mois, le jour de la
semaine. La plupart de ces fonctions sont aussi ennuyeuses qu'elles devraient l'être — Year, Month,
Day ne font que lire le nombre. Weekday est celle qui a mis fin à plus de macros qu'elle ne le devrait,
entièrement à cause d'une valeur par défaut que personne ne retient.
Ce que vous allez apprendre
- Les extracteurs simples —
Year,Month,Day,Hour,Minute,Second— un entier chacun - Pourquoi
Weekdayrenvoie 2 pour lundi par défaut, et l'unique argument qui corrige cela - Comment écrire des tests de week-end et de jour ouvré qui ne sont pas secrètement faux
DatePart— l'extracteur général qui atteint le numéro de semaine et le trimestre- Pourquoi les numéros de semaine de
DatePart("ww", …)peuvent être décalés d'un à la limite de l'année (ISO 8601) WeekdayNameetMonthNamerenvoient des noms localisés — pour l'affichage, pas pour l'analyse
Les extracteurs simples : un entier chacun
Year, Month et Day découpent une date en ses composantes calendaires ; Hour, Minute et Second
découpent la fraction horaire. Chacun renvoie un simple Integer, et il n'y a rien qui accroche :
Dim d As Date: d = Now ' 2026-08-26 14:30:07
Debug.Print Year(d) ' 2026
Debug.Print Month(d) ' 8 (un nombre 1-12, pas le nom)
Debug.Print Day(d) ' 26
Debug.Print Hour(d) ' 14 (24 heures)
Debug.Print Minute(d) ' 30
Debug.Print Second(d) ' 7
Month renvoie 8, pas "August" — c'est un nombre. Ce sont les briques que vous réinjectez dans
DateSerial pour construire des dates liées (le premier du mois, le même jour l'an
prochain, et ainsi de suite). Aucune surprise ici — et c'est justement pour cela que Weekday prend les
gens au dépourvu.
Pourquoi Weekday renvoie 2 pour lundi
Weekday(date, [firstDayOfWeek]) renvoie un nombre de 1 à 7 — mais quel jour vaut 1 est fixé par le
second argument, et quand vous l'omettez VBA prend vbSunday, donc dimanche = 1 et lundi = 2 :
Weekday(#2026-08-24#) ' 2 - ce lundi-la, car dimanche=1 par defaut
Weekday(#2026-08-24#, vbMonday) ' 1 - maintenant lundi=1 ... dimanche=7
C'est le bug vedette de toute la famille. Un code comme If Weekday(d) = 1 Then ' lundi est faux — 1
c'est dimanche dans un appel par défaut — et un code comme
If Weekday(d) = 6 Or Weekday(d) = 7 Then ' week-end dépend entièrement d'une hypothèse sur le premier
jour, invisible au point d'appel. Il y a deux correctifs robustes, et les deux suppriment la devinette :
' Correctif 1 - fixez le premier jour explicitement, alors lundi vaut vraiment 1 :
If Weekday(d, vbMonday) >= 6 Then MsgBox "weekend" ' 6 = sam, 7 = dim
' Correctif 2 - comparez aux constantes nommees, jamais des nombres magiques :
If Weekday(d) = vbSaturday Or Weekday(d) = vbSunday Then MsgBox "weekend"
Les constantes vb* (vbSunday, vbMonday, … vbSaturday) sont correctes quel que soit l'argument du
premier jour, et c'est pourquoi les comparer est l'habitude la plus sûre. La règle : n'écrivez jamais un
nombre nu pour un jour de la semaine — soit vous passez vbMonday pour que la numérotation soit celle que
vous attendez, soit vous comparez à une constante vb*.
DatePart : l'extracteur général
DatePart(interval, date, [firstDayOfWeek], [firstWeekOfYear]) est la version couteau suisse : il prend les
mêmes codes d'intervalle que DateAdd et DateDiff et en extrait l'unité. Pour
l'année, le mois, le jour et l'heure, il fait doublon avec les fonctions dédiées — mais c'est le seul
moyen intégré d'atteindre deux parties qui n'ont pas de fonction propre :
DatePart("q", d) ' trimestre de l'annee (1-4) - aucune fonction Quarter() n'existe
DatePart("ww", d) ' numero de semaine de l'annee (1-53)
DatePart("y", d) ' jour de l'annee (1-366) - le "y" qui veut dire jour-de-l'annee
DatePart("m", d) ' 8 - identique a Month(d)
Recourez à DatePart quand vous avez besoin du trimestre ou du numéro de semaine, et utilisez les
fonctions Year / Month / Day pour les parties courantes car elles se lisent plus clairement. Notez le
même piège de code que dans DateAdd : "y" c'est le jour de l'année et "ww" la semaine — dites-les à
voix haute une fois.
Le piège du numéro de semaine à la limite de l'année
DatePart("ww", …) a sa propre valeur par défaut qui surprend : la première semaine de l'année et le
premier jour de la semaine valent tous deux une règle à l'américaine (vbSunday, vbFirstJan1), qui
n'est pas ISO 8601 — la norme qu'utilisent la majeure partie de l'Europe et la plupart des calendriers
d'entreprise. Ainsi, les derniers jours de décembre et les premiers de janvier peuvent tomber dans un numéro
de semaine inattendu :
DatePart("ww", #2026-12-31#) ' 53 (regle US par defaut)
DatePart("ww", #2026-12-31#, vbMonday, vbFirstFourDays) ' la reponse facon ISO
Si vos numéros de semaine comptent — semaines de paie, numéros de sprint, tout ce qui doit concorder avec un
calendrier au mur — passez vbMonday comme premier jour de la semaine et vbFirstFourDays comme règle de
première semaine pour coller à l'ISO 8601. Le classique « mes numéros de semaine sont décalés d'un autour du
Nouvel An » vient toujours de ces deux valeurs par défaut.
WeekdayName et MonthName sont localisés
Pour transformer un numéro de jour ou de mois en nom, utilisez WeekdayName et MonthName. Tous
deux renvoient le nom dans la langue de la machine, ce qui les rend parfaits pour l'affichage et néfastes
pour tout ce que vous analysez ensuite :
WeekdayName(2) ' "Monday" sur une machine anglaise, "Montag" sur une allemande
MonthName(8) ' "August" / "August" / "aout" selon les parametres regionaux
WeekdayName(2, True) ' abrege : "Mon"
Parce que la sortie suit les paramètres régionaux de l'utilisateur, ne la comparez jamais à une chaîne
anglaise fixe et ne l'écrivez pas dans un fichier qu'un autre système lira — c'est un bug de localisation en
germe. Pour un libellé stable que vous maîtrisez, formatez plutôt la date : Format(d, "dddd") donne le
nom complet du jour et Format(d, "mmmm") le nom du mois, toujours sensibles aux paramètres régionaux mais
explicites, via Format. Utilisez WeekdayName / MonthName pour l'affichage à
l'écran ; utilisez des nombres (Weekday, Month) pour la logique.
Le verdict honnête : les parties sont faciles, les valeurs par défaut non
Extraire les parties d'une date est la chose la moins mystérieuse des dates VBA — avec un astérisque qui cause une part démesurée des bugs :
- Parties simples, fonctions simples →
Year,Month,Day,Hour,Minute,Second. Chacune renvoie un entier ;Monthest un nombre, pas un nom. Weekdaya une valeur par défaut cachée → c'estvbSunday, donc lundi vaut 2. PassezvbMonday, ou comparez àvbSaturday/vbSunday— jamais un nombre nu.DatePartpour ce qui n'a pas de fonction → le trimestre ("q") et le numéro de semaine ("ww") ; alignez les semaines ISO avecvbMonday+vbFirstFourDays.- Les noms sont localisés →
WeekdayName/MonthNamesuivent la langue de la machine ; servez-vous-en pour afficher, jamais pour analyser.
L'unique habitude qui prévient le plus de bugs : un numéro de jour de la semaine ne devrait jamais être un littéral. Dites quel jour vient en premier, ou nommez le jour que vous visez.
Comment ExcelMaster aide
Les bugs d'extraction de parties sont sournois parce que le code a l'air manifestement juste : un filtre de
week-end qui teste Weekday = 1, une colonne de numéro de semaine qui contredit le calendrier de paie chaque
janvier, un rapport qui écrit WeekdayName dans un fichier qu'un système d'une autre langue ne parvient
ensuite pas à relire. Chacun est une valeur par défaut que personne n'a retenue.
ExcelMaster écrit l'extraction juste du
premier coup. Décrivez la règle — « ignore les week-ends », « regroupe les lignes par trimestre », « étiquette
chaque ligne avec sa semaine ISO » — et il utilise Weekday(d, vbMonday) ou les constantes vb* pour la
logique de jour de la semaine, DatePart avec les arguments ISO pour les numéros de semaine, et garde les
noms d'affichage séparés des nombres sur lesquels vous branchez. Vous décrivez la règle calendaire ; il écrit
l'extraction de parties qui ne repose pas sur une valeur par défaut cachée.
Questions fréquentes
Pourquoi Weekday renvoie-t-il le mauvais numéro de jour en VBA ?
Parce que Weekday numérote la semaine à partir de son second argument, qui vaut vbSunday par défaut —
donc dimanche vaut 1 et lundi 2. Si vous supposiez que lundi vaut 1, chaque résultat est décalé d'un. Passez
le premier jour explicitement, Weekday(d, vbMonday), pour que lundi soit 1 jusqu'à dimanche 7, ou comparez
le résultat aux constantes nommées vbSaturday et vbSunday plutôt qu'à des nombres codés en dur.
Comment vérifier qu'une date est un week-end en VBA ?
Utilisez les constantes pour que la valeur par défaut du premier jour ne puisse pas vous piéger :
If Weekday(d) = vbSaturday Or Weekday(d) = vbSunday Then …. Les constantes vb* sont correctes quel que
soit l'argument de premier jour de la semaine en jeu. Autrement, Weekday(d, vbMonday) >= 6 traite 6
(samedi) et 7 (dimanche) comme le week-end — assurez-vous simplement d'avoir passé vbMonday.
Comment obtenir le trimestre ou le numéro de semaine d'une date en VBA ?
Utilisez DatePart, car il n'existe pas de fonction Quarter ni Week dédiée. DatePart("q", d) renvoie
le trimestre de 1 à 4, et DatePart("ww", d) renvoie le numéro de semaine. Pour des numéros de semaine ISO
8601, passez les arguments supplémentaires : DatePart("ww", d, vbMonday, vbFirstFourDays), sinon la semaine
autour du Nouvel An peut être décalée d'un.
Quelle est la différence entre Month et MonthName en VBA ?
Month(d) renvoie le mois sous forme de nombre (1 à 12) pour la logique ; MonthName(n) transforme un
numéro de mois en son nom sous forme de texte (MonthName(8) donne « August »). MonthName suit la
langue de la machine, alors ne l'utilisez que pour l'affichage — pour brancher ou comparer, servez-vous du
nombre issu de Month.
WeekdayName renvoie-t-il des noms anglais en VBA ?
Seulement sur une machine en anglais. WeekdayName et MonthName renvoient les noms dans les paramètres
régionaux du système, si bien que le même code produit « Monday », « Montag » ou « lundi » selon les
machines. Ne comparez jamais leur sortie à une chaîne anglaise fixe ; pour un libellé maîtrisé, utilisez
Format(d, "dddd"), et pour la logique, le Weekday numérique.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 26/08/2026.
Guides connexes : VBA DateAdd & DateDiff · VBA Now, Date & Time · VBA Format · VBA CStr, CDate & Val · Boucle For VBA
