Передача строк табличной части как набора документов с использованием формата EnterpriseData

23.06.25

Интеграция - Перенос данных 1C

Хотел бы поделиться решением технически сложной задачи при разработке обмена с использованием формата Enterprise Data. Суть задачи в следующем. В базе Источнике есть документ, который при передаче данных в базу Получатель должен формировать документы по каждой строке табличной части Источника. При этом должна быть обеспечена ссылочная связанность объектов в базах: корректировка документа в Источнике (например, удаление строки ТЧ) должна вызывать корректное изменение в Получателе (лишние документы должны быть удалены).

Постановка задачи

Суть задачи в следующем. В базе Источнике есть документ, который при передаче данных в базу Получатель должен формировать документы по каждой строке табличной части Источника.

При этом должна быть обеспечена ссылочная связанность объектов в базах: корректировка документа в Источнике (например, удаление строки ТЧ) должна вызывать корректное изменение в Получателе (лишние документы должны быть удалены).

Для конкретности, опишу задачу целиком.

База Источник-ЕРП 2.5 (кратко, ЕРП)

База Получатель-Бухгалтерия предприятия (кратко, БП - бухгалтерия одной из стран СНГ).

В Источнике есть документ «Производство без Заказа», в документе есть ТЧ Продукция и ТЧ Материалы. Каждая строка ТЧ Материалы связана с ТЧ Продукция через реквизит-ключ Номер строки затрат.

В БП есть документ Отчет производства за смену, который содержит ТЧ продукция, но не содержит ТЧ Материалы. Есть также документ Требование-накладная, который содержит ТЧ Материалы, а также в Шапке содержит Продукцию, на которую пошли материалы.

Для корректного отражения «Производства без заказа» в бухгалтерской программе был выбран вариант разбиения документа на строки. Строка ТЧ Продукции формирует в БП документ Отчет продукции за смену, а также документ «Требование накладная» с выборкой строк «Материалы», которые относятся к выбранной строке Продукции

 

 

Исходный документ

 

 

Документы в БП

 

 

Решение

Поскольку строка документа 1С не является самостоятельной сущностью, создать документ из строки документа можно при наличии идентификатора строки ТЧ. Этот идентификатор может храниться как в сторонней таблице, так и непосредственно в ТЧ. В нашем случае этот идентификатор присутствовал и в ТЧ Продукция и в ТЧ Материалы. (к счастью, 1С в новых конфигурациях добавила реквизит Идентификатор строки почти во все табличные части документов).

Второй момент, дилемма: в какой момент преобразовывать объект XDTO, на этапе формирования исходящего пакета или при обработке входящего сообщения в БП.

Вначале мне казалось, что на стороне приемника это сделать проще и надежнее. Однако, после анализа кода на стороне Приемника, я не нашел простого решения, как вклиниться в код, чтобы разбить один объект XDTO на массив нужных нам объектов.

А вот разбить один объект на массив объектов стороне Источника оказалось несложно.

  1. Устанавливаем возможность дополнительной обработки для наших правил конвертации объектов.

 

&ИзменениеИКонтроль("КоллекцияПравилКонвертации")
Функция БПро_КоллекцияПравилКонвертации(ВерсияФорматаМенеджераОбмена)

	// Инициализация таблицы правил конвертации.
	ПравилаКонвертации = Новый ТаблицаЗначений;
	ПравилаКонвертации.Колонки.Добавить("ИмяПКО", Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("ОбъектДанных");
	ПравилаКонвертации.Колонки.Добавить("ОбъектФормата",                         Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("ТипПолученныхДанныхСтрокой",            Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(300)));
	ПравилаКонвертации.Колонки.Добавить("ИмяТаблицыПолученныхДанных",            Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(300)));
	ПравилаКонвертации.Колонки.Добавить("ПредставлениеТипаПолученныхДанных",     Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(300)));
	ПравилаКонвертации.Колонки.Добавить("Свойства",                              Новый ОписаниеТипов("ТаблицаЗначений"));
	ПравилаКонвертации.Колонки.Добавить("ПоляПоиска",                            Новый ОписаниеТипов("Массив"));
	ПравилаКонвертации.Колонки.Добавить("ПоляПредставленияОбъекта",              Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(300)));
	ПравилаКонвертации.Колонки.Добавить("РеквизитыШапкиПолученныхДанных",        Новый ОписаниеТипов("Массив"));
	ПравилаКонвертации.Колонки.Добавить("ПриОтправкеДанных",                     Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("ПриКонвертацииДанныхXDTO",              Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("ПередЗаписьюПолученныхДанных",          Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("ПослеЗагрузкиВсехДанных",               Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("ПравилоДляГруппыСправочника",           Новый ОписаниеТипов("Булево"));
	ПравилаКонвертации.Колонки.Добавить("ВариантИдентификации",                  Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(60)));
	ПравилаКонвертации.Колонки.Добавить("АлгоритмПоиска",                        Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("Расширения",                            Новый ОписаниеТипов("Соответствие"));
	ПравилаКонвертации.Колонки.Добавить("ПространствоИмен",                      Новый ОписаниеТипов("Строка"));
	ПравилаКонвертации.Колонки.Добавить("РазрешитьСоздаватьОбъектИзСтруктуры");

	Если ВерсияФорматаМенеджераОбмена = "1" Тогда
		ОписаниеТиповСвойстваТЧ = Новый ОписаниеТипов("Структура");
		ПравилаКонвертации.Колонки.Добавить("СвойстваТабличныхЧастейОбработанные", Новый ОписаниеТипов("ТаблицаЗначений"));
	Иначе
		ОписаниеТиповСвойстваТЧ = Новый ОписаниеТипов("ТаблицаЗначений");
	КонецЕсли;
	ПравилаКонвертации.Колонки.Добавить("СвойстваТабличныхЧастей", ОписаниеТиповСвойстваТЧ);
 	#Вставка
	ПравилаКонвертации.Колонки.Добавить("БПро_СпецОбработка",  Новый ОписаниеТипов("Булево"));
	#КонецВставки

	Возврат ПравилаКонвертации;

КонецФункции

 

  1. В модуле МенеджерОбменаЧерезУниверсальныйФормат формируем для одного объекта ЕРП два правила конвертации объекта и устанавливаем признак необходимости вызова дополнительного метода (ПравилоКонвертации.БПро_СпецОбработка = Истина) при обработке объекта XDTO также в сами правила: ДобавитьПКО_Документ_ПроизводствоБезЗаказа_Отправка и БПро_Добавить_ПКО_Документ_ПроизводствоБезЗаказаВТребованиеНакладная_Отправка

    1. Производство без заказа в Отчет производства за смену

    2. Производство без заказа в Требование-накладную

&ИзменениеИКонтроль("ДобавитьПКО_Документ_ПроизводствоБезЗаказа_Отправка")
Процедура БПро_ДобавитьПКО_Документ_ПроизводствоБезЗаказа_Отправка(ПравилаКонвертации)

	ПравилоКонвертации = ОбменДаннымиXDTOСервер.ИнициализироватьПравилоКонвертацииОбъекта(ПравилаКонвертации);
	ПравилоКонвертации.ИмяПКО            = "Документ_ПроизводствоБезЗаказа_Отправка";
	ПравилоКонвертации.ОбъектДанных      = Метаданные.Документы.ПроизводствоБезЗаказа;
	ПравилоКонвертации.ПриОтправкеДанных = "ПКО_Документ_ПроизводствоБезЗаказа_Отправка_ПриОтправкеДанных";
	ПравилоКонвертации.ОбъектФормата     = "Документ.ВыпускПродукции"; //@NON-NLS-1  
	#Вставка
	ПравилоКонвертации.БПро_СпецОбработка =  Истина; 
	#КонецВставки
***********
Процедура БПро_Добавить_ПКО_Документ_ПроизводствоБезЗаказаВТребованиеНакладная_Отправка(ПравилаКонвертации)
	
	ПравилоКонвертации = ОбменДаннымиXDTOСервер.ИнициализироватьПравилоКонвертацииОбъекта(ПравилаКонвертации);
	ПравилоКонвертации.ИмяПКО            = "БПро_ПКО_Документ_ПроизводствоБезЗаказаВТребованиеНакладная_Отправка";
	ПравилоКонвертации.ОбъектДанных      = Метаданные.Документы.ПроизводствоБезЗаказа;
	ПравилоКонвертации.ПриОтправкеДанных = "БПро_ПКО_Документ_ПередачаМатериаловВПроизводство_Отправка_ПриОтправкеДанных";
	ПравилоКонвертации.ОбъектФормата     = "Документ.ПередачаМатериаловВПроизводство"; //@NON-NLS-1
	ПравилоКонвертации.БПро_СпецОбработка =  Истина; 
	
**********
  1. В процедуре ВыгрузкаОбъектаВыборки добавляем вставку вызова метода дополнительной обработки структуры XDTO

&ИзменениеИКонтроль("ВыгрузкаОбъектаВыборки")
Процедура БПро_ВыгрузкаОбъектаВыборки(КомпонентыОбмена, Объект, ПравилоОбработки)

	ОбъектСсылочногоТипа = (ТипЗнч(Объект) <> Тип("Структура"))
	И ОбщегоНазначения.ЭтоОбъектСсылочногоТипа(Объект.Метаданные());

	Если (ТипЗнч(Объект) <> Тип("Структура"))
		И ПравилоОбработки = Неопределено Тогда
		ПолучитьПравилоОбработкиДляОбъекта(КомпонентыОбмена, Объект, ПравилоОбработки);
	КонецЕсли;

	КомпонентыОбмена.ВыгруженныеОбъекты.Добавить(?(ОбъектСсылочногоТипа, Объект.Ссылка, Объект));

	// Отработка ПОД
	ИспользованиеПКО = Новый Структура;
	Для Каждого ТекущееПКО Из ПравилоОбработки.ИспользуемыеПКО Цикл
		ИспользованиеПКО.Вставить(ТекущееПКО, Истина);
	КонецЦикла;

	ПрерватьОбработку = Ложь;
	ВзвестиФлагОшибки = Ложь;

	ПриОбработкеПОД(
	КомпонентыОбмена,
	ПравилоОбработки,
	Объект,
	ИспользованиеПКО,
	ПрерватьОбработку);

	Если ПрерватьОбработку Тогда
		ВзвестиФлагОшибки = Истина;
	КонецЕсли;

	Если Не ПрерватьОбработку Тогда
		// Отработка ПКО
		НесколькоПКО = (ИспользованиеПКО.Количество() > 1);
		ЕстьКолонкаОчисткаДанных = КомпонентыОбмена.ПравилаОбработкиДанных.Колонки.Найти("ОчисткаДанных") <> Неопределено;

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

			Если Не ОбъектФорматаПроходитПоФильтруXDTO(КомпонентыОбмена, ПравилоКонвертации.ОбъектФормата) Тогда
				Продолжить;
			КонецЕсли;

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

			ПропуститьОбработку = Ложь;
			Попытка
				// 2. Конвертируем Данные в Структуру по правилам конвертации.
				ВремяНачала = ОбменДаннымиОценкаПроизводительности.НачатьЗамер();

				ДанныеXDTO = ДанныеXDTOИзДанныхИБ(КомпонентыОбмена, Объект, ПравилоКонвертации, Неопределено);  
				#Вставка
				Если ПравилоКонвертации.БПро_СпецОбработка Тогда
					
					МенеджерОбменаЧерезУниверсальныйФормат.AdditionalInfoВставить(ДанныеXDTO, "ЭтоКорневойДокумент", Истина);
					МенеджерОбменаЧерезУниверсальныйФормат.AdditionalInfoВставить(ДанныеXDTO, "КорневойДокумент", XMLСтрока(Объект.Ссылка));
					БПро_ВыгрузкаДопОбъектаВыборки(КомпонентыОбмена, ПравилоКонвертации, ПравилоОбработки, ДанныеXDTO, Объект,  ПрерватьОбработку, ВзвестиФлагОшибки);
				
					МассивДанныеXDTO = БПро_СпецОбработка(ДанныеXDTO, Объект, ПравилоКонвертации.ИмяПКО);
					Сч = 0;
					Для каждого ДанныеXDTO Из МассивДанныеXDTO Цикл
						Сч = Сч + 1;
						МенеджерОбменаЧерезУниверсальныйФормат.AdditionalInfoВставить(ДанныеXDTO, "ЭтоКорневойДокумент", Ложь);
					    Если Сч < МассивДанныеXDTO.Количество() Тогда
						    БПро_ВыгрузкаДопОбъектаВыборки(КомпонентыОбмена, ПравилоКонвертации, ПравилоОбработки, ДанныеXDTO, Объект,  ПрерватьОбработку, ВзвестиФлагОшибки);
						КонецЕсли;
					    Если ПрерватьОбработку или ВзвестиФлагОшибки Тогда
							Прервать;	
						КонецЕсли;
					КонецЦикла;
				КонецЕсли;
				#КонецВставки

				Событие = "ДанныеXDTOИзДанныхИБ." + ПравилоКонвертации.ИмяПКО;
				ОбменДаннымиОценкаПроизводительности.ЗавершитьЗамер(
				ВремяНачала, Событие, Объект, КомпонентыОбмена,
				ОбменДаннымиОценкаПроизводительности.ТипСобытияБиблиотека());

				Если ДанныеXDTO = Неопределено Тогда
					Продолжить;
				КонецЕсли;

				// 3. Конвертируем Структуру в ОбъектXDTO.
				ВремяНачала = ОбменДаннымиОценкаПроизводительности.НачатьЗамер();

				СсылкиИзОбъекта = Новый Массив;
				ОбъектXDTO = ОбъектXDTOИзДанныхXDTO(КомпонентыОбмена, ДанныеXDTO, ПравилоКонвертации.ТипXDTO, СсылкиИзОбъекта, , ПравилоКонвертации.Расширения);

				Событие = "ОбъектXDTOИзДанныхXDTO." + ПравилоКонвертации.ИмяПКО;
				ОбменДаннымиОценкаПроизводительности.ЗавершитьЗамер(
				ВремяНачала, Событие, Объект, КомпонентыОбмена, 
				ОбменДаннымиОценкаПроизводительности.ТипСобытияБиблиотека());

			Исключение
				ПропуститьОбработку = Истина;
				ВзвестиФлагОшибки   = Истина;

				ОписаниеОшибки = ОписаниеОшибкиПКО(
				КомпонентыОбмена.НаправлениеОбмена,
				ПравилоОбработки.Имя,
				ПравилоКонвертации.ИмяПКО,
				ПредставлениеОбъектаДляПротокола(Объект, ПравилоКонвертации.ОбъектДанных),
				ИнформацияОбОшибке());

				ЗафиксироватьПроблемуПриОбработкеОбъекта(КомпонентыОбмена,
				Объект,
				Перечисления.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриОтправкеДанных,
				ОписаниеОшибки.ПодробноеПредставление,
				ОписаниеОшибки.КраткоеПредставление);
			КонецПопытки;

			Если Не ПропуститьОбработку Тогда
				ОшибкаПроверкиПоСхеме = Ложь;
				ОписаниеОшибкиПроверкиПоСхеме = Неопределено;

				Контекст = Новый Структура;
				Контекст.Вставить("НаправлениеОбмена",    КомпонентыОбмена.НаправлениеОбмена);
				Контекст.Вставить("ИмяПОД",               ПравилоОбработки.Имя);
				Контекст.Вставить("ИмяПКО",               ПравилоКонвертации.ИмяПКО);
				Контекст.Вставить("ПредставлениеОбъекта", ПредставлениеОбъектаДляПротокола(Объект, ПравилоКонвертации.ОбъектДанных));

				ПроверитьОбъектXDTOПоСхеме(ОбъектXDTO, ПравилоКонвертации.ТипXDTO, Контекст, ОшибкаПроверкиПоСхеме, ОписаниеОшибкиПроверкиПоСхеме);

				Если ОшибкаПроверкиПоСхеме Тогда
					ПропуститьОбработку = Истина;

					ЗафиксироватьПроблемуПриОбработкеОбъекта(КомпонентыОбмена,
					Объект,
					Перечисления.ТипыПроблемОбменаДанными.ОшибкаПроверкиСконвертированногоОбъекта,
					ОписаниеОшибкиПроверкиПоСхеме.ПодробноеПредставление,
					ОписаниеОшибкиПроверкиПоСхеме.КраткоеПредставление);
				КонецЕсли;
			КонецЕсли;

			Если ПропуститьОбработку Тогда
				ПрерватьОбработку = Истина;
				Продолжить;
			КонецЕсли;

			ВыгрузитьОбъектыПоСсылке(КомпонентыОбмена, СсылкиИзОбъекта);

			// 4. Записываем ОбъектXDTO в XML-файл.
			ФабрикаXDTO.ЗаписатьXML(КомпонентыОбмена.ФайлОбмена, ОбъектXDTO);
		КонецЦикла;
	КонецЕсли;

	Если ПрерватьОбработку Тогда
		КомпонентыОбмена.НеВыгруженныеОбъекты.Добавить(?(ОбъектСсылочногоТипа, Объект.Ссылка, Объект));
	КонецЕсли;

	Если ВзвестиФлагОшибки Тогда
		КомпонентыОбмена.ФлагОшибки = Истина;
		КомпонентыОбмена.СостояниеОбменаДанными.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
	КонецЕсли;

КонецПроцедуры
  1. Добавляем в AdditionalInfo информацию: корневой ли это объект или преобразованный и ссылку на корневой документ (см скрин выше).

  2. Отправляем основной объект (он технический и проводиться на стороне БП не должен!). У него в доп свойствах указываем признак «Корневой» = Истина

  3. А также производим нужные нам преобразования объекта: из одного объекта XDTO получаем массив нужных нам «дочерних объектов» XDTO. При этом копируем исходную структуру и преобразуем ее: лишние строки удаляем, в ссылку записываем идентификаторы строк(!), делаем нужную нам нумерацию документов. На данном этапе нам доступны как данные XDTO, так и данные самого объекта Производство без заказа.


Функция БПро_СпецОбработка(ДанныеXDTO, Объект, ИмяПКО) 
	МассивДанныеXDTO = Новый Массив; 
	Если ИмяПКО = "Документ_ПроизводствоБезЗаказа_Отправка" Тогда 
		МассивДанныеXDTO = БПро_СпецОбработка_Документ_ПроизводствоБезЗаказа_Отправка(ДанныеXDTO, Объект, ИмяПКО);
	ИначеЕсли ИмяПКО = "БПро_ПКО_Документ_ПроизводствоБезЗаказаВТребованиеНакладная_Отправка" Тогда
		МассивДанныеXDTO = БПро_СпецОбработка_Документ_ПроизводствоБезЗаказаВТребованиеНакладная_Отправка(ДанныеXDTO, Объект, ИмяПКО);
	ИначеЕсли ИмяПКО = "Документ_ПересортицаВСборку" Тогда
		МассивДанныеXDTO = БПро_СпецОбработка_Документ_ПересортицаВСборку(ДанныеXDTO, Объект, ИмяПКО);
	КонецЕсли;   
	Возврат МассивДанныеXDTO;
КонецФункции

Функция БПро_СпецОбработка_Документ_ПроизводствоБезЗаказа_Отправка(ДанныеXDTO, Объект, ИмяПКО) 
	ГруппыЗатрат = Новый Соответствие;
	МассивДанныеXDTO = Новый Массив; 
	ЕстьПродукция = ДанныеXDTO.Свойство("Продукция"); 
	ЕстьМатериалы = ДанныеXDTO.Свойство("Материалы"); 
	Если ЕстьПродукция Тогда
		Счетчик = 0;
		Для каждого СтрокаПродукция Из ДанныеXDTO.Продукция Цикл
			Счетчик = Счетчик + 1;
			НовыеДанныеXDTO = ГруппыЗатрат.Получить(СтрокаПродукция.НомерСтрокиДокумента); 
			НомерСтрокиДокумента = СтрокаПродукция.НомерСтрокиДокумента;   
			Если НовыеДанныеXDTO = Неопределено Тогда
				НовыеДанныеXDTO = ОбщегоНазначения.СкопироватьРекурсивно(ДанныеXDTO);   
				НовыеДанныеXDTO.AdditionalInfo.ТоварыДопИнф = Новый Массив;
				НовыеДанныеXDTO.AdditionalInfo.Материалы = Новый Массив;
				Если ЕстьПродукция Тогда
					
					НовыеДанныеXDTO.Продукция.Очистить(); 
					
				КонецЕсли;
				Если ЕстьМатериалы Тогда
					
					НовыеДанныеXDTO.Материалы.Очистить();    
					
				КонецЕсли;
				НовыеДанныеXDTO.КлючевыеСвойства.Ссылка = XMLЗначение(Тип("ДокументСсылка.ПроизводствоБезЗаказа"), СтрокаПродукция.ИдентификаторСтроки);  
				НовыеДанныеXDTO.КлючевыеСвойства.Дата = ДатаПроизводствоБезЗаказа(ДанныеXDTO.КлючевыеСвойства.Дата, Ложь);  
				НовыеДанныеXDTO.КлючевыеСвойства.Номер = СтрШаблон("00%1.%2", Сред(НовыеДанныеXDTO.КлючевыеСвойства.Номер, 6), 
				Прав("00000000" + Формат(Счетчик,"ЧГ=0"), 2));
				
			КонецЕсли;	 
			
			НоваяСтрока = НовыеДанныеXDTO.Продукция.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаПродукция);
			Для каждого ЭлМасс Из ДанныеXDTO.AdditionalInfo.ТоварыДопИнф Цикл
				
				Если ЭлМасс.НомерГруппыЗатрат = НомерСтрокиДокумента Тогда
					НовыеДанныеXDTO.AdditionalInfo.ТоварыДопИнф.Добавить(ОбщегоНазначения.СкопироватьРекурсивно(ЭлМасс));
					Прервать;	
				КонецЕсли;	
				
			КонецЦикла;
			ГруппыЗатрат.Вставить(НомерСтрокиДокумента, НовыеДанныеXDTO);    
		КонецЦикла;
	КонецЕсли;
	
	Для каждого КиЗ Из ГруппыЗатрат Цикл
		
		МассивДанныеXDTO.Вставить(0, КиЗ.Значение);
		
	КонецЦикла; 
	
	Возврат МассивДанныеXDTO;
КонецФункции

Функция БПро_СпецОбработка_Документ_ПроизводствоБезЗаказаВТребованиеНакладная_Отправка(ДанныеXDTO, Объект, ИмяПКО) 
	ГруппыЗатрат = Новый Соответствие;
	МассивДанныеXDTO = Новый Массив; 
	ЕстьТовары = ДанныеXDTO.Свойство("Товары");  
	Если ЕстьТовары Тогда
		Счетчик = 0;
		Для каждого СтрокаТовары Из ДанныеXDTO.Товары Цикл  
			НомерСтрокиДокумента = СтрокаТовары.НомерСтрокиДокумента;
			НовыеДанныеXDTO = ГруппыЗатрат.Получить(НомерСтрокиДокумента);
			
			Если НовыеДанныеXDTO = Неопределено Тогда
				Счетчик = Счетчик + 1; 
				НовыеДанныеXDTO = ОбщегоНазначения.СкопироватьРекурсивно(ДанныеXDTO); 
				НовыеДанныеXDTO.AdditionalInfo.ТоварыДопИнф = Новый Массив;
				НовыеДанныеXDTO.AdditionalInfo.Материалы = Новый Массив;
				НовыеДанныеXDTO.Товары.Очистить();   
				
				Для каждого ЭлМасс Из ДанныеXDTO.AdditionalInfo.ТоварыДопИнф Цикл
					
					Если ЭлМасс.НомерГруппыЗатрат = НомерСтрокиДокумента Тогда  
						
						НовыеДанныеXDTO.КлючевыеСвойства.Ссылка = XMLЗначение(Тип("ДокументСсылка.ПроизводствоБезЗаказа"), ЭлМасс.ИдентификаторСтроки); 
						НовыеДанныеXDTO.КлючевыеСвойства.Дата = ДатаПроизводствоБезЗаказа(ДанныеXDTO.КлючевыеСвойства.Дата, Истина);  
						НовыеДанныеXDTO.КлючевыеСвойства.Номер = СтрШаблон("00%1.%2", Сред(НовыеДанныеXDTO.КлючевыеСвойства.Номер, 6), 
						Прав("00000000" + Формат(Счетчик,"ЧГ=0"), 2));
						НовыеДанныеXDTO.AdditionalInfo.Вставить("ПроизводствоБезЗаказа", 
						Новый Структура("Ссылка, НомерГруппыЗатрат, Номенклатура, СчетаГФУ",
						ЭлМасс.ИдентификаторСтроки, 
						НомерСтрокиДокумента, 
						ЭлМасс.Номенклатура,
						ЭлМасс.СчетаГФУ));
						Прервать;
					КонецЕсли;
					
				КонецЦикла;
				
			КонецЕсли;	
			
			Для каждого ЭлМасс Из ДанныеXDTO.AdditionalInfo.Материалы Цикл
				
				Если ЭлМасс.НомерГруппыЗатрат = НомерСтрокиДокумента Тогда  
					
					НовыеДанныеXDTO.AdditionalInfo.ТоварыДопИнф.Добавить(ОбщегоНазначения.СкопироватьРекурсивно(ЭлМасс));
				КонецЕсли;
				
			КонецЦикла;
			НоваяСтрока = НовыеДанныеXDTO.Товары.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТовары);
			ГруппыЗатрат.Вставить(НомерСтрокиДокумента, НовыеДанныеXDTO);
		КонецЦикла;  
		
	КонецЕсли;
	Для каждого КиЗ Из ГруппыЗатрат Цикл
		
		МассивДанныеXDTO.Вставить(0, КиЗ.Значение);
		
	КонецЦикла; 
	
	Возврат МассивДанныеXDTO;
КонецФункции
  1. Далее система работает типовым образом: в пакет уходит массив объектов Производство без заказа, и массив объектов Требование-накладная.

  2. Единственный момент  - пришлось добавить еще один дополнительный метод БПро_ВыгрузкаДопОбъектаВыборки(КомпонентыОбмена, ПравилоКонвертации, ПравилоОбработки, ДанныеXDTO, Объект,  ПрерватьОбработку, ВзвестиФлагОшибки), аналогичный методу ВыгрузкаОбъектаВыборки, который не позволял выгружать массив элементов ДанныеXDTO, а строго преобразовывал один объект. Это пришлось добавить.
    Процедура БПро_ВыгрузкаДопОбъектаВыборки(КомпонентыОбмена, ПравилоКонвертации, ПравилоОбработки, ДанныеXDTO, Объект,  ПрерватьОбработку, ВзвестиФлагОшибки)
    	ВзвестиФлагОшибки = Ложь;
    
    	Если ПрерватьОбработку Тогда
    		ВзвестиФлагОшибки = Истина;
    	КонецЕсли;
    
    	Если Не ПрерватьОбработку Тогда
    		// Отработка ПКО
    
    		Если Не ОбъектФорматаПроходитПоФильтруXDTO(КомпонентыОбмена, ПравилоКонвертации.ОбъектФормата) Тогда
    			Возврат;
    		КонецЕсли;
    
    		ПропуститьОбработку = Ложь;
    		Попытка
    			// 2. Конвертируем Данные в Структуру по правилам конвертации.
    			ВремяНачала = ОбменДаннымиОценкаПроизводительности.НачатьЗамер();
    
    			Событие = "ДанныеXDTOИзДанныхИБ." + ПравилоКонвертации.ИмяПКО;
    			ОбменДаннымиОценкаПроизводительности.ЗавершитьЗамер(
    			ВремяНачала, Событие, Объект, КомпонентыОбмена,
    			ОбменДаннымиОценкаПроизводительности.ТипСобытияБиблиотека());
    
    			Если ДанныеXDTO = Неопределено Тогда
    				Возврат;
    			КонецЕсли;
    
    			// 3. Конвертируем Структуру в ОбъектXDTO.
    			ВремяНачала = ОбменДаннымиОценкаПроизводительности.НачатьЗамер();
    
    			СсылкиИзОбъекта = Новый Массив;
    			ОбъектXDTO = ОбъектXDTOИзДанныхXDTO(КомпонентыОбмена, ДанныеXDTO, ПравилоКонвертации.ТипXDTO, СсылкиИзОбъекта, , ПравилоКонвертации.Расширения);
    
    			Событие = "ОбъектXDTOИзДанныхXDTO." + ПравилоКонвертации.ИмяПКО;
    			ОбменДаннымиОценкаПроизводительности.ЗавершитьЗамер(
    			ВремяНачала, Событие, Объект, КомпонентыОбмена, 
    			ОбменДаннымиОценкаПроизводительности.ТипСобытияБиблиотека());
    
    		Исключение
    			ПропуститьОбработку = Истина;
    			ВзвестиФлагОшибки   = Истина;
    
    			ОписаниеОшибки = ОписаниеОшибкиПКО(
    			КомпонентыОбмена.НаправлениеОбмена,
    			ПравилоОбработки.Имя,
    			ПравилоКонвертации.ИмяПКО,
    			ПредставлениеОбъектаДляПротокола(Объект, ПравилоКонвертации.ОбъектДанных),
    			ИнформацияОбОшибке());
    
    			ЗафиксироватьПроблемуПриОбработкеОбъекта(КомпонентыОбмена,
    			Объект,
    			Перечисления.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриОтправкеДанных,
    			ОписаниеОшибки.ПодробноеПредставление,
    			ОписаниеОшибки.КраткоеПредставление);
    		КонецПопытки;
    
    		Если Не ПропуститьОбработку Тогда
    			ОшибкаПроверкиПоСхеме = Ложь;
    			ОписаниеОшибкиПроверкиПоСхеме = Неопределено;
    
    			Контекст = Новый Структура;
    			Контекст.Вставить("НаправлениеОбмена",    КомпонентыОбмена.НаправлениеОбмена);
    			Контекст.Вставить("ИмяПОД",               ПравилоОбработки.Имя);
    			Контекст.Вставить("ИмяПКО",               ПравилоКонвертации.ИмяПКО);
    			Контекст.Вставить("ПредставлениеОбъекта", ПредставлениеОбъектаДляПротокола(Объект, ПравилоКонвертации.ОбъектДанных));
    
    			ПроверитьОбъектXDTOПоСхеме(ОбъектXDTO, ПравилоКонвертации.ТипXDTO, Контекст, ОшибкаПроверкиПоСхеме, ОписаниеОшибкиПроверкиПоСхеме);
    
    			Если ОшибкаПроверкиПоСхеме Тогда
    				ПропуститьОбработку = Истина;
    
    				ЗафиксироватьПроблемуПриОбработкеОбъекта(КомпонентыОбмена,
    				Объект,
    				Перечисления.ТипыПроблемОбменаДанными.ОшибкаПроверкиСконвертированногоОбъекта,
    				ОписаниеОшибкиПроверкиПоСхеме.ПодробноеПредставление,
    				ОписаниеОшибкиПроверкиПоСхеме.КраткоеПредставление);
    			КонецЕсли;
    		КонецЕсли;
    
    		Если ПропуститьОбработку Тогда
    			ПрерватьОбработку = Истина;
    			Возврат;
    		КонецЕсли;
    
    		ВыгрузитьОбъектыПоСсылке(КомпонентыОбмена, СсылкиИзОбъекта);
    
    		// 4. Записываем ОбъектXDTO в XML-файл.
    		ФабрикаXDTO.ЗаписатьXML(КомпонентыОбмена.ФайлОбмена, ОбъектXDTO);
    	КонецЕсли;
    
    	Если ПрерватьОбработку Тогда
    		КомпонентыОбмена.НеВыгруженныеОбъекты.Добавить(Объект.Ссылка);
    	КонецЕсли;
    
    	Если ВзвестиФлагОшибки Тогда
    		КомпонентыОбмена.ФлагОшибки = Истина;
    		КомпонентыОбмена.СостояниеОбменаДанными.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
    	КонецЕсли;
    КонецПроцедуры
    

Обеспечение ссылочной целостности.

Обеспечение ссылочной связанности объектов в БП выполняется целиком на стороне БП: при получении всех документов:

  1. Записываем документы. Если объект пришел с признаком «Корневой»= да, то его не проводим, но записываем в доп свойства этот признак. Также идентификатор самого корневого документа записываем в свойство документа (далее объясню зачем).

Процедура ОтложеннаяОбработка_ВыпускПродукции(Объект, ПараметрыКонвертации, ОбъектМодифицирован)
	
	БПро_ОбновитьРеквизитыОбщиеТребования(Объект);  
	УстановитьДопСвойствоИзAdditionalInfo(Объект, "НомерERP");
	УстановитьДопСвойствоИзAdditionalInfo(Объект, "ЭтоКорневойДокумент");
	УстановитьДопСвойствоИзAdditionalInfo(Объект, "КорневойДокумент");
*********
&ИзменениеИКонтроль("ОтложеннаяОбработка_ТребованиеНакладная")
Процедура БПро_ОтложеннаяОбработка_ТребованиеНакладная(Объект, ПараметрыКонвертации, ОбъектМодифицирован)
******
	#Вставка     
	БПро_ОбновитьРеквизитыОбщиеТребования(Объект);   
	УстановитьДопСвойствоИзAdditionalInfo(Объект, "НомерERP");
	УстановитьДопСвойствоИзAdditionalInfo(Объект, "ЭтоКорневойДокумент");
	УстановитьДопСвойствоИзAdditionalInfo(Объект, "КорневойДокумент");
	#КонецВставки
КонецПроцедуры
  1. Если на стороне ЕРП документ сняли с проведения (или удалили) в БП придет объект «УдалениеОбъекта» со ссылкой на удаляемый объект. В этом случае при получении мы получаем идентификатор удаляемого корневого документа и запросом получаем весь массив дочерних документов по признаку «Корневой документ»

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

&После("ДополнитьСписокОбъектовКУдалению")
Процедура БПро_ДополнитьСписокОбъектовКУдалению(КомпонентыОбмена, ТипДанных, УникальныйИдентификатор, МассивОбъектовКУдалению)  
	Если ТипДанных = Тип("ДокументСсылка.ТребованиеНакладная") Тогда
		МассивДопОбъектовКУдалению = СписокОбъектовПоКорневойСсылке(УникальныйИдентификатор, "ТребованиеНакладная");
		ОбщегоНазначенияКлиентСервер.ДополнитьМассив(МассивОбъектовКУдалению,МассивДопОбъектовКУдалению, Истина);
	ИначеЕсли ТипДанных = Тип("ДокументСсылка.ОтчетПроизводстваЗаСмену") Тогда
		МассивДопОбъектовКУдалению = СписокОбъектовПоКорневойСсылке(УникальныйИдентификатор, "ОтчетПроизводстваЗаСмену");
		ОбщегоНазначенияКлиентСервер.ДополнитьМассив(МассивОбъектовКУдалению,МассивДопОбъектовКУдалению, Истина);
	КонецЕсли;
КонецПроцедуры


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

  1. Если на стороне ЕРП документ изменили (например, изменили табличную часть), то в БП нам придет новый набор объектов. При этом нам надо все уже существующие «дочерние» объекты» надо пометить на удаление, а затем их заново загрузить. Для этого достаточно один раз вызвать соответствующий метод при загрузке именно «корневого» объекта.

Процедура ПКО_Документ_ВыпускПродукции_Получение_ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена)
**************	
	Если AdditionalInfo<>Неопределено Тогда
		УстановитьДопИнф_ТЧ(ПолученныеДанные.Продукция, AdditionalInfo, Истина, "ОтчетПроизводстваЗаСмену", Неопределено);	
		
		ЭтоКорневойДокумент = AdditionalInfo.Свойство("ЭтоКорневойДокумент") и AdditionalInfo.ЭтоКорневойДокумент;
		Если ЭтоКорневойДокумент Тогда  
			ОбработатьКорневойДокумент(ПолученныеДанные, AdditionalInfo, КомпонентыОбмена, "ОтчетПроизводстваЗаСмену");
		КонецЕсли;
		
		Если ПолученныеДанные.Продукция.Количество()>0 Тогда
		
			ГруппаАналитическогоУчета = НоменклатурнаяГруппаПоНаименованиюНоменклатуры(ПолученныеДанные.Продукция[0].Номенклатура);
			ПолученныеДанные.НоменклатурнаяГруппа = ГруппаАналитическогоУчета;
		
		КонецЕсли;
	КонецЕсли;  
	
***************	
КонецПроцедуры
&ИзменениеИКонтроль("ПКО_Документ_ТребованиеНакладная_Получение_ПередЗаписьюПолученныхДанных")
Процедура БПро_ПКО_Документ_ТребованиеНакладная_Получение_ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена)
*****
	#Вставка
	ПолученныеДанные.УчитыватьКПН = Истина;
	ПолученныеДанные.ВидУчетаНУ = Справочники.ВидыУчетаНУ.НУ;
	AdditionalInfo = Неопределено; ПроизводствоБезЗаказа = Неопределено; ГруппаАналитическогоУчета = Неопределено;
	
	Если ПолученныеДанные.ДополнительныеСвойства.Свойство("AdditionalInfo", AdditionalInfo) Тогда
	    ЕстьПроизводствоБезЗаказа = AdditionalInfo.Свойство("ПроизводствоБезЗаказа", ПроизводствоБезЗаказа); 
		
		ЭтоКорневойДокумент = AdditionalInfo.Свойство("ЭтоКорневойДокумент") и AdditionalInfo.ЭтоКорневойДокумент;
		Если ЭтоКорневойДокумент Тогда  
			ОбработатьКорневойДокумент(ПолученныеДанные, AdditionalInfo, КомпонентыОбмена, "ТребованиеНакладная");
		КонецЕсли;
		
******
	#КонецВставки
********
КонецПроцедуры

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

Разработка велась на Платформе 1С:Предприятие 8.3 (8.3.24.1691), ERP(2.5.17.140) Формат ED - http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.8

Если полезно - плюсуйте)

См. также

SALE! 10%

Перенос данных 1C Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос документов, начальных остатков и справочной информации из УПП 1.3 в ERP 2 | из УПП 1.3 в УТ 11 | из УПП в КА 2 | Правила конвертации (КД 2) | Более 360 предприятий выполнили переход с использованием этого продукта! | Сэкономьте время - используйте готовое решение для перехода! | Позволяет перенести из УПП 1.3 в ERP / УТ 11 / КА 2 всю возможную информацию | В переносе есть фильтр по организации и множество других опциональных параметров выгрузки | Есть несколько алгоритмов выгрузки остатков на выбор

55778 50200 руб.

04.08.2015    173548    374    287    

401

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен и синхронизацию в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

27660 руб.

12.06.2017    148064    855    302    

451

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.88.x) и УТ 11.5 (11.5.21.x).

35000 руб.

23.07.2020    58486    267    75    

223

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.246.x) и БП 3.0 (3.0.175.x). Правила подходят для версии ПРОФ и КОРП.

35000 руб.

15.12.2021    27631    196    56    

151

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в БП 3 | из КА 2 в БП 3 | из УТ 11 в БП 3 | из ЕРП в БП 3 | Сэкономьте время - используйте готовое решение для перехода! | Перенос разработан в формате КД 2 (правила конвертации данных) | Переносятся все возможные виды документов, начальных остатков и нормативно-справочная информация| Можно опционально выгружать каждую пару "номенклатура+характеристика" как отдельную номенклатуру | Есть выгрузка настроек счетов учета и зарплатных данных из ERP / КА 2 | Можно проверить на вашем сервере перед покупкой

55778 50200 руб.

15.04.2019    75954    203    158    

142

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена | Можно выполнить переход с УПП на БП 3 или запускать выгрузку данных за выбранный период времени | Переносятся документы, начальные остатки и вся справочная информация | Есть фильтр по организации и множество других параметров выгрузки | Поддерживается несколько сценариев работы: как первичный полный перенос, так и перенос только новых документов | Перенос данных возможен в "1С: Бухгалтерия 3.0" версии ПРОФ, КОРП или базовую | Переход с "1С: УПП1.3" / "1С:КА 1.1" на "1С:БП3.0" с помощью правил конвертации будет максимально комфортным! | Можно бесплатно проверить перенос на вашем сервере!

48278 43450 руб.

25.02.2015    174932    317    267    

387

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Платформа 1C v8.2 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием Россия Платные (руб)

Регулярный обмен, выгрузка, перенос из КА 1.1, УПП 1.3, УТ 10.3 для обмена с любыми конфигурациями, поддерживающими обмен в формате EnterpriseData (КД3) - БП 3.0, ERP, КА 2, УТ 11, Розница 2, УНФ 1.6 и другими. Правила для старых и доработанных конфигураций не требуют синхронного обновления и совместимы с новыми и будущими конфигурациями. Обмен по расписанию, через папку, FTP, почту.

16260 руб.

18.02.2016    190672    622    534    

542

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

53111 47800 руб.

03.12.2020    39572    112    73    

106
Оставьте свое сообщение