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