Как перенести кастомный реквизит "Менеджер" договора из УТ 10.3 в УТ 11.5, если типовая выгрузка его игнорирует?

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

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

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

Суть проблемы

В исходной базе УТ 10.3 в справочник ДоговорыКонтрагентов был добавлен реквизит Менеджер (ссылка на справочник Пользователи). Это позволяло закреплять за каждым договором конкретного ответственного, отличного от основного менеджера контрагента.

При использовании типовой обработки перехода данные переносятся, но поле менеджера в УТ 11.5 либо остается пустым, либо заполняется значением по умолчанию (из карточки партнера/контрагента). Наша задача — перенести именно историческое значение из договора.

Способ 1: Использование собственного механизма выгрузки/загрузки через XML

Если доработка правил конвертации кажется слишком сложной или требует быстрого решения «здесь и сейчас», можно воспользоваться прямым обменом через XML-файл. Рассмотрим код, который позволяет выгрузить соответствие «Договор — Менеджер» из УТ 10.3 и загрузить его в УТ 11.5.

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

Этап 1: Выгрузка данных из УТ 10.3

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

Функция выгрузки на сервере будет выглядеть следующим образом:


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

Этот код создает простой XML-файл, содержащий структуру, понятную для человека и машины. Обратите внимание, что мы выгружаем строковое представление менеджера. Это сработает, если в базе-приемнике пользователи называются так же.

Этап 2: Загрузка данных в УТ 11.5

В базе-приемнике нам нужно прочитать этот файл, найти соответствующие справочники и обновить реквизит. В УТ 11 реквизит, отвечающий за менеджера, обычно называется Ответственный или может быть также добавлен вручную как доп. реквизит. В примере ниже предполагается, что реквизит называется Менеджер (или вы замените его на нужное имя, например, Ответственный).

Код процедуры чтения и обработки данных:


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

&НаСервере
Процедура ОбработатьДоговор(ИмяКонтрагента, ИмяДоговора, МенеджерСтрока)
    // 1. Ищем контрагента
    Контрагент = Справочники.Контрагенты.НайтиПоНаименованию(ИмяКонтрагента);
    Если Контрагент.Пустая() Тогда
        Сообщить("Не найден контрагент: " + ИмяКонтрагента);
        Возврат;
    КонецЕсли;
    
    // 2. Ищем договор, принадлежащий этому контрагенту
    // Важно: НайтиПоНаименованию ищет по всему справочнику, если не задан владелец или родитель.
    // Для точности лучше использовать запрос, но в простейшем варианте проверяем владельца
    ДоговорСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию(ИмяДоговора, Истина, , Контрагент); 
    // Четвертый параметр в НайтиПоНаименованию - Владелец (если применимо)
    // В УТ 11 структура может отличаться, часто поиск нужен через запрос для надежности.
    
    Если ДоговорСсылка.Пустая() Тогда
        // Попробуем найти просто по наименованию, если структура владения сложная
         ДоговорСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию(ИмяДоговора);
    КонецЕсли;

    Если ДоговорСсылка.Пустая() Тогда
        Сообщить("Не найден договор: " + ИмяДоговора);
        Возврат;
    КонецЕсли;

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

Способ 2: Настройка правил конвертации (Правильный путь)

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

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

  1. Зайти в вашу базу УТ 10.3 и выгрузить структуру метаданных (файл MD или XML через обработку выгрузки метаданных, идущую в комплекте с КД).
  2. Загрузить эту структуру в конфигурацию «Конвертация данных». Теперь КД «увидит», что у объекта ДоговорКонтрагента есть реквизит Менеджер.
  3. Найти правило конвертации объектов (ПКО) для договоров.
  4. В правилах конвертации свойств (ПКС) добавить новое правило:
    • Источник: Ваш реквизит Менеджер.
    • Приемник: Реквизит в УТ 11 (обычно Ответственный). Если в УТ 11 это тоже нетиповой реквизит, необходимо предварительно загрузить метаданные УТ 11 и выбрать его.
  5. Сохранить обновленные правила обмена и использовать их при выгрузке.

Этот способ предпочтительнее, так как он сохраняет целостность ссылок (GUID) и не зависит от изменения наименований.

Проблема переноса упаковок и единиц измерения

Часто после переноса данных из УТ 10.3 в УТ 11 возникает проблема: единицы измерения перенеслись, но выбрать упаковки в документах невозможно. Это связано с кардинальным отличием архитектуры этих подсистем.

В УТ 10.3: У номенклатуры был список единиц измерения с коэффициентами (шт, коробка = 10 шт).

В УТ 11.5: Существует двухуровневая система:

  1. Единицы измерения: Базовые физические величины (штуки, килограммы, метры).
  2. Упаковки: Отдельный справочник, который привязывается к Наборам упаковок.

Чтобы «включить» перенесенные упаковки в УТ 11, недостаточно просто перенести справочник. Необходимо:

Если автоматический перенос создал только единицы измерения, но не создал наборы упаковок, вам придется либо вручную создавать наборы и привязывать их к товарам, либо писать обработку, которая на основании коэффициентов из УТ 10.3 сгенерирует элементы справочника Упаковки и НаборыУпаковок в УТ 11.

← На главную