Как отформатировать вывод функции ВычислитьВыражениеСГруппировкойТаблицаЗначений в СКД?

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

Когда мы работаем с Системой Компоновки Данных (СКД) в 1С, часто возникает необходимость выводить агрегированные данные, сгруппированные по определенным полям. Для этого мы можем использовать мощную функцию ВычислитьВыражениеСГруппировкойТаблицаЗначений. Однако стандартный формат вывода этой функции может не соответствовать нашим требованиям. Рассмотрим ситуацию, когда функция выдает результат в виде "ТипРациона; 1\nАдаптационный; 20", а нам нужно получить "ТипРациона = 1\nАдаптационный = 20". То есть, нам требуется заменить разделитель колонок (точку с запятой и пробел) на знак равенства и убедиться, что каждый элемент выводится с новой строки.

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

Понимание функции ВычислитьВыражениеСГруппировкойТаблицаЗначений

Прежде чем перейти к форматированию, нам важно понять, что именно возвращает функция ВычислитьВыражениеСГруппировкойТаблицаЗначений. Вопреки распространенному заблуждению, эта функция не возвращает строку напрямую. Она возвращает таблицу значений, которая затем компоновщиком макета автоматически преобразуется в строку для вывода в ячейку отчета. Это ключевой момент, поскольку понимание типа возвращаемого значения позволяет нам выбрать наиболее эффективный способ форматирования.

Когда мы указываем:


ВычислитьВыражениеСГруппировкойТаблицаЗначений("ТипРациона, Количество(Различные ДатаКормления)", "ТипРациона")

СКД выполняет следующие действия:

  1. Вычисляет агрегатное выражение Количество(Различные ДатаКормления).
  2. Группирует результаты по полю ТипРациона.
  3. Возвращает внутреннюю таблицу значений, где одна колонка содержит ТипРациона, а другая — вычисленное количество.
  4. При выводе этой таблицы в текстовое поле, СКД использует свои внутренние правила для преобразования таблицы в строку: по умолчанию колонки разделяются строкой "; ", а строки (элементы) таблицы — символом перевода строки.

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

Решение 1: Использование функции СоединитьСтроки с явными разделителями (Рекомендуемый подход)

Наиболее правильным и элегантным способом форматирования вывода таблицы значений в строку является использование функции СоединитьСтроки с ее специализированными параметрами. Эта функция позволяет нам явно указать, какие разделители использовать между колонками и между строками таблицы значений.

Давайте посмотрим на синтаксис функции СоединитьСтроки в контексте СКД:

СоединитьСтроки(Значение, РазделительЭлементов, РазделителиКолонок)

Разберем каждый параметр:

  1. Значение: Это может быть массив или, как в нашем случае, таблица значений, возвращаемая функцией ВычислитьВыражениеСГруппировкойТаблицаЗначений. Функция СоединитьСтроки будет обрабатывать каждую строку и каждую колонку этой таблицы.
  2. РазделительЭлементов: Эта строка будет вставлена между строками (элементами) таблицы значений. По умолчанию СКД использует символ перевода строки. Если мы хотим, чтобы каждый сгруппированный результат выводился с новой строки, мы должны указать соответствующий символ.
  3. РазделителиКолонок: Эта строка будет вставлена между колонками внутри каждой строки таблицы значений. Это именно тот параметр, который нам нужен для замены "; " на " = ".

Используя эти параметры, мы можем сразу получить желаемый результат. Нам необходимо указать " = " в качестве разделителя колонок и символ перевода строки в качестве разделителя элементов. В языке выражений СКД для символа перевода строки часто используется Символы.ПС. Однако, как показывает практика, Символы.ПС не всегда корректно работает напрямую в выражениях СКД и может вызывать ошибки. В таких случаях можно использовать явный перевод строки, вставленный прямо в выражение (Shift+Enter), или ASCII-код символа (например, Alt+013 для символа возврата каретки и новой строки).

Применяем это к нашему примеру. Окончательное выражение будет выглядеть так:


СоединитьСтроки(ВычислитьВыражениеСГруппировкойТаблицаЗначений("ТипРациона, Количество(Различные ДатаКормления)", "ТипРациона"), "
", " = ")

Здесь " " (с переводом строки между кавычками) используется как РазделительЭлементов, что обеспечит вывод каждого сгруппированного значения с новой строки. А " = " – это наш РазделителиКолонок, который заменит "; ".

Давайте подробнее рассмотрим, почему изначальная попытка в сообщении 2 не сработала так, как ожидалось:


СоединитьСтроки(ВычислитьВыражениеСГруппировкойТаблицаЗначений("ТипРациона, Количество(Различные ДатаКормления)", "ТипРациона"), " = ")

В этом случае строка " = " была передана как второй параметр, который интерпретируется как РазделительЭлементов. В результате, вместо того чтобы заменить разделитель колонок, она использовалась как разделитель между строками таблицы, что привело к выводу "Ростовой; 1 = Адаптационный; 20". Это показывает важность понимания порядка и назначения параметров функции СоединитьСтроки.

Важный момент по Символы.ПС: Хотя в общем коде 1С Символы.ПС прекрасно работает для обозначения перевода строки, в выражениях СКД, особенно в некоторых версиях платформы или контекстах, он может не распознаваться или вызывать синтаксические ошибки. В таких ситуациях, как было отмечено в сообщениях 13 и 14, можно использовать:

  1. Прямой перевод строки: Вставить перевод строки непосредственно в кавычки в выражении СКД, нажимая Shift+Enter. Например: " ".
  2. Символ по ASCII-коду: Для более надежного варианта можно использовать символы возврата каретки (Alt+013) или новой строки (Alt+010), если они поддерживаются в данном контексте СКД, но прямой перевод строки обычно более универсален и читабелен.

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

Решение 2: Многоступенчатая замена строк с использованием временного разделителя (Рабочий, но менее прямой подход)

Если по каким-либо причинам прямой подход с СоединитьСтроки кажется сложным или не работает в вашей конкретной конфигурации/версии, мы можем использовать обходной путь с функцией СтрЗаменить. Этот метод требует нескольких последовательных операций замены и использования временного уникального разделителя.

Предположим, что исходный вывод функции ВычислитьВыражениеСГруппировкойТаблицаЗначений выглядит так:


Ростовой; 1
Адаптационный; 20

Наша цель — заменить "; " на " = " и сохранить переводы строк. Проблема заключается в том, что функция СтрЗаменить работает с одной строкой, а не с таблицей значений, и нам нужно управлять двумя разными разделителями: разделителем колонок ("; ") и разделителем строк (переводом строки).

Разберем шаги этого метода:

Шаг 1: Объединяем строки с временным уникальным разделителем

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


СоединитьСтроки(ВычислитьВыражениеСГруппировкойТаблицаЗначений("ТипРациона, Количество(Различные ДатаКормления)", "ТипРациона"), " @@@ ")

Этот шаг преобразует наш вывод в одну строку, например:

Ростовой; 1 @@@ Адаптационный; 20

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

Шаг 2: Заменяем разделитель колонок

Далее мы используем функцию СтрЗаменить для замены исходного разделителя колонок ("; ") на желаемый " = ".


СтрЗаменить(СоединитьСтроки(ВычислитьВыражениеСГруппировкойТаблицаЗначений("ТипРациона, Количество(Различные ДатаКормления)", "ТипРациона"), " @@@ "), "; ", " = ")

После этого шага наша строка будет выглядеть так:

Ростовой = 1 @@@ Адаптационный = 20

Мы успешно заменили "; " на " = ", но нам все еще нужно вернуть переводы строк.

Шаг 3: Заменяем временный разделитель на перевод строки

Наконец, мы снова используем СтрЗаменить, чтобы заменить наш временный разделитель " @@@ " на реальный символ перевода строки. Как мы уже выяснили, прямой перевод строки в кавычках (" ") является надежным способом.


СтрЗаменить(СтрЗаменить(СоединитьСтроки(ВычислитьВыражениеСГруппировкойТаблицаЗначений("ТипРациона, Количество(Различные ДатаКормления)", "ТипРациона"), " @@@ "), "; ", " = "), " @@@ ", "
")

После выполнения всех этих операций мы получим желаемый результат:


Ростовой = 1
Адаптационный = 20

Этот многоступенчатый подход, хотя и менее прямой, чем использование всех параметров СоединитьСтроки, является рабочим решением и может быть полезен, если возникают сложности с прямым указанием разделителей колонок или элементов.

Дополнительные аспекты и советы

Мы рассмотрели два основных способа решения нашей задачи. Выбор между ними зависит от вашей конкретной ситуации, версии платформы и предпочтений в читаемости кода.

Язык выражений СКД

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

Расширенные возможности форматирования (в новых версиях 1С)

В более новых версиях платформы 1С:Предприятие (начиная с 8.3.27 и выше) появилась расширенная поддержка форматированных строк в СКД. Это открывает еще больше возможностей для гибкого управления внешним видом отчетов. Мы можем:

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

Использование экспортных функций общих модулей

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

Заключение

Мы выяснили, что функция ВычислитьВыражениеСГруппировкойТаблицаЗначений возвращает таблицу значений, а не строку, и это понимание является ключом к правильному форматированию. Мы рассмотрели два основных подхода для преобразования вывода в желаемый формат:

  1. Прямое использование функции СоединитьСтроки с полным набором параметров (Значение, РазделительЭлементов, РазделителиКолонок), которое является наиболее чистым и рекомендуемым решением.
  2. Многоступенчатая замена строк с использованием временного разделителя, которая является рабочим обходным путем, если первый метод вызывает затруднения.

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

← На главную