К статье
Практический материал

Отчеты и Аналитика · 13 мин

Тип документа как параметр в СКД 1С

Как передать тип документа в СКД 1С как параметр: составные типы, функции ВЫРАЗИТЬ и ТИПЗНАЧЕНИЯ, отбор по типу документа, готовые примеры запросов и настроек.

В отчётах на СКД нередко нужно, чтобы пользователь сам выбирал, по какому виду документов строить данные: реализациям, поступлениям, перемещениям или любому другому типу. Проблема в том, что платформа 1С не позволяет напрямую передать «имя типа» строкой в запрос и подставить его в имя таблицы — текст запроса формируется до выполнения, а параметры подставляются только в значения. Поэтому задача решается обходными, но вполне рабочими приёмами: составными типами, условиями по ТИПЗНАЧЕНИЯ, динамической подстановкой текста запроса или выбором источника данных.

Правильный приём зависит от того, что именно требуется: отфильтровать движения разных документов в одном регистре, дать пользователю выбор конкретного документа-ссылки или переключать сам источник данных отчёта. Ниже разобраны все основные сценарии с конкретными фрагментами запросов и настроек СКД, условиями применимости и типичными ошибками.

Почему тип документа нельзя передать «как есть»

В языке запросов 1С параметр (начинается с символа «&») может участвовать только как значение: в условиях сравнения, в списках В(), в функциях, принимающих значения. Имя таблицы, имя поля, имя типа в конструкции ТИП() — это элементы синтаксиса запроса, которые разбираются компилятором до того, как параметры получат свои значения. Поэтому конструкция вида «ВЫБРАТЬ * ИЗ &ТипДокумента» невозможна в принципе, и попытка так её написать приведёт к ошибке ещё на этапе проверки запроса.

Из этого ограничения следуют четыре практических подхода. Первый — параметр-ссылка на конкретный документ, когда пользователь выбирает сам документ, а СКД работает с его типом автоматически. Второй — отбор по типу значения через ТИПЗНАЧЕНИЯ и ТИП() в запросе или в отборе СКД. Третий — вычисляемое поле, которое выводит тип документа как строку, и отбор уже по этой строке. Четвёртый — программная генерация текста запроса в модуле объекта отчёта, где имя таблицы подставляется строковой конкатенацией до создания схемы компоновки.

Маршрут решения

Как выбрать подход

Пользователь должен выбрать конкретный документИспользуйте параметр со ссылочным типом нужного документа
Нужно отфильтровать движения по виду документа-регистратораДобавьте условие ТИПЗНАЧЕНИЯ(Регистратор) = ТИП(Документ.Имя) или отбор СКД по вычисляемому полю типа
Нужно переключать сам источник данных (таблицу документа)Формируйте текст запроса программно в событии ПриКомпоновкеРезультата или создавайте несколько наборов данных с объединением

Параметр со ссылкой на документ: самый простой сценарий

Если задача — отбор по конкретному документу, в схеме компоновки на закладке «Параметры» добавьте параметр, например «ДокументОтбора», и задайте ему тип «ДокументСсылка.РеализацияТоваровУслуг» (или другой нужный вид). В запросе используйте его обычным образом: Регистратор = &ДокументОтбора. Пользователь отчёта увидит поле выбора со стандартной формой подбора документа.

Чтобы дать выбор из нескольких видов документов, сделайте тип параметра составным: в редакторе типа отметьте несколько «ДокументСсылка.…». Платформа сама предложит пользователю сначала выбрать тип, затем документ. Это встроенный механизм, не требующий кода. Ограничение: список типов фиксируется в схеме, добавить «любой документ конфигурации» без перечисления нельзя, хотя можно отметить все нужные виды вручную.

Полезная деталь: для составного параметра в запросе можно проверять, какой именно тип выбрал пользователь, через ТИПЗНАЧЕНИЯ(&ДокументОтбора). Это позволяет, например, по-разному рассчитывать ресурсы для разных видов документов в одном запросе.

Отбор по виду документа через ТИПЗНАЧЕНИЯ и ТИП()

Когда отчёт строится по регистру, а регистраторами выступают разные виды документов, классический фильтр выглядит так: в запросе добавляется условие ГДЕ ТИПЗНАЧЕНИЯ(Движения.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг). Но это жёстко зашитый тип. Чтобы сделать его управляемым, применяют два приёма.

Первый приём — отбор в настройках СКД, а не в запросе. Добавьте в схему вычисляемое поле «ТипРегистратора» с выражением ТИПЗНАЧЕНИЯ(Регистратор). Затем в настройках отчёта (на закладке «Отбор») пользователь сможет наложить условие «ТипРегистратора Равно ТИП(Документ.РеализацияТоваровУслуг)». Значение типа в отборе выбирается через специальный редактор — пользователь указывает вид документа из списка метаданных. Это полностью декларативное решение без программирования.

Второй приём — параметр-ссылка с проверкой типа. В запросе пишется условие: ВЫБОР КОГДА &РегистраторДокумент = НЕОПРЕДЕЛЕНО ТОГДА ИСТИНА ИНАЧЕ ТИПЗНАЧЕНИЯ(Регистратор) = ТИПЗНАЧЕНИЯ(&РегистраторДокумент) КОНЕЦ. Пользователь выбирает любой документ нужного вида, а отбор срабатывает по его типу, а не по самой ссылке. Приём удобен, когда в интерфейсе проще указать «пример» документа, чем выбирать тип в редакторе отбора.

bsl
ВЫБРАТЬ
	Движения.Регистратор КАК Регистратор,
	Движения.Номенклатура КАК Номенклатура,
	СУММА(Движения.Количество) КАК Количество
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК Движения
ГДЕ
	ВЫБОР
		КОГДА &ПримерДокумента = НЕОПРЕДЕЛЕНО
			ТОГДА ИСТИНА
		ИНАЧЕ ТИПЗНАЧЕНИЯ(Движения.Регистратор) = ТИПЗНАЧЕНИЯ(&ПримерДокумента)
	КОНЕЦ
СГРУППИРОВАТЬ ПО
	Движения.Регистратор,
	Движения.Номенклатура

Вывод типа документа строкой в поле отчёта

Частая потребность — показать в отчёте колонку «Вид документа» с понятным названием: «Реализация товаров», «Поступление товаров» и т.п. Для этого в запросе используют функцию ПРЕДСТАВЛЕНИЕ срезами: ПРЕДСТАВЛЕНИЕ(Регистратор) даёт полное представление ссылки, а для выделения именно типа применяют ВЫБОР с перечислением вариантов: КОГДА Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг ТОГДА «Реализация» КОГДА Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг ТОГДА «Поступление» ИНАЧЕ «Прочее» КОНЕЦ.

Оператор «ССЫЛКА» в языке запросов проверяет принадлежность значения типу и работает быстрее, чем связка ТИПЗНАЧЕНИЯ + ТИП, поэтому для перечисления конкретных видов предпочтителен именно он. По такому строковому вычисляемому полю можно строить группировки и отборы в настройках СКД — пользователь получит привычный список строковых значений вместо технического выбора типа.

Ограничение приёма: список видов перечисляется в запросе вручную, и при добавлении в конфигурацию нового документа-регистратора он попадёт в ветку «ИНАЧЕ», пока запрос не доработают. Для отчётов по конкретному регистру это обычно приемлемо, так как состав регистраторов меняется редко.

Типичные ошибки
01
Попытка подставить параметр в имя таблицы (ИЗ &ИмяТаблицы) — запрос не скомпилируется, параметры работают только как значения
02
Использование строки с именем типа вместо ТИП(Документ.Имя) — сравнение типа со строкой всегда ложно, отбор молча ничего не вернёт
03
Сравнение ТИПЗНАЧЕНИЯ(Поле) = &ПараметрСтрокой — параметр должен содержать значение типа Тип, а не текст «Документ.Реализация»
04
Забытая обработка пустого параметра — без ветки НЕОПРЕДЕЛЕНО отбор по типу отсекает все записи, когда пользователь ничего не выбрал

Программная подстановка текста запроса

Когда нужно переключать сам источник данных — например, отчёт строится то по таблице документа «РеализацияТоваровУслуг», то по «ПоступлениеТоваровУслуг» — единственный надёжный способ: сформировать текст запроса в коде. Для этого отчёт создаётся с основной схемой компоновки, а в модуле объекта отчёта переопределяется событие ПриКомпоновкеРезультата, где схема подменяется или модифицируется до вызова компоновщика.

Типовая последовательность: на форму отчёта выносится реквизит «ВидДокумента» (строка или перечисление), в ПриКомпоновкеРезультата по его значению выбирается готовый шаблон текста запроса (обычно хранится в нескольких константах-строках модуля или строится конкатенацией с проверкой по белому списку имён), создаётся новый объект СхемаКомпоновкиДанных, и дальше выполняется стандартная цепочка: компоновщик макета, процессор компоновки, вывод в табличный документ.

Критически важно: имя таблицы должно подставляться только из заранее заданного списка допустимых значений, а не из произвольного ввода пользователя. Прямая подстановка пользовательской строки в текст запроса — это риск синтаксических ошибок и потенциальный канал внедрения произвольного кода запроса. Белый список из двух-пяти видов документов полностью закрывает проблему.

Альтернатива: несколько наборов данных с объединением

Если программирование нежелательно, а видов документов немного, схема СКД позволяет собрать данные декларативно: создайте в наборе данных типа «Объединение» несколько запросов — по одному на каждый вид документа. Каждый запрос выбирает поля в единой структуре (Документ, Контрагент, Сумма и т.д.) из своей таблицы. СКД объединит результаты, и пользователь сможет отбирать по строковому полю «ВидДокумента», которое в каждом подзапросе зашито константой.

Плюс подхода — полностью настроечное решение, которое поддерживается через конструктор без кода. Минус — объединение выполняет все подзапросы всегда, даже если пользователь отобрал только один вид. На больших таблицах это заметно сказывается на времени формирования. Частично проблему смягчает отбор в настройках, но он применяется уже после выполнения запроса, поэтому для тяжёлых источников лучше программная схема.

Сравнение вариантов

Отбор по ТИПЗНАЧЕНИЯ в настройках СКД

Без кода, работает с регистрами; не подходит для переключения таблицы-источника

Объединение наборов данных

Без кода, переключает источники; выполняет все подзапросы, медленнее на больших данных

Программная подстановка запроса

Гибко и быстро, выполняется только нужный запрос; требует кода и белого списка имён таблиц

Проверка результата и настройка доступности параметров

После настройки проверьте три вещи. Во-первых, поведение при пустом параметре: отчёт должен либо выводить все данные (ветка НЕОПРЕДЕЛЕНО в запросе), либо явно требовать заполнения — для этого в свойствах параметра схемы снимите флаг «Доступен список значений» при необходимости и настройте «Значение по умолчанию». Во-вторых, корректность отбора: сформируйте отчёт с выбранным видом документа и сверьте количество записей с контрольным запросом в консоли. В-третьих, видимость параметра для пользователя: на закладке «Параметры» схемы включите «Ограничение доступности» там, где параметр служебный, и добавьте параметр в настройки пользователя, если он должен быть виден на форме.

Для отбора по типу через настройки СКД убедитесь, что вычисляемое поле типа добавлено в список доступных полей отбора. Если поле не видно в настройках, чаще всего причина в том, что оно не перенесено в ресурсы/поля набора или у него снят флаг использования. Проверка занимает минуту и избавляет от типичной жалобы «отбор не работает».

Контрольные точки

Как проверить результат

Отчёт с выбранным видом документа
Норма

В результате только регистраторы выбранного типа, количество совпадает с контрольным запросом

Тревожный признак

Пустой результат или записи всех типов — проверьте условие и тип параметра

Пустое значение параметра
Норма

Выводятся все данные или выдаётся понятное требование заполнить параметр

Тревожный признак

Пустой отчёт без пояснений — нет ветки НЕОПРЕДЕЛЕНО

Отбор по типу в настройках
Норма

Поле типа доступно в списке отборов, значение выбирается из метаданных

Тревожный признак

Поля нет в списке — не настроены доступные поля отбора

В большинстве реальных задач достаточно связки «вычисляемое поле ТИПЗНАЧЕНИЯ + отбор в настройках СКД». К программной подстановке запроса стоит переходить только когда структура полей у разных видов документов существенно различается и объединение наборов становится громоздким.
ПЗ
Практическое замечание
Итог

Что важно запомнить

Тип документа нельзя передать параметром в имя таблицы запроса. Используйте параметр-ссылку с составным типом, отбор через ТИПЗНАЧЕНИЯ и ТИП(), строковое вычисляемое поле вида документа, объединение наборов данных или программную подстановку текста запроса по белому списку. Всегда обрабатывайте пустое значение параметра и проверяйте отчёт контрольным запросом.

Частые вопросы

Можно ли в параметр СКД передать строку «Документ.РеализацияТоваровУслуг» и сравнить с типом поля?

Нет. Сравнение ТИПЗНАЧЕНИЯ(Поле) со строкой всегда ложно, потому что тип и строка — разные типы данных. Если нужен параметр, передавайте значение типа Тип (в коде: Тип("ДокументСсылка.РеализацияТоваровУслуг")) или используйте строковое вычисляемое поле и сравнивайте строку со строкой.

Как дать пользователю выбор «все документы или один вид»?

Добавьте в запрос условие ВЫБОР КОГДА &Параметр = НЕОПРЕДЕЛЕНО ТОГДА ИСТИНА ИНАЧЕ <условие по типу> КОНЕЦ. При незаполненном параметре отбор отключается, при заполненном — работает. Альтернатива: отбор в настройках СКД, который пользователь сам включает флажком использования.

Чем отличается проверка «ССЫЛКА» от ТИПЗНАЧЕНИЯ в запросе?

Оператор «Поле ССЫЛКА Документ.Имя» проверяет принадлежность типу напрямую и обычно эффективнее. ТИПЗНАЧЕНИЯ возвращает значение типа Тип, которое затем сравнивается с ТИП(...). Для фиксированного списка видов предпочтительнее ССЫЛКА, для сравнения с типом параметра-ссылки — ТИПЗНАЧЕНИЯ.

Почему отбор по типу в настройках СКД не виден пользователю?

Чаще всего вычисляемое поле не добавлено в доступные поля отбора: откройте закладку «Настройки» схемы, узел «Отбор», и перенесите поле в доступные. Также проверьте, что у поля в наборе данных не снято ограничение использования в отборе.

Можно ли переключать таблицу-источник без программирования?

Да, через набор данных типа «Объединение» с несколькими подзапросами — по одному на вид документа. Платой будет выполнение всех подзапросов при каждом формировании, поэтому на крупных таблицах предпочтительнее программная подстановка текста запроса.

Как вывести в отчёт синоним вида документа, а не техническое имя?

Используйте конструкцию ВЫБОР с проверками «ССЫЛКА» по каждому виду и задайте понятные строки в ветках ТОГДА. Либо соединяйте запрос с таблицей документа и выводите представление нужного реквизита. ПРЕДСТАВЛЕНИЕ(Ссылка) даёт полное представление документа с номером и датой, а не только вид.