Работа с конвертацией данных

Публикация № 597573

Программирование - Практика программирования

конвертация данных ключевые особенности работы перечисления пример работа с конвертацией структура в пкс

345
Поскольку к конвертации обращаюсь время от времени и какие-то детали забываются, хочу выделить несколько пунктов, чтобы "было где посмотреть". Статья сделана преимущественно «для себя», так что просьба не судить строго. (Примечание читающим/комментирующим: код в примерах очень сильно сокращен.)

Передача программным путём Массива (Таблицы значений, Списка значений) в параметры.

На примере ЗУП 2.5: в обработке «Выгрузка данных в бухгалтерскую программу» на форме размещен реквизит, в котором пользователь подбирает нужные счета дебета, далее требуется передать выбранные пользователем счета в правила выгрузки.

В типовых конфигурациях есть удобный механизм "СериализоватьОбъектXDTO", саму функцию легко найти в интернете, а мне достаточно в процедуре "ВыгрузитьПоПравиламБух30" формы вписать вот это:

МассивСчетовДТ = ТиповыеОтчеты.СериализоватьОбъектXDTO(МассивСчетовВыбранныхПользователем);

И далее там же:

НовыйПараметр = мУниверсальнаяВыгрузкаДанных.ТаблицаНастройкиПараметров.Добавить();
НовыйПараметр.Значение = МассивСчетовДТ;
НовыйПараметр.Имя = "МассивСчетовДТ";
НовыйПараметр.Наименование = "МассивСчетовДТ";
НовыйПараметр.ПередаватьПараметрПриВыгрузке = Истина;

Далее в Конвертации данных добавляем параметр.

Перед выгрузкой данных выполняем проверку:

Если ЗначениеЗаполнено(Параметры.МассивСчетовДТ) Тогда
	МассивСчетовДТ = ТиповыеОтчеты.ПрочитатьОбъектXDTO(Параметры.МассивСчетовДТ);
КонецЕсли;

И используем десериализованный массив, например вот так:

Если МассивСчетовДТ<>Неопределено Тогда
//ваш код
КонецЕсли;

 

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

В ПВД (правило выгрузки данных):

ТекстЗапроса = Запросы.Прием.Текст;

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ПустаяДата", Дата(1,1,1));
Запрос.УстановитьПараметр("ДатаОкончания",	КонецДня(ДатаОкончания));

РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
	Отказ = Истина
КонецЕсли;

ВыборкаДанных = РезультатЗапроса.Выгрузить();

Запросы размещаются на закладке "Алгоритмы\Запросы" без кавычек.

 

Установка своего Значения (Вариант 1).

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

Создавать новые ВидыРасчетов в базе загрузки из базы выгрузки я не хочу (отключаю поиск по "Коду", "Пометка на удаление" мне тоже не интересна), пытаюсь найти объекты по Наименованию

и в случае, если Наименование определенное, то присваиваю ему другое значение (другими словами. устанавливаю соответствие).

 

Если Источник.Наименование = "Оклад по среднечасовой за год учетный период 2014" Тогда					
	Значение = "Оклад по часам";				
КонецЕсли;

Если Источник.Наименование = "Оклад по среднечасовой за год учетный период 2017" Тогда					
	Значение = "Оклад по часам";				
КонецЕсли;

Если Источник.Наименование = "Оклад по среднечасовой за год учетный период 2016" Тогда					
	Значение = "Оклад по часам";				
КонецЕсли;

 

Установка своего Значения (Вариант 2).

Ситуация вторая, мне не интересно что было в источнике, я хочу просто задать своё конкретное значение.

Наименование у нас имеет тип "Строка", так что Значение задано строкой.

 

Особенности выгрузки документов (Задать своё значение реквизита в произвольном запросе).

Рассмотрим вариант произвольного запроса.

Как видно из картинки выше, в запросе выводим и реквизиты и табличную часть (и) документа (обведено голубым квадратом).

В ПВД:

ТекстЗапроса = Запросы.ОтражениеЗарплатыВРеглУчете.Текст;
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Организация",	Данные.Организация);

ТаблицаДанных = Запрос.Выполнить().Выгрузить();

Для каждого СтрокаТД Из ТаблицаДанных Цикл

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

ВыборкаДанных = ТаблицаДанных.Скопировать();
ТаблицаДанных = Неопределено;

//1 - табличная часть документа

//2 - не суть, просто какое-то условие (завист от задачи)

//3 - задаём другое значение

 

Задать своё значение реквизиту табличной части в ПКС, использование Алгоритма, задать другое ПКО.

"Источник" содержит в себе ссылку.

Обратиться к строке табличной части можно с помощью переменной "ОбъектКоллекции".

Если ОбъектКоллекции.СчетДт.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.РасчетыПоСоциальномуСтрахованию) Тогда
	ИмяПКО = "РегистрацииВНалоговомОргане";
Иначе	
	Источник = ОбъектКоллекции.СубконтоДт2;
	Выполнить(Алгоритмы.ПолучитьПКОСубконтоПоТипуЗначения);
	Если ИмяПКО = "" Тогда
		Отказ = Истина;
	КонецЕсли;
КонецЕсли;

Далее всё просто.

Алгоритм выглядит вот так:

Если в результате получаем ИмяПКО = "", отключаем ПКС (Отказ = Истина;), удобно для случаев, когда в одном документе есть реквизит, а в другом - нет. Например, подобная ситуация возникает, если в одной системе ЗУП 2.5 установлена программа  Бухучета 7.7, а в другой - Бухгалтерия 3.0

 

Несколько часто используемых строчек кода в ПКО.

Перед выгрузкой:

РежимЗаписи = "Проведение";

При загрузке:

Отказ = ОбъектНайден;

После загрузки:

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

 

Несколько часто используемых строчек кода в ПВД.

Перед выгрузкой (подойдет для варианта стандартной выгрузки, когда при обмене выгружаются зарегистрированные объекты):

Отказ = Не Объект.Проведен;

 

Разное.

Значение = ПривестиНомерКДлине(Источник.НомерДок,8);

 

 Найти ссылку в приёмнике, которой нет в источнике.

Пример приведён, чтобы показать все возможности конвертации.

Предположим, в источнике есть информация о табельном номере сотрудника, мне необходимо определить сотрудника.

Вариант 1 приведен с целью, чтобы показать идею. Но, поскольку запрос в цикле - это зло, смотри Вариант 2 :)

В запросе установите галочку: 

 

  Еще одна проблема, с которой мне пришлось давным-давно столкнуться и по неопытности было потрачено какое-то время -  

  Конвертация документа "Перенос данных", или, например "Операция" (Перенос движений документа).

В выгрузке описания структуры установите галочку, как показано на рис. ниже.

Далее в конвертации данных:

Галочками отметьте необходимые регистры, по которым хотите перенести движения, они будут добавлены так же, как и табличные части документа. Менять стандартные правила выгрузки не нужно (то есть не нужно писать никаких запросов), движения будут выгружены автоматически.

 

 Конвертация перечисления.

Если исходного значения перечисления в базе источнике нет, то нам не нужно ПКО для перечисления.

Рассмотрим простейший пример:

ПКС такого перечисления:

 

 Использование параметра в табличной части.

 

В табличной части "ОтражениеВУчете" добавим параметр "ВидРезерва" и зададим ему нужное нам значение.

Далее после загрузки объекта можем обратиться к параметрам любым способом.

Я привела два примера:

ТаблицаПараметровТовары = ПараметрыОбъекта["ОтражениеВУчетеТабличнаяЧасть"];

1. МассивПараметровИзТЧ = ТаблицаПараметровТовары.ВыгрузитьКолонку("ВидРезерва");

ИЛИ

2. ТЗОтражениеВУчете = Объект.ОтражениеВУчете.Выгрузить();
ТЗОтражениеВУчете.Колонки.Добавить("ВидРезерва",Новый ОписаниеТипов("Строка",,,,Новый КвалификаторыСтроки(6)));
ТЗОтражениеВУчете.ЗагрузитьКолонку(ТаблицаПараметровТовары.ВыгрузитьКолонку("ВидРезерва"),"ВидРезерва");

 

 Выгрузка структуры в ПКС.

 

Зачем нужно: например, в Договоре контрагента при выгрузке нужно подменить Владельца.

Пример:

Если выполняется какое-либо условие, то при выгрузке в договоре Владелец будет другой.

 

Если, условие перестаёт выполняться, Договор контрагента выгружается стандартным образом.

345

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. Sergafan10 17.03.17 08:45 Сейчас в теме
Становится мене актуальным, в связи с КД 3.
2. TODD22 17 17.03.17 08:49 Сейчас в теме
(1)И что там стало менее актуально?
КД 3 это не замена КД2.
fomix; Gendelf; kolya_tlt; sagatel; vovan_victory; artmakc; user774630; smit1c; wowik; Артано; Kesak; red80; OVladius; pm74; DrAku1a; Dementor; serg_infostart; Zeskord; maxdmt; dj_serega; Westbound; +21 Ответить
3. dj_serega 364 17.03.17 09:41 Сейчас в теме
(1) КД3 еще лет 5 будет раскручиваться.
А еще остались 7.7 и нужно делать выгрузку из них... Поэтому... Пока жива 7.7 и будет жить КД2 ;)
13. MaxS 1689 05.04.17 04:45 Сейчас в теме
(3)
Поэтому... Пока жива 7.7 и будет жить КД2
Не факт. )) Уже появилась одна публикация для связи 1С 7.7 через EnterpriseData.
Но всё равно КД2 останется, т.к. возможности безграничны, в отличие от КД3, где ограничен формат.
4. unichkin 1183 17.03.17 10:50 Сейчас в теме
в п.1 лишнее
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
	Отказ = Истина
КонецЕсли;


ВыборкаДанных = РезультатЗапроса.Выгрузить();

Можно сразу:
ВыборкаДанных = Запрос;


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

Запросы.Прием.УстановитьПараметр("ПустаяДата", Дата(1,1,1));
Запросы.Прием.УстановитьПараметр("ДатаОкончания",	КонецДня(ДатаОкончания));
ВыборкаДанных =Запросы.Прием;


не нужны никакие отказы при пустом результате. Он если пустой, и так ничего не будет.

в п.5 запрос в цикле + см. п.2

п.6 тяжеловато
ОбъектКоллекции.СчетДт.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.РасчетыПоСоциальномуСтрахованию)

п.7 не понял смысла
"При загрузке:
Отказ = ОбъектНайден;"
- т.е. если объект найден, то не обновлять? Там галка есть у ПКО "Не замещать существующие объекты в приемнике..."
п.8 - а как эти объекты уйдут из таблицы регистрации изменений? Их туда и помещать не надо, если они не должны выгружаться.

Почему-то когда дело касается КД люди сразу забывают о том что такое точка. Вообще, все это довольно субъективно.
5. unichkin 1183 17.03.17 11:21 Сейчас в теме
Про п.1 - зачеркнуть, это дубль про п.2
6. d4rkmesa 17.03.17 12:30 Сейчас в теме
Плохо все-таки писать РежимЗаписи = "Проведение" в обработчике, нужно пользоваться механизмом отложенного проведения, либо вынести проведение всех документов отдельно в обработчик "после загрузки данных", хотя для каких-то простых документов сойдет. Остальное имеет право на жизнь, нюансы реализации не так важны в целом.
sagatel; jobkostya1c8; CSiER; +3 Ответить
7. vano-ekt 523 17.03.17 21:44 Сейчас в теме
в обработчики ПКС/ПВД понапихают запросов, а потом ждут пока обмен час пройдет
Rollam; корум; oleganatolievich; DrAku1a; unichkin; dj_serega; +6 2 Ответить
8. serg_infostart 308 21.03.17 15:19 Сейчас в теме
(7) в ПКС не увидел, что понапихано...
В ПВД оно само собой разумеющееся.

(0) не хватает описания обработчиков Поля поиска.
jobkostya1c8; +1 Ответить
10. Zhilyakovdr 91 22.03.17 11:39 Сейчас в теме
(7) Запросы в ПВД вполне нормальное явление, в ПКС нет.
Гляньте типовые обмены, там и не такое увидите.
jobkostya1c8; Дмитрий74Чел; +2 Ответить
24. alex_bitti 122 09.09.19 11:11 Сейчас в теме
(7) обмен идет часами в основном из-за итогов в регистрах, в частности в бух долго грузятся реализации товаров при включенных итогах, запросы в правилах работают также как и стандартная выгрузка/загрузка практически, в стандартной тоже можно напихать параметров))
9. Zhilyakovdr 91 22.03.17 11:38 Сейчас в теме
ТекстЗапроса = Запросы.ОтражениеЗарплатыВРеглУчете.Текст;
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Организация",	Данные.Организация);


меняем на

Запрос = Запросы.ОтражениеЗарплатыВРеглУчете;
Запрос.УстановитьПараметр("Организация",	Данные.Организация);


а можно и на
Запросы.ОтражениеЗарплатыВРеглУчете.УстановитьПараметр("Организация",	Данные.Организация);
11. Zhilyakovdr 91 22.03.17 11:42 Сейчас в теме
Все что вы описали в статье можно легко найти в типовых правилах и примерах в самой КД.
Пора потихоньку КД3 пользовать
12. Lem0n 164 04.04.17 23:10 Сейчас в теме
Удобное использование шаблонов обработчиков реализовано в http://infostart.ru/public/398595/ (см. видео с 9:46 и с 16:35),
14. Поручик 4310 15.05.17 11:09 Сейчас в теме
КД 2 ещё долго будет жить, потому что с ней намного легче накидать правила переноса. Попробуйте это сделать быстро с КД 3.
fomix; vovan_victory; wowik; jobkostya1c8; lefthander; +5 Ответить
15. q_i 380 16.05.17 15:52 Сейчас в теме
П.10, Вариант 2: какой текст запроса у Запросы.ПоискСотрудника2.Текст?
Есть подозрение, что "Объект.Работники.ЗагрузитьКолонку(Результат, "Сотрудник")" потенциально может загрузить сотрудников в неправильном порядке.
16. vovan_victory 61 30.01.19 10:11 Сейчас в теме
П.5. А зачем в цикле создавать объект запрос?
Для каждого СтрокаТД Из ТаблицаДанных Цикл

	ТаблицаПроводок = СтрокаТД.ОтражениеВУчете;  //1
	
	Для каждого СтрокаТП  Из ТаблицаПроводок Цикл
		
		Если МассивСчетовДТ<>Неопределено И МассивСчетовДТ.Найти(СтрокаТП.СчетДт) <> Неопределено И НЕ СтрокаТП.ПодразделениеДт.Родитель.Пустая() Тогда	//2				
			Запрос = Новый Запрос;


Может лучше:
//Создаем до цикла 1 раз
Запрос = Новый Запрос;

Для каждого СтрокаТД Из ТаблицаДанных Цикл

	ТаблицаПроводок = СтрокаТД.ОтражениеВУчете;  //1
	
	Для каждого СтрокаТП  Из ТаблицаПроводок Цикл
		
		Если МассивСчетовДТ<>Неопределено И МассивСчетовДТ.Найти(СтрокаТП.СчетДт) <> Неопределено И НЕ СтрокаТП.ПодразделениеДт.Родитель.Пустая() Тогда	//2				
		//А в цикле уже устанавливаем текст, параметры и выполняем
                //Да и текст запроса, если не меняется, тоже выносим из цикла.
			Запрос.Текст = Запросы.ПодразделениеОрганизацииРодитель.Текст;
			Запрос.УстановитьПараметр("Ссылка", СтрокаТП.ПодразделениеДт);
			РезультатЗапроса = Запрос.Выполнить();
Показать
17. perepetulichka 619 30.01.19 13:31 Сейчас в теме
(16) Это понятно, пользуюсь таким способом :) Пункт 5 показан просто как один из способов. Спасибо за комментарий!
18. AlexeyK1 14 16.04.19 15:14 Сейчас в теме
Здравствуйте, подскажите пожалуйста.
настраиваю конвертацию между двумя разными "переписанными" конфигурациями(УТ -> WMS) возникла проблема со справочниками.
в источнике
Номенклатура + ЕдиницаИзмерения
переносится в связку
Номенклатура + ЕдиницаИзмерения1 + ЕдиницаИзмерения2 вторая подчиненна первой, а Владелец у них один,
так вот когда переносим новую Номенклатуру не могу придумать как ЕдиницуИзмерения2 подчинить ЕдиницеИзмерения1 ведь на момент прогона ссылки у меня на ЕдиницуИзмерения1 не существует (если прогнать 2 раза "Загрузку", то все пучком, понимаю что это неправильно)
ЕдиницаИзмерения1 и ЕдиницаИзмерения2 переносятся не по ссылке, а создаются
Может кто то сталкивался с подобной проблемой, и есть возможность это побороть?
19. perepetulichka 619 16.04.19 16:31 Сейчас в теме
(18) я так понимаю, если вы из ЕдиницаИзмерения формируете ЕдиницаИзмерения1 и ЕдиницаИзмерения2, то все это делается в одном алгоритме.
Запросом проверяем есть ли объекты в системе (судя по всему ГУИД с источником или у одного элемента или не совпадает совсем, для удобства кстати можно в приёмнике добавить реквизит "ГУИДИсточника" объекту и по нему искать).
Затем если их нет, создаём первый, записываем его и второму Владельцем заполняем ссылку.

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

Или показывайте правила, как вы их создаёте.
20. AlexeyK1 14 17.04.19 10:41 Сейчас в теме
вот в ПКО при выгрузке Номенклатуры делаю выгрузить по правилу сразу создаю 2 ЕдиницыХранения, понимаю что такая ситуация что у меня нету GUID для этих элементов был бы GUID я бы его пихнул в сыль родителя второй ЕдиницыХранения и всё пучком было бы
ВходящиеДанные = Новый Структура;
ВходящиеДанные.Вставить("Владелец", Источник);
ВходящиеДанные.Вставить("Наименование", "Пар");
ВходящиеДанные.Вставить("Код", "0000000001");
ВходящиеДанные.Вставить("Родитель", "");
ВходящиеДанные.Вставить("Коэффициент", 1);
ВходящиеДанные.Вставить("КоэффициентКИС", Источник.абРазмерныйРяд.Количество);
ВходящиеДанные.Вставить("МодельСкладскогоУчета", "001");
ВходящиеДанные.Вставить("АктивнаяОбластьОтбора", "000000001");
ВходящиеДанные.Вставить("ОбластьРазмещения", "000000001");
ВходящиеДанные.Вставить("КлассЕдиницыХранения" ,"715");
ВходящиеДанные.Вставить("ОтборПоДатам" ,"НеВыполнять");
ВходящиеДанные.Вставить("РучноеРазмещение" ,"Истина");
ВыгрузитьПоПравилу(,,ВходящиеДанные,,"усЕдиницыХранения");


ВходящиеДанные1 = Новый Структура;
ВходящиеДанные1.Вставить("Наименование", "Короб(" + Строка(ВходящиеДанные.КоэффициентКИС) + ")");
ВходящиеДанные1.Вставить("Владелец", Источник);
ВходящиеДанные1.Вставить("Родитель",  "0000000001"); //понимаю что тут ссыль должна быть ВходящиеДанные, но какая ? прост вставить 
                                                                                 // ВыгрузитьПоПравилу(,,ВходящиеДанные,,"усЕдиницыХранения");?
ВходящиеДанные1.Вставить("Код", "0000000001");
ВходящиеДанные1.Вставить("Коэффициент", ВходящиеДанные.КоэффициентКИС);
ВходящиеДанные1.Вставить("КоэффициентКИС", ВходящиеДанные.КоэффициентКИС);
ВходящиеДанные1.Вставить("МодельСкладскогоУчета", "001");
ВходящиеДанные1.Вставить("АктивнаяОбластьОтбора", "000000001");
ВходящиеДанные1.Вставить("ОбластьРазмещения", "000000001");
ВходящиеДанные1.Вставить("КлассЕдиницыХранения" ,"778");
ВходящиеДанные1.Вставить("ОтборПоДатам" ,"НеВыполнять");
ВходящиеДанные1.Вставить("РучноеРазмещение" ,"Истина");

ВыгрузитьПоПравилу(,,ВходящиеДанные1,,"усЕдиницыХраненияКороба");

Показать


Сейчас понимаю что первую ЕдиницуХранения можно было привязать к ЕдиницеИзмерения в базе Источнике и его GUID юзать... но поезд ушел....
теперь походу придётся правила переписывать и завязываться на ЕдиницуИзмерения для первой ЕдиницыХранения... с проверкой на существование Единицы хранения старыми правилами
21. perepetulichka 619 17.04.19 11:51 Сейчас в теме
(20) но смотрите, вы перед выгрузкой по правилу выгружаете ЕдиницаИзмерения1 и ЕдиницаИзмерения2, а затем самим ПКО формируете Источник.
Следовательно в файле у вас сначала ЕдиницаИзмерения1 и ЕдиницаИзмерения2, а потом сама Номенклатура (владелец), система все записывает последовательно.
Как насчет переместить ваши структуры в модуль "После выгрузки"?
22. perepetulichka 619 17.04.19 11:55 Сейчас в теме
(21) правильнее в модуль "После выгрузки в файл".

Условия возникновения события
Событие выполняется после выгрузки объекта в файл обмена. Может быть использован для выгрузки дополнительной информации по выгруженному объекту в файл обмена. При этом информация будет записана в файл обмена после выгруженного объекта.
23. AlexeyK1 14 17.04.19 14:47 Сейчас в теме
25. alex_bitti 122 09.09.19 11:14 Сейчас в теме
отлично написано! такую бы статью лет 6 назад прочитать бы мне)) большинство приемчиков пришлось придумывать самому, похоже у всех так)
Оставьте свое сообщение