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