В форме MS Access, как раскрасить фон выбранной записи? - PullRequest
2 голосов
/ 11 марта 2010

У меня довольно сложная форма доступа с непрерывным отображением (то есть одновременно показываются несколько записей). Я хотел бы изменить цвет фона только для выбранной записи , чтобы конечный пользователь мог легко определить, на какой записи он находится.

Я думаю об условном формате или что-то вроде этого:

Private Sub Detail_HasFocus()
    Detail.BackColor(me.color)=vbBlue
End Sub

и что-то подобное, когда этот ряд теряет фокус. Этот фрагмент кода, очевидно, не будет работать, но это тот код, который я хотел бы получить.

Ответы [ 3 ]

0 голосов
/ 28 марта 2017

ОП здесь. Кейд указал, что ссылка оригинального решения указывает на 97 дБ, которые больше не могут быть открыты. Кроме того, к сожалению, мой оригинальный код давно ушел.

Однако недавно я сделал что-то подобное, используя метод условного форматирования, который не требует VBA. Это в Access 2016 в непрерывной форме:

  1. В свой набор данных добавьте поле да / нет. Давайте назовем это Rcd_Selected.
  2. Сделать текстовое поле. Также установите для параметра Control Source значение Rcd_Selected.
  3. Измените цвет переднего плана на #FFFFFF (это будет не выбранный цвет)
  4. Изменить формат на «True / False»
  5. Установить Включено = Да, Заблокировано = Нет
  6. На ленте перейдите в «Формат-> Условное форматирование» и создайте новое правило: где «Значение поля» = «Истина», установите для цвета переднего и заднего цветов выбранный цвет и нажмите «Включено».
  7. Очистите, растянув текстовое поле по всему разделу Detail и переместив его назад.
  8. Сделайте поле флажка. Отправил контрольный источник в Rcd_Selected.
  9. Растяните флажок на весь раздел Detail и переместите его вперед.

Каждый раз, когда вы нажимаете на область, флажок будет включаться / выключаться, вызывая условное форматирование текстового поля на заднем плане для изменения цвета. Одним из ограничений является то, что он делает всю запись доступной только для чтения. У меня никогда не было проблем со скоростью, и это работает, когда несколько записей выбраны и не выбраны.

0 голосов
/ 10 мая 2017

Еще один способ для непрерывных форм ...

  1. В событии Form_Current формы установите TempVar равным значению идентификатора текущей записи, например, ` TempVars! CurrentRecordID = Me.ID_xxx.value Me.ControlName.Refresh 'Это должен быть один из условно отформатированных элементов управления в шаге 2 ниже NB. вторая строка кода выше необходима для запуска условного форматирования. Вам нужно только обновить один из условно отформатированных элементов управления.
  2. Выражение правила условного форматирования: [ID_xxx]=[TempVars]![CurrentRecordID] и установите желаемое форматирование, например, BackColor
    1. Примените шаг 2 к любому элементу управления, который требуется условно отформатировать, когда выбрана запись.
    2. Подсвечиваются только элементы управления текущей записи

Private Sub Form_Current()

10       On Error GoTo Form_Current_Error

  '=============================================================


20     TempVars!CurrentRecordID = Me.MatterID.Value

30      Me.fldDateEngagedEnquiry.Requery


'================================================================

MyExit:

40       On Error GoTo 0

50       Application.Screen.MousePointer = 0 'reset to default mouse pointer

60       Exit Sub

Form_Current_Error:

70        MsgBox "Code Line Number: " & Erl & vbCrLf & vbCrLf & "Error " & Err.Number & vbCrLf & vbCrLf & " (" & Err.Description & ") in procedure " & vbCrLf & vbCrLf & " Form_Current of Sub Form_frmMyMatters_SVR"

80        GoTo MyExit

End Sub
0 голосов
/ 25 марта 2017

Вот полное решение, которое корректно обрабатывает вновь отредактированные записи, а также обрабатывает причуды интерфейса пользователя 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...