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