Как правильно выполнить конкатенацию ссылочного типа и строки в вычисляемом поле СКД?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой IT и автоматизация бизнеса
← На главную

При разработке отчетов с использованием Системы Компоновки Данных (СКД) разработчики часто сталкиваются с необходимостью объединить (выполнить конкатенацию) ссылочное поле (например, документ) и строковый реквизит. Давайте подробно проанализируем ситуацию, когда вместо ожидаемой строки в отчете выводится пустое значение, и разберем по шагам, как грамотно решать эту задачу с учетом всех технических нюансов платформы 1С.

Суть проблемы: почему пропадает текст в вычисляемом поле?

Рассмотрим пример из практики. Допустим, мы пытаемся создать в отчете СКД строку вида "Наряд на внутренние работы (обучение стажера)". У нас есть поле ТипДокумента (содержащее ссылку на документ) и поле ОписаниеРаботы (строка). Первоначальное выражение в вычисляемом поле выглядит так:


ВЫБОР 
    КОГДА ТИПЗНАЧЕНИЯ(ТипДокумента) = ТИП("Документ.НарядНаВнутренниеРаботы") 
    ТОГДА ТипДокумента + " (" + ОписаниеРаботы + ")" 
КОНЕЦ

В результате выполнения этого кода мы получаем пустоту. Выясним причину такого поведения. Дело в том, что выражение ТипДокумента + " (" + ОписаниеРаботы + ")" представляет собой попытку сложить ДокументСсылка и строку. В отличие от встроенного языка 1С, где платформа часто "прощает" такие вещи и выполняет неявное преобразование типов, СКД не выполняет неявное приведение типов при конкатенации. Выражение возвращает ошибку вычисления, и в отчет выводится пустая ячейка.

Решение 1: Явное приведение к строке

Чтобы код заработал, рассмотрим главное правило конкатенации в СКД: перед сложением со строкой мы обязаны явно привести все значения к типу "Строка". Для этого в СКД существует функция Строка(). Посмотрим на исправленный вариант кода:


ВЫБОР 
    КОГДА ТИПЗНАЧЕНИЯ(ТипДокумента) = ТИП("Документ.НарядНаВнутренниеРаботы") 
    ТОГДА Строка(ТипДокумента) + " (" + ОписаниеРаботы + ")" 
КОНЕЦ

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

Решение 2: Использование жестко заданной строки (если тип известен)

Если в ветке ТОГДА мы точно знаем, что тип документа — это "Наряд на внутренние работы", и нам не обязательно выводить его стандартное представление (включающее номер и дату), мы можем сразу написать нужный текст. Разберем этот пример:


ВЫБОР 
    КОГДА ТИПЗНАЧЕНИЯ(ТипДокумента) = ТИП("Документ.НарядНаВнутренниеРаботы") 
    ТОГДА "Документ Наряд на внутренние работы (" + ОписаниеРаботы + ")" 
КОНЕЦ

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

Дополнительные технические нюансы и оптимизация

Проанализируем ситуацию глубже. Чтобы вычисляемое поле работало надежно и без сбоев на любых данных, необходимо учесть ряд важных особенностей платформы.

1. Проблема пустых значений (NULL)

При использовании оператора + в СКД есть коварная особенность: если хотя бы один из операндов равен NULL (например, поле ОписаниеРаботы не заполнено и получено через левое соединение), результатом всего сложения станет NULL, и вся строка исчезнет. Защитим наше выражение с помощью функции ЕстьNull():


ВЫБОР 
    КОГДА ТИПЗНАЧЕНИЯ(ТипДокумента) = ТИП("Документ.НарядНаВнутренниеРаботы") 
    ТОГДА Строка(ТипДокумента) + " (" + ЕстьNull(ОписаниеРаботы, "") + ")" 
КОНЕЦ

2. Использование оператора ССЫЛКА

Вместо громоздкой конструкции ТИПЗНАЧЕНИЯ(Поле) = ТИП("...") рассмотрим более элегантный и рекомендуемый 1С способ проверки типа — оператор ССЫЛКА. Он делает код лаконичнее:


ВЫБОР 
    КОГДА ТипДокумента ССЫЛКА Документ.НарядНаВнутренниеРаботы 
    ТОГДА Строка(ТипДокумента) + " (" + ЕстьNull(ОписаниеРаботы, "") + ")" 
КОНЕЦ

3. Функция Представление() против Строка()

Для получения текста ссылки можно использовать не только Строка(), но и функцию ПРЕДСТАВЛЕНИЕ(). На практике ПРЕДСТАВЛЕНИЕ(ТипДокумента) часто отрабатывает эффективнее при массовом выводе строк, так как СКД умеет оптимизировать получение представлений.

4. Локализация отчета

Если конфигурация рассчитана на работу с несколькими языками, жестко вшивать текст не рекомендуется. Разберем использование функции НСтр() для мультиязычности:


ВЫБОР 
    КОГДА ТипДокумента ССЫЛКА Документ.НарядНаВнутренниеРаботы 
    ТОГДА НСтр("ru='Наряд на работы'") + " (" + ЕстьNull(ОписаниеРаботы, "") + ")" 
КОНЕЦ

5. Проверка на пустую ссылку

Посмотрим на еще одну потенциальную ошибку. Даже если тип совпал (это действительно документ нужного вида), ссылка может быть пустой (например, битая ссылка или незаполненный реквизит). Если мы попробуем получить от нее строковое представление, отчет может выглядеть некрасиво. Добавим проверку:


ВЫБОР 
    КОГДА ТипДокумента ССЫЛКА Документ.НарядНаВнутренниеРаботы И ТипДокумента.Ссылка ЕСТЬ НЕ NULL 
    ТОГДА ПРЕДСТАВЛЕНИЕ(ТипДокумента) + " (" + ЕстьNull(ОписаниеРаботы, "") + ")" 
КОНЕЦ

Вычисление в запросе или в вычисляемом поле?

В завершение проанализируем производительность. Вычисляемые поля СКД рассчитываются процессором уже после того, как данные получены из СУБД. Если в вашем отчете сотни тысяч строк, сложная склейка строк через условия ВЫБОР КОГДА в вычисляемых полях может существенно замедлить формирование отчета.

Рекомендация: по возможности переносите сложную логику и конкатенацию строковых полей на уровень запроса SQL (в текст основного набора данных). Используйте оператор объединения строк ПОДСТРОКА() и функции работы с NULL непосредственно в тексте запроса. Это позволит СУБД выполнить тяжелую работу, а СКД останется лишь вывести готовые данные.

← На главную