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

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

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

Способ 1. Использование встроенного механизма «ОбработкаПроверкиЗаполнения»

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

Рассмотрим, как управлять проверкой реквизитов табличной части через массив ПроверяемыеРеквизиты:

  1. Если у реквизита табличной части в свойствах метаданных установлено свойство «Проверка заполнения» в значение Выдавать ошибку, платформа автоматически добавит проверку вида "ИмяТабличнойЧасти.ИмяРеквизита" в массив.
  2. Если необходимо проверять реквизит только при выполнении определенных условий, мы можем динамически добавлять или удалять имя реквизита из массива проверяемых полей.

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


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

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

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

Способ 2. Ручной обход строк с точной привязкой ошибки через «СообщениеПользователю»

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

Разберем реализацию такой проверки внутри процедуры ОбработкаПроверкиЗаполнения или ПередЗаписью:


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

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

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

Способ 3. Проверка в событии «ПередЗаписью» и защита групповой обработки

Иногда требуется жесткий контроль данных непосредственно в момент записи объекта в базу данных. В таких ситуациях проверку помещают в обработчик ПередЗаписью модуля объекта. Однако здесь важно учитывать программную запись документов и обмен данными.

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


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

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

Способ 4. Проверка наличия строк в табличной части

Выясним, как правильно проверить, что табличная часть документа не пуста. В платформе 1С метод Количество() является функцией, поэтому вызывать его необходимо со скобками.

Посмотрим на примеры проверки количества строк:


// Вариант 1. Проверка через метод Количество()
Если РасшифровкаПлатежа.Количество() = 0 Тогда
    Отказ = Истина;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Табличная часть ""Расшифровка платежа"" не может быть пустой!";
    Сообщение.Поле = "РасшифровкаПлатежа";
    Сообщение.УстановитьДанные(ЭтотОбъект);
    Сообщение.Сообщить();
КонецЕсли;

// Вариант 2. Проверка через массив в ОбработкаПроверкиЗаполнения
// Если передать просто имя табличной части без точки, платформа проверит наличие хотя бы одной строки
ПроверяемыеРеквизиты.Добавить("РасшифровкаПлатежа");

Итог: для большинства интерактивных сценариев оптимально использовать процедуру ОбработкаПроверкиЗаполнения вместе с объектом СообщениеПользователю. Это гарантирует корректную подсветку ошибочных строк в интерфейсе и исключает проблемы при программном перепроведении документов.

← На главную