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