В процессе разработки бизнес-логики в 1С часто возникает задача: сделать заполнение реквизита в табличной части обязательным не всегда, а только при определенных обстоятельствах. Классический пример — наличие флажка (типа Булево), при установке которого пользователь обязан заполнить соседнее числовое поле (например, сумму или количество). Рассмотрим, какими способами можно реализовать такую проверку, проанализируем их плюсы и минусы, и разберем правильную архитектуру решения.
Самый очевидный для начинающего разработчика способ — это ручной перебор строк табличной части непосредственно перед сохранением данных в базу. Проанализируем пример кода, который часто используется в таких случаях. Мы обходим коллекцию строк и проверяем наши условия.
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Пройдем циклом по всей табличной части "Лимиты"
Для каждого СтрТч Из Лимиты Цикл
// Проверяем условие: если флаг установлен, а сумма не заполнена (равна 0)
Если СтрТч.ЧастичнаяОплата И СтрТч.СуммаЧастичнойОплаты = 0 Тогда
Сообщить("В строке № " + СтрТч.НомерСтроки + " установлена частичная оплата, но не указана сумма!");
Отказ = Истина; // Прерываем запись документа
Возврат; // Выходим из процедуры после первой же ошибки
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важный нюанс: как справедливо отмечено в обсуждении, такой подход имеет существенный недостаток. Если в документе 100 строк с ошибками, система будет выдавать сообщение только по одной строке за раз. Пользователю придется 100 раз нажимать кнопку "Записать", что крайне неудобно. Чтобы избежать этого, лучше собрать все ошибки в один массив или использовать стандартные механизмы оповещения.
Разберем наиболее правильный с точки зрения платформы 1С метод. В модуле объекта существует предопределенная процедура ОбработкаПроверкиЗаполнения. Она вызывается системой автоматически, когда пользователь нажимает "Записать" или "Провести", и именно здесь должна быть сосредоточена логика контроля данных.
Рассмотрим, как реализовать проверку правильно, чтобы платформа подсветила поле с ошибкой красным цветом и позволила пользователю мгновенно перейти к нужной строке:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Для каждого СтрТч Из Лимиты Цикл
// Если флаг оплаты стоит, а сумма пустая
Если СтрТч.ЧастичнаяОплата И СтрТч.СуммаЧастичнойОплаты = 0 Тогда
// Формируем структуру сообщения
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не заполнена сумма частичной оплаты в строке " + СтрТч.НомерСтроки;
Сообщение.Поле = "Лимиты[" + (СтрТч.НомерСтроки - 1) + "].СуммаЧастичнойОплаты";
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
Отказ = Истина; // Запрещаем запись
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В данном примере мы используем объект СообщениеПользователю. Свойство Поле крайне важно: оно строится по шаблону ИмяТабличнойЧасти[ИндексСтроки].ИмяРеквизита. Обратите внимание, что индекс строки начинается с 0, поэтому мы вычитаем единицу из НомерСтроки. Благодаря этому пользователь сможет кликнуть по сообщению об ошибке, и программа сама переведет фокус на нужную ячейку в таблице.
Если табличная часть содержит тысячи строк, полный перебор в цикле Для каждого может замедлить работу. Проанализируем ситуацию: нам нужны только те строки, где установлен флаг. Мы можем использовать метод НайтиСтроки(), чтобы получить только интересующий нас массив данных.
ПараметрыОтбора = Новый Структура("ЧастичнаяОплата", Истина);
СтрокиСЧастичнойОплатой = Лимиты.НайтиСтроки(ПараметрыОтбора);
Для каждого Стр Из СтрокиСЧастичнойОплатой Цикл
Если Стр.СуммаЧастичнойОплаты = 0 Тогда
// Логика вывода ошибки...
КонецЕсли;
КонецЦикла;
Этот метод работает быстрее, так как платформа оптимизирует поиск по индексированным или внутренним структурам таблицы, избавляя нас от проверки заведомо "неинтересных" строк, где флаг не установлен.
Для улучшения UX (пользовательского опыта) желательно не просто выдавать ошибку при записи, но и визуально подсказывать пользователю, что поле стало обязательным, прямо в процессе редактирования. Выясним, как это сделать без написания сложного кода на клиенте.
Посмотрим на механизм Условного оформления формы:
Истина.Объект.Лимиты.ЧастичнаяОплата Равно Истина И Объект.Лимиты.СуммаЧастичнойОплаты Равно 0.ЛимитыСуммаЧастичнойОплаты.Теперь, как только пользователь поставит галочку в строке, соседняя ячейка сразу подсветится красным пунктиром, сигнализируя о необходимости заполнения. Это наиболее современный и дружелюбный к пользователю подход.
Мы проанализировали различные подходы к установке обязательности заполнения полей. Подведем итоги нашей совместной работы:
ОбработкаПроверкиЗаполнения в модуле объекта. Это гарантирует, что некорректные данные не попадут в базу, даже если документ записывается программно.Поле и ПутьКДанным в объекте СообщениеПользователю, чтобы привязать ошибку к конкретной строке табличной части.Использование этих методов в комплексе сделает ваше решение профессиональным, производительным и удобным для конечного пользователя.