Расскажи про директивы управляемой формы
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Директивы управляемых форм в 1С
Директивы управляемых форм — это один из мощнейших механизмов 1С для создания сложного поведения интерфейса без усложнения кода. Это часто недооценённая тема, которая отделяет опытных разработчиков от новичков.
Что такое директива?
Директива — это декларативное описание логики условного отображения элементов управления.
Вместо того чтобы писать код вроде:
// ПЛОХО — procedural, много кода
Процедура ПриИзменении(Элемент) Экспорт
Если Объект.Статус = "Утверждён" Тогда
Элементы.КнопкаУтверждения.Видимость = Ложь;
Элементы.КнопкаОтказа.Видимость = Истина;
Иначе
Элементы.КнопкаУтверждения.Видимость = Истина;
Элементы.КнопкаОтказа.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
Мы можем использовать директивы в XML формы, которые автоматически обновляются при изменении данных.
Основные виды директив
1. Директива видимости: visible
<!-- Кнопка видима только если статус != "Утверждён" -->
<Button name="КнопкаУтверждения" visible="Объект.Статус <> \"Утверждён\""/>
<!-- Эквивалент в коде требует:-->
Процедура ПриОткрытии(Отказ) Экспорт
ОновитьВидимостьКнопок();
КонецПроцедуры
Процедура ПриИзменении(Элемент) Экспорт
ОновитьВидимостьКнопок();
КонецПроцедуры
Преимущество директивы: автоматическое обновление при любом изменении данных.
2. Директива доступности: enabled
<!-- Поле недоступно если документ проведён -->
<TextBox name="СуммаТовара" enabled="Не Объект.Проведён"/>
<!-- Или с более сложной логикой -->
<Field name="Цена" enabled="Объект.Статус = \"Черновик\" И Объект.Роль = \"Редактор\""/>
Это позволяет предотвратить редактирование поля без написания кода.
3. Директива обязательности: title для пометки звёздочкой
<!-- Пользователь видит звёздочку, если поле обязательно -->
<Label name="КонтрагентЛабель" title="Контрагент*" visible="Объект.Контрагент.Пусто()"/>
4. Директива зависимости: depended
Используется для объявления зависимостей (для оптимизации):
<Field name="Сумма" depended="Объект.КоличествоТовара,Объект.Цена"/>
Это говорит платформе: пересчитай это поле, если изменилось количество или цена.
Сложные выражения в директивах
Логические операции:
<!-- AND (И) -->
<Button visible="Объект.Проведён И Объект.Статус = \"Утверждён\""/>
<!-- OR (ИЛИ) -->
<Button visible="Объект.Роль = \"Администратор\" ИЛИ Объект.Роль = \"Менеджер\""/>
<!-- NOT (НЕ) -->
<Button visible="Не Объект.Проведён"/>
<!-- Сравнение -->
<Button visible="Объект.Сумма > 1000000"/>
<!-- Функции -->
<Field enabled="СтрДлина(Объект.Реквизит) > 0"/>
Практические примеры
Пример 1: Управление видимостью полей в зависимости от типа контрагента
<!-- Поле "ИНН" видимо только для ЮЛ -->
<TextBox name="ИНН" visible="Объект.ТипКонтрагента = \"ЮридическоеЛицо\""/>
<!-- Поле "Паспорт" видимо только для ФЛ -->
<TextBox name="Паспорт" visible="Объект.ТипКонтрагента = \"ФизическоеЛицо\""/>
Пример 2: Управление доступностью при проведении
<Group>
<TextBox name="Контрагент" enabled="Не Объект.Проведён"/>
<TextBox name="СуммаТовара" enabled="Не Объект.Проведён"/>
<DateField name="Дата" enabled="Не Объект.Проведён"/>
</Group>
Это гораздо чище, чем писать 3 обработчика в коде.
Пример 3: Скрытие команд для неавторизованных пользователей
<!-- Удаление доступно только администраторам -->
<Button name="КомандаУдалить" visible="ТекущийПользователь() = \"Администратор\""/>
<!-- Или через роль, если она в объекте -->
<Button name="КомандаУдалить" visible="Объект.ЕстьПравоНаУдаление"/>
Ограничения директив
Что можно делать в директивах:
- Простые сравнения
- Логические операции (И, ИЛИ, НЕ)
- Функции строк (СтрДлина, СтрПолучить, ...)
- Функции Дата/Время
- Обращение к реквизитам объекта
- Обращение к глобальным функциям
Что НЕЛЬЗЯ делать:
<!-- ❌ НЕПРАВИЛЬНО: сложная бизнес-логика -->
<Button visible="ПроверитьВсеОгранничения(Объект) И РассчитатьПотребности() > Объект.Сумма"/>
Для сложной логики используйте код в обработчиках события ПриОткрытии или ПриИзменении.
Когда использовать директивы, а когда код
Используйте директивы для:
✓ Условное отображение элементов
✓ Простая логика (if/else)
✓ Зависимость только от реквизитов
✓ Это снижает объём кода и упрощает maintenance
Используйте код для:
✓ Сложная логика (много условий)
✓ Вызов сервисов, БД запросы
✓ Пересчёты, валидация
✓ Инициализация при открытии
Оптимизация производительности
Проблема: слишком много директив = медленный интерфейс
Когда платформа парсит директивы, она создаёт зависимости между полями. При изменении одного поля может пересчитаться десять других.
Решение:
<!-- Неправильно: объявить зависимость от всего объекта -->
<Button visible="Объект"/> <!-- ❌ Слишком много зависимостей -->
<!-- Правильно: точная зависимость -->
<Button visible="Объект.Статус = \"Утверждён\""/> <!-- ✓ Конкретная зависимость -->
Best Practice:
- Используйте
dependedдля явного объявления зависимостей - Не парсите всю таблицу в условии видимости
- Для часто меняющихся полей используйте код, а не директивы
Продвинутые техники
Техника 1: Использование вычисляемых реквизитов
Вместо директивы:
<Button visible="Объект.Статус = \"Черновик\" И Не Объект.Проведён И Объект.Роль = \"Редактор\""/>
Создайте вычисляемый реквизит:
&ВычисляемыйРеквизит
Функция МожноРедактировать() Экспорт
Возврат Объект.Статус = "Черновик" И Не Объект.Проведён И Объект.Роль = "Редактор";
КонецФункции
А потом используйте в директиве:
<Button visible="Объект.МожноРедактировать"/>
Это делает код более читаемым и переиспользуемым.
Техника 2: Условное форматирование текста
<!-- Цвет зависит от статуса -->
<Field name="Статус"
textColor="?(Объект.Статус = \"Просрочен\", \"Красный\", \"Чёрный\")"/>
Типичные ошибки
Ошибка 1: Забыли экранировать кавычки в XML
<!-- ❌ НЕПРАВИЛЬНО -->
<Button visible="Объект.Статус = \"Утверждён\"/>
<!-- ✓ ПРАВИЛЬНО (экранируем кавычки) -->
<Button visible="Объект.Статус = \"Утверждён\""/>
Ошибка 2: Использовать директиву для того, что требует кода
<!-- ❌ НЕПРАВИЛЬНО: директива станет нечитаемой -->
<Button visible="Объект.Статус <> \"Утверждён\" И Объект.Дата > ТекущаяДата() И СтрДлина(Объект.Комментарий) > 100 И ПроверитьПрава()"/>
<!-- ✓ ПРАВИЛЬНО: используйте вычисляемый реквизит -->
<Button visible="Объект.ВычКнопкаВидима"/>
Ошибка 3: Циклические зависимости в depended
<!-- ❌ НЕПРАВИЛЬНО: A зависит от B, B зависит от A -->
<Field name="A" depended="B"/>
<Field name="B" depended="A"/>
<!-- ✓ ПРАВИЛЬНО: только одно направление -->
<Field name="A" depended="B"/>
Итоговые рекомендации
- Используйте директивы для простой логики — это делает интерфейс отзывчивым
- Создавайте вычисляемые реквизиты для сложных условий — это повышает читаемость
- Избегайте сложных выражений в директивах — это сложно отлаживать
- Помните про производительность — много директив = медленный интерфейс
- Документируйте директивы, если логика нетривиальна — коллегам нужно понять, почему элемент скрывается
Директивы управляемых форм — это один из лучших инструментов 1С для создания динамических интерфейсов. Правильное их использование делает код чище, а интерфейс отзывчивее.