Как в Конвертации данных исключить из табличной части документа товары, которых нет в базе-приемнике?

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

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

Шаг 1. Запрет создания новых объектов в ПКО номенклатуры

Проанализируем базовый механизм сопоставления. Если в правиле конвертации объекта (ПКО) для справочника Номенклатура разрешено автоматическое создание, платформа при отсутствии найденного элемента создаст новую позицию в базе-приемнике. Поэтому первым делом настроим запрет на создание новых элементов:

  1. Открываем ПКО для справочника Номенклатура.
  2. Устанавливаем флаг «Не создавать новый объект в приемнике, если он не найден».
  3. В этом случае при отсутствии товара поиск вернет пустую ссылку (или Неопределено, если реквизит имеет составной тип), а новый элемент в справочнике создан не будет.

Шаг 2. Очистка табличной части документа в обработчике «После загрузки»

После того как поиск объекта завершился неудачно, в табличную часть документа попадает строка с незаполненной номенклатурой. Рассмотрим, как удалить такие строки в обработчике «После загрузки» ПКО соответствующего документа.

Типичная ошибка — попытка найти строки со значением Неопределено. В реквизитах ссылочного типа при незаполненном значении находится пустая ссылка соответствующего типа справочника (Справочники.Номенклатура.ПустаяСсылка()). Универсальным решением для проверки является системная функция ЗначениеЗаполнено().

Посмотрим на классический и наиболее надежный способ удаления строк через обратный цикл по индексам (с конца к началу):


// Обработчик "После загрузки" ПКО документа
Индекс = Объект.Товары.Количество() - 1;
Пока Индекс >= 0 Цикл
    СтрокаТЧ = Объект.Товары[Индекс];
    Если Не ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
        Объект.Товары.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

Разберем также альтернативный вариант с использованием метода НайтиСтроки(). Если реквизит Номенклатура имеет однозначный ссылочный тип, в структуру поиска передается пустая ссылка:


// Вариант с поиском пустых ссылок
СтруктураПоиска = Новый Структура("Номенклатура", Справочники.Номенклатура.ПустаяСсылка());
МассивПустыхСтрок = Объект.Товары.НайтиСтроки(СтруктураПоиска);

Для Каждого Строка Из МассивПустыхСтрок Цикл
    Объект.Товары.Удалить(Строка);
КонецЦикла;

Шаг 3. Пересчет итогов документа и обработка пустой ТЧ

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


// 1. Удаляем строки с ненайденной номенклатурой
Индекс = Объект.Товары.Количество() - 1;
Пока Индекс >= 0 Цикл
    СтрокаТЧ = Объект.Товары[Индекс];
    Если Не ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
        Объект.Товары.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

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

// 3. Пересчитываем реквизиты шапки
Если Не Отказ Тогда
    Объект.СуммаДокумента = Объект.Товары.Итог("Сумма");
КонецЕсли;

Альтернативное решение: фильтрация на стороне источника

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

Для этого в ПКС табличной части документа в обработчике «Перед выгрузкой» формируют готовую таблицу значений с отфильтрованными строками и присваивают ее переменной КоллекцияОбъектов:


// Обработчик "Перед выгрузкой" ПКС табличной части Товары
ТаблицаВыгрузки = Источник.Товары.Выгрузить();

// Удаляем лишние строки по условию источника
Индекс = ТаблицаВыгрузки.Количество() - 1;
Пока Индекс >= 0 Цикл
    СтрокаДанных = ТаблицаВыгрузки[Индекс];
    Если СтрокаДанных.Номенклатура.Услуга Тогда // Пример условия фильтрации
        ТаблицаВыгрузки.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

КоллекцияОбъектов = ТаблицаВыгрузки;

Таким образом, сочетание запрета создания новых элементов в ПКО номенклатуры и очистки табличной части в обработчике После загрузки позволяет гибко управлять составом строк загружаемого документа.

← На главную