Как перенести номенклатуру из БП 3.0 в КА 1.1 и заполнить единицы хранения остатков?

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

При настройке правил обмена в конфигурации «Конвертация данных 2.0» для переноса справочника номенклатуры из «Бухгалтерии предприятия 3.0» в «Комплексную автоматизацию 1.1» разработчики часто сталкиваются с несоответствием структуры метаданных. В БП 3.0 реквизит ЕдиницаИзмерения ссылается на общий классификатор, а в КА 1.1 учет разделен: реквизит БазоваяЕдиницаИзмерения связан с классификатором, а ЕдиницаХраненияОстатков и ЕдиницаДляОтчетов ссылаются на подчиненный справочник ЕдиницыИзмерения. В результате стандартной загрузки эти реквизиты остаются пустыми. Разберем по шагам, почему возникает эта проблема, как программно создать единицы измерения в правилах обмена и как устранить ошибку неуникального кода.

Анализ причин проблемы

Выясним причину, почему типовые механизмы не заполняют единицы измерения автоматически при обмене данными:

  1. Разная архитектура справочников: в конфигурации КА 1.1 единицы хранения остатков и для отчетов являются элементами справочника СправочникСсылка.ЕдиницыИзмерения, владельцем которого обязательно выступает конкретная позиция номенклатуры.
  2. Отключение экранной логики: в типовой конфигурации создание единиц измерения прописано в модуле формы элемента при интерактивной работе пользователя. При обмене данными загрузка происходит программно с установленным свойством ОбменДанными.Загрузка = Истина, из-за чего события форм не срабатывают.
  3. Коллизия автонумерации: при попытке создать подчиненную единицу измерения может возникать системная ошибка Ошибка при вызове метода контекста (Записать): Значение "999" поля "Код" не уникально. Это происходит из-за появления в базе элементов с кодами максимальной числовой длины или со скрытыми хвостовыми пробелами, что сбивает встроенный платформенный автонумератор.

Способ 1. Создание подчиненных единиц в обработчике «ПослеЗагрузки» ПКО

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

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


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

Обратите внимание: при обращении к свойствам загружаемого объекта в контексте обработчиков КД обязательно нужно указывать префикс Объект. (например, Объект.ЭтоГруппа, Объект.БазоваяЕдиницаИзмерения), так как переменные модуля объекта напрямую в контексте обработчика КД недоступны.

Способ 2. Устранение ошибки уникальности кода «999»

Проанализируем ситуацию с ошибкой Значение "999" поля "Код" не уникально. Если в справочнике ЕдиницыИзмерения длина кода мала (например, 3 символа) или был записан элемент с неформатированным кодом без ведущих нулей (например, строка "999" вместо "000000999"), механизм автонумерации платформы 1С блокирует создание новых строк.

Разберем по шагам порядок исправления нумерации:

  1. Поиск проблемных записей: выполним запрос к справочнику ЕдиницыИзмерения, чтобы найти элементы, код которых оканчивается на «999» или содержит максимальное числовое значение с пробелами в конце.
  2. Перенумерация справочника: используем типовую обработку «Перенумерация справочников» с диска ИТС или напишем собственную групповую обработку, которая приведет все существующие коды к единой длине с ведущими нулями (например, "000000001").
  3. Установка режима загрузки: если ошибка возникает при программной записи подчиненной единицы, всегда включайте свойство НоваяЕдиница.ОбменДанными.Загрузка = Истина; перед вызовом Записать(). Это временно отключает встроенный контроль уникальности номеров платформой.

Способ 3. Постобработка номенклатуры внешней обработкой в КА 1.1

Если правила конвертации уже отработали, а номенклатура перенесена с пустыми единицами хранения остатков, не обязательно выполнять повторную выгрузку из БП 3.0. Достаточно запустить внешнюю обработку непосредственно в базе «Комплексная автоматизация 1.1».

Посмотрим на пример кода для группового заполнения единиц в уже загруженных данных:


Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    Если Выборка.ЭтоГруппа Тогда
        Продолжить;
    КонецЕсли;
    
    Если НЕ ЗначениеЗаполнено(Выборка.ЕдиницаХраненияОстатков) 
        И ЗначениеЗаполнено(Выборка.БазоваяЕдиницаИзмерения) Тогда
        
        ОбъектНоменклатура = Выборка.ПолучитьОбъект();
        
        // Создаем подчиненный элемент единицы
        НоваяЕдиница = Справочники.ЕдиницыИзмерения.СоздатьЭлемент();
        НоваяЕдиница.Владелец = ОбъектНоменклатура.Ссылка;
        НоваяЕдиница.ЕдиницаПоКлассификатору = ОбъектНоменклатура.БазоваяЕдиницаИзмерения;
        НоваяЕдиница.Коэффициент = 1;
        НоваяЕдиница.Наименование = СокрЛП(ОбъектНоменклатура.БазоваяЕдиницаИзмерения.Наименование);
        НоваяЕдиница.ОбменДанными.Загрузка = Истина;
        НоваяЕдиница.Записать();
        
        // Привязываем реквизиты и сохраняем без лишних проверок формы
        ОбъектНоменклатура.ЕдиницаХраненияОстатков = НоваяЕдиница.Ссылка;
        ОбъектНоменклатура.ЕдиницаДляОтчетов = НоваяЕдиница.Ссылка;
        ОбъектНоменклатура.ОбменДанными.Загрузка = Истина;
        ОбъектНоменклатура.Записать();
        
    КонецЕсли;
КонецЦикла;

Важный момент: использование флага ОбменДанными.Загрузка = Истина как для подчиненного справочника, так и для самой номенклатуры позволяет избежать падения транзакции из-за проверок прав доступа, заполненности ставок НДС или других регламентных ограничений конфигурации КА 1.1.

← На главную