Как создать подчиненный справочник Договоры при переносе остатков из 1С 7.7 в 1С 8.3 через Конвертацию данных?

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

При переходе со старых версий платформ (например, 1С 7.7) на современные конфигурации 1С 8.3 разработчики часто сталкиваются с несовместимостью структур данных. Типичный пример — перенос бухгалтерских остатков по взаиморасчетам. В конфигурациях на платформе 1С 7.7 учет часто велся в разрезе двух независимых субконто: Контрагенты и Типы счетов (или виды договоров), которые никак не были связаны на уровне метаданных справочников. В современных же конфигурациях 1С 8.3 учет требует обязательного указания справочника Договоры контрагентов, который подчинен справочнику Контрагенты и сам по себе содержит реквизит ссылки на Тип счета.

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

Постановка задачи и анализ структуры

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

Наша цель — при переносе остатков автоматически генерировать договоры в приемнике, привязывать их к соответствующему контрагенту, заполнять в договоре реквизит Тип счета и подставлять созданный договор в документ ввода остатков.

Рассмотрим четыре практических варианта реализации этой задачи.

---

Вариант 1. Перенос логики на сторону базы-приемника (Обработчик «После загрузки» в 1С 8.3)

Этот вариант считается одним из самых надежных и простых в отладке. Вместо того чтобы усложнять выгрузку на стороне устаревшей платформы 1С 7.7 (где нет полноценного конфигуратора для отладки кода конвертации), мы передаем сырые данные в приемник и создаем договоры средствами самой платформы 1С 8.3.

Пошаговый алгоритм реализации:

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

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

Преимущества: Простота реализации. Код полностью компилируется и отлаживается в конфигураторе базы-приемника 8.3, где доступны современные инструменты отладки (брекпоинты, табло вычислить выражение).

---

Вариант 2. Динамическое создание через «ИсходящиеДанные» в 1С 7.7

Если мы хотим решить задачу исключительно в рамках методологии Конвертации данных, не прибегая к ручному программированию в приемнике, мы можем генерировать объекты виртуально во время выгрузки.

Для этого используется механизм ПКС с передачей структуры через ИсходящиеДанные. Важная техническая деталь: в платформе 1С 7.7 отсутствует тип данных «Структура». Вместо нее разработчики используют объект СписокЗначений.

Пошаговый алгоритм реализации:

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

// В 1С 7.7 вместо структуры используем СписокЗначений
КонтейнерДанных = СоздатьОбъект("СписокЗначений");
КонтейнерДанных.Установить("Владелец", ТЗ.Контрагент);
КонтейнерДанных.Установить("Наименование", "Договор (" + ТЗ.ТипСчета.Наименование + ")");
КонтейнерДанных.Установить("ТипСчета", ТЗ.ТипСчета);

ИсходящиеДанные = КонтейнерДанных;
ИмяПКО = "Договоры";

При такой настройке XML-выгрузка сформирует виртуальный узел для договора, передаст его в ПКО «Договоры», а загрузчик на стороне 1С 8.3 корректно создаст элемент справочника с заполненным владельцем и реквизитом типа счета.

---

Вариант 3. Предварительная генерация договоров в ПВД (Произвольный алгоритм)

Чтобы гарантировать, что все договоры уже созданы в базе-приемнике на момент импорта документов ввода остатков, мы можем выгрузить их заранее. Для этого используется Правило выгрузки данных (ПВД) с типом выборки «Произвольный алгоритм».

Пошаговый алгоритм реализации:

  1. Создаем ПВД для справочника Договоры.
  2. В обработчике «Перед обработкой» пишем код, который с помощью бухгалтерских итогов (или прямых запросов) обходит базу и собирает уникальные пары «Контрагент - Тип счета» из остатков:

// Создаем таблицу уникальных комбинаций для выгрузки
ТабУникальности = СоздатьОбъект("ТаблицаЗначений");
ТабУникальности.НоваяКолонка("Контрагент");
ТабУникальности.НоваяКолонка("ТипСчета");

БИ = СоздатьОбъект("БухгалтерскиеИтоги");
БИ.ИспользоватьСубконто(ВидыСубконто.Контрагенты);
БИ.ИспользоватьСубконто(ВидыСубконто.ТипыСчетов);
БИ.ВыполнитьЗапрос(ДатаОстатков, ДатаОстатков, "62, 60, 76"); // Укажите ваши счета

БИ.ВыбратьСубконто(1);
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
    ТекущийКонтрагент = БИ.Субконто(1);
    БИ.ВыбратьСубконто(2);
    Пока БИ.ПолучитьСубконто(2) = 1 Цикл
        ТекущийТипСчета = БИ.Субконто(2);
        
        // Добавляем проверку на уникальность в ТЗ
        // ... (код свертки или поиска дублей в ТЗ)
        
        ТабУникальности.НоваяСтрока();
        ТабУникальности.Контрагент = ТекущийКонтрагент;
        ТабУникальности.ТипСчета = ТекущийТипСчета;
    КонецЦикла;
КонецЦикла;

// Выгружаем полученные пары по правилу конвертации договоров
ТабУникальности.ВыбратьСтроки();
Пока ТабУникальности.ПолучитьСтроку() = 1 Цикл
    ДанныеДоговора = СоздатьОбъект("СписокЗначений");
    ДанныеДоговора.Установить("Владелец", ТабУникальности.Контрагент);
    ДанныеДоговора.Установить("Наименование", "Договор " + ТабУникальности.ТипСчета.Наименование);
    ДанныеДоговора.Установить("ТипСчета", ТабУникальности.ТипСчета);
    
    ВыгрузитьПоПравилу(,, ДанныеДоговора,, "Договоры");
КонецЦикла;

Преимущества: При таком подходе к моменту начала загрузки документов все необходимые договоры уже гарантированно существуют в базе-приемнике. Документы сопоставят их автоматически по стандартным полям поиска без написания дополнительного кода в обработчиках документов.

---

Важные технические ограничения платформы 1С 7.7, о которых нужно помнить

При переносе данных с платформы 1С 7.7 на 1С 8.3 разработчики часто наступают на классические «грабли». Рассмотрим, как их избежать:

  1. Проблема нехватки оперативной памяти (Out of Memory):

    Стандартная обработка выгрузки для 1С 7.7 (V77Exp.ert) работает по технологии DOM — она полностью строит дерево XML-документа в оперативной памяти перед записью на диск. Поскольку процесс 1cv7s.exe является 32-битным, операционная система выделяет ему максимум 2 ГБ адресного пространства. При выгрузке больших объемов остатков с десятками тысяч контрагентов выгрузка неминуемо аварийно завершится. Решение: выгружайте данные частями (по группам контрагентов или по отдельным счетам учета) либо используйте оптимизированные под SAX-парсер версии обработки выгрузки.

  2. Настройка полей поиска подчиненных справочников:

    В ПКО справочника Договоры критически важно правильно настроить поля поиска. Если вы укажете поиск только по реквизиту Наименование, система сопоставит договоры с одинаковыми именами у совершенно разных контрагентов! Обязательно устанавливайте флаг «Искать по родителю/владельцу» в настройках ПКО. Поиск должен осуществляться по связке «Владелец (Контрагент) + Наименование».

Мы подробно разобрали основные подходы к решению проблемы несовместимости аналитики при переносе данных из 1С 7.7 в 1С 8.3. Выберите наиболее подходящий вариант для вашей архитектуры и приступайте к реализации!

← На главную