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

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

При разработке конфигураций на платформе 1С:Предприятие 8.3 часто возникает задача: сделать поле обязательным для заполнения только при выполнении определенного условия. Например, если в шапке документа выбран конкретный тип мероприятия, то колонка в табличной части должна стать обязательной. Многие начинающие разработчики пытаются изменить свойство ПроверкаЗаполнения напрямую через программный код в событии ПриИзменении, однако платформа не позволяет менять метаданные объекта «на лету».

В этой статье мы подробно разберем, как правильно реализовать динамическую проверку заполнения, используя штатные механизмы платформы: программную обработку проверки, условное оформление и визуальные индикаторы.

Метод 1: Использование события ОбработкаПроверкиЗаполнения

Наиболее правильный с точки зрения архитектуры 1С способ — это использование серверного события модуля объекта или модуля формы ОбработкаПроверкиЗаполнения. Этот метод вызывается автоматически при нажатии кнопки «Записать и закрыть» или «Провести».

Рассмотрим ситуацию, когда у нас есть реквизит шапки ТипМероприятия и табличная часть Участники с колонкой Комментарий. Нам нужно, чтобы комментарий проверялся только для вебинаров. Разберем по шагам, как это реализовать:

  1. В метаданных у реквизита Комментарий установите свойство Проверка заполнения в значение Не проверять.
  2. В модуле документа создайте обработчик события ОбработкаПроверкиЗаполнения.
  3. Внутри обработчика проанализируем условие и добавим путь к реквизиту в массив ПроверяемыеРеквизиты.

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


Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
	
	// Если тип мероприятия — Вебинар, добавляем колонку в список проверяемых
	Если ТипМероприятия = Перечисления.ТипыМероприятий.Вебинар Тогда
		// Для табличных частей используется синтаксис: ИмяТаблицы.ИмяРеквизита
		ПроверяемыеРеквизиты.Добавить("Участники.Комментарий");
	КонецЕсли;

КонецПроцедуры

Важный нюанс: Если в метаданных изначально стоит Выдавать ошибку, но в некоторых случаях проверку нужно отключить, мы должны найти этот реквизит в массиве и удалить его:


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

Метод 2: Визуальное выделение через Условное оформление

Метод через ОбработкаПроверкиЗаполнения работает отлично, но пользователь узнает об ошибке только в момент сохранения документа. Чтобы сделать интерфейс более дружелюбным, мы можем подсветить обязательное поле красным пунктиром сразу после выбора типа мероприятия. Для этого воспользуемся Условным оформлением формы.

Мы можем настроить условное оформление как вручную в конфигураторе, так и программно. Проанализируем программный способ в процедуре ПриСозданииНаСервере, так как он более гибкий:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Создаем элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();
    
    // Определяем, что мы будем менять — свойство "Отметка незаполненного"
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ОтметкаНезаполненного", Истина);
    
    // Условие: ТипМероприятия равен "Вебинар"
    ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ТипМероприятия");
    ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементУсловия.ПравоеЗначение = ПредопределенноеЗначение("Перечисление.ТипыМероприятий.Вебинар");
    
    // Указываем поле, к которому применяется оформление
    ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
    ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("УчастникиКомментарий");

КонецПроцедуры

Этот код заставит систему динамически рисовать красное подчеркивание в колонке «Комментарий» во всех строках таблицы, как только в шапке будет выбран «Вебинар».

Метод 3: Использование свойства ОтметкаНезаполненного в событии ПриИзменении

Если нам нужно управлять визуальным состоянием поля максимально оперативно на клиенте, мы можем обратиться к свойству элемента формы ОтметкаНезаполненного. Это не инициирует проверку данных, но дает пользователю визуальную подсказку.

Выясним, как это работает в связке с событием ТипМероприятияПриИзменении:


&НаКлиенте
Процедура ТипМероприятияПриИзменении(Элемент)
    
    // Определяем видимость отметки в зависимости от значения
    НужнаПроверка = (Объект.ТипМероприятия = ПредопределенноеЗначение("Перечисление.ТипыМероприятий.Вебинар"));
    
    // Обращаемся к элементу формы (колонке таблицы)
    Элементы.УчастникиКомментарий.ОтметкаНезаполненного = НужнаПроверка;
    
    // Дополнительно можно принудительно запустить проверку формы
    // ПроверитьЗаполнение(); 
КонецПроцедуры

Важно: Свойство ОтметкаНезаполненного у элемента формы влияет только на визуальное отображение. Оно не заменяет реальную проверку в ОбработкаПроверкиЗаполнения. Для надежности рекомендуется комбинировать Метод 1 и Метод 2.

Сложные случаи: Ручная валидация и Сообщения пользователю

Иногда стандартный механизм «заполнено/пусто» не подходит. Например, если комментарий обязателен только для тех строк таблицы, где заполнена определенная сумма. В этом случае массив ПроверяемыеРеквизиты не поможет, так как он включает проверку для всех строк сразу.

Выясним, как реализовать выборочную проверку строк в ОбработкаПроверкиЗаполнения:

  1. Удаляем реквизит из стандартной проверки.
  2. В цикле обходим строки таблицы.
  3. Если условие нарушено, формируем объект СообщениеПользователю.

Рассмотрим пример кода:


Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

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

    // Проверяем только если это вебинар
    Если Объект.ТипМероприятия = Перечисления.ТипыМероприятий.Вебинар Тогда
        Для Каждого СтрокаТЧ Из Объект.Участники Цикл
            Если ПустаяСтрока(СтрокаТЧ.Комментарий) Тогда
                Сообщение = Новый СообщениеПользователю;
                Сообщение.Текст = "В строке #" + СтрокаТЧ.НомерСтроки + " необходимо заполнить комментарий!";
                Сообщение.Поле = "Объект.Участники[" + (СтрокаТЧ.НомерСтроки - 1) + "].Комментарий";
                Сообщение.УстановитьДанные(Объект);
                Сообщение.Сообщить();
                
                Отказ = Истина; // Прерываем запись документа
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;

КонецПроцедуры

Использование свойства Сообщение.Поле позволяет привязать текст ошибки непосредственно к конкретной ячейке в таблице. Когда пользователь нажмет на сообщение в панели сообщений, курсор автоматически переместится в нужную строку и колонку.

Резюме

Для реализации качественной динамической проверки заполнения реквизитов табличной части следуйте этим правилам:

Комбинируя эти подходы, мы создаем надежное и интуитивно понятное решение для конечного пользователя, соблюдая при этом стандарты разработки на платформе 1С.

← На главную