Поступила задача наладить обмен между Управление Торговлей 11 для Узбекистана и Бухгалтерией Предприятия 3.0 (тоже Узбекистан) через УниверсальныйФормат
Основная ошибка звучала так: "Ключевое свойство "КодВПрограмме" не найдено".
Эта проблема возникла потому, что в БП последняя версия формата - 1.5, а в УТ11 - 1.8. Не смотря на наличие у обеих конфигураций таких XDTO-пакетов как EnterpriseData 1.8.6, УТ постоянно выгружало в формате 1.8, а БП принимала в 1.5. Понижение формата 1.8 до 1.5 через групповое изменение реквизитов ни к чему не приводило, так как шло несовпадение свойства"НДС15". Конфигурации были обновлены до последнего релиза. Искусственно перевыставляла в расширениях версии форматов - безуспешно.
Истоки проблемы
Разработкой УТ и БП занимаются две разные компании.
И за два года пользования данными продуктами обмен по умолчанию не работал никогда.
Если свойство не ключевое
Решение: Баним его в коде. У меня была ошибка, что свойство "РегистрационныйКодПлательщикаНДС" не найден. Убедившись, что в Бухгалтерии он, в принципе, и не нужен, я его "забанила" в правилах конвертации в блоке "МенеджерОбменаЧерезУниверсальныйФормат".
&Вместо("ДобавитьПКО_Документ_СчетФактураВыданный_Отправка")
Процедура Расш1_ДобавитьПКО_Документ_СчетФактураВыданный_Отправка(ПравилаКонвертации)
ПравилоКонвертации = ОбменДаннымиXDTOСервер.ИнициализироватьПравилоКонвертацииОбъекта(ПравилаКонвертации);
ПравилоКонвертации.ИмяПКО = "Документ_СчетФактураВыданный_Отправка";
ПравилоКонвертации.ОбъектДанных = Метаданные.Документы.СчетФактураВыданный;
ПравилоКонвертации.ПриОтправкеДанных = "ПКО_Документ_СчетФактураВыданный_Отправка_ПриОтправкеДанных";
ПравилоКонвертации.ОбъектФормата = "Документ.СчетФактураВыданный"; //@NON-NLS-1
СвойстваШапки = ПравилоКонвертации.Свойства;
ДобавитьПКС(СвойстваШапки, "Валюта", "Валюта", , "Справочник_Валюты");
ДобавитьПКС(СвойстваШапки, "Дата", "Дата");
ДобавитьПКС(СвойстваШапки, "ДатаВыставления", "ДатаВыставления");
ДобавитьПКС(СвойстваШапки, "Исправление", "Исправление");
ДобавитьПКС(СвойстваШапки, "КодВидаОперации", "КодВидаОперации");
ДобавитьПКС(СвойстваШапки, "Номер", "Номер");
ДобавитьПКС(СвойстваШапки, "НомерИсправления", "НомерИсправления");
ДобавитьПКС(СвойстваШапки, "СчетФактураОснование", "ИсправляемыйСчетФактура", , "Документ_СчетФактураВыданный_Отправка");
ДобавитьПКС(СвойстваШапки, "", "ВидСчетаФактуры", 1);
ДобавитьПКС(СвойстваШапки, "", "Выставлен", 1);
ДобавитьПКС(СвойстваШапки, "", "ГлавныйБухгалтер", 1, "Справочник_ФизическиеЛица_Отправка");
ДобавитьПКС(СвойстваШапки, "", "Договор", 1);
ДобавитьПКС(СвойстваШапки, "", "ИННКонтрагента", 1);
ДобавитьПКС(СвойстваШапки, "", "Контрагент", 1, "Справочник_Контрагенты");
//ДобавитьПКС(СвойстваШапки, "", "РегистрационныйКодПлательщикаНДС", 1);
ДобавитьПКС(СвойстваШапки, "", "НомерИсправленияИсходногоДокумента", 1);
ДобавитьПКС(СвойстваШапки, "", "Руководитель", 1, "Справочник_ФизическиеЛица_Отправка");
ДобавитьПКС(СвойстваШапки, "", "СпособВыставления", 1);
ДобавитьПКС(СвойстваШапки, "", "СтавкаНДС", 1, "Перечисление_СтавкиНДС");
ДобавитьПКС(СвойстваШапки, "", "Сумма", 1);
ДобавитьПКС(СвойстваШапки, "", "СуммаНДС", 1);
ДобавитьПКС(СвойстваШапки, "Организация", "Организация", 1, "Справочник_Организации_Отправка");
СвойстваТЧ = ДобавитьПКТЧ(ПравилоКонвертации, "", "ДокументыОснования");
ДобавитьПКС(СвойстваТЧ, "", "ДокументОснование", 1);
ДобавитьПКС(СвойстваТЧ, "", "ИсходныйДокумент", 1, "Документ_СчетФактураВыданный_Отправка");
СвойстваТЧ = ДобавитьПКТЧ(ПравилоКонвертации, "", "ДополнительныеРеквизиты");
ДобавитьПКС(СвойстваТЧ, "", "ЗначениеСвойства", 1);
ДобавитьПКС(СвойстваТЧ, "", "Свойство", 1, "Справочник_ДополнительныеРеквизиты");
СвойстваТЧ = ДобавитьПКТЧ(ПравилоКонвертации, "", "ПлатежноРасчетныеДокументы");
ДобавитьПКС(СвойстваТЧ, "", "ДатаДокумента", 1);
ДобавитьПКС(СвойстваТЧ, "", "НомерДокумента", 1);
КонецПроцедуры
Если свойство ключевое
А вот если свойство является ключевым, то его никак забанить и нельзя. И сама суть проблемы была в следующем: в УТ11 было ключевое свойство подразделений "КодВПрограмме", а в Бухгалтерии его нет. Где посмотреть: XDTO пакеты -> EnterpriseData -> ТипыОбъектов ->КлючевыеСвойстваПодразделение.
В моём случае обмен настроен через файл. Ищу место, где объект XDTO записывается в файл XML.
Есть такой модуль, как "ОбменДаннымиXDTOСервер". Находим процедуру: ВыгрузкаОбъектаВыборки(КомпонентыОбмена, Объект, ПравилоОбработки). "Объект" это объект, который будет выгружаться.
А ОбъектXDTO это преобразованный объект, записываемый в файл. В моём случае ОбъектXDTO.Подразделение.КодВПрограмме был типа "Неопределено", что и давало ошибку. Вписываю свои данные, но можно брать данные и из самого объекта.
Если ТипЗнч(Объект) = Тип("СправочникОбъект.СтруктураПредприятия") Тогда
//ОбъектXDTO.КлючевыеСвойства.КодВПрограмме = Объект.Код;
ОбъектXDTO.КлючевыеСвойства.КодВПрограмме = "00-000001";
ОбъектXDTO.КлючевыеСвойства.Наименование = "Администрация";
КонецЕсли;
Если ТипЗнч(Объект) = Тип("ДокументОбъект.ПриобретениеТоваровУслуг")
ИЛИ ТипЗнч(Объект) = Тип("СправочникОбъект.Склады")
ИЛИ ТипЗнч(Объект) = Тип("ДокументОбъект.РеализацияТоваровУслуг")
ИЛИ ТипЗнч(Объект) = Тип("ДокументОбъект.ТаможеннаяДекларацияИмпорт")
ИЛИ ТипЗнч(Объект) = Тип("ДокументОбъект.ЗаказПоставщику")
Тогда
Если ОбъектXDTO.Подразделение <> Неопределено Тогда
//ОбъектXDTO.Подразделение.КодВПрограмме = Объект.Подразделение.Код;
ОбъектXDTO.Подразделение.КодВПрограмме = "00-000001";
ОбъектXDTO.Подразделение.Наименование = "Администрация";
КонецЕсли;
Если ТипЗнч(Объект) = Тип("ДокументОбъект.ПриобретениеТоваровУслуг") Тогда
Если ОбъектXDTO.Услуги <> Неопределено Тогда
л_КоличествоСтрокВсего = ОбъектXDTO.Услуги.Строка.Количество();
Для л_Счётчик = 0 По л_КоличествоСтрокВсего - 1 Цикл
//ОбъектXDTO.Услуги.Строка[л_Счётчик].ДанныеЗатрат.ПодразделениеЗатрат.КодВПрограмме = Объект.Товары[л_Счётчик].Подразделение.Код;
ОбъектXDTO.Услуги.Строка[л_Счётчик].ДанныеЗатрат.ПодразделениеЗатрат.КодВПрограмме = "00-000001";
ОбъектXDTO.Услуги.Строка[л_Счётчик].ДанныеЗатрат.ПодразделениеЗатрат.Наименование = "Администрация";
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Сама процедура выглядит так:
&Вместо("ВыгрузкаОбъектаВыборки")
Процедура Расш1_ВыгрузкаОбъектаВыборки(КомпонентыОбмена, Объект, ПравилоОбработки)
ОбъектСсылочногоТипа = (ТипЗнч(Объект) <> Тип("Структура"))
И ОбщегоНазначения.ЭтоОбъектСсылочногоТипа(Объект.Метаданные());
Если (ТипЗнч(Объект) <> Тип("Структура"))
И ПравилоОбработки = Неопределено Тогда
ПолучитьПравилоОбработкиДляОбъекта(КомпонентыОбмена, Объект, ПравилоОбработки);
КонецЕсли;
КомпонентыОбмена.ВыгруженныеОбъекты.Добавить(?(ОбъектСсылочногоТипа, Объект.Ссылка, Объект));
// Отработка ПОД
ИспользованиеПКО = Новый Структура;
Для Каждого ТекущееПКО Из ПравилоОбработки.ИспользуемыеПКО Цикл
ИспользованиеПКО.Вставить(ТекущееПКО, Истина);
КонецЦикла;
ПрерватьОбработку = Ложь;
ВзвестиФлагОшибки = Ложь;
ПриОбработкеПОД(
КомпонентыОбмена,
ПравилоОбработки,
Объект,
ИспользованиеПКО,
ПрерватьОбработку);
Если ПрерватьОбработку Тогда
ВзвестиФлагОшибки = Истина;
КонецЕсли;
Если Не ПрерватьОбработку Тогда
// Отработка ПКО
НесколькоПКО = (ИспользованиеПКО.Количество() > 1);
ЕстьКолонкаОчисткаДанных = КомпонентыОбмена.ПравилаОбработкиДанных.Колонки.Найти("ОчисткаДанных") <> Неопределено;
Для Каждого ТекущееПКО Из ИспользованиеПКО Цикл
ПравилоКонвертации = КомпонентыОбмена.ПравилаКонвертацииОбъектов.Найти(ТекущееПКО.Ключ, "ИмяПКО");
Если ПравилоКонвертации = Неопределено Тогда
// Допустимо указание ПКО, не предназначенного для текущей версии формата данных.
Продолжить;
КонецЕсли;
Если Не ОбъектФорматаПроходитПоФильтруXDTO(КомпонентыОбмена, ПравилоКонвертации.ОбъектФормата) Тогда
Продолжить;
КонецЕсли;
Если Не ТекущееПКО.Значение Тогда
// Если правил конвертации несколько, и некоторые из них не используются -
// необходимо выгрузить удаление объекта на случай если ранее он был выгружен по этим правилам.
Если НесколькоПКО
И ОбъектСсылочногоТипа
И (Не ЕстьКолонкаОчисткаДанных
Или ПравилоОбработки.ОчисткаДанных) Тогда
ВыгрузитьУдаление(КомпонентыОбмена, Объект.Ссылка, ПравилоКонвертации);
КонецЕсли;
Продолжить;
КонецЕсли;
ПропуститьОбработку = Ложь;
Попытка
// 2. Конвертируем Данные в Структуру по правилам конвертации.
ДанныеXDTO = ДанныеXDTOИзДанныхИБ(КомпонентыОбмена, Объект, ПравилоКонвертации, Неопределено);
Если ДанныеXDTO = Неопределено Тогда
Продолжить;
КонецЕсли;
// 3. Конвертируем Структуру в ОбъектXDTO.
СсылкиИзОбъекта = Новый Массив;
ОбъектXDTO = ОбъектXDTOИзДанныхXDTO(КомпонентыОбмена, ДанныеXDTO, ПравилоКонвертации.ТипXDTO, СсылкиИзОбъекта, , ПравилоКонвертации.Расширения);
Если ТипЗнч(Объект) = Тип("СправочникОбъект.СтруктураПредприятия") Тогда
//Если ОбъектXDTO.Подразделение <> Неопределено Тогда
//ОбъектXDTO.КлючевыеСвойства.КодВПрограмме = Объект.Код;
ОбъектXDTO.КлючевыеСвойства.КодВПрограмме = "00-000001";
ОбъектXDTO.КлючевыеСвойства.Наименование = "Администрация";
//КонецЕсли;
КонецЕсли;
Если ТипЗнч(Объект) = Тип("ДокументОбъект.ПриобретениеТоваровУслуг")
ИЛИ ТипЗнч(Объект) = Тип("СправочникОбъект.Склады")
ИЛИ ТипЗнч(Объект) = Тип("ДокументОбъект.РеализацияТоваровУслуг")
ИЛИ ТипЗнч(Объект) = Тип("ДокументОбъект.ТаможеннаяДекларацияИмпорт")
ИЛИ ТипЗнч(Объект) = Тип("ДокументОбъект.ЗаказПоставщику")
Тогда
Если ОбъектXDTO.Подразделение <> Неопределено Тогда
//ОбъектXDTO.Подразделение.КодВПрограмме = Объект.Подразделение.Код;
ОбъектXDTO.Подразделение.КодВПрограмме = "00-000001";
ОбъектXDTO.Подразделение.Наименование = "Администрация";
КонецЕсли;
Если ТипЗнч(Объект) = Тип("ДокументОбъект.ПриобретениеТоваровУслуг") Тогда
Если ОбъектXDTO.Услуги <> Неопределено Тогда
л_КоличествоСтрокВсего = ОбъектXDTO.Услуги.Строка.Количество();
Для л_Счётчик = 0 По л_КоличествоСтрокВсего - 1 Цикл
//ОбъектXDTO.Услуги.Строка[л_Счётчик].ДанныеЗатрат.ПодразделениеЗатрат.КодВПрограмме = Объект.Товары[л_Счётчик].Подразделение.Код;
ОбъектXDTO.Услуги.Строка[л_Счётчик].ДанныеЗатрат.ПодразделениеЗатрат.КодВПрограмме = "00-000001";
ОбъектXDTO.Услуги.Строка[л_Счётчик].ДанныеЗатрат.ПодразделениеЗатрат.Наименование = "Администрация";
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
ПропуститьОбработку = Истина;
ВзвестиФлагОшибки = Истина;
ОписаниеОшибки = ОписаниеОшибкиПКО(
КомпонентыОбмена.НаправлениеОбмена,
ПравилоОбработки.Имя,
ПравилоКонвертации.ИмяПКО,
ПредставлениеОбъектаДляПротокола(Объект, ПравилоКонвертации.ОбъектДанных),
ИнформацияОбОшибке());
ЗафиксироватьПроблемуПриОбработкеОбъекта(КомпонентыОбмена,
Объект,
Перечисления.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриОтправкеДанных,
ОписаниеОшибки.ПодробноеПредставление,
ОписаниеОшибки.КраткоеПредставление);
КонецПопытки;
Если Не ПропуститьОбработку Тогда
ОшибкаПроверкиПоСхеме = Ложь;
ОписаниеОшибкиПроверкиПоСхеме = Неопределено;
Контекст = Новый Структура;
Контекст.Вставить("НаправлениеОбмена", КомпонентыОбмена.НаправлениеОбмена);
Контекст.Вставить("ИмяПОД", ПравилоОбработки.Имя);
Контекст.Вставить("ИмяПКО", ПравилоКонвертации.ИмяПКО);
Контекст.Вставить("ПредставлениеОбъекта", ПредставлениеОбъектаДляПротокола(Объект, ПравилоКонвертации.ОбъектДанных));
ПроверитьОбъектXDTOПоСхеме(ОбъектXDTO, ПравилоКонвертации.ТипXDTO, Контекст, ОшибкаПроверкиПоСхеме, ОписаниеОшибкиПроверкиПоСхеме);
Если ОшибкаПроверкиПоСхеме Тогда
ПропуститьОбработку = Истина;
ЗафиксироватьПроблемуПриОбработкеОбъекта(КомпонентыОбмена,
Объект,
Перечисления.ТипыПроблемОбменаДанными.ОшибкаПроверкиСконвертированногоОбъекта,
ОписаниеОшибкиПроверкиПоСхеме.ПодробноеПредставление,
ОписаниеОшибкиПроверкиПоСхеме.КраткоеПредставление);
КонецЕсли;
КонецЕсли;
Если ПропуститьОбработку Тогда
ПрерватьОбработку = Истина;
Продолжить;
КонецЕсли;
ВыгрузитьОбъектыПоСсылке(КомпонентыОбмена, СсылкиИзОбъекта);
// 4. Записываем ОбъектXDTO в XML-файл.
ФабрикаXDTO.ЗаписатьXML(КомпонентыОбмена.ФайлОбмена, ОбъектXDTO);
КонецЦикла;
КонецЕсли;
Если ПрерватьОбработку Тогда
КомпонентыОбмена.НеВыгруженныеОбъекты.Добавить(?(ОбъектСсылочногоТипа, Объект.Ссылка, Объект));
КонецЕсли;
Если ВзвестиФлагОшибки Тогда
КомпонентыОбмена.ФлагОшибки = Истина;
КомпонентыОбмена.СостояниеОбменаДанными.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
КонецЕсли;
КонецПроцедуры