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