[Из песочницы] Подводные камни условного форматирования в MS Access
В интерфейсе Access кнопку Условное форматирование можно найти на вкладке Формат (Format), предварительно поставив фокус на форматируемый элемент управления (control). УФ можно подвергнуть лишь два типа элементов управления: Поле (Text Box) и Поле со списком (Combo Box).
Нажав на кнопку, мы сможем настроить правила условного форматирования в Диспетчере условного форматирования (Conditional Formatting Rules Manager), при этом правила ниже по списку имеют больший приоритет.
Пример. Имеем два правила:
- Значение должно быть больше 50, тогда фон красный.
- Значение должно быть меньше 200, тогда фон зелёный.
Если мы введём 100, то значение будет удовлетворять обоим условиям, и выполняться будет второе правило, то, которое ниже по списку. Фон станет зелёным.
На уровне VBA инструмент представлен двумя объектами: FormatCondition и FormatConditions. Первый, собственно, хранит условия форматирования, а второй это коллекция первых.
FormatConditions одновременно является свойством для контролов типа acTextBox и acComboBox.
Вот, собственно, и все базовые понятия, но не тут-то было! Access не позволяет добавлять через VBA новые правила, если у нашего контрола их уже хотя бы три. А если ваша бизнес-задача требует маркировки пятью цветами? А если при определённых условиях нужно отключать контрол? Тогда придётся поработать руками, что не так уж и страшно, как кажется. Как сделать это оптимально, я сейчас и расскажу.
Для начала пишем процедуру создания первых трёх правил:
Sub setFormatConditions()
'создаёт первые три правила условного форматирования
Dim fcnVar As FormatCondition 'объект типа FormatCondition
Dim frmVar As Form 'форма, на которой расположены контролы
Dim ctlVar As Control 'перебираемые контролы
Dim btCtlType As Byte 'тип контрола
On Error Resume Next
'обратите внимание, что форма обязательно должа быть открыта
'если она закрыта, то надо её открыть руками или соответствующим кодом
Set frmVar = Forms![Название формы]
With frmVar
'ищем комбобоксы и текстбокы среди контролов
For Each ctlVar In .Controls
btCtlType = ctlVar.ControlType
If (btCtlType = acComboBox) Or (btCtlType = acTextBox) Then
'очищаем все условия для контрола и применяем создание условного форматирования
ctlVar.FormatConditions.Delete
Set fcnVar = ctlVar.FormatConditions.Add(acExpression, , "blablabla")
Set fcnVar = ctlVar.FormatConditions.Add(acExpression, , "blablabla")
Set fcnVar = ctlVar.FormatConditions.Add(acExpression, , "blablabla")
End If 'btCtlType = acComboBox
Next ctlVar 'In .Controls
End With 'frmVar
Set fcnVar = Nothing
Set ctlVar = Nothing
Set frmVar = Nothing
End Sub
В данном случае мы создаём правила для всех объектов TextBox И ComboBox, однако, в зависимости от задачи, можно прописать проверку на дополнительные условия. Во всех трёх случаях добавляются правила основанные на выражении, о чём свидетельствует параметр acExpression, а в качестве текста выражения используется любая произвольная строка, например «blablabla», второй параметр пропущен, потому что его можно пропустить. Использованы именно такие параметры, потому что это самый простой и короткий вариант кода для создания правил форматирования, настраивать их будем позже.
Далее открываем Диспетчер условного форматирования и в выпадающем списке «Показать правила условного форматирования для:» последовательно проходим по всем нужным полям и руками добавляем правила. При добавлении правила по умолчанию предлагают условие «Значение поля между», оставляем как есть, заполняем оба пустых поля любыми буквами или цифрами, например »1» и »1», жмём OK и создаём следующее. Таким образом экономим время при ручном вводе, не тратя его на лишние действия.
Когда создание нужного количества правил для всех контролов завершено, массово модифицируем эти правила в VBA.
Для этого создаём процедуру модификации:
Sub modifyFormatConditions()
'модифицирует созданные правила форматирования
Dim fcnVar As FormatCondition 'объект типа FormatCondition
Dim frmVar As Form 'форма, на которой расположены контролы
Dim ctlVar As Control 'перебираемые контролы
Dim i As Integer
On Error Resume Next
'обратите внимание, что форма обязательно должа быть открыта
'если она закрыта, то надо её открыть руками или соответствующим кодом
Set frmVar = Forms![Название таблицы]
With frmVar
'ищем комбобоксы и текстбокы среди контролов
For Each ctlVar In .Controls
btCtlType = ctlVar.ControlType
If (btCtlType = acComboBox) Or (btCtlType = acTextBox) Then
'перебираем все правила по индексу, начиная с 0
For i = 0 To 20
'Метод Modify имеет такой же синтаксис, как и Add, с помощью него можно поменять все параметры правила
'Modify возвращает Nothing, поэтому его надо присвоить хотя бы чему-нибудь
ddd = ctlVar.FormatConditions(i).Modify(acExpression, , "ololo")
Set fcnVar = ctlVar.FormatConditions(i)
'Настраиваем формат, в данном случае делаем фон красным
fcnVar.BackColor = vbRed
Next i
End If 'btCtlType = acComboBox
Next ctlVar 'In .Controls
End With 'frmVar
Set fcnVar = Nothing
Set ctlVar = Nothing
Set frmVar = Nothing
End Sub
Всё, правила готовы, контент форматируется. Надо иметь в виду, что условное форматирование требует заметного времени для вычисления, поэтому лучше всего его использовать на формах, к которым не будут применяться Refresh, Redraw, Recalc и Requery. Если на стадии открытия формы пользователь ещё может немного подождать, чтобы потом продолжительно с ней общаться, то зависания при перерисовке условного форматирования в процессе работы с формой сделают эту работу практически невозможной.
В этом примере показано массовое создание большого количества одинаковых правил для разных контролов. Естественно, в зависимости от задачи, необходимо будет делать множество разных проверок, и этот метод не подойдёт для большого количества контролов, с разными наборами правил. Хотя, если эти наборы со временем меняются, может оказаться, что прописать матрицу настроек в коде и переписывать константы будет значительно проще, чем бегать мышкой по экрану и нажимать разные кнопки.
Полезные ссылки:
» Типы контролов
» Свойства и методы объекта FormatCondition
» Свойства и методы объекта FormatConditions
» Метод FormatConditions.Add