При переходе со старых версий платформ (например, 1С 7.7) на современные конфигурации 1С 8.3 разработчики часто сталкиваются с несовместимостью структур данных. Типичный пример — перенос бухгалтерских остатков по взаиморасчетам. В конфигурациях на платформе 1С 7.7 учет часто велся в разрезе двух независимых субконто: Контрагенты и Типы счетов (или виды договоров), которые никак не были связаны на уровне метаданных справочников. В современных же конфигурациях 1С 8.3 учет требует обязательного указания справочника Договоры контрагентов, который подчинен справочнику Контрагенты и сам по себе содержит реквизит ссылки на Тип счета.
Возникает дилемма: в базе-источнике договоров нет, но в базе-приемнике без них невозможно провести документ ввода остатков. В этой статье мы подробно разберем, как решить эту задачу с помощью универсального инструмента «1С:Конвертация данных 2.1» (КД 2.1), и рассмотрим несколько профессиональных подходов.
Прежде чем перейти к написанию кода, проанализируем исходные данные:
Контрагенты, Субконто 2 — Справочник ТипыСчетов. Связи между ними нет.Контрагент и Договор. Справочник Договоры подчинен Контрагентам и имеет реквизит ТипСчета (ссылка на аналогичный справочник).Наша цель — при переносе остатков автоматически генерировать договоры в приемнике, привязывать их к соответствующему контрагенту, заполнять в договоре реквизит Тип счета и подставлять созданный договор в документ ввода остатков.
Рассмотрим четыре практических варианта реализации этой задачи.
---
Этот вариант считается одним из самых надежных и простых в отладке. Вместо того чтобы усложнять выгрузку на стороне устаревшей платформы 1С 7.7 (где нет полноценного конфигуратора для отладки кода конвертации), мы передаем сырые данные в приемник и создаем договоры средствами самой платформы 1С 8.3.
Пошаговый алгоритм реализации:
Контрагента напрямую.Договор в ПКС оставляем пустым (не сопоставляем источник).ТипСчета. Выгружаем туда значение субконто Тип счета из 7.7.
Для Каждого СтрокаТЧ Из Объект.РазделРасчетов Экспорт
Если ЗначениеЗаполнено(СтрокаТЧ.Контрагент) И ЗначениеЗаполнено(СтрокаТЧ.ТипСчета) Тогда
// Ищем существующий договор по владельцу и типу счета
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДоговорыКонтрагентов.Ссылка КАК Ссылка
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
| ДоговорыКонтрагентов.Владелец = &Владелец
| И ДоговорыКонтрагентов.ТипСчета = &ТипСчета";
Запрос.УстановитьПараметр("Владелец", СтрокаТЧ.Контрагент);
Запрос.УстановитьПараметр("ТипСчета", СтрокаТЧ.ТипСчета);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
СтрокаТЧ.Договор = Выборка.Ссылка;
Иначе
// Если договор не найден, создаем его программно
НовыйДоговор = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
НовыйДоговор.Владелец = СтрокаТЧ.Контрагент;
НовыйДоговор.ТипСчета = СтрокаТЧ.ТипСчета;
НовыйДоговор.Наименование = "Договор по типу: " + СокрЛП(СтрокаТЧ.ТипСчета.Наименование);
Попытка
НовыйДоговор.Записать();
СтрокаТЧ.Договор = НовыйДоговор.Ссылка;
Исключение
ЗаписьЖурналаРегистрации("Конвертация.ОшибкаСозданияДоговора",
УровеньЖурналаРегистрации.Ошибка,,,
ОписаниеОшибки());
КонецПопытки;
EndЕсли;
КонецЕсли;
КонецДляЗаписи;
Преимущества: Простота реализации. Код полностью компилируется и отлаживается в конфигураторе базы-приемника 8.3, где доступны современные инструменты отладки (брекпоинты, табло вычислить выражение).
---
Если мы хотим решить задачу исключительно в рамках методологии Конвертации данных, не прибегая к ручному программированию в приемнике, мы можем генерировать объекты виртуально во время выгрузки.
Для этого используется механизм ПКС с передачей структуры через ИсходящиеДанные. Важная техническая деталь: в платформе 1С 7.7 отсутствует тип данных «Структура». Вместо нее разработчики используют объект СписокЗначений.
Пошаговый алгоритм реализации:
Договоры. Источник оставляем пустым, приемник — справочник ДоговорыКонтрагентов.Владелец, Наименование и ТипСчета устанавливаем флаг «Получить из входящих данных».Договоры по комбинации свойств Владелец и Наименование (или ТипСчета), чтобы избежать дублирования элементов при повторном запуске обмена.
// В 1С 7.7 вместо структуры используем СписокЗначений
КонтейнерДанных = СоздатьОбъект("СписокЗначений");
КонтейнерДанных.Установить("Владелец", ТЗ.Контрагент);
КонтейнерДанных.Установить("Наименование", "Договор (" + ТЗ.ТипСчета.Наименование + ")");
КонтейнерДанных.Установить("ТипСчета", ТЗ.ТипСчета);
ИсходящиеДанные = КонтейнерДанных;
ИмяПКО = "Договоры";
При такой настройке XML-выгрузка сформирует виртуальный узел для договора, передаст его в ПКО «Договоры», а загрузчик на стороне 1С 8.3 корректно создаст элемент справочника с заполненным владельцем и реквизитом типа счета.
---
Чтобы гарантировать, что все договоры уже созданы в базе-приемнике на момент импорта документов ввода остатков, мы можем выгрузить их заранее. Для этого используется Правило выгрузки данных (ПВД) с типом выборки «Произвольный алгоритм».
Пошаговый алгоритм реализации:
Договоры.
// Создаем таблицу уникальных комбинаций для выгрузки
ТабУникальности = СоздатьОбъект("ТаблицаЗначений");
ТабУникальности.НоваяКолонка("Контрагент");
ТабУникальности.НоваяКолонка("ТипСчета");
БИ = СоздатьОбъект("БухгалтерскиеИтоги");
БИ.ИспользоватьСубконто(ВидыСубконто.Контрагенты);
БИ.ИспользоватьСубконто(ВидыСубконто.ТипыСчетов);
БИ.ВыполнитьЗапрос(ДатаОстатков, ДатаОстатков, "62, 60, 76"); // Укажите ваши счета
БИ.ВыбратьСубконто(1);
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
ТекущийКонтрагент = БИ.Субконто(1);
БИ.ВыбратьСубконто(2);
Пока БИ.ПолучитьСубконто(2) = 1 Цикл
ТекущийТипСчета = БИ.Субконто(2);
// Добавляем проверку на уникальность в ТЗ
// ... (код свертки или поиска дублей в ТЗ)
ТабУникальности.НоваяСтрока();
ТабУникальности.Контрагент = ТекущийКонтрагент;
ТабУникальности.ТипСчета = ТекущийТипСчета;
КонецЦикла;
КонецЦикла;
// Выгружаем полученные пары по правилу конвертации договоров
ТабУникальности.ВыбратьСтроки();
Пока ТабУникальности.ПолучитьСтроку() = 1 Цикл
ДанныеДоговора = СоздатьОбъект("СписокЗначений");
ДанныеДоговора.Установить("Владелец", ТабУникальности.Контрагент);
ДанныеДоговора.Установить("Наименование", "Договор " + ТабУникальности.ТипСчета.Наименование);
ДанныеДоговора.Установить("ТипСчета", ТабУникальности.ТипСчета);
ВыгрузитьПоПравилу(,, ДанныеДоговора,, "Договоры");
КонецЦикла;
Преимущества: При таком подходе к моменту начала загрузки документов все необходимые договоры уже гарантированно существуют в базе-приемнике. Документы сопоставят их автоматически по стандартным полям поиска без написания дополнительного кода в обработчиках документов.
---
При переносе данных с платформы 1С 7.7 на 1С 8.3 разработчики часто наступают на классические «грабли». Рассмотрим, как их избежать:
Стандартная обработка выгрузки для 1С 7.7 (V77Exp.ert) работает по технологии DOM — она полностью строит дерево XML-документа в оперативной памяти перед записью на диск. Поскольку процесс 1cv7s.exe является 32-битным, операционная система выделяет ему максимум 2 ГБ адресного пространства. При выгрузке больших объемов остатков с десятками тысяч контрагентов выгрузка неминуемо аварийно завершится. Решение: выгружайте данные частями (по группам контрагентов или по отдельным счетам учета) либо используйте оптимизированные под SAX-парсер версии обработки выгрузки.
В ПКО справочника Договоры критически важно правильно настроить поля поиска. Если вы укажете поиск только по реквизиту Наименование, система сопоставит договоры с одинаковыми именами у совершенно разных контрагентов! Обязательно устанавливайте флаг «Искать по родителю/владельцу» в настройках ПКО. Поиск должен осуществляться по связке «Владелец (Контрагент) + Наименование».
Мы подробно разобрали основные подходы к решению проблемы несовместимости аналитики при переносе данных из 1С 7.7 в 1С 8.3. Выберите наиболее подходящий вариант для вашей архитектуры и приступайте к реализации!