При разработке правил обмена в конфигурации «1С:Конвертация данных 2.1» разработчики часто сталкиваются со сложными сценариями трансформации данных. Один из классических случаев — когда один документ информационной базы источника (например, Управление торговлей 10.3) при переносе преобразуется в несколько отдельных документов базы-приемника (например, Бухгалтерия предприятия 2.0 / 3.0). В таких ситуациях прямое сопоставление по внутренним идентификаторам (ГУИД) невозможно, из-за чего стандартные механизмы автоматической привязки подчиненных документов, таких как СчетФактураПолученный или СчетФактураВыданный, перестают работать.
Разберем подробно, почему возникает эта проблема, как передать параметры документа-основания при выгрузке счета-фактуры и какие варианты архитектурных решений существуют в КД 2.1.
В стандартном механизме КД 2.1 при выгрузке ссылки на документ-основание система ищет соответствующее ПКО (Правило конвертации объектов). Если документ-основание конвертируется «один в один», КД сопоставляет объекты по уникальному идентификатору или ключевым полям поиска. Однако при расщеплении документа («один ко многим»):
ВыгрузитьПоПравилу приводит к тому, что реквизит ДокументОснование остается пустым либо ссылается на неверный объект.Для решения этой задачи необходимо вручную передать данные для идентификации нужного документа-основания и подставить найденную ссылку в приемнике. Рассмотрим основные способы реализации.
Этот способ является наиболее прозрачным со стороны КД 2.1. Он позволяет передать ключевые поля документа-основания (номер, дата, контрагент, организация) через параметр ВходящиеДанные непосредственно в процедуру ВыгрузитьПоПравилу, а затем найти существующий документ приемника штатными средствами поиска конвертации.
Разберем пошагово настройку данного варианта:
ПослеВыгрузки) находим подчиненный счет-фактуру, формируем структуру с реквизитами для поиска основания и передаем ее в качестве входящих данных для счета-фактуры.
// Обработчик "ПослеВыгрузки" в ПВД основного документа
СчетФактура = УчетНДС.НайтиПодчиненныйСчетФактуру(Объект, "СчетФактураПолученный");
Если ЗначениеЗаполнено(СчетФактура) Тогда
// Формируем структуру с полями поиска основания
ДанныеОснования = Новый Структура;
ДанныеОснования.Вставить("НомерВходящегоДокумента", Объект.НомерВходящегоДокумента);
ДанныеОснования.Вставить("ДатаВходящегоДокумента", Объект.ДатаВходящегоДокумента);
ДанныеОснования.Вставить("Организация", Объект.Организация);
ДанныеОснования.Вставить("Контрагент", Объект.Контрагент);
// Упаковываем в общие входящие данные счета-фактуры
ВходящиеДанныеСФ = Новый Структура;
ВходящиеДанныеСФ.Вставить("ДанныеОснования", ДанныеОснования);
// Выгружаем подчиненный счет-фактуру по персональному ПКО
ВыгрузитьПоПравилу(СчетФактура, , ВходящиеДанныеСФ, , "СчетФактураПолученный");
КонецЕсли;
СчетФактураПолученный находим правило конвертации свойства (ПКС) ДокументОснование. В поле «Правило» указываем специальное ПКО (например, ПоступлениеТоваровУслуг_ПоискПоРеквизитам), а в обработчике ПередВыгрузкой свойства перенаправляем данные:
// ПКС "ДокументОснование" -> Обработчик "ПередВыгрузкой"
Если ВходящиеДанные <> Неопределено И ВходящиеДанные.Свойство("ДанныеОснования") Тогда
ИсходящиеДанные = ВходящиеДанные.ДанныеОснования;
КонецЕсли;
ДокументСсылка.ПоступлениеТоваровУслуг. Добавляем ПКС для реквизитов НомерВходящегоДокумента, ДатаВходящегоДокумента, Организация, Контрагент. Для каждого ПКС устанавливаем флаг «Получить из входящих данных» и флаг «Поиск». При загрузке 1С автоматически найдет в базе-приемнике уже созданный ранее документ поступления.Проанализируем второй надежный способ, который исключает создание дополнительных ПКО без источника. Мы можем передать поисковые поля основания через коллекцию ПараметрыОбъекта, а затем в базе-приемнике выполнить прямой запрос в обработчике ПослеЗагрузки.
ПередВыгрузкой ПКО СчетФактураПолученный заполняем параметры объекта:
// ПКО "СчетФактураПолученный" -> Обработчик "ПередВыгрузкой"
ПередатьОдинРеквизитВПриемник = Истина;
ПараметрыОбъекта.Вставить("НомерВходящегоДокумента", Источник.ДокументОснование.НомерВходящегоДокумента);
ПараметрыОбъекта.Вставить("ДатаВходящегоДокумента", Источник.ДокументОснование.ДатаВходящегоДокумента);
ПослеЗагрузки ПКО СчетФактураПолученный считываем переданные параметры, находим ссылку нужного документа и заполняем реквизит:
// ПКО "СчетФактураПолученный" -> Обработчик "ПослеЗагрузки"
Если Не РежимЗаписи.Запись Тогда
Возврат;
КонецЕсли;
НомерВх = Неопределено;
ДатаВх = Неопределено;
Если ПараметрыОбъекта.Свойство("НомерВходящегоДокумента", НомерВх)
И ПараметрыОбъекта.Свойство("ДатаВходящегоДокумента", ДатаВх)
И ЗначениеЗаполнено(НомерВх) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Поступление.Ссылка КАК Ссылка
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК Поступление
|ГДЕ
| Поступление.НомерВходящегоДокумента = &НомерВходящегоДокумента
| И Поступление.ДатаВходящегоДокумента = &ДатаВходящегоДокумента
| И Поступление.Организация = &Организация
| И Поступление.Проведен = ИСТИНА";
Запрос.УстановитьПараметр("НомерВходящегоДокумента", НомерВх);
Запрос.УстановитьПараметр("ДатаВходящегоДокумента", ДатаВх);
Запрос.УстановитьПараметр("Организация", Объект.Организация);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Заполняем реквизит или табличную часть в зависимости от конфигурации
Объект.ДокументОснование = Выборка.Ссылка;
КонецЕсли;
КонецЕсли;
Посмотрим на практическое решение, к которому пришел автор обсуждения. Если требуется быстро передать составные данные без создания дополнительных структурных вложений, номер и дату можно объединить в строку с разделителями (например, #), передать через ВходящиеДанные, а затем разобрать в ПКС:
// Обработчик "ПослеВыгрузки" в ПВД
СчетФактура = УчетНДС.НайтиПодчиненныйСчетФактуру(Объект, "СчетФактураПолученный");
ВходящиеДанные = Новый Структура;
ВходящиеДанные.Вставить("ДокументОснование", "#" + Объект.НомерДокумента + "#" + Объект.ДатаВходящегоДокумента + "#");
Если ЗначениеЗаполнено(СчетФактура) Тогда
ВыгрузитьПоПравилу(СчетФактура, , ВходящиеДанные, , "СчетФактураПолученный");
КонецЕсли;
В ПКО без источника для поиска документа в обработчике ПередВыгрузкой свойства выполняется обратный парсинг строки:
// ПКС "Номер" в ПКО без источника
МассивСтроки = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(Источник, "#");
Значение = МассивСтроки[1];
Важное замечание: строковый парсинг работает, однако является менее надежным по сравнению с передачей структуры, так как он чувствителен к форматам дат, наличию спецсимволов в номерах и требует аккуратной обработки возможных исключений при выходе индекса за границы массива.
При переносе данных в конфигурации Бухгалтерия предприятия (редакций 2.0 и 3.0) необходимо учитывать особенности метаданных документа СчетФактураПолученный:
ДокументОснование, а табличную часть ДокументыОснования. Если один документ источника распался на несколько документов поступления, в табличную часть ДокументыОснования необходимо добавить ссылки на все эти созданные документы, иначе суммы в книге покупок будут распределены некорректно.Бухгалтерии предприятия входящий счет-фактура может регистрироваться непосредственно полями «Номер входящего СФ» и «Дата входящего СФ» в самом документе ПоступлениеТоваровУслуг. В этом случае выгружать отдельный документ СчетФактураПолученный не требуется — достаточно перенести входящие реквизиты в поступление, и программа при проведении сформирует счет-фактуру автоматически.