poniedziałek, 29 lutego 2016

Ostatni biznesowy dzień miesiąca (funkcja)

Dziś krótka odpowiedź na pytanie- jak pobrać datę odpowiadającą ostatniemu dniu miesiąca z pominięciem weekendu? Jeżeli ostatni dzień miesiąca wypada w sobotę lub niedzielę naszym celem będzie otrzymanie daty odpowiadającej piątkowi poprzedzającemu ten weekend. Poniżej gotowe rozwiązanie w postaci funkcji UDF.
01Public Function EndOfBusinessMonth(RefDate) As Date
02  
03Dim LastDay As Date
04  
05LastDay = DateSerial(Year(RefDate), Month(RefDate) + 1, 0)
06 
07Select Case Weekday(LastDay)
08Case 'Niedziela
09  EndOfBusinessMonth = DateAdd("d", -2, LastDay)
10Case 'Sobota
11  EndOfBusinessMonth = DateAdd("d", -1, LastDay)
12Case Else
13  EndOfBusinessMonth = LastDay
14End Select
15  
16End Function
Proszę też zwrócić uwagę na ten zapis:
1LastDay = DateSerial(Year(RefDate), Month(RefDate) + 1, 0)
którego celem jest zwrócenie daty ostatniego dnia miesiąca (poprzedniego).
Warto przy okazji też podkreślić, że funkcja DateSerial() jest funkcją bardzo elastyczną, która umożliwia wprowadzenie ilości miesięcy spoza przedziału 1-12 co powoduje automatyczną konwersję na odpowiedni miesiąc dokonując przejścia przez kolejne lata (mniejsze od 0- lata wcześniejsze, większe od 12- lata późniejsze). Podobnie kwestia wygląda w zakresie dni, gdzie dopuszczalne są wartości spoza przedziału 1-31, a czego przykład widać w powyższej funkcji.

środa, 24 lutego 2016

Szybka kowersja daty w zapisie String do typu Date

W czasie jednego ze szkoleń z obszarów Access VBA pojawiło się pytanie dot. sposobu konwersji daty przekazywanej w postaci ciągu tekstowego w układzie YYYYMMDD na układ daty YYYY-MM-DD.

Pierwsze podejście, bardzo klasyczne i naturalne, to rozebranie otrzymanego tekstu na czynniki z wykorzystaniem instrukcji Left(), Right() i Mid(), a następnie wykorzystanie funkcji DateSerial() i stworzenie z tego daty. rozwiązanie to mogło by wyglądać następująco:
1Dim DataTekstowo As String
2    DataTekstowo = "20161222"
3Debug.Print DateSerial(Left(DataTekstowo, 4), Mid(DataTekstowo, 5, 2), Right(DataTekstowo, 2))

Tymczasem okazuje się, że z pomocą funkcji Format() możemy bardzo skutecznie skrócić powyższy zapis zyskując dodatkową elastyczność. Oto przykłady:
1Dim DataTekstowo As String
2    DataTekstowo = "20161222"
3 
4'z wykorzystaniem funkcji konwersji
5Debug.Print CDate(Format(DataTekstowo, "0000-00-00"))
6 
7'działa także dla innego zapisu bazowego daty
8    DataTekstowo = "161222"
9Debug.Print CDate(Format(DataTekstowo, "0000-00-00"))

Oczywiście zachęcam do samodzielnych dalszych eksperymentów z wykorzystaniem funkcji Format.