Коллеги, приветствую!
Клиент хочет выборочно документы "Чек ККМ" из Розницы 2 переносить в Бухгалтерию 3.0 как документ "Поступление товаров" и в некоторых случаях в обратную сторону. Базы между собой не связаны обменами. Это разные организации и базы.
Собственно, клиенту нужна табличная часть с номенклатурой и цифрами..
Вопрос заключается в том как правильнее подойти к решению вопроса? Т.е. каким способом реализовать.
Так как это все планируется делать выборочно, то штатный обмен по разработанным правилам обмена отпадает. Да и клиент хочет наглядности процесса. Т.е. выбрал несколько документов, нажал кнопочку "Выгрузить". Пошел в другую базу и там нажал "Загрузить", выбрав файл с выгруженными данными.
Вы бы писали обработку или по другому решали задачу? И я так понимаю, что выгрузку можно реализовать разными способами. Подскажите какой-нибудь наглядный пример, пожалуйста.
(1) самый эффективный путь - тот, который исполнитель знает лучше всего.
Если речь только о т.ч. одного документа, то мне например было бы быстрее написать обмен через текстовый файлик. Или если можно через Оле подключиться из одной базы в другую, так и еще лучше. Клиенту это тоже будет удобнее всего, я думаю. Одну кнопку нажал и готово.
А через конвертацию с подключением обработки выбора документов, конечно, красивее, но это на полдня в лучшем случае. Но может есть мастера конвертации, которые все это за полчаса набросают. Преимущество конвертации в общем только в масштабируемости. Когда клиент захочет еще один документ, то обработка самодельная удваивается, а к конвертации дописать совсем немного надо.
Запись = Новый ЗаписьJSON;
Запись.ОткрытьФайл(ПутьКФайлу);
// создадим массив строк документа (строки документа сериализуются как структуры)
Данные = Новый Массив;
Для каждого стр Из ТаблицаДокументовВыгрузка Цикл
ДанныеДокумента = Новый Массив;
ЧекККМ = стр.СсылкаНаДокумент;
Для каждого СтрокаТабличнойЧасти Из ЧекККМ.Товары Цикл
СтрокаДокумента = Новый Структура("Номенклатура,Количество,Цена,Сумма", );
ЗаполнитьЗначенияСвойств(СтрокаДокумента,СтрокаТабличнойЧасти);
ДанныеДокумента.Добавить(СтрокаДокумента);
КонецЦикла;
Если ДанныеДокумента.Количество()>0 Тогда
Данные.Добавить(ДанныеДокумента);
КонецЕсли;
КонецЦикла;
СериализаторXDTO.ЗаписатьJSON(Запись, Данные);
Запись.Закрыть();
Показать
Чтение файла трудностей не вызвало пока.
Мне осталось отработать те случаи, когда мы не можем найти объект справочника по ссылке (например, Номенклатура).
А как бы мне при сериализации передать структуру всех реквизитов объектов ссылочного типа?
Файл я десериализую в таблицу значений, чтобы потом загрузить ее в ТЧ нужного мне документа. А когда номенклатура не найдена по ссылке, мне надо ее создать в базе-приемнике с теми же полями, включая ГУИД.
(4) Насколько я понимаю, в базе с другой структурой будут проблемы с восстановлением значений объектного типа(десериализацией). Так что тут вероятно, придется передавать реквизиты именно коллекцией(ТЗ или например Соответствием по артикулу, в случае когда они уникальны).
(6) Так и сделал.
Еще бы теперь как-то проверку написать после десериализации на те поля,в которых "Объект не найден".
см. рисунок.
Сериализация XDTO-объекта нам позволяет при последующей десериализации сразу получить ссылку на объект по ссылке. Т.е. не надо его искать по наименованию (или еще как-то).
ДанныеДокумента = Новый Массив;
ЧекККМ = стр.СсылкаНаДокумент;
Для каждого СтрокаТабличнойЧасти Из ЧекККМ.Товары Цикл
СтрокаДокумента = Новый Структура("Номенклатура,Количество,Цена,Сумма,НоменклатураМетаданные", );
ЗаполнитьЗначенияСвойств(СтрокаДокумента,СтрокаТабличнойЧасти);
МетаданныеЗначения = СтрокаТабличнойЧасти.Номенклатура.Метаданные();
ЗначениеСтруктурой = Новый Структура;
Значение = СтрокаТабличнойЧасти.Номенклатура;
Для каждого Реквизит Из МетаданныеЗначения.Реквизиты Цикл
Если ЗначениеЗаполнено(Значение[Реквизит.Имя]) Тогда
ЗначениеСтруктурой.Вставить(Реквизит.Имя,Значение[Реквизит.Имя]);
КонецЕсли;
КонецЦикла;
СтрокаДокумента.НоменклатураМетаданные = ЗначениеСтруктурой;
ДанныеДокумента.Добавить(СтрокаДокумента);
КонецЦикла;
Если ДанныеДокумента.Количество()>0 Тогда
Данные.Добавить(ДанныеДокумента);
КонецЕсли;
КонецЦикла;
СериализаторXDTO.ЗаписатьJSON(Запись, Данные);
Запись.Закрыть();
(8) Вот так для себя я потом проверяю результат десериализации объектов ссылочных типов:
// Проверяет физическое наличие записи в информационной базе данных о переданном значении ссылки
//
// Параметры:
// ЛюбаяСсылка - значение любой ссылки информационной базы данных
//
// Возвращаемое значение:
// Истина - ссылка физически существует;
// Ложь - ссылка физически не существует
//
Функция СсылкаСуществует(ЛюбаяСсылка) Экспорт
ТекстЗапроса = "
|ВЫБРАТЬ
| Ссылка
|ИЗ
| [ИмяТаблицы]
|ГДЕ
| Ссылка = &Ссылка
|";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяТаблицы]", ИмяТаблицыПоСсылке(ЛюбаяСсылка));
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Ссылка", ЛюбаяСсылка);
//УстановитьПривилегированныйРежим(Истина);
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции
// Возвращает полное имя объекта метаданных по переданному значению ссылки
// Например,
// "Справочник.Номенклатура";
// "Документ.ПриходнаяНакладная"
//
// Параметры:
// Ссылка - ЛюбаяСсылка - значение ссылки, для которого необходимо получить имя таблицы ИБ
//
// Возвращаемое значение:
// Строка - полное имя объекта метаданных для указанного значения ссылки
//
Функция ИмяТаблицыПоСсылке(Ссылка) Экспорт
Возврат Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
КонецФункции
(10) Ну собственно это и происходит. Просто уид пишется в тексте JSON, а потом по этой ссылке находится объект.
Если не нашли так, то дальше можно создавать объект по выгруженным реквизитам.
Там, правда, тоже геморр небольшой с реквизитами ссылочного типа. Допустим, не нашли номенклатуру. Создаем. У номенклатуры есть поле "Вид номенклатуры" ссылочного типа. А если вид номенклатуры не найдем? А у "Вида номенклатуры" свои реквизиты ссылочные имеются...
Короче, я не знаю пока как написать алгоритм так, чтобы "вглубь" проходиться по всем ссылочным полям, которые не были определены по ссылке.
Все зависит от того кто и как часто будет выгружать.
Мое мнение любые обработки по ole и иже сними не заменять грамотных правил написанных в Конвертации данных