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