Как программно изменить проверку заполнения реквизита табличной части в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие 8 часто возникает задача динамического управления обязательными полями. Типичный сценарий: в конфигураторе для реквизита табличной части установлено свойство «Проверка заполнения» в значение «Выдавать ошибку», но при определенных условиях (например, в зависимости от вида операции или роли пользователя) нам нужно разрешить запись документа с пустым значением этого реквизита.

Разберем детально, почему нельзя просто поменять свойство реквизита «в лоб» и какие инструменты предоставляет платформа для решения этой задачи.

Принцип неизменности метаданных в рантайме

Прежде всего, проанализируем фундаментальное ограничение системы. Свойства, которые мы задаем в окне «Свойства» объекта метаданных в конфигураторе, жестко фиксируются в структуре конфигурации. Платформа 1С не позволяет программно изменять метаданные во время работы сеанса пользователя. Это означает, что вы не сможете написать код вида Объект.Метаданные().ТабличныеЧасти.ТЧ1.Реквизиты.Реквизит1.ПроверкаЗаполнения = ПроверкаЗаполнения.НеПроверять.

Все «динамические изменения», о которых пойдет речь ниже, — это способы управления поведением стандартных механизмов платформы, а не модификация самих метаданных.

Основное решение: ОбработкаПроверкиЗаполнения

Наиболее правильным и стандартным методом является использование обработчика события ОбработкаПроверкиЗаполнения, который располагается в модуле объекта (документа, справочника и т.д.). Рассмотрим подробнее, как работает этот механизм.

Когда пользователь нажимает кнопку «Записать» или «Провести», платформа формирует массив ПроверяемыеРеквизиты. В него попадают имена всех реквизитов, у которых в конфигураторе стоит признак проверки. Наша задача — программно удалить ненужный реквизит из этого массива при выполнении определенного условия.

Посмотрим на пример кода в модуле документа:


Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    
    // Проверяем условие, при котором проверку нужно отключить
    Если ВидОперации = Перечисления.ВидыОпераций.Прочее Тогда
        
        // Для удаления реквизита табличной части используется путь "ИмяТЧ.ИмяРеквизита"
        Индекс = ПроверяемыеРеквизиты.Найти("ТЧ1.Реквизит1");
        
        Если Индекс <> Неопределено Тогда
            ПроверяемыеРеквизиты.Удалить(Индекс);
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Важные нюансы работы с массивом:

  1. Удаление всей колонки: Если вы удаляете строку "ИмяТабличнойЧасти.ИмяРеквизита", платформа перестанет проверять этот реквизит во всех строках табличной части.
  2. Удаление всей таблицы: Если вам нужно пропустить проверку заполнения всей табличной части целиком (например, когда она может быть пустой), нужно удалить элемент с именем "ИмяТабличнойЧасти".
  3. Поиск в массиве: Всегда проверяйте результат метода Найти(). Если реквизита в массиве нет (например, он уже был удален другим кодом или не включен в метаданных), попытка удаления по значению Неопределено приведет к аварийному завершению работы программы.

Условная визуализация на уровне формы

Иногда программисту нужно не просто отключить проверку, а управлять визуальной индикацией (красным пунктиром) на форме. Для этого существует свойство элемента формы АвтоОтметкаНезаполненного. Рассмотрим ситуацию: мы хотим, чтобы поле подсвечивалось только в том случае, если документ еще не утвержден.

Проанализируем пример кода в модуле формы:


&НаСервере
Процедура УстановитьВизуальнуюПроверку()
    
    // Управляем визуальным отображением обязательности
    НужноПроверять = (Объект.Статус = Перечисления.Статусы.Черновик);
    Элементы.ТЧ1Реквизит1.АвтоОтметкаНезаполненного = НужноПроверять;
    
КонецПроцедуры

Внимание: Установка АвтоОтметкаНезаполненного = Ложь убирает только визуальную подсветку. Если в метаданных реквизита стоит «Выдавать ошибку», при записи объект все равно выдаст системную ошибку заполнения. Поэтому использование АвтоОтметкаНезаполненного должно идти в паре с ОбработкаПроверкиЗаполнения в модуле объекта.

Метод «ОбменДанными.Загрузка» — радикальный подход

В обсуждении на форуме упоминался флаг Загрузка = Истина. Выясним причину, почему этот способ часто используют, и в чем его опасность. Когда у объекта установлен признак ОбменДанными.Загрузка = Истина, платформа полностью игнорирует вызов ОбработкаПроверкиЗаполнения и не выполняет стандартные проверки метаданных.

Пример использования при программном создании документа:


НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// Заполнение данных...
НовыйДок.ОбменДанными.Загрузка = Истина; 
НовыйДок.Записать(РежимЗаписиДокумента.Запись);

Последствия использования этого режима:

Программный вызов проверки заполнения

Разберем ситуацию, когда вы создаете объект программно и хотите убедиться, что он заполнен корректно, прежде чем записывать его. По умолчанию метод Записать() в коде (не из формы) не инициирует проверку заполнения. Чтобы запустить механизм, нужно вызвать метод ПроверитьЗаполнение().


Если ЭтотОбъект.ПроверитьЗаполнение() Тогда
    ЭтотОбъект.Записать();
Иначе
    // Обработка ситуации, когда данные не валидны
КонецЕсли;

Этот метод внутри себя вызывает ту самую процедуру ОбработкаПроверкиЗаполнения, которую мы рассматривали в первом пункте. Это позволяет централизованно управлять логикой проверки и для интерактивной работы пользователя, и для программных обработок. Для наглядного анализа порядка срабатывания обработчиков при записи и валидации данных можно использовать разработку для изучения последовательности событий платформы 1С.

Рекомендации по проектированию

Для того чтобы ваша конфигурация была гибкой и удобной в поддержке, мы рекомендуем придерживаться следующей стратегии:

  1. В Конфигураторе устанавливайте свойство «Проверка заполнения» в значение «Не проверять» для тех реквизитов, чья обязательность зависит от условий.
  2. Всю сложную логику проверки (включая проверку в зависимости от ролей пользователя через РольДоступна()) описывайте в ОбработкаПроверкиЗаполнения.
  3. Если реквизит обязателен всегда — ставьте «Выдавать ошибку» в метаданных, это сэкономит вам время на написание кода.
  4. Для визуального комфорта пользователя используйте свойство АвтоОтметкаНезаполненного на форме, синхронизируя его с логикой в модуле объекта.

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

← На главную