Как в Конвертации Данных перенести документ ОперацияБух и программно изменить движения после загрузки?

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

При переносе данных между конфигурациями 1С часто возникает задача конвертации документов производственного или торгового характера в документ ОперацияБух (Операция, введенная вручную) в "1С:Бухгалтерия предприятия 3.0". Это актуально, когда выполняется перенос данных из 1С:УПП 1.3 в 1С:БП 3.0 (поможет готовое решение для переноса из УПП 1.3 в БП 3.0) или при обмене с другими учетными системами. Это "документ-обертка", который напрямую управляет записями регистров бухгалтерии.

Рассмотрим ситуацию, с которой сталкиваются многие разработчики, когда настраивают правила конвертации данных из 1С:Производство+Услуги+Бухгалтерия или иных решений (помогут правила переноса из 1С:КА 1.1 в 1С:БП 3.0): данные переносятся, документ создается, но нам необходимо после загрузки изменить аналитику (Субконто) в проводках в зависимости от параметров, переданных из Источника. Например, подставить Договор контрагента в зависимости от Склада. Мы разберем, почему стандартное обращение к коллекции движений может возвращать пустое значение и как правильно манипулировать записями регистра бухгалтерии при обмене.

Почему движения документа недоступны в обработчике "ПослеЗагрузки"?

Частая проблема: вы пытаетесь обратиться к коллекции Объект.Движения.Хозрасчетный в обработчике ПКО (Правило конвертации объектов) ПослеЗагрузки, но метод Количество() возвращает 0, хотя в файле обмена проводки есть. Даже если используется специализированная загрузка в Бухгалтерию 3.0 в формате XML, поведение платформы остается прежним — для этого подойдут правила переноса из УТ 10.3 в БП 3.0.

Это происходит из-за порядка обработки данных XML-файла. Если правила выгрузки настроены так, что движения идут как подчиненные данные или как отдельные правила после самого объекта, то в момент события ПослеЗагрузки документа платформа еще не прочитала и не поместила движения в объект.

Существует два пути решения этой задачи. Разберем их подробно.

Способ 1: Прямая работа с Набором Записей (через базу данных)

Если данные движений в памяти объекта недоступны, мы можем принудительно записать сам документ, а затем создать отдельный Набор Записей, прочитать его из базы, изменить и записать обратно. Этот метод часто применяется, когда дорабатываются правила конвертации для обмена с 1С:БП ред.3.0 в сложных условиях постобработки.

В обработчике ПослеЗагрузки документа выполняем следующие шаги:

  1. Проверяем, новый ли это объект, и записываем его, чтобы получить Ссылку.
  2. Создаем набор записей регистра бухгалтерии.
  3. Устанавливаем отбор по регистратору.
  4. Читаем записи, модифицируем их в цикле и записываем обратно.

Посмотрим на пример кода реализации этого алгоритма:


// Принудительная запись объекта, если он новый, чтобы появилась Ссылка в БД
Если Объект.ЭтоНовый() Тогда
    Объект.СпособЗаполнения = "Вручную"; // Важно для БП 3.0
    Объект.ОбменДанными.Загрузка = Истина;
    Объект.Записать();
КонецЕсли;

// Получаем параметры, переданные из источника (например, таблицу соответствия складов)
ПараметрыТаблицы = ПараметрыОбъекта["ХозрасчетныйНаборЗаписей"]; 

// Создаем и читаем набор записей
НЗ = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Объект.Ссылка);
НЗ.Прочитать();

Счетчик = 0;
Для Каждого Запись ИЗ НЗ Цикл
    ТекДанные = ПараметрыТаблицы[Счетчик]; 
    
    СкладПолучатель = Справочники.Склады.НайтиПоКоду(ТекДанные.СкладПолучатель);
    If ЗначениеЗаполнено(СкладПолучатель) Тогда
        Запись.ПодразделениеДт = СкладПолучатель.ПодразделениеОрганизации;
    КонецЕсли;
    
    // Пример заполнения Субконто (Статьи затрат) для 20 счета
    Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01") Тогда
         Запись.СубконтоДт.Вставить(
             ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат, 
             Справочники.СтатьиЗатрат.НайтиПоКоду("Ц00000083")
         );
    КонецЕсли;

    Счетчик = Счетчик + 1;
КонецЦикла;

// Обязательно записываем набор с флагом Загрузка
НЗ.ОбменДанными.Загрузка = Истина;
НЗ.Записать();

Важное замечание: При работе с документом ОперацияБух в БП 3.0 необходимо следить за реквизитом, отвечающим за режим ввода (обычно это СпособЗаполнения или аналогичный). Если не установить его в значение "Вручную", при следующей интерактивной записи документа движения могут очиститься.

Способ 2: Формирование корректных данных на этапе выгрузки (Рекомендуемый)

Более правильный архитектурный подход — не исправлять данные "костылями" после загрузки, а подготовить их корректно еще на стороне Источника, используя стандартные правила обмена данными в формате XML. Для этой задачи есть правила переноса в БП 3.0 на КД 2.

Если вам нужно, чтобы в зависимости от Склада подставлялся Договор контрагента, реализуйте это правило в КД:

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

Пример логики в ПКС (на стороне Источника):


// Обработчик ПередВыгрузкой свойства "Субконто"
Если ТипЗнч(Источник.Склад) = Тип("СправочникСсылка.Склады") Тогда
    // Ваша логика определения договора
    Если Источник.Склад.Код = "001" Тогда
         Значение = "КодДоговораДляОсновногоСклада"; 
    Иначе
         Значение = "КодДоговораПоУмолчанию";
    КонецЕсли;
КонецЕсли;

В этом случае на сторону Приемника прилетит уже готовое значение, которое КД сама найдет и подставит в нужное субконто. Вам не придется перебирать записи регистра после записи документа.

Особенности работы с Субконто

В ОперацияБух субконто хранятся в коллекции видов характеристик. Простое присвоение через точку может не сработать. Кроме того, важно учитывать возможные ошибки платформы, такие как ошибка в порядке субконто в записи проводок, которая иногда встречается в типовых алгоритмах обмена.

Наиболее надежный способ установки субконто в КД или во встроенном языке — использование метода Вставить с явным указанием Вида Субконто.

Правильный пример кода:


// Получаем вид субконто через ПланВидовХарактеристик
ВидСубконтоСтатья = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат;
ЗначениеСтатьи = Справочники.СтатьиЗатрат.НайтиПоКоду("00007747");

// Вставляем значение в коллекцию
Запись.СубконтоДт.Вставить(ВидСубконтоСтатья, ЗначениеСтатьи);

Создание связанных объектов (Документ расчетов), если они не найдены

Иногда при переносе операций требуется указать в качестве субконто "Документ расчетов с контрагентом". Если такого документа в базе-приемнике нет, его нужно создать.

В КД это делается штатными средствами, без написания громоздкого кода Если НайтиПоНомеру() = Неопределено Тогда Создать....

  1. Создайте Правило Конвертации Объектов (ПКО) для документа расчетов.
  2. Настройте поля поиска (Номер, Дата, Контрагент, Организация).
  3. Установите флажки "Искать объект приемника по внутреннему идентификатору" и "Продолжить поиск по полям поиска".
  4. В ПКО Операции для свойства Субконто укажите это правило конвертации.
  5. Передайте в Значение структуру или объект источника, содержащий необходимые поля.

Резюме

  1. Чтобы увидеть и изменить движения документа ОперацияБух после загрузки, надежнее всего использовать отдельное чтение РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей() с отбором по Ссылке, предварительно записав сам документ.
  2. Лучшая практика — формировать корректные данные (например, вычислять Договор по Складу) на этапе выгрузки (в базе Источнике), чтобы в Приемник попадали уже готовые значения.
  3. При работе с Субконто программно используйте конструкцию Субконто.Вставить(ВидСубконто, Значение).
← На главную