Use the BeforeUpdate event procedure of the *form* (not controls) to look up
the Odometer table to see if:
a) the most recent prior reading was higher, or
b) the next subsequent reading that is lower.
By looking only that the closest dates you don't create problems if an
odometer (or motor or whatever) is replaced at some point.
DLookup() is not up to scratch for this, so grab the ELookup() function from
here:
http://allenbrowne.com/ser-42.html
This lets you specify a sort order so we can define which value to return.
There's an example event procedure below. Since it returns you the previous
and next date's entries, it would be easy enough to modify it to include a
warning if the distance travelled since the previous entry is unlikely.
If you ever need to get the next/previous row's value in a query, a subquery
could do that for you. Here's an example:
http://allenbrowne.com/subquery-01.html#AnotherRecord
Since it's based on a meter-reading, it's very similar.
BTW, the field name Date is likely to cause you problems. I've tried to
craft the code to avoid those issues, but a better solution would be to
rename it to something else, e.g. TripDate. There are actually thousands of
field names that can cause you grief. Here's a list to refer to when
designing tables:
http://allenbrowne.com/AppIssueBadWord.html
Sample code (untested: needs debugging):
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim varResult As Variant
Dim strWhere As String
Dim strMsg As String
Dim bWarn As Boolean
Const strcJetDate = "\#mm\/dd\/yyyy\#"
If IsNull(Me.UnitNum) Then
Cancel = True
strMsg = strMsg & "UnitNum required." & vbCrLf
End If
If IsNull(Me.[Date].Value) Then
Cancel = True
strMsg = strMsg & "Date required." & vbCrLf
End If
If IsNull(Me.Odometer) Then
Cancel = True
strMsg = strMsg & "Odometer required." & vbCrLf
End If
If Cancel Or ((Me.UnitNum = Me.UnitNum.OldValue) And _
(Me.[Date].Value = Me.[Date].OldValue) And _
(Me.Odometer = Me.Odometer.OldValue)) Then
'Do nothing
Else
'Higher previous entry?
strWhere = "(UnitNum = """ & Me.UnitNum & """) AND (Odometer.[Date] <= "
& _
Format(Me.[Date].Value - 1, strcJetDate) & ")"
varResult = ELookup("Odometer", "Odometer", strWhere, "Odometer.[Date]
DESC")
If varResult > Me.Odometer Then
bWarn = True
strMsg = strMsg & "Previous date's entry was " & varResult & "." &
vbCrLf
End If
'Lower later entry?
strWhere = "(UnitNum = """ & Me.UnitNum & """) AND (Odometer.[Date] >= "
& _
Format(Me.[Date].Value + 1, strcJetDate) & ")"
varResult = ELookup("Odometer", "Odometer", strWhere, "Odometer.[Date]")
If varResult < Me.Odometer Then
bWarn = True
strMsg = strMsg & "Next date's entry is " & varResult & "." & vbCrLf
End If
End If
If Cancel then
strMsg = strMsg & vbCrLf & "Correct the entry, or press Esc to undo."
MsgBox strMsg, vbExclamation, "Cannot save record"
ElseIf bWarn Then
strMSg = strMsg & vbCrLf & "Proceed anyway?"
If MsgBox strMsg, vbYesNo+vbDefaultButton2+vbQuestion, "Are you sure?")
<> vbYes Then
Cancel = True
End If
End If
End Sub
--
Allen Browne - Microsoft MVP. Perth, Western Australia
Tips for Access users -
http://allenbrowne.com/tips.html
Reply to group, rather than allenbrowne at mvps dot org.
"Rob" <dy DeleteThis @woodyallan.biz> wrote in message
news:Y_vIk.5017$sc2.2940@news-server.bigpond.net.au...
> Part of my Access 2003 DB tracks Vehicle Events and records a date and an
> odometer reading along with the Vehicle registration
>
> Vehicle Table contains VehicleNumber
> Driver Table contains DriverName
> Maintenace Table contains JobNumber
> Odometer Table contains 'UnitNum', 'Date' and 'Odometer' and is linked to
> the Vehicle Table
>
> Data is entered at the time it is received from the various paperwork
> sources, consequently it is stored in random order.
>
> LineID UnitNum Date Odometer
> 1 Q-27 1/01/08 5000
> 2 Q-27 3/01/08 6048
> 3 Q-27 2/01/08 5407
> 4 Q-27 6/01/08 6503
> 5 Q-27 4/01/08 6201
> 6 Q-27 2/01/08 5534
> 7 Q-27 2/01/08 5592
> 8 Q-27 1/01/08 5117
> 9 Q-27 2/01/08 5609
> 10 Q-27 3/01/08 5983
> 11 Q-27 1/01/08 5613 This entry has an error
> 12 Q-27 7/01/08 6569
> 13 Q-27 3/01/08 5739
> 14 Q-27 4/01/08 6447
> 15 Q-27 7/01/08 6662
> 16 Q-27 2/01/08 5288
>
> There has been an error in the data entered which shows up if the data is
> sorted by date or by Odometer, but is not yet obvious to the eye. Below is
> the data sorted by each.
>
> DATA SORTED BY DATE:
>
> LineID UnitNum Date Odometer
> 1 Q-27 1/01/08 5000
> 8 Q-27 1/01/08 5117
> 11 Q-27 1/01/08 5613 Odometer out of order
> 3 Q-27 2/01/08 5407
> 6 Q-27 2/01/08 5534
> 7 Q-27 2/01/08 5592
> 9 Q-27 2/01/08 5609
> 16 Q-27 2/01/08 5288
> 2 Q-27 3/01/08 6048
> 10 Q-27 3/01/08 5983
> 13 Q-27 3/01/08 5739
> 5 Q-27 4/01/08 6201
> 14 Q-27 4/01/08 6447
> 4 Q-27 6/01/08 6503
> 12 Q-27 7/01/08 6569
> 15 Q-27 7/01/08 6662
>
> DATA SORTED BY ODOMETER:
>
> LineID UnitNum Date Odometer
> 1 Q-27 1/01/08 5000
> 8 Q-27 1/01/08 5117
> 16 Q-27 2/01/08 5288
> 3 Q-27 2/01/08 5407
> 6 Q-27 2/01/08 5534
> 7 Q-27 2/01/08 5592
> 9 Q-27 2/01/08 5609
> 11 Q-27 1/01/08 5613 Date out of order
> 13 Q-27 3/01/08 5739
> 10 Q-27 3/01/08 5983
> 2 Q-27 3/01/08 6048
> 5 Q-27 4/01/08 6201
> 14 Q-27 4/01/08 6447
> 4 Q-27 6/01/08 6503
> 12 Q-27 7/01/08 6569
> 15 Q-27 7/01/08 6662
>
> (The error here was the Odometer should have been 5163). I would like to
> trap these errors at the time of entry and causes the conflict. I think
> that something like a comparison of the odometer relative to existing
> entries should then check that the date would be in the correct
> chronological order. Any suggestions how I would go about this?
>
> Many thanks
> ROB >> Stay informed about: Need an error trap for Date/Milage