При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с необходимостью вывести в одной ячейке список связанных данных, например, номера и даты входящих документов. Стандартная агрегатная функция Сумма здесь не поможет, и на сцену выходит мощный инструмент — СоединитьСтроки. Однако при попытке объединить данные разных типов или добавить разделители строк возникают ошибки типизации или неожиданные результаты в виде текста "Пустое значение".
В этой статье мы подробно разберем, как правильно настраивать выражения в ресурсах СКД, почему возникают ошибки при использовании оператора "+" и как добиться идеального отображения данных с переносом каждой записи на новую строку.
Рассмотрим ситуацию, когда в ресурсах СКД пишется выражение следующего вида:
СоединитьСтроки(Массив(ВЫБОР КОГДА ЗНАЧЕНИЕЗАПОЛНЕНО(НомерВходящего) ТОГДА НомерВходящего + " от " + ДатаВходящего КОНЕЦ), ",", "")
Система выдает ошибку, хотя, казалось бы, логика верна. Выясним причину. В языке выражений СКД оператор + крайне чувствителен к типам операндов. Если НомерВходящего — это строка, а ДатаВходящего — это дата, система не может автоматически привести их к общему знаменателю внутри агрегатной функции Массив. Кроме того, если одно из полей содержит значение NULL, вся цепочка сложения может превратиться в NULL.
Для решения этой проблемы необходимо обеспечить строковый тип для всех участников конкатенации. Проанализируем способы приведения типов:
Представление(). Она преобразует любое значение (ссылку, дату, число) в строку так, как оно отображается в пользовательском интерфейсе.Формат(). Это наиболее предпочтительный вариант для дат, так как позволяет жестко задать вид строки, например, Формат(ДатаВходящего, "ДФ=dd.MM.yyyy").Как показала практика обсуждения, использование функции Массив внутри СоединитьСтроки не всегда удобно, если нужно объединить несколько колонок с разделителями. Более гибким инструментом является функция ТаблицаЗначений. Рассмотрим эффективную конструкцию, которая позволяет собрать номер, статичный текст и дату:
СоединитьСтроки(ВЫБОР КОГДА ЗНАЧЕНИЕЗАПОЛНЕНО(НомерВходящего) ТОГДА
ТаблицаЗначений("№ ", НомерВходящего, " от ", Формат(ДатаВходящего, "ДФ=dd.MM.yyyy"))
КОНЕЦ, , "")
Разберем, что здесь происходит. Функция ТаблицаЗначений внутри ресурсов СКД формирует временную структуру данных из переданных аргументов. Важный нюанс: мы вынесли условие ВЫБОР КОГДА наружу. Это позволяет системе вообще не создавать строку в итоговом списке, если номер документа не заполнен. Если оставить условие внутри, вы рискуете получить в отчете строки вида " от <Пустое значение>" или технический текст <Объект не найден>.
Часто требуется, чтобы документы в ячейке не шли сплошным текстом через запятую, а располагались друг под другом. Многие пытаются использовать Символы.ПС, но в языке выражений СКД эта константа напрямую не доступна.
Посмотрим на параметры функции СоединитьСтроки(Коллекция, РазделительСтрок, РазделительКолонок):
Поэтому, чтобы каждый документ выводился с новой строки, достаточно написать:
СоединитьСтроки(Массив(ПредставлениеНомера), , "")
Обратите внимание на пустой второй параметр. Именно он заставляет СКД вставлять невидимый символ \n между элементами массива.
Для того чтобы не загромождать вкладку "Ресурсы" сложными конструкциями, мы рекомендуем использовать двухэтапный подход. Это значительно упрощает отладку отчета.
Шаг 1. На вкладке Вычисляемые поля создаем поле, например, СтрокаДокумента. В выражении пишем логику формирования одной строки:
ВЫБОР
КОГДА ЗначениеЗаполнено(НомерВходящего)
ТОГДА НомерВходящего + " от " + Формат(ДатаВходящего, "ДФ=dd.MM.yyyy")
ИНАЧЕ ""
КОНЕЦ
Шаг 2. На вкладке Ресурсы для этого поля используем простую и понятную агрегатную функцию:
СоединитьСтроки(Массив(СтрокаДокумента), , "")
Такой подход позволяет избежать проблем с "Неверными параметрами +", так как сложение происходит на уровне вычисляемого поля, где типы данных обрабатываются более предсказуемо, а в ресурс попадает уже готовая строка. Для объединения данных в одну ячейку также можно использовать способ сбора значений колонки из нескольких строк в СКД.
Проанализируем ситуацию, когда в данных могут быть дубликаты (например, один и тот же номер документа попал в выборку несколько раз из-за связей с другими таблицами). Чтобы в итоговой ячейке номера не повторялись, используйте ключевое слово РАЗЛИЧНЫЕ:
СоединитьСтроки(Массив(РАЗЛИЧНЫЕ СтрокаДокумента), , "")
Если же вам важно, чтобы список документов внутри ячейки был отсортирован по дате, можно воспользоваться функцией Упорядочить (доступно в последних версиях платформы 8.3):
СоединитьСтроки(Упорядочить(Массив(СтрокаДокумента), "СтрокаДокумента Возр"), , "")
Выясним еще один момент: как избавиться от NULL. В языке выражений СКД хорошим тоном считается использование функции ЕСТЬNULL(Поле, ""). Это гарантирует, что даже если в базе данных значение отсутствует, ваша функция СоединитьСтроки получит пустую строку, а не неопределенность, которая может прервать выполнение всего выражения.
Подводя итог, можно сказать, что наиболее стабильным и гибким решением для вывода списков в ресурсах СКД является комбинация вычисляемого поля (для подготовки текста) и функции СоединитьСтроки с использованием массива и стандартного разделителя для переноса строк. Для практического ознакомления с реализацией подобных отчетов можно использовать примеры использования функций СКД Массив и СоединитьСтроки в отчетах.