MsAccess updating leave table [duplicate] - ms-access

MS Access 2003.
I need to get the array of dates which are located in the range start_date to end_date.
I not found such function in standard set of MS Access.
I write VBA function:
Option Compare Database
' © Andrey Bushman, 2014
' Get the array of dates which are located in the range start_date to end_date.
' The result is an array of Date items.
Public Function GetDays(start_date As Date, end_date As Date)
If start_date > end_date Then
' end_date can't be less than start_date.
GetDays = Null
Exit Function
End If
Dim size As Long
size = end_date - start_date
Dim result() As Date
ReDim result(size) ' including the range boundaries.
Dim index As Long
index = 0
Dim day As Date
day = start_date
Do While day <= end_date
result(index) = day
day = day + 1
index = index + 1
Loop
GetDays = result
End Function
My SQL query:
SELECT tbChecks.CheckId, tbChecks.[In], tbChecks.Back, GetDays([In],[Back]) AS DayItem FROM tbChecks;
But I get an #Error text in the DayItem field for each record.
This is not work too:
SELECT GetDays(CDate("01.01.2014"), CDate("05.01.2014")) as DayItem;
I get the error: Data type mismatch in criteria expression. (Error 3464).
How can I solve it?

You are getting errors because your VBA function is returning an array of Date values but the Access Database Engine does not have an Array field type. Even if it did, you would wind up with a single row containing an array of dates and (according to the comments to the question) you want each date in a separate row.
You should be able to accomplish your goal without using VBA at all if you create a "Numbers" table with sequential integer values from 0 to a sufficiently large value, e.g.,
n
----
0
1
2
3
...
998
999
1000
and then use a query like this:
SELECT DateAdd("d",n,#2014-01-01#) AS DayItem
FROM Numbers
WHERE n <= DateDiff("d",#2014-01-01#,#2014-01-05#)
returning
DayItem
----------
2014-01-01
2014-01-02
2014-01-03
2014-01-04
2014-01-05

Related

MSAccess: Return query for specific date from datetime value

I am trying to run a query from a linked table in MS SQL Server that has a datetime field. I'm trying to run a simple query to search for records for a specific date (#03/24/2018#), but since the datetime field has the time as well, I am not getting any records unless I specify the time range using BETWEEN with the time (Between #03/24/2018 00:00:00 AM# And #03/24/2018 11:59:59 PM#).
Original query which does not return desired output:
SELECT *
WHERE MyDateTimeField) = #3/24/2018#;
Query
SELECT *
WHERE MyDateTimeField) Between #3/24/2018 00:00:00 AM# And #3/24/2018 23:59:59#);
Is there a workaround to this as to not have to use a BETWEEN operator with the time?
To avoid time portion, check forMyDateTimeFieldequal/greater than searched day and less than next day:
SELECT *
FROM MyTable
WHERE
MyDateTimeField >= #3/24/2018#
AND
MyDateTimeField < DateAdd("d",1,#3/24/2018#);
In opposite of convertingMyDateTimeFieldto date, this does not prevent index usage and handlesNullValues onMyDateTimeField.

Calendar query from table [duplicate]

MS Access 2003.
I need to get the array of dates which are located in the range start_date to end_date.
I not found such function in standard set of MS Access.
I write VBA function:
Option Compare Database
' © Andrey Bushman, 2014
' Get the array of dates which are located in the range start_date to end_date.
' The result is an array of Date items.
Public Function GetDays(start_date As Date, end_date As Date)
If start_date > end_date Then
' end_date can't be less than start_date.
GetDays = Null
Exit Function
End If
Dim size As Long
size = end_date - start_date
Dim result() As Date
ReDim result(size) ' including the range boundaries.
Dim index As Long
index = 0
Dim day As Date
day = start_date
Do While day <= end_date
result(index) = day
day = day + 1
index = index + 1
Loop
GetDays = result
End Function
My SQL query:
SELECT tbChecks.CheckId, tbChecks.[In], tbChecks.Back, GetDays([In],[Back]) AS DayItem FROM tbChecks;
But I get an #Error text in the DayItem field for each record.
This is not work too:
SELECT GetDays(CDate("01.01.2014"), CDate("05.01.2014")) as DayItem;
I get the error: Data type mismatch in criteria expression. (Error 3464).
How can I solve it?
You are getting errors because your VBA function is returning an array of Date values but the Access Database Engine does not have an Array field type. Even if it did, you would wind up with a single row containing an array of dates and (according to the comments to the question) you want each date in a separate row.
You should be able to accomplish your goal without using VBA at all if you create a "Numbers" table with sequential integer values from 0 to a sufficiently large value, e.g.,
n
----
0
1
2
3
...
998
999
1000
and then use a query like this:
SELECT DateAdd("d",n,#2014-01-01#) AS DayItem
FROM Numbers
WHERE n <= DateDiff("d",#2014-01-01#,#2014-01-05#)
returning
DayItem
----------
2014-01-01
2014-01-02
2014-01-03
2014-01-04
2014-01-05

return daily rows for a range of dates

MS Access 2003.
I need to get the array of dates which are located in the range start_date to end_date.
I not found such function in standard set of MS Access.
I write VBA function:
Option Compare Database
' © Andrey Bushman, 2014
' Get the array of dates which are located in the range start_date to end_date.
' The result is an array of Date items.
Public Function GetDays(start_date As Date, end_date As Date)
If start_date > end_date Then
' end_date can't be less than start_date.
GetDays = Null
Exit Function
End If
Dim size As Long
size = end_date - start_date
Dim result() As Date
ReDim result(size) ' including the range boundaries.
Dim index As Long
index = 0
Dim day As Date
day = start_date
Do While day <= end_date
result(index) = day
day = day + 1
index = index + 1
Loop
GetDays = result
End Function
My SQL query:
SELECT tbChecks.CheckId, tbChecks.[In], tbChecks.Back, GetDays([In],[Back]) AS DayItem FROM tbChecks;
But I get an #Error text in the DayItem field for each record.
This is not work too:
SELECT GetDays(CDate("01.01.2014"), CDate("05.01.2014")) as DayItem;
I get the error: Data type mismatch in criteria expression. (Error 3464).
How can I solve it?
You are getting errors because your VBA function is returning an array of Date values but the Access Database Engine does not have an Array field type. Even if it did, you would wind up with a single row containing an array of dates and (according to the comments to the question) you want each date in a separate row.
You should be able to accomplish your goal without using VBA at all if you create a "Numbers" table with sequential integer values from 0 to a sufficiently large value, e.g.,
n
----
0
1
2
3
...
998
999
1000
and then use a query like this:
SELECT DateAdd("d",n,#2014-01-01#) AS DayItem
FROM Numbers
WHERE n <= DateDiff("d",#2014-01-01#,#2014-01-05#)
returning
DayItem
----------
2014-01-01
2014-01-02
2014-01-03
2014-01-04
2014-01-05

Updating a column based on another column + interval

Our database currently has a course_start_date, but not a course_end_date. My goal is to set each course _end_date based on course_start_date + 3 days based on course_type_id. course_start_date is currently stored as a unix_timestamp. Here is my code.
UPDATE system_course
SET course_end_date = 'UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(course_start_date), INTERVAL 3 DAY))'
WHERE course_type_id = '1'
This code is placing 0 in everything.
Both course_start_date and course_end_date are structured:
INT(11) unassigned
Running the following code shows me good results (obviously End Date is not stored in the db)
SELECT FROM_UNIXTIME(course_start_date) as "Start Date", DATE_ADD(FROM_UNIXTIME(course_start_date), INTERVAL 4 DAY) as "End Date"
FROM system_course
WHERE course_type_id = '1'
Select Results:
Start Date End Date
2011-10-31 07:30:00 2011-11-03 07:30:00
Can I not use row parameters in the set column? How do I get around this?
Your UNIX_TIMESTAMP is in single quotes, this will treat it as a string and cast to zero as demonstrated. What you want is this;
SET course_end_date = UNIX_TIMESTAMP(DATE_ADD(FROM_UN...

Using DatePart() with date ranges crossing the datepart boundary

I am currently trying to summarise some data tables into a report. Each record in the table consists of a date range, something like this:
StartDate EndDate
--------------------
13/04/13 15/04/13
17/04/13 24/04/13
28/04/13 03/05/13
05/05/13 10/05/13
Assuming the date ranges signify something like days of leave, I want to be able to calculate the total amount of days of leave per month. I came across the DatePart function which seems to work apart from one edge case: when the date range crosses a month boundary. Since the DatePart function returns the month for one given date, I am no longer able to use that to determine the amount of days of leave for that edge case record (in the example above it is record 3), since it applies to two separate months.
Ideally I want my final table to look like:
Month #OfDays
--------------------
4 11 (1st record - 2, 2nd record - 7, 3rd record - 2)
5 8 (3rd record - 3, 4th record - 5)
I've considered some messy options, such as populating a temporary table having each record signifying a different day and then doing a query on that, but I am not sure how this ties in with a report. Right now my report record source is the (incorrect) query, is it possible to have a record source as a VBA function that returns a recordsource?
Another thing I thought was to possibly to have an initial query that splits up any edge cases into two seperate records, where the date range only covers one month, and then use that for my final grouping query. Is that even possible?
I feel there may be a much simpler solution to this problem yet I can't see it.
If anyone has any ideas it would be much appreciated!
To accomplish your task using Access queries you will need to create a table named [Numbers] with a single Number (Long Integer) column named [n] containing the numbers 1, 2, 3, ... up to the highest year you expect to be working with. I created mine as follows
n
----
1
2
3
...
2499
2500
You'll also need to paste the following VBA function into an Access Module
Public Function IsValidDayOfYear(YearValue As Long, DayValue As Long) As Boolean
Dim IsLeapYear As Boolean
If (YearValue Mod 400) = 0 Then
IsLeapYear = True
ElseIf (YearValue Mod 100) = 0 Then
IsLeapYear = False
ElseIf (YearValue Mod 4) = 0 Then
IsLeapYear = True
Else
IsLeapYear = False
End If
IsValidDayOfYear = (DayValue <= IIf(IsLeapYear, 366, 365))
End Function
Let's assume that your source table is called [DateRanges]. We'll start by creating a query that generates every day of the year for each year represented in the source table. The trick here is that DateSerial() "rolls over" month boundaries, so
DateSerial(2013, 1, 32) = #2013-02-01#
and
DateSerial(2013, 1, 234) = #2013-08-22#
SELECT DateSerial(yr.n, 1, dy.n) AS [Date]
FROM Numbers yr, Numbers dy
WHERE
(
yr.n
BETWEEN (SELECT MIN(DatePart("yyyy", DateRanges.StartDate)) FROM DateRanges)
AND (SELECT MAX(DatePart("yyyy", DateRanges.EndDate)) FROM DateRanges)
)
AND (dy.n < 367) AND IsValidDayOfYear(yr.n, dy.n)
For your sample data, that query returns all days in 2013.
Let's save that query as [AllDays]. Now we can use it to extract the individual days for each date range (omitting StartDate so the final counts match yours in the question)
SELECT [Date] FROM AllDays
WHERE EXISTS
(
SELECT * FROM DateRanges
WHERE AllDays.[Date] BETWEEN DateAdd("d", 1, DateRanges.StartDate) AND DateRanges.EndDate
)
That returns the individual days corresponding to each range, i.e.,
Date
----------
2013-04-14
2013-04-15
2013-04-18
2013-04-19
2013-04-20
2013-04-21
2013-04-22
2013-04-23
2013-04-24
2013-04-29
2013-04-30
2013-05-01
2013-05-02
2013-05-03
2013-05-06
2013-05-07
2013-05-08
2013-05-09
2013-05-10
We can save that query as [RangeDays] and then use it to calculate our counts by month...
SELECT DatePart("m", [Date]) AS [Month], COUNT(*) AS NumOfDays
FROM RangeDays
GROUP BY DatePart("m", [Date])
...returning
Month NumOfDays
----- ---------
4 11
5 8