При переносе данных между конфигурациями 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С:БП ред.3.0 в сложных условиях постобработки.
В обработчике ПослеЗагрузки документа выполняем следующие шаги:
Посмотрим на пример кода реализации этого алгоритма:
// Принудительная запись объекта, если он новый, чтобы появилась Ссылка в БД
Если Объект.ЭтоНовый() Тогда
Объект.СпособЗаполнения = "Вручную"; // Важно для БП 3.0
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
КонецЕсли;
// Получаем параметры, переданные из источника (например, таблицу соответствия складов)
ПараметрыТаблицы = ПараметрыОбъекта["ХозрасчетныйНаборЗаписей"];
// Создаем и читаем набор записей
НЗ = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Объект.Ссылка);
НЗ.Прочитать();
Счетчик = 0;
Для Каждого Запись ИЗ НЗ Цикл
ТекДанные = ПараметрыТаблицы[Счетчик];
СкладПолучатель = Справочники.Склады.НайтиПоКоду(ТекДанные.СкладПолучатель);
If ЗначениеЗаполнено(СкладПолучатель) Тогда
Запись.ПодразделениеДт = СкладПолучатель.ПодразделениеОрганизации;
КонецЕсли;
// Пример заполнения Субконто (Статьи затрат) для 20 счета
Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01") Тогда
Запись.СубконтоДт.Вставить(
ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат,
Справочники.СтатьиЗатрат.НайтиПоКоду("Ц00000083")
);
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
// Обязательно записываем набор с флагом Загрузка
НЗ.ОбменДанными.Загрузка = Истина;
НЗ.Записать();
Важное замечание: При работе с документом ОперацияБух в БП 3.0 необходимо следить за реквизитом, отвечающим за режим ввода (обычно это СпособЗаполнения или аналогичный). Если не установить его в значение "Вручную", при следующей интерактивной записи документа движения могут очиститься.
Более правильный архитектурный подход — не исправлять данные "костылями" после загрузки, а подготовить их корректно еще на стороне Источника, используя стандартные правила обмена данными в формате XML. Для этой задачи есть правила переноса в БП 3.0 на КД 2.
Если вам нужно, чтобы в зависимости от Склада подставлялся Договор контрагента, реализуйте это правило в КД:
Значение.Пример логики в ПКС (на стороне Источника):
// Обработчик ПередВыгрузкой свойства "Субконто"
Если ТипЗнч(Источник.Склад) = Тип("СправочникСсылка.Склады") Тогда
// Ваша логика определения договора
Если Источник.Склад.Код = "001" Тогда
Значение = "КодДоговораДляОсновногоСклада";
Иначе
Значение = "КодДоговораПоУмолчанию";
КонецЕсли;
КонецЕсли;
В этом случае на сторону Приемника прилетит уже готовое значение, которое КД сама найдет и подставит в нужное субконто. Вам не придется перебирать записи регистра после записи документа.
В ОперацияБух субконто хранятся в коллекции видов характеристик. Простое присвоение через точку может не сработать. Кроме того, важно учитывать возможные ошибки платформы, такие как ошибка в порядке субконто в записи проводок, которая иногда встречается в типовых алгоритмах обмена.
Наиболее надежный способ установки субконто в КД или во встроенном языке — использование метода Вставить с явным указанием Вида Субконто.
Правильный пример кода:
// Получаем вид субконто через ПланВидовХарактеристик
ВидСубконтоСтатья = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат;
ЗначениеСтатьи = Справочники.СтатьиЗатрат.НайтиПоКоду("00007747");
// Вставляем значение в коллекцию
Запись.СубконтоДт.Вставить(ВидСубконтоСтатья, ЗначениеСтатьи);
Иногда при переносе операций требуется указать в качестве субконто "Документ расчетов с контрагентом". Если такого документа в базе-приемнике нет, его нужно создать.
В КД это делается штатными средствами, без написания громоздкого кода Если НайтиПоНомеру() = Неопределено Тогда Создать....
Значение структуру или объект источника, содержащий необходимые поля.ОперацияБух после загрузки, надежнее всего использовать отдельное чтение РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей() с отбором по Ссылке, предварительно записав сам документ.Субконто.Вставить(ВидСубконто, Значение).