При работе с механизмами XDTO (XML Data Transfer Objects) начинающие разработчики часто сталкиваются с ошибкой Поле объекта не обнаружено (Множественное). Эта ситуация возникает, когда программист пытается «на лету» указать платформе 1С, что конкретное свойство должно быть списком (массивом), используя синтаксис Объект.Свойство.Множественное = Истина. Рассмотрим подробнее, почему этот подход ошибочен и как правильно реализовать выгрузку множественных свойств.
Главное, что нам необходимо усвоить при работе с XDTO: структура объекта жестко определяется его типом (схемой), а не самим экземпляром объекта. В языке 1С объекты XDTO являются строго типизированными. Когда вы создаете объект через ФабрикаXDTO.Создать(), вы получаете экземпляр, структура которого уже определена в XDTO-пакете или внешней схеме XML (XSD).
Попытка написать XDTOналог.множественное = истина; вызывает ошибку, потому что у объекта типа ОбъектXDTO нет свойства множественное. Понятие «множественности» — это характеристика свойства типа (метаданных), которая описывается параметрами Минимальное количество (minOccurs) и Максимальное количество (maxOccurs) в схеме. Изменить эти параметры у уже созданного объекта в коде невозможно.
Для того чтобы свойство могло содержать несколько значений, нам нужно правильно настроить XDTO-пакет. Выполним следующие действия:
Цена).Налог).-1. В терминологии XML это означает unbounded (неограниченное количество). Если установить число больше 1, это также сделает свойство множественным, но ограничит его размер.0 (если список может быть пустым) или в 1 (если хотя бы один элемент обязателен).После этих манипуляций свойство Налог в коде 1С будет распознаваться не как одиночное значение, а как объект типа СписокXDTO.
Теперь проанализируем, как изменится наш код. Со списками XDTO нельзя работать через обычное присваивание (=). Для добавления элементов используются специальные методы коллекции. Разберем правильный алгоритм создания структуры «Цены с несколькими налогами».
Рассмотрим пример кода, исправляющий логику из вопроса:
// 1. Получаем типы из фабрики
XDTOЦеныТип = ПараметрыОбмена.МояФабрикаXDTO.Тип("http://www.example.com/crm", "Цены");
XDTOЦенаТип = ПараметрыОбмена.МояФабрикаXDTO.Тип("http://www.example.com/crm", "Цена");
XDTOНалогТип = ПараметрыОбмена.МояФабрикаXDTO.Тип("http://www.example.com/crm", "Налог");
// 2. Создаем корневой объект (Цены)
XDTOЦены = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЦеныТип);
// 3. Создаем объект Цена и добавляем его в список Цены (если Цены.Цена тоже список)
// Предположим, свойство "Цена" в типе "Цены" имеет Максимальное количество = -1
НоваяЦена = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЦенаТип);
XDTOЦены.Цена.Добавить(НоваяЦена);
// 4. Добавляем налоги в объект Цена
// Здесь Налог — это множественное свойство внутри Цены
Для Каждого СтрокаНалога Из ТаблицаНалогов Цикл
// Метод Добавить() создает новый пустой объект нужного типа и возвращает его
НовыйНалог = НоваяЦена.Налог.Добавить();
НовыйНалог.Наименование = СтрокаНалога.Наименование;
НовыйНалог.Ставка = СтрокаНалога.Ставка;
КонецЦикла;
Проанализируем основные методы, которые нам доступны, когда свойство определено как множественное:
Добавить(Значение) — позволяет добавить в список уже созданный объект или простое значение. Если вызвать метод без параметров Добавить(), 1С создаст новый объект того типа, который указан в схеме для этого свойства.Удалить(Объект) — удаляет конкретный элемент из коллекции.Количество() — возвращает число элементов в списке.Получить(Индекс) — позволяет обратиться к элементу по номеру.Выясним причину еще одной частой ошибки. Часто разработчики пытаются создать объект «в воздухе» и присвоить его свойству-списку напрямую:
// ОШИБОЧНЫЙ ПУТЬ
МойНалог = ФабрикаXDTO.Создать(ТипНалога);
МойНалог.Значение = 18;
XDTOЦена.Налог = МойНалог; // Ошибка! Налог — это СписокXDTO, ему нельзя присвоить ОбъектXDTO
Правильный способ в этой ситуации — использовать метод Добавить, передавая в него подготовленный объект:
// ПРАВИЛЬНЫЙ ПУТЬ
МойНалог = ФабрикаXDTO.Создать(ТипНалога);
МойНалог.Значение = 18;
XDTOЦена.Налог.Добавить(МойНалог); // Теперь объект добавлен в коллекцию
Если вы не уверены, правильно ли настроен XDTO-пакет, воспользуйтесь отладчиком. Остановите выполнение кода после создания родительского объекта и раскройте его свойства:
ОбъектXDTO или Неопределено — свойство единичное.СписокXDTO — свойство множественное.Важный нюанс: Если свойство в схеме помечено как список, но в него еще не добавлено ни одного элемента, обращение к нему (например, XDTOЦена.Налог) все равно вернет пустой объект СписокXDTO, а не Неопределено.
Если вы не используете статические XDTO-пакеты в конфигурации, а создаете модель XDTO программно (например, на основе внешней схемы XSD), убедитесь, что при формировании ОпределениеСвойстваXDTO вы правильно указали параметры количества. Изменить их после того, как тип был добавлен в фабрику, будет невозможно. Используйте построитель схем или корректно описывайте структуру в .xsd файле перед чтением его фабрикой.
Таким образом, решение проблемы сводится к двум этапам: декларативному (настройка схемы в пакете) и процедурному (использование методов работы со списками в коде). Следуя этим правилам, вы избежите ошибок обращения к несуществующим полям метаданных и обеспечите корректную выгрузку данных любой вложенности.