We developed the following function last month:
Function HolidaysOffCount(dtmBegin As
Date, dtmEnd As Date) As Long
Dim db As DAO.Database
Dim rst As
DAO.Recordset
Dim strSQL As String
Dim rv As Long
Set db = CurrentDb
strSQL = "SELECT
tblHoliday.HolidayDate,
tblHoliday.Workday, " & _
"Format([HolidayDate],'ddd') " &
_
"FROM tblHoliday " & _
"WHERE (((tblHoliday.HolidayDate)
>=#1/1/2007# " & _
"And (tblHoliday.HolidayDate)
<=#12/31/2007#) " & _
"AND ((tblHoliday.Workday)=False) " &
_
"AND ((Format([HolidayDate],'ddd'))<>'Sat' "
& _
"And (Format([HolidayDate],'ddd'))
<>'Sun'));"
Set rst = db.OpenRecordset
(strSQL)
If rst.EOF And rst.BOF
Then
rv = 0
Else
rst.MoveLast
rv =
rst.RecordCount
End If
HolidaysOffCount = rv
End Function
Our function has one major problem - it's inflexible.
I've bolded the lines that cause the problem. The
dates are hard coded. No matter what dates are
passed in, the function as it stands uses 1/1/2007 as
a begin date and 12/31/2007 as an end date. To
make our function flexible we'll change the lines
above to:
"WHERE (((tblHoliday.HolidayDate)>=#" &
dtmBegin
& "# " & _
"And (tblHoliday.HolidayDate)<=#" & dtmEnd & "# "
& _
With this change we replace the hard coded dates
with the dates passed in by our function. The only
other part that may be less than immediately clear is
the section that says:
Set rst = db.OpenRecordset(strSQL)
If rst.EOF And rst.BOF Then
rv = 0
Else
rst.MoveLast
rv =
rst.RecordCount
End If
HolidaysOffCount = rv
This section essentially says to use the SQL
statement (with the passed in dates) to create a
record set (a set of records that we can inspect or act
on). If the record set, when first opened, is at the
beginning and at the end we have no records,
therefore return a zero, otherwise move to the last
record and then whatever the record count is, return
that as the number of records. Why move to the last
record? When Access opens a record set it doesn't
know how many records there are until it gets to the
end, so it moves there and then it knows how many
records it is dealing with.
So our completed Holiday function is:
Function HolidaysOffCount(dtmBegin As
Date, dtmEnd As Date) As Long
Dim db As DAO.Database
Dim rst As
DAO.Recordset
Dim strSQL As String
Dim rv As Long
Set db = CurrentDb
strSQL = "SELECT
tblHoliday.HolidayDate,
tblHoliday.Workday, " & _
"Format([HolidayDate],'ddd') " &
_
"FROM tblHoliday " & _
"WHERE (((tblHoliday.HolidayDate)
>=>=#" & dtmBegin &"# " & _
"And (tblHoliday.HolidayDate)
<=>=#" & dtmEnd &"# ) " & _
"AND ((tblHoliday.Workday)=False) " &
_
"AND ((Format([HolidayDate],'ddd'))<>'Sat' "
& _
"And (Format([HolidayDate],'ddd'))
<>'Sun'));"
Set rst = db.OpenRecordset
(strSQL)
If rst.EOF And rst.BOF
Then
rv = 0
Else
rst.MoveLast
rv =
rst.RecordCount
End If
HolidaysOffCount = rv
End Function