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