Strona główna Makra / VBA Który to tydzień kalendarzowy?

Wybrana funkcja

Który to tydzień kalendarzowy?

Ostatnio pracując z Excelem spotkałem się z problemem numeru tygodnia. Mając podaną datę chciałem uzyskać numer tygodnia kalendarzowego w roku, w który ta data wypada. Na początku zignorowałem lekko ten problem, bo przecież jest funkcja wbudowana, która robi dokładnie to co chcę osiągnąć. Czy jednak jest to samo?

Pierwsze podejście - funkcja DZIEŃ.TYG(data;typ_wyniku). Funkcja ta przyjmuje dwa argumenty. Oczywiście pierwszym z nich jest data, natomiast drugi określa dzień od którego zaczyna się tydzień:

  • 1 - tydzień trwa od niedzieli do soboty,
  • 2 - tydzień trwa od poniedziałku do niedzieli.

Prosty test pokazuje, że ta funkcja nie działa poprawienie:

  • 1 stycznia 2010 - tydzień 1,
  • 31 grudnia 2009 - tydzień 53.

Zaglądając do kalendarza można zobaczyć, że w przypadku 31.12.2009 tydzień został poprawienie odczytany. Natomiast w przypadku 01.01.2010 wynik jest nieprawidłowy. Powinien być 53 tydzień a jest 1.

Problem, ten jest związany ze sposobem obliczania daty w Europie. Zgodnie ze standardem ISO (ISO8601:2004) za pierwszy tydzień roku uznaje się ten tydzień, który posiada cztery dni stycznia. Należy pamiętać, że tydzień zgodnie z ISO rozpoczyna się poniedziałkiem. Oznacza to, że powyższe stwierdzanie można zastąpić następującym: Za pierwszy tydzień roku uznaje się tydzień, w którym występuje pierwszy czwartek stycznia. Taka interpretacja stosowana jest we wszystkich kalendarzach w Europie.

Spróbujmy rozwiązać ten problem.

Podejście 1 - użycie formuły.

Zakładając, że nasza data znajduje się w komórce A1 można użyć następującej formuły:

=ZAOKR.DO.CAŁK((A1-DATA(ROK(A1-DZIEŃ.TYG(A1-1)+4);1;3)+DZIEŃ.TYG(DATA(ROK(A1-DZIEŃ.TYG(A1-1)+4);1;3))+5)/7)

Rozwiązanie to jest kłopotliwe ponieważ przy wpisywaniu tak długiej formuły może się pojawić błąd. Szczególnie wtedy gdy chcemy, aby numer tygodnia był argumentem w innej funkcji. Dlatego też najlepszym rozwiązaniem jest opracowanie własnej funkcji.

Podejście 2 - własna funkcja VBA

Naturalnym sposobem ominięcia długi i dziwnie wyglądających formuł jest zdefiniowanie funkcji użytkownika. W tym celu należy dodać do modułu następującą funkcję:

 

1
2
3
4
5
Public Function IsoWeekNumber(data As Date) As Integer
Dim temp As Long
temp = DateSerial(Year(data - WeekDay(data - 1) + 4), 1, 3)
IsoWeekNumber = Int((data - temp + WeekDay(d2) + 5) / 7)
End Function

I na koniec ją wywołać: = IsoWeekNumber(A1).

Osoby programujące w VBA mogą zdziwić się dlaczego nie została użyta funkcja: DatePart("ww",date,vbMonday,vbFirstFourDays). Teoretycznie powinna on zwrócić też tą samą wartość. Jednak tak nie jest. Znalazł się w niej błąd. Jeżeli będziemy chcieli określić tydzień dla daty, np. 29.12.2003 to funkcja ta zwróci warość 53. Pomimo, że jest to poniedziałek, a 01.01.2004 wypada w czwartek. Aby użyć tej funkcji należy dodać dodatkowy warunek:

1
2
3
4
5
6
7
8
Function IsoWeekNumber (data As Date) As Integer
	IsoWeekNumber = Format(data, "ww", vbMonday, vbFirstFourDays)
	If IsoWeekNumber > 52 Then
		If Format(data + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then
			IsoWeekNumber = 1
		End If
	End If
End Function

 


 

 

 

 

Dodaj komentarz


Kod antysapmowy
Odśwież