Каталог решений - Загрузка данных в БП 3.0 (Универсальный обмен данными XML)

Загрузка данных в БП 3.0 (Универсальный обмен данными XML)

Загрузка данных в БП 3.0 (Универсальный обмен данными XML)

В наличии

Решение задачи по загрузке данных из имеющегося файла в формате xml в БП 3.0 (в том числе на 1cfresh.com) без доработок

Категория:

Описание

Настоящая статья написана по итогам реального кейса, когда надо было загрузить некий файл, полученный с помощью правил обмена из Конвертации Данных v2 в облачную Бухгалтерию. На локальной версии вопросов вообще не возникает, так как через "Все функции" вызываешь обработку "Универсальный обмен данными в формате XML" и просто используешь ее. В облаке 1cfresh.com такая функция очевидно недоступна, и пришлось искать другое решение.

 

Итак, начнем

Все тексты модулей взяты из конфигурации БП версии 3.0.70.39

Сначала для торопливых (или ленивых; или нелюбопытных — кому что ближе). Загрузку произвольного файла, который корректно написан для конфигурации, можно произвести через пункт меню из раздела Главное — "Загрузка из 1С:Отчётность предпринимателя".

Загрузка из ОП

Все. На этом статью можно было бы и завершить. Но надо же написать раздел и для любопытных ))

Вообще, в Бухгалтерии предприятия на момент написания статьи есть несколько обработок, которые умеют загружать файлы xml.  Вот они:

1. ЗагрузкаДанныхИзЗиК (Синоним Загрузка из ЗиК 7.7)

2. ЗагрузкаДанныхИзЗУП (Синоним Загрузка из ЗУП ред. 2.5)

3. ЗагрузкаДанныхИзОП (Синоним Загрузка из 1С: Отчетность предпринимателя 2.0)

4. ЗагрузкаДанныхИзТиС (Синоним Загрузка из ТиС 7.7)

Не смотря на то, что все эти обработки делают примерно одно и то же, у них различаются обработчики, которые запускаются ПОСЛЕ загрузки, а также проверки, которые запускаются ДО загрузки. Ниже рассмотрим все 4 обработки более подробно

1. Загрузка из ЗиК 7.7

Кто не помнит — была такая конфигурация на платформе версии 7.7 — Зарплата и Кадры. Собственно, она до сих пор поддерживается, ради чего и была сделана эта обработка

Смотрим в модуль менеджера обработки:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

Процедура ЗагрузитьДанныеВИБ(ПараметрыВыгрузки, АдресХранилища) Экспорт
	
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
	ДвоичныеДанныеФайла = ПараметрыВыгрузки.ДвоичныеДанныеФайла;
	ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
	
	ФайлОбмена = Новый ЧтениеXML();
	ФайлОбмена.ОткрытьФайл(ИмяВременногоФайла);
	
	Попытка
		ФайлОбмена.Прочитать();		
	Исключение
		ТекстСообщения = НСтр("ru = 'Загрузка из файлов данного типа не поддерживается.'");		
		ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
		Возврат;
	КонецПопытки;

	ИНН = СокрЛП(Строка(ФайлОбмена.ПолучитьАтрибут("ИНН")));
	КПП = СокрЛП(Строка(ФайлОбмена.ПолучитьАтрибут("КПП")));
	Если НЕ ЗначениеЗаполнено(ИНН) И НЕ ЗначениеЗаполнено(КПП) Тогда
		ТекстСообщения = НСтр("ru = 'При загрузке данных произошла ошибка: файл не содержит сведений об организации.'");
		ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
		Возврат;
	Иначе
		Запрос = Новый Запрос;
		Запрос.Текст = "ВЫБРАТЬ
		               |	Организации.Ссылка
		               |ИЗ
		               |	Справочник.Организации КАК Организации
		               |ГДЕ
		               |	Организации.ИНН = &ИНН
		               |	И Организации.КПП = &КПП";
		Запрос.УстановитьПараметр("ИНН", ИНН);
		Запрос.УстановитьПараметр("КПП", КПП);
		Выборка = Запрос.Выполнить().Выбрать();
		Если Выборка.Количество() = 0 Тогда
			ТекстСообщения = НСтр("ru = 'При загрузке данных произошла ошибка: не найдена организация, для которой производится загрузка.'");
			ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	ОбработкаОбмена = Обработки.УниверсальныйОбменДаннымиXML.Создать();
	ОбработкаОбмена.РежимОбмена = "Загрузка";
	ОбработкаОбмена.ИмяФайлаОбмена = ИмяВременногоФайла;
	ОбработкаОбмена.РежимОтладкиАлгоритмов = 3;
	ОбработкаОбмена.ФлагРежимОтладкиОбработчиков = Истина;
	ОбработкаОбмена.ФлагРежимОтладки = Истина;
	ОбработкаОбмена.ИмяФайлаВнешнейОбработкиОбработчиковСобытий = "ОбработчикиЗагрузкиИзЗиК";
		
	ОбработкаОбмена.ВыполнитьЗагрузку();
		
	Если ОбработкаОбмена.ФлагОшибки Тогда		
		ТекстСообщения = НСтр("ru = 'При загрузке данных произошла ошибка.'");		
	Иначе		
		ТекстСообщения =  "";
	КонецЕсли;
		
	ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
	
КонецПроцедуры

#КонецЕсли

Видим, что 

1) перед загрузкой проверяется наличие атрибутов ИНН и КПП в файле, а также наличие необходимой организации в базе по этим параметрам

2) устанавливается обработка с обработчиками загрузки, а именно "ОбработчикиЗагрузкиИзЗиК"

Смотрим модуль обработки ОбработчикиЗагрузкиИзЗиК (ниже приведен не весь модуль, а только часть, относящаяся к обработке после загрузки):

////////////////////////////////////////////////////////////////////////////////
// ОБРАБОТЧИКИ КОНВЕРТАЦИИ ОБЪЕКТОВ

Процедура ПКО_ПослеЗагрузки_ОтражениеЗарплатыВУчете(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта, ОбъектМодифицирован, 
                                           ИмяТипаОбъекта, ОбъектНайден, НаборЗаписей) Экспорт

	Объект.Ответственный = Пользователи.ТекущийПользователь();

КонецПроцедуры

Процедура ПКО_ПослеЗагрузки_СтатьиЗатрат(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта, ОбъектМодифицирован, 
                                           ИмяТипаОбъекта, ОбъектНайден, НаборЗаписей) Экспорт

	Если Не ОбъектНайден Тогда
		Объект.Записать();
		УчетЗарплаты.ЗаполнитьНедостающиеРеквизитыЗагруженныхОбъектов(Объект) 
	КонецЕсли;

КонецПроцедуры

Процедура ПКО_ПоследовательностьПолейПоиска_ФизическиеЛица(НомерВариантаПоиска, СвойстваПоиска, ПараметрыОбъекта, ПрекратитьПоиск, 
                                           СсылкаНаОбъект, УстанавливатьУОбъектаВсеСвойстваПоиска, 
                                           СтрокаИменСвойствПоиска) Экспорт

	Если СвойстваПоиска["ЭтоГруппа"] = Истина Тогда
		СтрокаИменСвойствПоиска = "ЭтоГруппа, Наименование";
	Иначе
		СтрокаИменСвойствПоиска = "ЭтоГруппа, Наименование, ДатаРождения";
	КонецЕсли;

КонецПроцедуры

Процедура ПКО_ПослеЗагрузки_ПрочиеДоходыИРасходы(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта, ОбъектМодифицирован, 
                                           ИмяТипаОбъекта, ОбъектНайден, НаборЗаписей) Экспорт

	Если Не ОбъектНайден Тогда
		Объект.Записать();
		УчетЗарплаты.ЗаполнитьНедостающиеРеквизитыЗагруженныхОбъектов(Объект) 
	КонецЕсли;

КонецПроцедуры

Процедура ПКО_ПослеЗагрузки_Контрагенты(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта, ОбъектМодифицирован, 
                                           ИмяТипаОбъекта, ОбъектНайден, НаборЗаписей) Экспорт

	Если Не ОбъектНайден Тогда
		Объект.Записать();
		Объект.ГоловнойКонтрагент = Объект.Ссылка; 
		Объект.Записать();
	КонецЕсли;

КонецПроцедуры

Т.е. выполняется минимальное изменение объектов. Наверное, если бы не проверка на атрибуты ИНН и КПП, можно было бы и эту обработку использовать для загрузки данных

2. Загрузка из ЗУП ред. 2.5

Смотрим модуль менеджера обработки:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

Процедура ЗагрузитьДанныеВИБ(ПараметрыВыгрузки, АдресХранилища) Экспорт
	
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
	ДвоичныеДанныеФайла = ПараметрыВыгрузки.ДвоичныеДанныеФайла;
	ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
	
	ТекстДок = Новый ТекстовыйДокумент;
	
	Попытка
		ТекстДок.Прочитать(ИмяВременногоФайла, КодировкаТекста.UTF8);
	Исключение
		ТекстСообщения = НСтр("ru = 'Загрузка из файлов данного типа не поддерживается.'");		
		ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
		Возврат;
	КонецПопытки;
	
	СодержимоеДок = ТекстДок.ПолучитьТекст();
	
	ТекстСообщения = "";
	Если СтрНайти(СодержимоеДок, "БухгалтерияПредприятия 3.0") = 0 
		И СтрНайти(СодержимоеДок, "БухгалтерияПредприятияКОРП 3.0") = 0 Тогда
		ТекстСообщения = НСтр("ru = 'При загрузке данных произошла ошибка.'");
		ТекстСообщения = ТекстСообщения + Символы.ПС + НСтр("ru = 'Данные не предназначенны для 1С:Бухгалтерии 8 ред. 3.0.'");
	КонецЕсли;
	
	Если ТекстСообщения <> "" Тогда
		Если СтрНайти(СодержимоеДок, "ЗарплатаИУправлениеПерсоналом") <> 0 Тогда
			ТекстСообщения = ТекстСообщения + Символы.ПС + НСтр("ru = 'Исправьте программу бухучета в настройках выгрузки в ЗУП, ред. 2.5.'");
			
		КонецЕсли;
		ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
		Возврат;
	КонецЕсли;
	
	СодержимоеДок = СтрЗаменить(СодержимоеДок, "ДокументСсылка.ЗарплатаКВыплатеОрганизаций","ДокументСсылка.ВедомостьНаВыплатуЗарплаты");
	СодержимоеДок = СтрЗаменить(СодержимоеДок, "ПеречислениеСсылка.СпособыВыплатыЗарплаты","ПеречислениеСсылка.ВидыМестВыплатыЗарплаты");
	СодержимоеДок = СтрЗаменить(СодержимоеДок, "СпособВыплаты","ВидМестаВыплаты");
	СодержимоеДок = СтрЗаменить(СодержимоеДок, "ЧерезКассу","Касса");
	СодержимоеДок = СтрЗаменить(СодержимоеДок, "ЧерезБанк","ЗарплатныйПроект");
	СодержимоеДок = СтрЗаменить(СодержимоеДок, "ДнейНеВыплаты","УдалитьДнейНеВыплаты");
	
	ТекстДок.УстановитьТекст(СодержимоеДок);
	ТекстДок.Записать(ИмяВременногоФайла, КодировкаТекста.UTF8);
	
	ОбработкаОбмена = Обработки.УниверсальныйОбменДаннымиXML.Создать();
	ОбработкаОбмена.РежимОбмена = "Загрузка";
	ОбработкаОбмена.ИмяФайлаОбмена = ИмяВременногоФайла;
	ОбработкаОбмена.РежимОтладкиАлгоритмов = 3;
	ОбработкаОбмена.ФлагРежимОтладкиОбработчиков = Истина;
	ОбработкаОбмена.ФлагРежимОтладки = Истина;
	ОбработкаОбмена.ИмяФайлаВнешнейОбработкиОбработчиковСобытий = "ОбработчикиЗагрузкиИзЗУП25";
	
	ОбработкаОбмена.ВыполнитьЗагрузку();
	УдалитьФайлы(ИмяВременногоФайла);
	
	Если ОбработкаОбмена.ФлагОшибки Тогда		
		ТекстСообщения = НСтр("ru = 'При загрузке данных произошла ошибка.'");
	Иначе		
		ТекстСообщения =  НСтр("ru = 'Загрузка данных завершена.'");
	КонецЕсли;
	
	
	ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
	
КонецПроцедуры

#КонецЕсли

Тут тоже:

1) Перед началом загрузки есть проверка на то, из какой и в какую конфигурацию идет загрузка (а именно из "ЗарплатаИУправлениеПерсоналом"), что уже ограничивает область ее применения.

2) Указана обработка с обработчиками "ОбработчикиЗагрузкиИзЗУП25". 

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

	Отказ = НЕ Параметры.ОрганизацияСуществует;

Еще для некоторых — устанавливается комментарий и ответственный:

	Объект.Комментарий = СОКРЛП(Объект.Комментарий) + ?(ПустаяСтрока(Объект.Комментарий),""," \ ") + "Перенесено из ЗУП";
	Объект.Ответственный = Пользователи.ТекущийПользователь();

И еще для некоторых устанавливаются необходимые реквизиты (целью настоящей статьи не является полный анализ всех событий, так что не будем вдаваться в подробности)

Таким образом, эту обработку тоже не получится использовать именно для загрузки ПРОИЗВОЛЬНОГО файла

3. Загрузка из 1С: Отчетность предпринимателя 2.0

Смотрим в модуль менеджера обработки:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область СлужебныйПрограммныйИнтерфейс

&НаСервере
Функция ВыполнитьЗагрузкуДанныхВФоне(Параметры, АдресРезультата) Экспорт
	
	ИмяФайлаДанных = ПолучитьИмяВременногоФайла("xml");
	ДвоичныеДанныеФайла = Параметры.ДвоичныеДанныеФайла;
	ДвоичныеДанныеФайла.Записать(ИмяФайлаДанных);
	
	ОбработкаОбмена = Обработки.УниверсальныйОбменДаннымиXML.Создать();
	ОбработкаОбмена.РежимОбмена = "Загрузка";
	ОбработкаОбмена.ИмяФайлаОбмена = ИмяФайлаДанных;
	
	ОбработкаОбмена.ВыполнитьЗагрузку();
	
	Если ОбработкаОбмена.ФлагОшибки Тогда		
		ТекстСообщения = НСтр("ru = 'При загрузке данных произошла ошибка.'");
	Иначе		
		ТекстСообщения =  НСтр("ru = 'Загрузка данных завершена.'");
	КонецЕсли;
	
	ПоместитьВоВременноеХранилище(ТекстСообщения, АдресРезультата);
	
	УдалитьФайлы(ИмяФайлаДанных);
	
КонецФункции

#КонецОбласти

#КонецЕсли

Какой замечательный и лаконичный текст! Ничего лишнего. Просто ВыполнитьЗагрузку(). Именно поэтому я рекомендую эту обработку к использованию

4. Загрузка из ТиС 7.7

ТиС — Торговля и Склад. Тоже легендарная конфигурация на платформе версии 7.7, которую до сих пор используют многие клиенты

На самом деле тоже интересный вариант — именно для загрузки торговых документов, так как после их загрузки выполняются обработки по корректному заполнению зависимых реквизитов (будет показано ниже). Для того, чтобы ей воспользоваться, надо включить функциональную опцию — Загрузка данных из конфигурации Торговля и Склад 7.7: Раздел Администрирование, Функциональность, закладка Торговля

Смотрим в модуль менеджера обработки:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

Процедура ЗагрузитьДанныеВИБ(ПараметрыВыгрузки, АдресХранилища) Экспорт
	
	СписокОшибок = Новый СписокЗначений;
	
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
	ДвоичныеДанныеФайла = ПараметрыВыгрузки.ДвоичныеДанныеФайла;
	ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
	
	ФайлОбмена = Новый ЧтениеXML();
	ФайлОбмена.ОткрытьФайл(ИмяВременногоФайла);
	
	Попытка
		ФайлОбмена.Прочитать();		
	Исключение
		ТекстСообщения = НСтр("ru = 'Загрузка из файлов данного типа не поддерживается.'");		
		ПоместитьВоВременноеХранилище(ТекстСообщения, АдресХранилища);
		Возврат;
	КонецПопытки;
		
	ОбработкаОбмена = Обработки.УниверсальныйОбменДаннымиXML.Создать();
	ОбработкаОбмена.РежимОбмена = "Загрузка";
	ОбработкаОбмена.ИмяФайлаОбмена = ИмяВременногоФайла;
	ОбработкаОбмена.РежимОтладкиАлгоритмов = 3;
	ОбработкаОбмена.ФлагРежимОтладкиОбработчиков = Истина;
	ОбработкаОбмена.ФлагРежимОтладки = Истина;
	ОбработкаОбмена.ИмяФайлаВнешнейОбработкиОбработчиковСобытий = "ОбработчикиЗагрузкиИзТиС";
	ОбработкаОбмена.ИмяФайлаПротоколаОбмена = ПолучитьИмяВременногоФайла("txt");
	
	ОбработкаОбмена.ВыполнитьЗагрузку();
	
  // (окончание процедуры опущено за низкой информативностью)

Видим, что никаких проверок перед загрузкой не происходит. Однако, обработчик событий указан, это обработка "ОбработчикиЗагрузкиИзТиС"

Если заглянуть в нее, то можно увидеть, что там находится просто очень большое количество кода, которое корректирует документы после загрузки. Приведу пример для документа РеализацияТоваровУслуг:

Процедура ПКО_ПослеЗагрузки_РеализацияТоваровУслуг(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта, ОбъектМодифицирован, 
                                           ИмяТипаОбъекта, ОбъектНайден, НаборЗаписей) Экспорт
			   
	ЭтоКомиссия = Ложь;
	Если ЗначениеЗаполнено(Объект.ДоговорКонтрагента) Тогда
		Если Объект.ДоговорКонтрагента.ВидДоговора  = Перечисления.ВидыДоговоровКонтрагентов.СКомиссионером Тогда
			ЭтоКомиссия = Истина;
		КонецЕсли;
	КонецЕсли;	
	
	Отбор = Новый Структура;
	Отбор.Вставить("НеЗаполненныеРеквизиты", Истина);
	
	СчетаУчетаВДокументах.Заполнить(Объект, Отбор);
	
	КомиссияПоСтрокамТабличнойЧасти = Параметры.КомиссияПоСтрокамТабличнойЧасти[Ссылка];
	
	Если КомиссияПоСтрокамТабличнойЧасти<> Неопределено Тогда
		Для каждого Значение из КомиссияПоСтрокамТабличнойЧасти Цикл
			СтрокаТЧ = Объект.Товары.Получить(Значение.Ключ - 1);
			СчетаУчета = БухгалтерскийУчетПереопределяемый.ПолучитьСчетаУчетаНоменклатуры(Объект.Организация, СтрокаТЧ.Номенклатура);
			Если Значение.Значение Тогда
				Если ЗначениеЗаполнено(СчетаУчета.СчетУчета) Тогда
					СтрокаТЧ.СчетУчета = СчетаУчета.СчетУчета;
				КонецЕсли;
			
				Если ЗначениеЗаполнено(СчетаУчета.СчетПередачи) Тогда
					СтрокаТЧ.ПереданныеСчетУчета = СчетаУчета.СчетПередачи;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
		
	КонецЕсли;
	
	СчетаУчета = БухгалтерскийУчетПереопределяемый.ПолучитьСчетаРасчетовСКонтрагентом(Объект.Организация, Объект.Контрагент, Объект.ДоговорКонтрагента);
	Если Объект.ДоговорКонтрагента.ВидДоговора = Перечисления.ВидыДоговоровКонтрагентов.СКомиссионером Тогда
		Объект.СчетУчетаРасчетовСКонтрагентом = ПланыСчетов.Хозрасчетный.ПустаяСсылка();
		Объект.СчетУчетаРасчетовПоАвансам     = ПланыСчетов.Хозрасчетный.ПустаяСсылка();
		Объект.СчетУчетаРасчетовПоТаре        = ПланыСчетов.Хозрасчетный.ПустаяСсылка();
	Иначе
		Объект.СчетУчетаРасчетовСКонтрагентом = СчетаУчета.СчетРасчетовПокупателя;
		Объект.СчетУчетаРасчетовПоАвансам     = СчетаУчета.СчетАвансовПокупателя;
		Объект.СчетУчетаРасчетовПоТаре        = СчетаУчета.СчетУчетаТарыПокупателя;
	КонецЕсли;
	Объект.СчетУчетаРасчетовПоТаре        = СчетаУчета.СчетУчетаТарыПокупателя;
	
	Для каждого СтрокаТоваров Из Объект.Товары Цикл
		СтрокаТоваров.Количество = СтрокаТоваров.Количество * СтрокаТоваров.Коэффициент;
		Если СтрокаТоваров.Коэффициент<> 0 Тогда 
			СтрокаТоваров.Цена       = СтрокаТоваров.Цена / СтрокаТоваров.Коэффициент;
		КонецЕсли;
	КонецЦикла;
		
	Объект.СуммаДокумента = УчетНДСПереопределяемый.ПолучитьСуммуДокументаСНДС(Объект, "Товары") + УчетНДСПереопределяемый.ПолучитьСуммуДокументаСНДС(Объект, "Услуги");
	Объект.СпособЗачетаАвансов = Перечисления.СпособыЗачетаАвансов.Автоматически;

	Если Объект.Ответственный.Пустая() Тогда
		Объект.Ответственный = Пользователи.ТекущийПользователь();
	КонецЕсли;

КонецПроцедуры

Если вникнуть, то можно увидеть, что тут:

1) Заполняются счета учета в шапке документа

2) Заполняются счета учета в табличной части

3) Идет пересчет колонки Цена и Суммы документа

4) Устанавливается Способ зачета авансов

5) Устанавливается Ответственный

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

		Если СтрокаТоваров.Коэффициент<> 0 Тогда 
			СтрокаТоваров.Цена       = СтрокаТоваров.Цена / СтрокаТоваров.Коэффициент;
		КонецЕсли;

Поэтому я вернулся обратно к обработке с загрузкой из Отчетности предпринимателя. Но для загрузки торговых документов рекомендую попробовать сначала эту обработку.

Надеюсь, что настоящая статья помогла немого разобраться с тем, как в бухгалтерии можно делать загрузку из файлов xml, сделанных для универсально обмена с помощью правил обмена написанных на Конвертации данных версии 2.

has been added to your cart:
Оформление заказа