are you interested in a crosstab query for this? that's the easiest. <edit> scratch that...maybe not. to do this for one record, here's is something I can come up with...
Code:
Function Assist(oTbl As String, _
nTbl As String, _
sDateFld As String, _
eDateFld As String)
On Error GoTo Cleanup
'******************************************************************************
'_____________________________________________________________________________*
' |
'THIS FUNCTION ASSUMES THAT YOU HAVE AN 'ID' FIELD THAT UNIQUELY |
'IDENTIFIES RECORDS IN YOUR DATE TABLE. IT ALSO ASSUMES THAT YOU HAVE A |
'START DATE FIELD AND AN END DATE FIELD. |
'_____________________________________________________________________________|
' *
'Author: Adam Evanovich *
'Date: 9/17/2010 *
'Purpose: To list the number of days between two dates grouped by year. *
' *
'Arguments: *
'oTbl > The table you want to produce grouped records from (table with dates) *
'nTbl > The new table that will act as the new query *
'sDateFld > Name of the field where the start dates are stored *
'eDateFld > Name of the field where the end dates are stored *
' *
'******************************************************************************
Dim sDateIndex As Long 'INDEX VALUE OF THE sDATE FIELD
Dim eDateIndex As Long 'INDEX VALUE OF THE eDATE FIELD
Dim ctr As Long 'GENERAL COUNTER
Dim sDate As Date 'START DATE FOR CURRENT RECORD
Dim eDate As Date 'END DATE FOR CURRENT RECORD
Dim yDiff As Long 'DIFFERENCE IN YEARS BETWEEN sDate and eDate
Dim db As DAO.Database
Dim rsOld As DAO.Recordset
Dim rsNew As DAO.Recordset
Set db = CurrentDb
db.Execute "DELETE * FROM tbl2" 'DELETE OLD DATA IN TABLE IF ANY THERE
Set rsOld = db.OpenRecordset(oTbl, dbOpenDynaset)
Set rsNew = db.OpenRecordset(nTbl, dbOpenDynaset)
'OPEN TABLES
rsOld.MoveLast
rsOld.MoveFirst
rsNew.MoveLast
rsNew.MoveFirst
'GET DATE FIELDS INDEXES HERE
For ctr = 0 To rs.Fields.Count - 1
If rs.Fields(ctr).Name = sDateFld Then
sDateIndex = ctr
Exit For
End If
Next ctr
For ctr = 0 To rs.Fields.Count - 1
If rs.Fields(ctr).Name = eDateFld Then
eDateIndex = ctr
Exit For
End If
Next ctr
With rsNew
Do Until rsOld.EOF
sDate = rsOld.Fields(sDateFld)
eDate = rsOld.Fields(eDateFld)
yDiff = Year(eDate) - Year(sDate) 'DIFFERENCE WITH BASE 0
For ctr = 0 To yDiff
.AddNew
If ctr = 0 Then
!ID = rsOld!ID
!cyear = Year(sDate)
!cDays = Abs(DateDiff("d", sDate, "12/31/" & Year(sDate)))
ElseIf ctr = yDiff Then
!ID = rsOld!ID
!cyear = Year(eDate)
!cDays = Abs(DateDiff("d", _
"1/1/" & Year(eDate), _
eDate))
Else
!ID = rsOld!ID
!cyear = Year(DateAdd("yyyy", CDbl(ctr), sDate))
!cDays = Abs(DateDiff("d", _
"1/1" & !cyear, _
"12/31" & !cyear))
End If
.Update
Next ctr
rsOld.MoveNext
Loop
End With
Cleanup:
rsOld.Close
rsNew.Close
db.Close
sDateIndex = 0
eDateIndex = 0
ctr = 0
sDate = 0
eDate = 0
yDiff = 0
Set db = Nothing
Set rsOld = Nothing
Set rsNew = Nothing
End Function
I did not test it. There are some things manually written in as you can see. the argument are from the table to be analyzed. There is a better way, but if you're in a hurry to produce something that works, this is one alternative...