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