Как при переносе "Поступления товаров и услуг" в "Реализацию" программно создать документ "Счет-фактура выданный" в Конвертации данных 2.1?

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

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

В этой статье мы подробно проанализируем, почему возникает популярная ошибка "Тип не определен (Не определено)" при попытке выгрузить структуру данных, и разберем два надежных сценария решения этой задачи: исправление выгрузки по правилу на стороне источника и более стабильное программное создание документа на стороне приемника.

Анализ ошибки "Тип не определен (Не определено)" при загрузке

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


ДанныеДляЗаполненияСчетфактуры = Новый Структура("Дата,ВалютаДокумента,Контрагент,ДоговорКонтрагента,Организация,ДокументОснование,КодВидаОперации,Проведен,Комментарий,ВидСчетаФактуры"); 
ДанныеДляЗаполненияСчетфактуры.Дата = Источник.Дата; 
ДанныеДляЗаполненияСчетфактуры.ВалютаДокумента = Источник.ВалютаДокумента; 
ДанныеДляЗаполненияСчетфактуры.Контрагент = Источник.Контрагент; 
ДанныеДляЗаполненияСчетфактуры.ДоговорКонтрагента = Источник.ДоговорКонтрагента; 
ДанныеДляЗаполненияСчетфактуры.Организация = Источник.Организация; 
ДанныеДляЗаполненияСчетфактуры.ДокументОснование = Источник.Ссылка; 
ДанныеДляЗаполненияСчетфактуры.КодВидаОперации = "01"; 
ДанныеДляЗаполненияСчетфактуры.Проведен = ЛОЖЬ; 
ДанныеДляЗаполненияСчетфактуры.Комментарий = "*"; 
ДанныеДляЗаполненияСчетфактуры.ВидСчетаФактуры = "НаРеализацию"; 

ВыгрузитьПоПравилу(, , ДанныеДляЗаполненияСчетфактуры, , "СчетФактураВыданный");

При попытке загрузить полученный XML-файл в базу-приемник универсальная обработка обмена завершается аварийно с ошибкой парсера: Тип не определен (Не определено). Выясним, почему это происходит.

Дело в том, что в функцию ВыгрузитьПоПравилу структура передается в качестве третьего параметра (ВходящиеДанные), а сам объект-источник (первый параметр) передается как Неопределено. Когда XML-процессор КД 2.1 начинает генерировать узел для правила "СчетФактураВыданный", он видит, что тип источника не задан. Если в самом ПКО "СчетФактураВыданный" в поле "Источник" выбран конкретный тип метаданных (например, ДокументСсылка.ПоступлениеТоваровУслуг), система ожидает получить именно этот объект. Из-за отсутствия явного типа генерируется некорректная XML-структура, которая и "падает" на этапе загрузки.

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

Рассмотрим, как правильно решить эту задачу двумя разными способами.

---

Способ №1. Исправление выгрузки по правилу через структуру на стороне Источника

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

Шаг 1. Настройка ПКО для Счета-фактуры.
Создаем отдельное ПКО (например, с именем "СчетФактураВыданный_Виртуальный"). В поле "Источник" обязательно оставляем пустое значение (удаляем любой тип данных). В поле "Приемник" выбираем ДокументСсылка.СчетФактураВыданный. Такое ПКО называют "виртуальным", так как оно работает не с физической таблицей БД, а со структурой свойств.

Шаг 2. Настройка ПКС (Правил конвертации свойств).
Внутри нашего виртуального ПКО создаем правила для всех необходимых реквизитов (Организация, Контрагент, ДокументОснование и т.д.). Имена свойств источника должны строго совпадать с ключами структуры, которую мы будем передавать.

Шаг 3. Изменение вызова функции выгрузки.
Перепишем код в обработчике "После выгрузки" исходного документа "Поступление товаров и услуг". Теперь мы будем передавать структуру не в качестве входящих данных, а в качестве самого источника (первым параметром):


ДанныеДляЗаполненияСчетфактуры = Новый Структура;
ДанныеДляЗаполненияСчетфактуры.Вставить("Дата", Источник.Дата);
ДанныеДляЗаполненияСчетфактуры.Вставить("Организация", Источник.Организация);
ДанныеДляЗаполненияСчетфактуры.Вставить("Контрагент", Источник.Контрагент);
ДанныеДляЗаполненияСчетфактуры.Вставить("ДоговорКонтрагента", Источник.ДоговорКонтрагента);
ДанныеДляЗаполненияСчетфактуры.Вставить("ДокументОснование", Источник.Ссылка);
ДанныеДляЗаполненияСчетфактуры.Вставить("ВидСчетаФактуры", "НаРеализацию");
ДанныеДляЗаполненияСчетфактуры.Вставить("КодВидаОперации", "01");

// Передаем структуру ПЕРВЫМ параметром
ВыгрузитьПоПравилу(ДанныеДляЗаполненияСчетфактуры, , , , "СчетФактураВыданный_Виртуальный");

Важное примечание по поводу Документа-основания:
В структуре мы передаем ДокументОснование = Источник.Ссылка (ссылка на "Поступление"). Но в базе-приемнике счет-фактура должен ссылаться на созданную "Реализацию". Чтобы произошла автоматическая замена, в ПКС для свойства ДокументОснование в виртуальном ПКО укажите правило конвертации (ПКО), по которому вы переносили "Поступление" в "Реализацию". При загрузке система сопоставит ссылки и подставит верный документ.

---

Способ №2. Программное создание Счета-фактуры на стороне Приемника (Рекомендуемый)

Практика разработки интеграционных решений показывает, что создание подчиненных документов на стороне приемника — гораздо более надежный и контролируемый процесс. Нам не нужно возиться с виртуальными ПКО, а на этапе загрузки у нас уже есть полноценная, записанная в базу данных ссылка на документ-основание (Реализацию).

Реализуем этот алгоритм. Перейдем в ПКО "Поступление_Реализация" и откроем обработчик "После загрузки". Напишем код, который будет автоматически генерировать и проводить счет-фактуру.


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

Использование штатных механизмов конфигурации-приемника

Если база-приемник построена на классических обычных формах (например, УТ 10.3 или БП 2.0), мы можем задействовать процедуры типовых модулей. Это позволит сократить объем ручного кода. Например, вместо ручного создания структуры можно вызвать метод контекста формирования:


// Пример для интеграции в УТ 10.3 / БП 2.0
// Код размещается в обработчике "После загрузки" ПКО Реализации
Объект.Записать(); // Обязательно записываем объект, чтобы получить ссылку

// Вызываем экспортную функцию создания СФ из общего модуля работы с диалогами
РаботаСДиалогами.ВвестиСчетФактуру(Объект, , "СчетФактураВыданный");

Для современных конфигураций на управляемых формах (БП 3.0, ERP, КА) рекомендуется заглянуть в общий модуль УчетНДС или аналогичный ему и использовать готовые процедуры автоматического создания счетов-фактур по переданному массиву документов-оснований. Это избавит вас от необходимости ручной поддержки изменений структуры метаданных при обновлениях конфигурации-приемника.

← На главную