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