Вот полное решение, которое корректно обрабатывает вновь отредактированные записи, а также обрабатывает причуды интерфейса пользователя Access (т.е. неудачные перерисовки, несогласованное поведение в зависимости от того, как выбрана запись - с помощью мыши или клавиатуры или селектора записей и т. Д. .). Я включаю подробные комментарии, потому что Access требует подробных объяснений из-за многочисленных несоответствий и / или ошибок. Я пытался использовать более простые решения, но это неизбежно ведет себя плохо без хитростей, заставляющих Access перекрашивать форму, или сложных способов определения текущей записи в обработчике событий Detail_Paint ().
Код предназначен для формы доступа с текстовым полем, связанным с полем идентификатора Autonumber. Форма также имеет элемент управления Rectangle с именем boxCurrent, который обновляется для выделения текущей выбранной записи (она имеет широкую ярко окрашенную границу). Я считаю, что элемент управления Rectangle предлагает больше визуальных опций, чем настройка Detail.BackColor, хотя такие детали можно настраивать с помощью общего шаблона. Разработано и протестировано с Access 2013 и 2016.
'* Set this value in From_Current event handler
Private vCurrentAutonumber As Variant
Private Sub Detail_Paint()
'* Delcare static variables to make often repeated calls more efficient.
Static iActive As Integer
Static vThisValue As Variant, vOldValue As Variant
On Error Resume Next
iActive = 0 '* Default to False/hidden value
vThisValue = Me.ID.Value
If Err.Number = 0 Then
If Not IsNull(vCurrentAutonumber) Then
If vThisValue = vCurrentAutonumber Then iActive = 1
ElseIf Me.NewRecord Then
'* Form currently set to "New Record", but may or may not be in edit mode.
'* When in EDIT MODE, AutonumberControl.Value will HAVE A VALUE
' AND AutonumberControl.OldValue will be null
' When NOT in edit mode, AutonumberControl.Value will be null
' AND AutonumberControl.OldValue will also be null
'*** That is the only way I have found to determine for sure
' if the currently-edited-new-record is the available record for
' this particular call of Detail_Paint().
' Other properties like CurrentRecord, NewRecord, etc. remain
' unchanged during repeated calls to Detail_Paint()
' and access has no other convenient way to determine the
' newly-added autonumber value, so it must be deduced using
' this trick.
If IsNull(vThisValue) Then
If Not Me.Dirty Then
'Record selector on *(New Record) row, but not edited yet.
If Err.Number = 0 Then iActive = 1
End If
Else
vOldValue = Me.ID.OldValue
If Err.Number = 0 Then
If IsNull(vOldValue) Then
'* Newly-edited record with fresh autonumber value is selected.
iActive = 1
'Else if vOldValue is not null, it is an existing record.
'* Not the current record since it can't be both existing and new.
End If
End If
End If
End If
End If
'* Set these values on EACH CALL, since their values will be retained
'* on subsequent calls.
With boxCurrent
.BackStyle = 0 'iActive
.BorderStyle = iActive
End With
End Sub
Private Sub Form_AfterDelConfirm(Status As Integer)
Me.Repaint
End Sub
Private Sub Form_AfterInsert()
If IsNull(vCurrentAutonumber) Then
'* If a new record is saved while staying on that record,
'* the Form_Current() handler is not called and so the
'* vCurrentAutonumber would not be updated with the newly
'* saved value. But now Me.NewRecord is false, so the
'* currently record would not be updated properly unless
'* vCurrentAutonumber is explicitly updated here.
On Error Resume Next
vCurrentAutonumber = Me.ID.Value
'* Force repaint (see comment in Form_Current)
boxCurrent.BackColor = vbBlue
End If
End Sub
'Private Sub Form_BeforeInsert(Cancel As Integer)
'* Attempted to set some variable or property in this event handler
'* --something to indicate to Detail_Paint() which record is the
'* new record being edited. But no matter what I set here, the
'* change is present and identical for each call of Detail_Paint(),
'* so for the most part this technique was not useful.
'* The only alternative is to set one of the data fields, because
'* those DO change for each each to Detail_Paint().
'* IF THE PRIMARY KEY IS NOT AN AUTONUMBER FIELD (OR IF ANOTHER
'* DATA FIELD IS AVAILABLE TO MANIPULATE), ONE COULD FLAG A NEWLY
'* EDITED RECORD BY SETTING SUCH A FIELD HERE AND INSPECTING
'* it in Detail_Paint(). Personally, I avoid dummy fields just for
'* making Access work well and my primary key is Autonumber so it cannot
'* bet set to a known new value.
'End Sub
Private Sub Form_Current()
On Error Resume Next
vCurrentAutonumber = Me.ID.Value
If Err.Number <> 0 Then vCurrentAutonumber = Null
On Error GoTo 0
'*** FORCE REPAINT of record detail section
'* If not forced, records are not necessarily repainted for every type of
'* UI event. For instance, changing records using the record selectors
'* has different behavior than clicking inside a record, but either way
'* the current record has changed and so should be repainted.
'* But calling Me.Repaint is not sufficient to actually repaint the form.
'* Even if the Detail_Paint event is called, the actual visible elements
'* are not always repainted (bug?). It seems that only changing some
'* visible feature/control of the form will force an actual repaint.
boxCurrent.BackColor = vbBlue
End Sub
Private Sub Form_Load()
vCurrentAutonumber = Null
End Sub