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