Работа с дополнительными реквизитами и сведениями — это стандартная задача для любого разработчика 1С, работающего с современными конфигурациями на базе Библиотеки стандартных подсистем (БСП). Несмотря на кажущуюся простоту, механизм имеет свои архитектурные особенности, которые важно понимать для написания эффективного и отказоустойчивого кода. В этой статье мы подробно разберем, как получить значение нужного свойства через запрос и с помощью встроенных функций БСП, а также выясним, в чем разница между реквизитами и сведениями.
Прежде чем приступать к написанию кода, проанализируем, где именно хранятся данные (поможет инструментарий для быстрой разработки и отладки запросов в 1С). В БСП реализовано два принципиально разных механизма:
ДополнительныеРеквизиты. Преимущество в том, что данные читаются и записываются вместе с объектом в одной транзакции. Если же стандартных реквизитов не хватает, можно использовать универсальный механизм добавления табличных частей с помощью расширения.ДополнительныеСведения. Это позволяет добавлять информацию к объектам, которые уже закрыты для редактирования (например, в закрытых периодах), не изменяя сам объект.Выясним причину, почему это важно для запроса: если вы ищете данные в регистре, а создали реквизит в табличной части, запрос вернет пустой результат. Всегда проверяйте тип созданного свойства в пользовательском интерфейсе.
Рассмотрим ситуацию, когда нам необходимо получить значение реквизита для конкретного договора или списка документов. Поскольку реквизиты хранятся в табличной части, мы обращаемся к ней как к виртуальной таблице. Разберем по шагам создание правильного запроса.
Важный нюанс: поскольку в одной табличной части может быть множество разных свойств, нам обязательно нужно наложить фильтр по полю Свойство. Чтобы ускорить разработку, можно использовать дополнительные отборы, которые позволяют гибко работать со списками значений и диапазонами.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДоговорыДополнительныеРеквизиты.Значение КАК ЗначениеРеквизита
|ИЗ
| Справочник.ДоговорыКонтрагентов.ДополнительныеРеквизиты КАК ДоговорыДополнительныеРеквизиты
|ГДЕ
| ДоговорыДополнительныеРеквизиты.Ссылка = &Ссылка
| И ДоговорыДополнительныеРеквизиты.Свойство = &Свойство";
Запрос.УстановитьПараметр("Ссылка", ОбъектСсылка);
// Рекомендуется искать свойство не по наименованию, а по уникальному идентификатору или предопределенному значению
Запрос.УстановитьПараметр("Свойство", ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ИмяВашегоРеквизита"));
Результат = Запрос.Выполнить();
Проанализируем этот код. Если у объекта нет искомого реквизита, запрос не вернет ни одной строки. Если вы используете этот запрос в составе большого отчета с ЛЕВОЕ СОЕДИНЕНИЕ, не забудьте использовать функцию ЕСТЬNULL(..., ""), чтобы избежать пустых значений в результате.
Часто возникает задача получить сразу несколько значений (например, "Размер", "Цвет" и "Артикул") для одного объекта. Делать несколько запросов в цикле — плохая практика. Посмотрим на пример эффективного соединения:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Договоры.Ссылка КАК Ссылка,
| МАКСИМУМ(ВЫБОР КОГДА ДопРеквизиты.Свойство = &Свойство1 ТОГДА ДопРеквизиты.Значение КОНЕЦ) КАК Значение1,
| МАКСИМУМ(ВЫБОР КОГДА ДопРеквизиты.Свойство = &Свойство2 ТОГДА ДопРеквизиты.Значение КОНЕЦ) КАК Значение2
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК Договоры
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов.ДополнительныеРеквизиты КАК ДопРеквизиты
| ПО Договоры.Ссылка = ДопРеквизиты.Ссылка
|ГДЕ
| Договоры.Ссылка = &Ссылка
|СГРУППИРОВАТЬ ПО
| Договоры.Ссылка";
В данном примере мы используем конструкцию ВЫБОР внутри агрегатной функции МАКСИМУМ. Это позволяет "развернуть" строки табличной части в колонки одной строки результата. Это значительно ускоряет работу системы при построении сложных реестров.
Если в вашей конфигурации внедрена БСП (что верно для большинства современных решений, таких как БП 3.0, УТ 11, ERP), мы можем не писать запросы вручную. Разработчики 1С уже подготовили удобный программный интерфейс. Изучить все возможности системы поможет актуальный справочник по методам БСП с примерами использования.
Рассмотрим функцию ЗначениеСвойства из общего модуля УправлениеСвойствами. Это самый надежный и "чистый" способ с точки зрения стандартов разработки 1С:
// Объект - это ссылка на справочник или документ
// Свойство - ссылка на ПВХ.ДополнительныеРеквизитыИСведения
Значение = УправлениеСвойствами.ЗначениеСвойства(ОбъектСсылка, "ИмяРеквизитаДляРазработчика");
Обратите внимание на параметр Свойство. В современных версиях БСП можно передавать не только ссылку, но и Имя для разработчиков. Поиск по нему делает ваш код независимым от интерфейсных правок пользователей.
Если вам нужно получить значения свойств для 1000 контрагентов, вызов УправлениеСвойствами.ЗначениеСвойства в цикле приведет к 1000 запросам к базе данных. В таких ситуациях, чтобы не допустить зависаний системы, лучше использовать конвейер обработки задач или метод массового получения данных:
// МассивОбъектов - массив ссылок на ваши документы или справочники
ТаблицаЗначенийСвойств = УправлениеСвойствами.ЗначенияСвойствОбъектов(МассивОбъектов, Истина);
Эта функция выполнит один оптимизированный запрос и вернет таблицу значений со всеми свойствами для всех объектов из массива. Дальнейший поиск в таблице значений на сервере 1С будет выполняться мгновенно.
При выводе дополнительных реквизитов в отчеты через СКД мы часто сталкиваемся с тем, что поле Значение имеет составной тип. Чтобы отчет работал быстро, в запросе СКД используйте конструкцию ВЫРАЗИТЬ:
ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК Справочник.ЗначенияСвойствОбъектов)
Это подскажет планировщику SQL, с какой таблицей соединяться. Если же вам требуется формировать сложные отчеты программно, рекомендуем использовать СКДБилдер для упрощения программного создания СКД, который значительно сокращает объем кода.
Не забывайте, что доступ к дополнительным реквизитам регулируется отдельными ролями. Если программный код возвращает Неопределено или вызывает ошибку, возможно, пользователю требуется точечный пересчет прав доступа.
При разработке тиражных решений всегда проверяйте права доступа с помощью функции ПравоДоступа("Чтение", ...) или выполняйте код в привилегированном модуле, если это допустимо бизнес-логикой.
Таким образом, мы рассмотрели три основных подхода к получению данных. Выбор конкретного метода зависит от вашей задачи: для простых разовых операций идеально подходит УправлениеСвойствами.ЗначениеСвойства, а для сложных отчетов и массовой обработки данных — прямые запросы к табличным частям с использованием группировок.