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