I'm trying to get a date range that takes the calendar year after the transaction date. Say if the date was this year then it should be 1/01/2018 - 12/31/2018.
I'm using this syntax but am getting the error that everything after the first line is not part of the formula. Any ideas?
Local DateVar d := CDate cstr(year({TransDate}));
Local DateVar Range dr := DateSerial (Year(d)+ 1, Month(d) - 1, 1) To
DateSerial (Year(d)+ 1, Month(d) - 1, 1);
You're missing parentheses for CDate in your first line. Proper syntax would be:
Local DateVar d := CDate(cstr(year({?Start Date})));
However that still won't work, because the result of a formula cannot be a date range. Instead, separate the range into a StartDate and EndDate field, then use those for your calculations.
StartDate: DateSerial(Year({?Date}) + 1, 1, 1)
EndDate: DateSerial(Year({?Date}) + 1, 12, 31)
Related
In Access, I would like to convert a date column in format yywwd to dd-mm-yy. (weekday nr. 1 is monday, and years can only from 2000 and later, so e.g. today (monday 15-06-2020) would be 20251 what I would like to be converted to 15-06-2020.
I'm not much of a coder so honestly asside from messing with Datepart I have not tried a whole lot. Does anyone have suggestion?
It seems that the function 'GetDayFromWeekNumber' mentioned here vba convert week number (and year) to date? could work but how is this used in MSAccess?
Thanks a lot in advance!
I have a function that works in Excel to convert YYWWD to a date, this should be very similar if not identical to the code needed in Access. It is quite verbose so you could probably make it simpler, but at least the calculation steps are clearly set out.
The function assumes the ISO definition of week number - i.e. the first week of the year is the week in which the 4th of Jan falls. The first day of a week is Monday, the last day of a week is Sunday.
Function dateFromYYWWD(yywwd)
Dim sYYWWD As String
Dim sYYYY As String
Dim ww As Integer
Dim d As Integer
Dim fourthOfJan As Date
Dim fourthOfJanWeekday As Integer
Dim week1StartDate As Date
Dim targetWeekStartDate As Date
Dim targetDate As Date
' Convert to string if not already
sYYWWD = "" & yywwd
' Get the year in full
sYYYY = "20" + Left(sYYWWD, 2)
' Get the week number and day in the week
ww = CInt(Mid(sYYWWD, 3, 2))
d = CInt(Right(sYYWWD, 1))
' Calculate the date of 4th Jan in the same year
fourthOfJan = CDate(sYYYY & "-01-04")
' Get the day of week of the 4th Jan
' NOTE - CALCULATES MONDAY AS DAY 1 OF THE WEEK, SUNDAY AS DAY 7
fourthOfJanWeekday = Weekday(fourthOfJan, vbMonday)
' Date of the first day of week #1 in the target year
week1StartDate = fourthOfJan - fourthOfJanWeekday + 1
' First day of the target week
targetWeekStartDate = week1StartDate + (ww - 1) * 7
' Target date
targetDate = targetWeekStartDate + d - 1
dateFromYYWWD = targetDate
End Function
It's as simple as this:
Public Function ConvertFromYYWWD(s) As Date
Dim t&
t = DateSerial(2000 + Mid(s, 1, 2), 1, 1) + 7 * (Mid(s, 3, 2) - 1)
ConvertFromYYWWD = t - Weekday(t, vbMonday) + Mid(s, 5, 1)
End Function
Just place the above function in a code module in the database project.
You mentioned in the comments under your question that the week number is always two digits. I am assuming the the year number is likewise always two digits.
The first task is to split the value:
YWDDate = 20251
Year = YWDDate \ 1000 + 2000
2020
Week = (YWDDate Mod 1000) \ 10
25
Weekday = YWDDate Mod 10
1
Then, as this probably is ISO 8601 week numbering, the year is not the calendar year but the ISO 8601 year, which native VBA knows nothing about, thus a custom function is needed:
' First day of the week.
WeekStart = DateYearWeek(25, 2020, vbMonday)
' Requested day of week (which here is the same)
WeekDate = DateAdd("d", 1 - 1, WeekStart)
The function is not that convoluted:
' Returns the date of Monday for the ISO 8601 week of IsoYear and Week.
' Optionally, returns the date of any other weekday of that week.
'
' 2017-05-03. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function DateYearWeek( _
ByVal IsoWeek As Integer, _
Optional ByVal IsoYear As Integer, _
Optional ByVal DayOfWeek As VbDayOfWeek = VbDayOfWeek.vbMonday) _
As Date
Dim WeekDate As Date
Dim ResultDate As Date
If IsoYear = 0 Then
IsoYear = Year(Date)
End If
' Validate parameters.
If Not IsWeekday(DayOfWeek) Then
' Don't accept invalid values for DayOfWeek.
Err.Raise DtError.dtInvalidProcedureCallOrArgument
Exit Function
End If
If Not IsWeek(IsoWeek, IsoYear) Then
' A valid week number must be passed.
Err.Raise DtError.dtInvalidProcedureCallOrArgument
Exit Function
End If
WeekDate = DateAdd(IntervalSetting(dtWeek), IsoWeek - 1, DateFirstWeekYear(IsoYear))
ResultDate = DateThisWeekPrimo(WeekDate, DayOfWeek)
DateYearWeek = ResultDate
End Function
but - as you can see - it calls some helper functions, which again call other functions, which will be too much to post here.
I can upload it somewhere, if you feel this will provide a solution for you.
i have problem finding solution on getting previous date from current's date. but i only want the months to change. for example, now is August, i want the output to display 3 months ago = May.
Heres my code that i wrote
givenDate= "14-August-15"
DD = Day (givenDate)
'MsgBox DD
MM = Month (givenDate)
'MsgBox MM
YY = Year (givenDate)
'MsgBox YY
SysDate = DD&"/"&MM&"/"&YY
MsgBox Month(DateAdd("m", -3, "14-August-2015"))
'MsgBox(FormatDateTime(SysDate,1))
If you just need to display the name of the month that was 3 months ago, combine DateAdd(), Month(), and MonthName(). For example:
Dim dt1, dt2
dt1 = Date() ' Use today's date, for example
dt2 = DateAdd("m", -3, dt1) ' Subtract 3 months
WScript.Echo MonthName(Month(dt2)) ' Display the name of the month
Month() returns the month number (1 - 12). MonthName() takes that number and returns the name of the month ("January" - "December").
So my default values for startDate and endDate in SSRS were set up with the following ssrs expressions.
first day of previous month ssrs expression
=DateAdd(DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))
last day of previous month ssrs expression
=DateAdd(DateInterval.Day, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))
But that won't work alone in my case unless I want to go in on the 16th of every month and generate this report for the people requesting it for the first 15 days of the current month.
So in my default value expression for start date i am trying this iif statement...
= iif(
DatePart(DateInterval.Day, Today() <> "20",
DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1),
DateInterval.Month, 1, DateSerial(Year(Date.Now), Month(Date.Now), 1)
)
Not working out so well. So what i'm trying to do is.....
Change the default start and end date based on what day of the current month it is, So if current day of the current month equals 16, make start date 1 of current month and end date 15 of current month, if current day of the month isn’t 16 make start date first of previous month and end date last day of previous month. So then the only thing needed is to get subscription emails and what day to send them out on.
Untested, but what if you try this? (for your start date parameter):
= iif(
DatePart(DateInterval.Day, Today()) <> "16",
DateAdd(DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1)),
DateSerial(Year(Date.Now), Month(Date.Now), 1)
)
How can I get the ISO-8601 week number of a given date in Crystal Reports XI?
Crystal Reports supports the DatePart-function which can give you the ISO week number of a given date.
NumberVar week := DatePart("ww", date, crMonday, crFirstFourDays);
However, in Crystal Reports XI there is a bug that gives erronous results round new year. The best solution is probably to create an own function getISOWeekNumber:
Function (optional DateVar d := CurrentDate)
NumberVar week := DatePart("ww", d, crMonday, crFirstFourDays);
// Correct for that CR doesn't handle the fact that the last days of a year can belong to week 1 of the next year:
if week = 53 and DatePart("ww", cDate(year(d) + 1, 1, 1), crMonday, crFirstFourDays) = 1 then
week := 1
// A bug in CR makes DatePart return values like 9363 for days in January that belongs to the last week of the previous year.
else if week > 53 then
week := DatePart("ww", cDate(year(d) - 1, 12, 31), crMonday, crFirstFourDays);
week;
To get the "week-year" of a specific date, you could then use the following function:
// Returns the year to which the ISO week of the specified date belongs.
// E.g. 2012-12-31 will return 2013, as that date belongs to week 1 of 2013.
Function (optional DateVar d := CurrentDate)
NumberVar week := getISOWeekNumber (d);
if week = 1 and month(d) = 12 then
year(d) + 1
else if week > 10 and month(d) = 1 then
year(d) - 1
else
year(d);
When using LastFullWeek i get the last Sunday - Saturday week, but for my reports i want the last Monday - Sunday week.
Is there any simple way to get this behaviour, or do I have to write my own function for it (which isn't that hard, but unconvenient for such a common date span.)
custom function:
//LastFullWeekEx
Function (DateVar date, Optional NumberVar firstDayOfWeek := crSunday)
(date - DayOfWeek(date, firstDayOfWeek)) - 6 TO (date - DayOfWeek(date, firstDayOfWeek))
usage:
// use with non-volatile DataDate and Sunday
{TABLE.DATE} IN LastFullWeekEx(DataDate)
// use with non-volatile DataDate and Monday
{TABLE.DATE} IN LastFullWeekEx(DataDate, crMonday)
testing:
// should return True
( Minimum(LastFullWeek) = Minimum(LastFullWeekEx(DataDate, crSunday)) ) AND
( Maximum(LastFullWeek) = Maximum(LastFullWeekEx(DataDate, crSunday)) )
Instead of using
{DATE} in LastFullWeek
use the form
{DATE}-1 in LastFullWeek
The code, if no better answer comes along, for others who find this question through the search engine:
{DATE} >= currentdate - dayofweek(currentdate, crMonday) - 6 AND
{DATE} < currentdate - dayofweek(currentdate, crMonday) + 1
You have no other choice than to use a custom formule as Crystal Reports uses fixed week settings (US). So a week is Sunday to Saturday and DayOfWeek starts with Sunday (value/index 1).
Add +1 to LastFullWeek min and max:
DateVar Start := Minimum(LastFullWeek)+1; //Monday
DateVar End := Maximum(LastFullWeek)+1; //Sunday
Edit: Since LastFullWeek always takes Sunday as the first day of the week, we need to check if the current day is Sunday. If so, we need to subtract a week:
// Check if the current day is Sunday
IF (DAYOFWEEK(CurrentDate) = 1)
THEN (
Start := Start - 7;
End := End - 7
);
Example: Date range to string
StringVar LastWeekRange := ToText(Start) + " - " + ToText(End);
LastWeekRange;
Return example: "MM/DD/YYYY - MM/DD/YYYY"
Example: Selecting all dates within date range
{datefield} >= Start and {datefield} <= End;