Kalenderwoche nach ISO bzw. DIN

In Excelver­sio­nen ab 2007 ist es ja recht ein­fach, die Kalen­der­woche nach ISO 8601 bzw. DIN EN 28601 (1993) zu berech­nen: =KALENDERWOCHE(Datum; 21) und das Ergeb­nis stimmt. In VBA lässt sich mit­tels WorksheetFunction.WeekNum(Datum, 21) ein kor­rek­tes Ergeb­nis berech­nen.

Anders sieht das aber bei den Ver­sio­nen bis 2003 aus. Da gibt es noch nicht die „21” als Über­gabepa­ra­me­ter. Dadurch kann dur­chaus ein fehler­haftes Ergeb­nis aus­gegeben wer­den. Als Excel-Formel bietet sich solch eine Lösung an, wenn in A1 das Datum ste­ht:
=KÜRZEN((A1-DATUM(JAHR(A1+3-REST(A1-2; 7)); 1; REST(A1-2; 7)-9))/7)
Quelle: Excelformeln).

Eine Lösung per VBA gibt es natür­lich auch. Sog­ar diverse Möglichkeit­en. Mir gefällt gefiel diese (bis heute) am besten:

Function KW_ISO(Datum)
   KW_ISO = DatePart("ww", Datum, vbMonday, vbFirstFourDays)
   'oder in (nicht besser lesbarer) Kurzform
   'KW_ISO = DatePart("ww", Datum, 2, 2)
End Function

Das Argu­ment Datum muss ein kalen­darisches Datum sein oder in irgend ein­er Form in ein solch­es umge­wan­delt wer­den kön­nen. Die Rück­gabe ist der numerische Wert der Kalen­der­woche.

Hin­weis: Ein acht­samer Tüftler und Leser dieses Forums hat fest­gestellt, dass die vor­ge­nan­nte UDF KW_ISO(Datum) in bes­timmten Fällen und für mich bis­lang nicht nachvol­lziehbaren Grün­den falsche Ergeb­nisse „pro­duziert”.  Danke Jörg! (Der volle Name und die E‑Mail liegen mir vor.) Ich habe die kalen­darischen Dat­en vom 01.03.1900 (der Tag nach dem nur in Win­dows-Excel existieren­den 29.02.1900) bis heute (14.01.2021) mit ein­er kleinen von Jörg erstell­ten VBA-Proze­dur gecheckt und fol­gende kalen­darische Dat­en sind sind in Sachen DIN-Kalen­der­woche falsch berech­net wor­den:

Datum seriell Dif­ferenz
30.12.1907 2921  
29.12.1919 7303 4382
31.12.1923 8766 1463
30.12.1935 13148 4382
29.12.1947 17530 4382
31.12.1951 18993 1463
30.12.1963 23375 4382
29.12.1975 27757 4382
31.12.1979 29220 1463
30.12.1991 33602 4382
29.12.2003 37984 4382
31.12.2007 39447 1463
30.12.2019 43829 4382

Ich habe zusät­zlich zu den kalen­darischen Werten noch die dazu passende serielle Zahl in di zweite Spalte geschrieben und die Dif­ferenz in Tagen in der drit­ten Spalte berech­nen lassen. So ist eine gewisse Rhyth­mik erkennbar, welche ich aber derzeit nicht analysieren kann.

Für mich ist diese UDF wegen der nicgt durchgängig kor­rek­ten Ergeb­nisse nicht ein­set­zbar, auch wenn es nur 3,178 Promille Falschergeb­nisse sind. Ich halte es da wie beim Aut­o­fahren: nur 0,00‰ sind okay und über 3,1 ‰ kön­nen tödlich sein. 💡  – Ich habe eben noch ein­mal in der Microsoft-Hil­fe zur Funk­tion DatePart() nachge­se­hen und fest­gestellt, dass MS diesen Fehler auch schon erkan­nt hat und direkt zu Beginn eine entsprechende War­nung einge­fügt hat  – Mein Tipp: Diese Funk­tion und entsprechend auch die von mir vorgestellte UDF nicht ver­wen­den. Alter­na­tiv kön­nte über eine WENN()-Funk­tion der Ergeb­niswert bei den betrof­fe­nen kalen­darischen Dat­en (siehe Tabelle oben) der Rück­gabe­w­ert angepasst wer­den.

Alter­na­tiv mit Jahreszahl

Soll die Funk­tion option­al eine Jahreszahl mit aus­geben, dann wird beispiel­sweise solch ein Code eher hil­fre­ich sein:

 Function KW_ISO(Datum, Optional Jahr As Boolean = False)
   Dim Rc As Variant, J As Integer
   
   Rc = DatePart("ww", Datum, vbMonday, vbFirstFourDays)
   'Alternativ immer 2 - stellig:
   'Rc = Format(DatePart("ww", Datum, vbMonday, vbFirstFourDays), "00")
   J = Year(Datum)
   If Jahr Then
      If Month(Datum) = 1 And Rc > 10 Then J = J - 1
      Rc = Rc & "/" & J
   End If
   KW_ISO = Rc
End Function

Sie kön­nen als zweites Argu­ment entwed­er 0 bzw. 1 eingeben, was einem FALSCH bzw. WAHR entspricht. 0, FALSCH oder keine Angabe sor­gen dafür, dass keine Jahreszahl aus­gegeben wird, bei 1 oder WAHR wird die Jahreszahl des zur KW passenden Jahres aus­gegeben. Das würde beispiel­sweise am 1. Jan­u­ar 2017 bedeuten: 522016, weil es die 52. KW des Jahres 2016 ist, in welch­er der erste Tag des Datums liegt. Die Rück­gabe ist naturgemäß ein String / Text.

Falls Sie Hil­fe bein Ein­binden der Benutzerdefinierten Funk­tion brauchen, schauen Sie ein­fach hier im Blog nach.

▲ nach oben …

Hat Ihnen der Beitrag gefallen?
Erleichtert dieser Beitrag Ihre Arbeit?

Dann würde ich mich über einen Beitrag Ihrer­seits z.B. 2,00  freuen … (← Klick mich!)

Dieser Beitrag wurde unter Code-Schnipsel, Datum und Zeit, Mit VBA/Makro, Ohne Makro/VBA, Tipps und Tricks veröffentlicht. Setze ein Lesezeichen auf den Permalink.