В современных конфигурациях 1С, таких как «Управление торговлей 11», «ERP» или «Комплексная автоматизация», механизмы работы со свойствами объектов реализованы через подсистему «Дополнительные реквизиты и сведения». Часто перед разработчиком встает задача выгрузить эти данные во внешние системы (например, на сайт или в XML-файл для обмена). Рассмотрим подробно, как правильно организовать обход табличной части ДополнительныеРеквизиты и какие технические нюансы необходимо учесть для корректной работы кода.
Для начала разберем простую ситуацию: у нас есть объект Номенклатура, и нам нужно перебрать все его дополнительные реквизиты, чтобы записать их в XML в формате "Имя=Значение". Дополнительные реквизиты хранятся в одноименной табличной части объекта. Каждая строка этой таблицы содержит ссылку на само свойство и его значение.
Проанализируем базовый пример кода для решения этой задачи:
// Предположим, Переменная НоменклатураОбъект уже получена
Для каждого СтрокаРеквизита Из НоменклатураОбъект.ДополнительныеРеквизиты Цикл
// Получаем наименование свойства и его значение
ИмяСвойства = СтрокаРеквизита.Свойство.Наименование;
ЗначениеСвойства = СтрокаРеквизита.Значение;
// Запись в XML (упрощенно)
ЗаписьXML.ЗаписатьНачалоЭлемента("property");
ЗаписьXML.ЗаписатьАтрибут("name", ИмяСвойства);
ЗаписьXML.ЗаписатьТекст(Строка(ЗначениеСвойства));
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЦикла;
В данном примере мы используем СтрокаРеквизита.Свойство.Наименование для получения названия и Строка(ЗначениеСвойства) для преобразования значения в текстовый вид. Однако при реальной эксплуатации этого кода вы столкнетесь с рядом проблем, которые мы разберем далее.
Если вы решите записывать имя свойства непосредственно в название XML-тега (например, <Цвет корпуса>Синий</Цвет корпуса>), программа выдаст ошибку. Правила XML запрещают использование пробелов, спецсимволов и начало тега с цифр. Рассмотрим, как подготовить имя свойства для использования в качестве имени тега.
Выясним причину: в 1С наименование свойства может быть любым (например, "Вес, кг"). Чтобы сделать из него валидный тег, нужно удалить все недопустимые символы. Разберем функцию-помощник:
Функция ПодготовитьИмяТега(ИсходноеИмя)
Результат = ИсходноеИмя;
// Удаляем пробелы
Результат = СтрЗаменить(Результат, " ", "");
// Удаляем знаки препинания и спецсимволы
НедопустимыеСимволы = ",.()/-+*&^%$#@![]{}|";
Для Индекс = 1 По СтрДлина(НедопустимыеСимволы) Цикл
Символ = Сред(НедопустимыеСимволы, Индекс, 1);
Результат = СтрЗаменить(Результат, Символ, "");
EndЦикла;
Возврат Результат;
КонецФункции
Использование такой функции позволит избежать критических ошибок при формировании XML-структуры. Однако более надежным способом считается запись названия свойства в атрибут тега property, как показано в первом примере кода.
Значения дополнительных реквизитов в 1С имеют составной тип данных. Это может быть число, строка, дата, булево или ссылка на специальный справочник Значения свойств объектов. Простое использование функции Строка() не всегда дает нужный результат.
Проанализируем ситуацию подробнее:
Строка() вернет наименование элемента. Это обычно то, что нужно для выгрузки.Формат(Значение, "ЧГ=0").Формат(Значение, "ДФ=yyyy-MM-dd").Важно помнить, что в УТ 11 подсистема свойств разделена на Дополнительные реквизиты и Дополнительные сведения.
Дополнительные реквизиты хранятся в табличной части самого объекта. Они обычно используются для характеристик, которые важны непосредственно при работе с карточкой товара.
Дополнительные сведения хранятся в независимом регистре сведений ДополнительныеСведения. Если ваша задача — выгрузить абсолютно все свойства товара, вам придется обратиться и к этому регистру.
Рассмотрим, как получить дополнительные сведения программно:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеСведения.Свойство.Наименование КАК Имя,
| ДополнительныеСведения.Значение КАК Значение
|ИЗ
| РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
|ГДЕ
| ДополнительныеСведения.Объект = &Номенклатура";
Запрос.УстановитьПараметр("Номенклатура", СсылкаНаНоменклатуру);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Логика записи в XML
КонецЦикла;
Если вам необходимо выгрузить не один товар, а весь каталог (например, 50 000 позиций), использование метода Объект.ДополнительныеРеквизиты.Выгрузить() внутри цикла по всем товарам приведет к катастрофическому падению производительности. Это происходит потому, что 1С будет вынуждена считывать каждый объект из базы данных целиком, чтобы получить доступ к его табличной части.
Вместо этого мы рекомендуем использовать один запрос ко всей табличной части Номенклатура.ДополнительныеРеквизиты. Посмотрим на пример эффективного запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураДополнительныеРеквизиты.Ссылка КАК Товар,
| НоменклатураДополнительныеРеквизиты.Свойство.Наименование КАК СвойствоИмя,
| НоменклатураДополнительныеРеквизиты.Значение КАК Значение
|ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
|ГДЕ
| НоменклатураДополнительныеРеквизиты.Ссылка В (&МассивТоваров)
|ИТОГИ ПО
| Товар";
Запрос.УстановитьПараметр("МассивТоваров", СписокСсылок);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаТовар = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаТовар.Следующий() Цикл
// Записываем начало элемента номенклатуры в XML
ВыборкаРеквизитов = ВыборкаТовар.Выбрать();
Пока ВыборкаРеквизитов.Следующий() Цикл
// Записываем свойства конкретного товара
КонецЦикла;
// Записываем конец элемента номенклатуры
КонецЦикла;
Такой подход позволяет получить все данные одним обращением к СУБД, что в десятки раз быстрее, чем получение объектов в цикле.
В табличной части дополнительных реквизитов часто встречаются "пустые" строки. Это происходит, когда для вида номенклатуры назначено свойство, но в конкретной карточке товара оно не заполнено. Выгрузка пустых тегов (например, <color></color>) обычно не имеет смысла и только увеличивает размер XML-файла.
Перед записью в XML обязательно добавьте проверку на заполненность значения. Рассмотрим правильный подход:
Значение = СтрокаРеквизита.Значение;
Если ЗначениеЗаполнено(Значение) Тогда
// Только если значение есть, пишем в файл
ЗаписьXML.ЗаписатьНачалоЭлемента(ПодготовитьИмяТега(СтрокаРеквизита.Свойство.Наименование));
ЗаписьXML.ЗаписатьТекст(Строка(Значение));
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;
Также стоит обратить внимание на поле Заголовок у объекта Свойство. В 1С Наименование свойства может быть служебным (например, "Цвет (Сайт)"), а Заголовок — пользовательским ("Цвет"). В зависимости от задачи, возможно, стоит использовать именно Заголовок для выгрузки в XML, чтобы конечный пользователь видел понятные названия характеристик.
Мы проанализировали процесс выгрузки дополнительных реквизитов из 1С:УТ 11 и выяснили, что качественное решение задачи требует большего, чем простого перебора строк. Важно учитывать правила именования XML-узлов, правильно обрабатывать типы данных, различать реквизиты и сведения, а также заботиться о производительности системы при работе с большими объемами данных. Использование запросов с группировками и предварительная очистка имен тегов — залог надежной интеграции вашей учетной системы с внешними ресурсами.