R
Robert Morley
Hi all,
Can I get somebody to verify this code for me...I *think* it works as is,
but I'm I'm tired and having a bad-programming day, so I'm not 100% sure.
What the code is *supposed* to do (and some of you may recognize this from
about a year ago when I was doing much the same thing) is to go through a
list of contacts for an account, each of which is active from StartDate to
EndDate, and merge any overlapping date ranges. If the date ranges don't
overlap, then they cannot be merged.
Basic concepts:
* EndDate is NULL if the contact is currently active (and should
therefore be treated as an infinitely high date).
* Any change in AccountID, TypeID, or ContactID constitutes a new
subset, and you cannot merge dates across subsets.
* Within each subset, the recordset is forcibly ordered by StartDate to
make the logic simpler.
Anyway, here's the code...if any of the above is unclear, please feel free
to ask me. And of course, if you find any bugs, please let me know! I
realize some of the code is less-than-optimal with all the EndDate handling,
but that was the least of my concerns at the time...once it works, I'll
worry about clarity and speed.
Oh, and the code as-posted is in "test mode" and won't actually change the
recordset, but if you're even thinking of having a look at this for me, I'm
sure you're smart enough to figure that out!
Thanks all!
Public Function MergeDates()
Const cMaxDate As Date = #6/6/2079# 'Max Date for SQL Server
smalldatetime
Dim rs As ADODB.Recordset
Dim strAccountID As String
Dim lngTypeID As Long
Dim lngContactID As Long
Dim dtMin As Date
Dim dtMax As Date
Dim lngDeletedTot As Long
Dim blnChanged As Boolean
Dim bm As Variant
Dim bm2 As Variant
lngDeletedTot = 0
Set rs = New ADODB.Recordset
With rs
.CursorLocation = adUseClient
.Open "SELECT * FROM acctTeam ORDER BY AccountID, TypeID, ContactID,
StartDate, COALESCE(EndDate, '2079-Jun-06') DESC"), DataProject.Connection,
adOpenStatic, adLockOptimistic, adCmdText
If Not .EOF Then
strAccountID = !AccountID.Value
lngTypeID = !TypeID.Value
lngContactID = !ContactID.Value
dtMin = !StartDate.Value
dtMax = Nz(!EndDate.Value, cMaxDate)
bm = .Bookmark
blnChanged = False
.MoveNext
End If
While Not .EOF
If (strAccountID = !AccountID.Value) And (lngTypeID =
!TypeID.Value) And (lngContactID = !ContactID.Value) And (!StartDate.Value -
1 <= dtMax) Then
If Nz(!EndDate.Value, cMaxDate) >= dtMax Then dtMax =
Nz(!EndDate.Value, cMaxDate)
blnChanged = True
Debug.Print "Would have deleted " & !UniqueID.Value,
!AccountID, !TypeID, !ContactID, !StartDate.Value, !EndDate.Value
' .Delete
lngDeletedTot = lngDeletedTot + 1
Else
If blnChanged Then
bm2 = .Bookmark 'Performs correctly in test scenario,
when delete has not actually occurred.
.Bookmark = bm
If (!StartDate.Value <> dtMin) Or (Nz(!EndDate.Value,
cMaxDate) <> dtMax) Then
Debug.Print "Would have updated " & !UniqueID.Value,
!AccountID.Value, !TypeID.Value, !ContactID.Value, !StartDate.Value,
!EndDate.Value; " to "; strAccountID, lngTypeID, lngContactID, dtMin,
IIf(dtMax = cMaxDate, Null, dtMax)
!StartDate.Value = dtMin
!EndDate.Value = IIf(dtMax = cMaxDate, Null, dtMax)
End If
.CancelUpdate
' .Update
If bm2 = Empty Then
.MoveLast
Else
.Bookmark = bm2
End If
blnChanged = False
End If
strAccountID = !AccountID.Value
lngTypeID = !TypeID.Value
lngContactID = !ContactID.Value
dtMin = !StartDate.Value
dtMax = Nz(!EndDate.Value, cMaxDate)
bm = .Bookmark
End If
.MoveNext
Wend
.Close
End With
Set rs = Nothing
MsgBox "Removed " & lngDeletedTot & " redundant records."
End Function
Can I get somebody to verify this code for me...I *think* it works as is,
but I'm I'm tired and having a bad-programming day, so I'm not 100% sure.
What the code is *supposed* to do (and some of you may recognize this from
about a year ago when I was doing much the same thing) is to go through a
list of contacts for an account, each of which is active from StartDate to
EndDate, and merge any overlapping date ranges. If the date ranges don't
overlap, then they cannot be merged.
Basic concepts:
* EndDate is NULL if the contact is currently active (and should
therefore be treated as an infinitely high date).
* Any change in AccountID, TypeID, or ContactID constitutes a new
subset, and you cannot merge dates across subsets.
* Within each subset, the recordset is forcibly ordered by StartDate to
make the logic simpler.
Anyway, here's the code...if any of the above is unclear, please feel free
to ask me. And of course, if you find any bugs, please let me know! I
realize some of the code is less-than-optimal with all the EndDate handling,
but that was the least of my concerns at the time...once it works, I'll
worry about clarity and speed.
Oh, and the code as-posted is in "test mode" and won't actually change the
recordset, but if you're even thinking of having a look at this for me, I'm
sure you're smart enough to figure that out!
Thanks all!
Public Function MergeDates()
Const cMaxDate As Date = #6/6/2079# 'Max Date for SQL Server
smalldatetime
Dim rs As ADODB.Recordset
Dim strAccountID As String
Dim lngTypeID As Long
Dim lngContactID As Long
Dim dtMin As Date
Dim dtMax As Date
Dim lngDeletedTot As Long
Dim blnChanged As Boolean
Dim bm As Variant
Dim bm2 As Variant
lngDeletedTot = 0
Set rs = New ADODB.Recordset
With rs
.CursorLocation = adUseClient
.Open "SELECT * FROM acctTeam ORDER BY AccountID, TypeID, ContactID,
StartDate, COALESCE(EndDate, '2079-Jun-06') DESC"), DataProject.Connection,
adOpenStatic, adLockOptimistic, adCmdText
If Not .EOF Then
strAccountID = !AccountID.Value
lngTypeID = !TypeID.Value
lngContactID = !ContactID.Value
dtMin = !StartDate.Value
dtMax = Nz(!EndDate.Value, cMaxDate)
bm = .Bookmark
blnChanged = False
.MoveNext
End If
While Not .EOF
If (strAccountID = !AccountID.Value) And (lngTypeID =
!TypeID.Value) And (lngContactID = !ContactID.Value) And (!StartDate.Value -
1 <= dtMax) Then
If Nz(!EndDate.Value, cMaxDate) >= dtMax Then dtMax =
Nz(!EndDate.Value, cMaxDate)
blnChanged = True
Debug.Print "Would have deleted " & !UniqueID.Value,
!AccountID, !TypeID, !ContactID, !StartDate.Value, !EndDate.Value
' .Delete
lngDeletedTot = lngDeletedTot + 1
Else
If blnChanged Then
bm2 = .Bookmark 'Performs correctly in test scenario,
when delete has not actually occurred.
.Bookmark = bm
If (!StartDate.Value <> dtMin) Or (Nz(!EndDate.Value,
cMaxDate) <> dtMax) Then
Debug.Print "Would have updated " & !UniqueID.Value,
!AccountID.Value, !TypeID.Value, !ContactID.Value, !StartDate.Value,
!EndDate.Value; " to "; strAccountID, lngTypeID, lngContactID, dtMin,
IIf(dtMax = cMaxDate, Null, dtMax)
!StartDate.Value = dtMin
!EndDate.Value = IIf(dtMax = cMaxDate, Null, dtMax)
End If
.CancelUpdate
' .Update
If bm2 = Empty Then
.MoveLast
Else
.Bookmark = bm2
End If
blnChanged = False
End If
strAccountID = !AccountID.Value
lngTypeID = !TypeID.Value
lngContactID = !ContactID.Value
dtMin = !StartDate.Value
dtMax = Nz(!EndDate.Value, cMaxDate)
bm = .Bookmark
End If
.MoveNext
Wend
.Close
End With
Set rs = Nothing
MsgBox "Removed " & lngDeletedTot & " redundant records."
End Function