Как проверить незаполненные строки в табличной части 1С и вывести их номера пользователю?

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

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

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

Способ №1. Программный обход строк в цикле (классический метод)

Рассмотрим наиболее очевидный и простой с точки зрения написания кода вариант — обход строк табличной части в цикле с использованием универсального метода ЗначениеЗаполнено(). Этот подход работает на стороне клиента и сервера, не требует обращения к базе данных и отлично подходит для оперативной проверки «на лету» при закрытии формы.

Разберем пример кода, который обходит табличную часть документа (например, Товары) и проверяет, заполнено ли поле ПараметрВыбора:


// Код размещается в модуле формы документа
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    
    Отказ = ПроверитьЗаполнениеТабличнойЧастиНаКлиенте();
    
КонецПроцедуры

&НаКлиенте
Функция ПроверитьЗаполнениеТабличнойЧастиНаКлиенте()
    
    МассивОшибок = Новый Массив;
    
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        // Проверяем заполнение конкретного реквизита строки
        Если Не ЗначениеЗаполнено(СтрокаТЧ.ПараметрВыбора) Тогда
            МассивОшибок.Добавить(СтрокаТЧ.НомерСтроки);
        КонецЕсли;
    КонецЦикла;
    
    Если МассивОшибок.Количество() > 0 Тогда
        // Формируем красивое сообщение для пользователя
        СписокНомеров = СтрСоединить(МассивОшибок, ", ");
        ТекстСообщения = НСтр("ru = 'В строках %1 не установлен выбор важного параметра!'");
        ТекстСообщения = СтрШаблон(ТекстСообщения, СписокНомеров);
        
        ПоказатьПредупреждение(, ТекстСообщения);
        Возврат Истина; // Возвращаем Истина для установки Отказа при закрытии формы
    КонецЕсли;
    
    Возврат Ложь;
    
КонецФункции

Преимущества метода: простота реализации, отсутствие лишних обращений к СУБД, мгновенная скорость работы на клиенте. Недостатки: если строк в табличной части будут десятки тысяч, обход коллекции на клиенте может вызвать кратковременное зависание интерфейса.

Способ №2. Использование платформенного свойства «Проверка заполнения»

Выясним, как решить задачу вообще без написания программного кода. Платформа 1С предлагает встроенный декларативный механизм контроля заполнения данных. Для его реализации достаточно выполнить несколько простых шагов в конфигураторе:

  1. Откройте дерево метаданных и найдите нужный документ.
  2. Перейдите на вкладку «Табличные части» и выберите интересующую вас таблицу.
  3. Откройте свойства реквизита, который обязательно должен быть заполнен в каждой строке.
  4. Найдите свойство «Проверка заполнения» и установите для него значение «Выдавать ошибку».

После этого платформа автоматически при попытке записи документа или проведении проверит табличную часть. Если какое-то поле останется пустым, пользователю будет выведено стандартное системное сообщение с точным указанием имени реквизита и номера строки, а сама строка выделится красным маркером.

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

Способ №3. Реализация проверки через запрос (профессиональный подход по ТЗ)

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

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

Разберем по шагам, как правильно написать и выполнить такой запрос на сервере:


&НаСервереБезКонтекста
Функция ПолучитьСписокПустыхСтрокЗапросом(ТаблицаДанных)
    
    Запрос = Новый Запрос;
    // Обязательно передаем таблицу значений в качестве параметра
    Запрос.УстановитьПараметр("ТаблицаТЧ", ТаблицаДанных);
    
    // Описываем во временной таблице структуру передаваемых данных
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ТЧ.НомерСтроки КАК НомерСтроки,
        |   ТЧ.ПараметрВыбора КАК ПараметрВыбора
        |ПОМЕСТИТЬ ВТ_ДанныеФормы
        |ИЗ
        |   &ТаблицаТЧ КАК ТЧ
        |;
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |   ВТ_ДанныеФормы.НомерСтроки КАК НомерСтроки
        |ИЗ
        |   ВТ_ДанныеФормы КАК ВТ_ДанныеФормы
        |ГДЕ
        |   // Ниже представлены различные варианты условий для проверки на пустоту:
        |   (ВТ_ДанныеФормы.ПараметрВыбора ЕСТЬ NULL 
        |   ИЛИ ВТ_ДанныеФормы.ПараметрВыбора = ЗНАЧЕНИЕ(Справочник.ПараметрыДокументов.ПустаяСсылка)
        |   ИЛИ ВТ_ДанныеФормы.ПараметрВыбора.Ссылка ЕСТЬ NULL)";
        
    РезультатЗапроса = Запрос.Выполнить();
    
    МассивНомеров = Новый Массив;
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Пока Выборка.Следующий() Цикл
            МассивНомеров.Добавить(Выборка.НомерСтроки);
        КонецЦикла;
    КонецЕсли;
    
    Возврат МассивНомеров;
    
КонецФункции

Чтобы запустить эту серверную функцию при попытке закрытия формы, нам потребуется выгрузить табличную часть и передать ее на сервер:


&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    
    // Выгружаем ТЧ в таблицу значений для передачи на сервер
    ТаблицаДляПроверки = Объект.Товары.Выгрузить();
    
    МассивПустыхСтрок = ПолучитьСписокПустыхСтрокЗапросом(ТаблицаДляПроверки);
    
    Если МассивПустыхСтрок.Количество() > 0 Тогда
        Отказ = Истина;
        СписокНомеров = СтрСоединить(МассивПустыхСтрок, ", ");
        ПоказатьПредупреждение(, "Пожалуйста, заполните выбор в строках: " + СписокНомеров);
    КонецЕсли;
    
КонецПроцедуры

Важные нюансы проверки «пустых» значений в запросах 1С

В отличие от программного метода ЗначениеЗаполнено(), который самостоятельно определяет тип переданного значения и проверяет его на пустоту, язык запросов 1С требует явного указания правил для каждого типа данных. Рассмотрим подробнее, как проверять разные виды «пустоты» в запросах:

Лайфхак: Универсальная проверка ссылок на пустоту

Если проверяемый реквизит имеет составной тип (например, там может находиться ссылка на справочник «Договоры» или документ «Акт»), прописывать проверку через ЗНАЧЕНИЕ(...) для каждого типа крайне неудобно.

В этом случае разработчики применяют профессиональный прием — обращение через точку (разыменование) к внутреннему полю ссылки (например, к полю Ссылка):

ГДЕ ПолеСоставногоТипа.Ссылка ЕСТЬ NULL

Как это работает: Поскольку у пустой ссылки любого типа (а также у значений NULL и Неопределено) физически нет записи в таблицах базы данных, попытка прочитать её внутреннее поле Ссылка через точку всегда возвращает значение NULL. Таким образом, одна простая и короткая проверка позволяет мгновенно отсечь любые незаполненные ссылочные значения составных типов данных.

← На главную