TL;DR —
Year(d),Month(d),Day(d),Hour(t),Minute(t),Second(t)liefern je eine Ganzzahl aus einem Datum — einfach und eindeutig.Weekday(d)ist die Falle: Es liefert 1–7, aber die Nummerierung hängt von einem zweiten Argument ab, das standardmäßigvbSunday(1) ist, sodass Montag standardmäßig 2 ist, nicht 1. Übergeben SievbMonday(oder vergleichen Sie gegen dievb*-Konstanten), und die Wochenend-Logik hört auf, still falsch zu sein.
Sub PartsDemo()
Dim d As Date: d = #2026-08-26# ' ein Mittwoch
Debug.Print Year(d), Month(d), Day(d) ' 2026 8 26
Debug.Print Weekday(d) ' 4 - Standard Sonntag=1, also Mi=4
Debug.Print Weekday(d, vbMonday) ' 3 - Montag=1, also Mi=3
Debug.Print DatePart("ww", d) ' 35 - Kalenderwoche (keine eigene Funktion)
End Sub
Teile herauszuziehen ist die Umkehrung von ein Datum aus Teilen bauen: Sie haben
den Double und wollen das Jahr, den Monat, den Wochentag. Die meisten Funktionen sind genau so
langweilig, wie sie sein sollten — Year, Month, Day lesen einfach die Zahl. Weekday ist die, die
mehr Makros beendet hat, als sie sollte, ganz allein wegen einer Vorgabe, an die sich niemand erinnert.
Was Sie lernen
- Die einfachen Extraktoren —
Year,Month,Day,Hour,Minute,Second— je eine Ganzzahl - Warum
Weekdayfür Montag standardmäßig 2 liefert, und das eine Argument, das es richtet - Wie Sie Wochenend- und Wochentagstests schreiben, die nicht heimlich falsch sind
DatePart— der allgemeine Extraktor, der an die Kalenderwoche und das Quartal kommt- Warum
DatePart("ww", …)-Wochennummern an der Jahresgrenze um eins danebenliegen können (ISO 8601) WeekdayNameundMonthNameliefern lokalisierte Namen — für die Anzeige, nicht zum Parsen
Die einfachen Extraktoren: je eine Ganzzahl
Year, Month und Day zerlegen ein Datum in seine Kalenderbestandteile; Hour, Minute und Second
zerlegen den Uhrzeit-Nachkommateil. Jede liefert eine schlichte Integer, und es gibt nichts, worüber man
stolpern könnte:
Dim d As Date: d = Now ' 2026-08-26 14:30:07
Debug.Print Year(d) ' 2026
Debug.Print Month(d) ' 8 (eine Zahl 1-12, nicht der Name)
Debug.Print Day(d) ' 26
Debug.Print Hour(d) ' 14 (24-Stunden)
Debug.Print Minute(d) ' 30
Debug.Print Second(d) ' 7
Month liefert 8, nicht "August" — es ist eine Zahl. Das sind die Bausteine, die Sie in
DateSerial zurückfüttern, um verwandte Datumswerte zu konstruieren
(Monatserster, gleicher Tag im nächsten Jahr und so weiter). Keine Überraschungen hier — genau deshalb
erwischt Weekday die Leute auf dem falschen Fuß.
Warum Weekday für Montag 2 liefert
Weekday(date, [firstDayOfWeek]) liefert eine Zahl von 1 bis 7 — aber welcher Tag die 1 ist, legt das
zweite Argument fest, und wenn Sie es weglassen, nimmt VBA vbSunday, also Sonntag = 1 und
Montag = 2:
Weekday(#2026-08-24#) ' 2 - jener Montag, weil Standard Sonntag=1
Weekday(#2026-08-24#, vbMonday) ' 1 - jetzt Montag=1 ... Sonntag=7
Das ist der Paradebug der ganzen Familie. Code wie If Weekday(d) = 1 Then ' Monday ist falsch — 1 ist
im Standardaufruf Sonntag — und Code wie If Weekday(d) = 6 Or Weekday(d) = 7 Then ' weekend hängt
ganz von einer Annahme über den ersten Tag ab, die an der Aufrufstelle unsichtbar ist. Es gibt zwei
robuste Fixes, und beide räumen das Raten aus:
' Fix 1 - den ersten Tag explizit setzen, dann ist Montag wirklich 1:
If Weekday(d, vbMonday) >= 6 Then MsgBox "weekend" ' 6 = Sa, 7 = So
' Fix 2 - gegen die benannten Konstanten vergleichen, nie magische Zahlen:
If Weekday(d) = vbSaturday Or Weekday(d) = vbSunday Then MsgBox "weekend"
Die vb*-Konstanten (vbSunday, vbMonday, … vbSaturday) stimmen unabhängig vom
Erster-Tag-Argument, weshalb der Vergleich gegen sie die sicherste Gewohnheit ist. Die Regel: Schreiben
Sie nie eine nackte Zahl für einen Wochentag — übergeben Sie entweder vbMonday, damit die Nummerierung
so ist, wie Sie sie erwarten, oder vergleichen Sie gegen eine vb*-Konstante.
DatePart: der allgemeine Extraktor
DatePart(interval, date, [firstDayOfWeek], [firstWeekOfYear]) ist die Schweizer-Taschenmesser-Variante:
Es nimmt dieselben Intervallcodes wie DateAdd und DateDiff und zieht diese
Einheit heraus. Für Jahr, Monat, Tag und Uhrzeit dupliziert es die eigenen Funktionen — aber es ist der
einzige eingebaute Weg, an ein paar Teile zu kommen, die keine eigene Funktion haben:
DatePart("q", d) ' Quartal des Jahres (1-4) - es gibt keine Quarter()-Funktion
DatePart("ww", d) ' Kalenderwoche des Jahres (1-53)
DatePart("y", d) ' Tag des Jahres (1-366) - hier meint y den Tag des Jahres
DatePart("m", d) ' 8 - dasselbe wie Month(d)
Greifen Sie zu DatePart, wenn Sie das Quartal oder die Kalenderwoche brauchen, und nehmen Sie
die schlichten Funktionen Year / Month / Day für die Alltagsteile, weil sie sich klarer lesen.
Beachten Sie dieselbe Code-Falle wie bei DateAdd: "y" ist Tag-des-Jahres und "ww" ist Woche —
sprechen Sie sie einmal laut aus.
Die Kalenderwochen-Falle an der Jahresgrenze
DatePart("ww", …) hat seine eigene Vorgabe, die Leute überrascht: Die erste Woche des Jahres und der
erste Tag der Woche stehen beide standardmäßig auf einer US-Regel (vbSunday, vbFirstJan1), die
nicht ISO 8601 ist — dem Standard, den der Großteil Europas und die meisten Geschäftskalender
verwenden. So können die letzten Dezembertage und die ersten Januartage in einer Kalenderwoche landen, die
Sie nicht erwartet haben:
DatePart("ww", #2026-12-31#) ' 53 (US-Standardregel)
DatePart("ww", #2026-12-31#, vbMonday, vbFirstFourDays) ' die ISO-Antwort
Wenn Ihre Kalenderwochen zählen — Lohnwochen, Sprint-Nummern, alles, was mit einem Kalender an der Wand
übereinstimmen muss — übergeben Sie vbMonday als ersten Tag der Woche und vbFirstFourDays als
Erste-Woche-Regel, um ISO 8601 zu treffen. Der klassische Bug „meine Kalenderwochen liegen rund um
Neujahr um eins daneben" sind immer diese zwei Vorgaben.
WeekdayName und MonthName sind lokalisiert
Um eine Wochentags- oder Monatszahl in einen Namen zu verwandeln, nehmen Sie WeekdayName und
MonthName. Beide liefern den Namen in der Sprache des Rechners, was sie ideal für die Anzeige macht
und zum Fehler für alles, was Sie zurück-parsen:
WeekdayName(2) ' "Monday" auf einer englischen Maschine, "Montag" auf einer deutschen
MonthName(8) ' "August" / "August" / "aout" je nach Locale
WeekdayName(2, True) ' abgekuerzt: "Mon"
Weil die Ausgabe der Locale des Nutzers folgt, vergleichen Sie sie nie mit einer festen englischen
Zeichenkette und schreiben Sie sie nie in eine Datei, die ein anderes System liest — das ist ein
Locale-Bug mit Ansage. Für eine stabile Beschriftung, die Sie kontrollieren, formatieren Sie
stattdessen das Datum: Format(d, "dddd") gibt den vollen Wochentagsnamen und Format(d, "mmmm") den
Monatsnamen, weiterhin Locale-bewusst, aber explizit, über Format. Nehmen Sie
WeekdayName / MonthName für die Anzeige am Bildschirm; nehmen Sie Zahlen (Weekday, Month) für die
Logik.
Das ehrliche Fazit: Die Teile sind leicht, die Vorgaben nicht
Teile aus einem Datum zu ziehen ist das am wenigsten mysteriöse an VBA-Datumswerten — mit einem Sternchen, das einen überproportionalen Anteil der Bugs verursacht:
- Einfache Teile, einfache Funktionen →
Year,Month,Day,Hour,Minute,Second. Jede liefert eine Ganzzahl;Monthist eine Zahl, kein Name. Weekdayhat eine versteckte Vorgabe → sie istvbSunday, also ist Montag 2. Übergeben SievbMonday, oder vergleichen Sie gegenvbSaturday/vbSunday— nie eine nackte Zahl.DatePartfür das, was keine Funktion hat → das Quartal ("q") und die Kalenderwoche ("ww"); treffen Sie ISO-Wochen mitvbMonday+vbFirstFourDays.- Namen sind lokalisiert →
WeekdayName/MonthNamefolgen der Rechnersprache; nehmen Sie sie zur Anzeige, nie zum Parsen.
Die eine Gewohnheit, die die meisten Bugs verhindert: Eine Wochentagszahl sollte nie ein Literal sein. Sagen Sie, welcher Tag der erste ist, oder benennen Sie den Tag, den Sie meinen.
Wie ExcelMaster hilft
Teil-Extraktions-Bugs sind subtil, weil der Code offensichtlich richtig aussieht: ein Wochenendfilter, der
Weekday = 1 prüft, eine Kalenderwochen-Spalte, die jeden Januar mit dem Lohnkalender uneins ist, ein
Bericht, der WeekdayName in eine Datei schreibt, die ein System in einer anderen Sprache dann nicht
lesen kann. Jeder ist eine Vorgabe, an die sich niemand erinnert hat.
ExcelMaster schreibt die Extraktion,
die auf Anhieb stimmt. Beschreiben Sie die Regel — „Wochenenden überspringen", „Zeilen nach Quartal
gruppieren", „jede Zeile mit ihrer ISO-Woche beschriften" — und es nutzt Weekday(d, vbMonday) oder die
vb*-Konstanten für Wochentags-Logik, DatePart mit den ISO-Argumenten für Kalenderwochen und hält
Anzeigenamen getrennt von den Zahlen, nach denen Sie verzweigen. Sie beschreiben die Kalenderregel; es
schreibt die Teil-Extraktion, die sich nicht auf eine versteckte Vorgabe verlässt.
Häufig gestellte Fragen
Warum liefert Weekday in VBA die falsche Tagesnummer?
Weil Weekday die Woche ab seinem zweiten Argument nummeriert, das standardmäßig vbSunday ist —
also ist Sonntag 1 und Montag 2. Wenn Sie annahmen, Montag sei 1, liegt jedes Ergebnis um eins daneben.
Übergeben Sie den ersten Tag explizit, Weekday(d, vbMonday), dann ist Montag 1 bis Sonntag 7, oder
vergleichen Sie das Ergebnis gegen die benannten Konstanten vbSaturday und vbSunday statt gegen fest
verdrahtete Zahlen.
Wie prüfe ich in VBA, ob ein Datum ein Wochenende ist?
Nehmen Sie die Konstanten, damit die Erster-Tag-Vorgabe Sie nicht beißen kann:
If Weekday(d) = vbSaturday Or Weekday(d) = vbSunday Then …. Die vb*-Konstanten stimmen, egal welches
Erster-Tag-der-Woche-Argument im Spiel ist. Alternativ behandelt Weekday(d, vbMonday) >= 6 die 6
(Samstag) und 7 (Sonntag) als Wochenende — stellen Sie nur sicher, dass Sie vbMonday übergeben haben.
Wie bekomme ich in VBA das Quartal oder die Kalenderwoche eines Datums?
Nehmen Sie DatePart, denn es gibt keine eigene Quarter- oder Week-Funktion. DatePart("q", d)
liefert das Quartal 1–4, und DatePart("ww", d) liefert die Kalenderwoche. Für
ISO-8601-Kalenderwochen übergeben Sie die zusätzlichen Argumente:
DatePart("ww", d, vbMonday, vbFirstFourDays), sonst kann die Woche rund um Neujahr um eins
danebenliegen.
Was ist der Unterschied zwischen Month und MonthName in VBA?
Month(d) liefert den Monat als Zahl (1–12) für den Einsatz in der Logik; MonthName(n) verwandelt
eine Monatszahl in ihren Namen als Text (MonthName(8) ergibt „August"). MonthName folgt der
Sprache des Rechners, nehmen Sie es also nur für die Anzeige — für Verzweigungen oder Vergleiche nehmen
Sie die Zahl aus Month.
Liefert WeekdayName in VBA englische Namen?
Nur auf einer englischsprachigen Maschine. WeekdayName und MonthName liefern Namen in der Locale des
Systems, sodass derselbe Code auf verschiedenen Rechnern „Monday" oder „Montag" oder „lundi" erzeugt.
Vergleichen Sie ihre Ausgabe nie mit einer festen englischen Zeichenkette; für eine kontrollierte
Beschriftung nehmen Sie Format(d, "dddd"), und für die Logik nehmen Sie das numerische Weekday.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 26.08.2026.
Verwandte Anleitungen: VBA DateAdd & DateDiff · VBA Now, Date & Time · VBA Format · VBA CStr, CDate & Val · VBA For Loop
