Как в Конвертации данных 2.1 задать один тип цен по умолчанию для документа «Установка цен номенклатуры»?

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

При настройке обмена данными между конфигурациями 1С (например, при переносе документов из «Розницы» в «Бухгалтерию предприятия») часто возникает необходимость упростить структуру переносимых документов. Типичный пример — документ «Установка цен номенклатуры». В исходной базе («Розница») цены могут устанавливаться сразу по множеству категорий в одном документе, тогда как в базе-приемнике требуется использовать лишь один конкретный тип цен (например, «Розничная»).

Попытки решить эту задачу «в лоб» часто приводят к ошибке при загрузке данных: «Поле "Тип цен" не может быть пустым». Даже если документ загружается непроведенным, платформа на стороне приемника все равно отказывается его записывать. В этой статье мы подробно разберем причины этой проблемы и рассмотрим три надежных способа ее решения с помощью механизмов «Конвертации данных 2.1» (КД 2.1).

Выясняем причины проблемы: почему простой поиск по коду не работает?

Прежде чем перейти к настройке правил, проанализируем, почему стандартные попытки программистов часто заканчиваются неудачей:

  1. Особенности работы метода НайтиПоКоду(). Если в кодовой базе приемника формат кода отличается (например, содержит префиксы или ведущие нули вроде «00-000001» вместо «00001»), метод вернет пустую ссылку (Справочники.ТипыЦенНоменклатуры.ПустаяСсылка()). Для платформы пустая ссылка по-прежнему является объектом базы данных, но при проверке заполнения реквизитов система расценивает ее как пустое значение и блокирует запись.
  2. Различия в метаданных конфигураций. В конфигурациях на управляемых формах (например, «Бухгалтерия предприятия 3.0») реквизит ТипЦен обычно располагается в шапке документа. В более старых решениях (например, «Бухгалтерия предприятия 2.0» или «Управление торговлей 10.3») документ спроектирован сложнее: типы цен хранятся в отдельной табличной части ТипыЦен, а в табличной части Товары для каждой строки может быть указан свой тип цен. Попытка записать значение в шапку в этом случае просто игнорируется платформой.
  3. Проверка заполнения «Перед записью». Ошибка валидации срабатывает на уровне объектной логики самого документа при попытке вызвать метод Записать(). Поэтому простое отключение проведения документа (установка режима записи в значение «Запись») не решает проблему — транзакция все равно откатывается назад.

Рассмотрим подробнее три проверенных способа решения этой проблемы в КД 2.1, начиная от самого простого и заканчивая наиболее гибким и универсальным.

Способ 1. Использование свойства «Выражение» в ПКС (Наиболее простой)

В Конвертации данных 2.1 у правил конвертации свойств (ПКС) есть встроенный механизм под названием «Выражение». Написанный в этом поле код выполняется непосредственно в базе-приемнике в момент загрузки файла обмена. Это идеальный вариант, когда нам нужно жестко прописать конкретное значение для реквизита.

Разберем настройку по шагам:

  1. Откроем правила конвертации объектов (ПКО) для нашего документа (например, УстановкаЦенНоменклатуры).
  2. Найдем в списке свойств (ПКС) реквизит ТипЦен (или создадим его вручную, если его там нет). Поле «Источник» оставляем пустым, так как мы не передаем это значение из базы-источника.
  3. Дважды кликнем по ПКС реквизита ТипЦен и перейдем на вкладку параметров свойства.
  4. В поле «Выражение» введем следующий код на встроенном языке 1С:

Result = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Розничная");

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

Способ 2. Архитектурный подход через сопоставление ПКО

Этот способ считается более правильным с точки зрения методологии разработки в КД 2.1, поскольку он не использует жесткое кодирование на стороне приемника и позволяет КД автоматически создать нужный элемент справочника, если его вдруг не окажется в базе-приемнике.

Для реализации этого подхода выполним следующие действия:

  1. В ПКО нашего документа выберем ПКС для свойства ТипЦен (источник оставляем пустым).
  2. В колонке «Правило конвертации» выберем ПКО для справочника ТипыЦенНоменклатуры (если его нет, его нужно предварительно создать).
  3. Откроем обработчик ПКС «Перед выгрузкой» и напишем код:

Значение = "Розничная";

  1. Перейдем в ПКО справочника ТипыЦенНоменклатуры. Убедимся, что для свойства Наименование установлена галочка «Поиск».

Как это работает: При выгрузке КД передаст строковое значение "Розничная" в качестве наименования типа цен. При загрузке в базу-приемник механизм КД попытается найти элемент справочника по этому наименованию. Если элемент будет найден — он подставится в документ; если нет — система автоматически создаст новый тип цен с этим наименованием, что предотвратит падение загрузки с ошибкой.

Способ 3. Универсальный скрипт в обработчике «После загрузки» (С учетом ТЧ)

Если вы не уверены в структуре базы-приемника (например, это может быть как «Бухгалтерия предприятия 3.0» с реквизитом в шапке, так и более старая версия с табличными частями), нам потребуется написать универсальный программный код в обработчике ПКО документа.

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


НайденныйТипЦен = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Розничная");

Если ЗначениеЗаполнено(НайденныйТипЦен) Тогда
    
    // 1. Попытка заполнения реквизита в шапке (для современных конфигураций вроде БП 3.0)
    Попытка
        Объект.ТипЦен = НайденныйТипЦен;
    Исключение
        // Исключение сработает, если реквизита "ТипЦен" нет в шапке документа
    КонецПопытки;
    
    // 2. Заполнение табличной части "ТипыЦен" (для старых конфигураций вроде БП 2.0 или УТ 10.3)
    Если Объект.Метаданные().ТабличныеЧасти.Найти("ТипыЦен") <> Неопределено Тогда
        Объект.ТипыЦен.Очистить();
        НоваяСтрока = Объект.ТипыЦен.Добавить();
        НоваяСтрока.ТипЦен = НайденныйТипЦен;
    КонецЕсли;
    
    // 3. Заполнение типа цен в строках табличной части "Товары" (если требуется платформой)
    Если Объект.Метаданные().ТабличныеЧасти.Товары.Реквизиты.Найти("ТипЦен") <> Неопределено Тогда
        Для Каждого СтрокаТовара Из Объект.Товары Цикл
            СтрокаТовара.ТипЦен = НайденныйТипЦен;
        КонецЦикла;
    КонецЕсли;
    
КонецЕсли;

Данный скрипт проверяет метаданные загружаемого объекта «на лету». Если в базе-приемнике реквизит находится в шапке, он заполнит шапку. Если в табличной части — он очистит ТЧ, добавит туда одну строку и запишет нужный тип цен, а также продублирует его во всех строках товарного состава. Это полностью исключает возникновение ошибки незаполненного типа цен при записи документа.

Дополнительный совет: Как отключить автоматическое проведение документов при загрузке?

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

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

  1. В ПКС для свойства Проведен в обработчике «Перед выгрузкой» напишем:

Значение = Ложь;

  1. В ПКО документа в обработчике «После загрузки» принудительно укажем режим записи объекта:

РежимЗаписи = "Запись";

Установка переменной РежимЗаписи в значение "Запись" гарантирует, что даже если в файле обмена документ был помечен как проведенный, универсальная обработка загрузки данных запишет его как обычный черновик, не вызывая лишних движений по регистрам сведений цен.

Проанализировав эти три подхода, мы можем выбрать наиболее подходящий под наши задачи. Для простых однотипных баз отлично подойдет первый способ с использованием поля «Выражение». Для сложных распределенных систем с потенциально изменяющимися данными лучше использовать второй или третий варианты.

← На главную