Как полностью вывести параметры в отчетах 1С СКД, когда они представлены списками значений?

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

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

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

Прежде чем перейти к решениям, давайте выясним причину такого поведения СКД:

  1. Ограничения платформы: Платформа 1С:Предприятие, как и многие другие системы, имеет внутренние ограничения на длину текста, отображаемого в стандартных элементах отчета, таких как шапка или область параметров. Это сделано для оптимизации производительности и предотвращения создания слишком широких или высоких элементов, которые могут нарушить общую структуру отчета и затруднить его чтение.
  2. Автоматический вывод: Когда мы устанавливаем флажок "Выводить параметры" в настройках СКД, система автоматически формирует текстовое представление выбранных значений. Для простых типов данных (дата, число, булево) это работает идеально. Однако для сложных типов, таких как списки значений, или для произвольных строк большой длины, применяется алгоритм сокращения, чтобы уместить информацию в отведенное пространство.
  3. Цель отображения: Изначально автоматический вывод параметров предназначен для краткого информирования пользователя о примененных отборах. Для детального анализа полного списка предполагается использование других механизмов или программная доработка.

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

Решение 1: Программное управление выводом параметров через процедуру ПриКомпоновкеРезультата

Этот подход является одним из наиболее мощных и гибких, позволяющим полностью контролировать вывод любых данных, включая списки параметров. Мы перехватим управление формированием отчета в процедуре ПриКомпоновкеРезультата модуля отчета.

  1. Получение значений параметров: Первым шагом является получение фактических значений параметров, которые пользователь ввел или выбрал. Для этого мы можем обратиться к объекту КомпоновщикНастроек.

    
    Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
        СтандартнаяОбработка = Ложь; // Отключаем стандартную компоновку, чтобы управлять ей вручную
    
        // Получаем значения параметров из текущих настроек компоновщика
        Настройки = КомпоновщикНастроек.Настройки;
        Параметры = Настройки.ПараметрыДанных;
    
        // Предположим, у нас есть параметр с именем "СписокПодразделений"
        ЗначениеПараметра = Неопределено;
        Для Каждого ЭлементПараметра Из Параметры.Элементы Цикл
            Если ЭлементПараметра.Имя = "СписокПодразделений" Тогда
                ЗначениеПараметра = ЭлементПараметра.Значение;
                Прервать;
            КонецЕсли;
        КонецЦикла;
    
        Если ЗначениеПараметра Тогда
            // Теперь ЗначениеПараметра содержит выбранный список значений.
            // Мы можем его преобразовать в нужный нам формат, например, в строку
            // или в несколько строк, чтобы вывести в макете.
            // Рассмотрим ниже, как это сделать.
        КонецЕсли;
    
        // Далее будет код для формирования макета и вывода
        // ...
    КонецПроцедуры
    

    Здесь ЗначениеПараметра, если оно было установлено пользователем как список, будет содержать объект типа СписокЗначений или Массив.

  2. Создание собственного макета для вывода: Мы рекомендуем создать отдельный макет в отчете, например, макет типа "Область" или "Таблица", который будет служить заголовком и отображать параметры. В этом макете мы можем использовать многострочные текстовые поля. Создадим макет "ШапкаОтчета" с одной ячейкой, назовем ее "ТекстПараметров".

  3. Формирование строки для вывода: Мы должны преобразовать наш список значений в удобный для отображения текстовый формат. Это может быть одна строка с разделителями или многострочный текст.

    
    // ... внутри процедуры ПриКомпоновкеРезультата, после получения ЗначениеПараметра
    
    ТекстДляВывода = "";
    Если ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений") Тогда
        Для Каждого ЭлементСписка Из ЗначениеПараметра Цикл
            Если Не ПустаяСтрока(ТекстДляВывода) Тогда
                ТекстДляВывода = ТекстДляВывода + РазделительСтрок; // Или ", "
            КонецЕсли;
            ТекстДляВывода = ТекстДляВывода + Строка(ЭлементСписка.Значение);
        КонецЦикла;
    ИначеЕсли ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда
        // Обработка массива аналогична
        Для Каждого ЭлементМассива Из ЗначениеПараметра Цикл
            Если Не ПустаяСтрока(ТекстДляВывода) Тогда
                ТекстДляВывода = ТекстДляВывода + РазделительСтрок; // Или ", "
            КонецЕсли;
            ТекстДляВывода = ТекстДляВывода + Строка(ЭлементМассива);
        КонецЦикла;
    КонецЕсли;
    
    // Если нужно более сложное форматирование, например, с нумерацией или в несколько колонок,
    // то логику формирования ТекстДляВывода следует усложнить.
    
  4. Вывод макета в ДокументРезультат: Теперь, когда у нас есть сформированный текст, мы выводим его с помощью нашего макета.

    
    // ... внутри процедуры ПриКомпоновкеРезультата
    
    // Получаем макет
    МакетКомпоновки = ПолучитьМакет("ШапкаОтчета"); // "ШапкаОтчета" - это имя макета в отчете
    ОбластьМакета = МакетКомпоновки.ПолучитьОбласть("ОбластьЗаголовка"); // Предположим, область называется "ОбластьЗаголовка"
    
    // Заполняем параметр макета
    ОбластьМакета.Параметры.ТекстПараметров = "Подразделения: " + ТекстДляВывода; // "ТекстПараметров" - это имя параметра в ячейке макета
    
    // Выводим область макета
    ДокументРезультат.Вывести(ОбластьМакета);
    
    // Затем вызываем стандартную компоновку, но уже без вывода параметров,
    // чтобы избежать дублирования или обрезки.
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(КомпоновщикНастроек, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина); // Истина - для добавления к существующему ДокументРезультат
    

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

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

Решение 2: Использование вычисляемого поля в СКД

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

  1. Создание вычисляемого поля: Мы добавим в набор данных-объект или набор данных-запрос новое вычисляемое поле. Предположим, что ваш параметр "СписокПодразделений" используется в отборе запроса. Тогда нам нужно будет получить его значение и преобразовать в строку.

    Если параметр передается в запрос, то мы можем попытаться использовать его в вычисляемом поле на уровне СКД. Например, если параметр &СписокПодразделений является типом СписокЗначений, его можно преобразовать в строку в самом запросе, если версия платформы позволяет использовать функции работы со строками над параметрами-коллекциями. Однако наиболее надежный способ — это передать список как временную таблицу в запрос, а затем объединить ее элементы.

    
    // Пример запроса, если список подразделений передается как временная таблица ВТ_Подразделения
    ВЫБРАТЬ
        Подразделения.Ссылка КАК Подразделение
    ПОМЕСТИТЬ ВТ_Подразделения
    ИЗ
        Справочник.Подразделения КАК Подразделения
    ГДЕ
        Подразделения.Ссылка В (&СписокПодразделений)
    ;
    
    ВЫБРАТЬ
        МАКСИМУМ(ОбъединитьСтроки(ВТ_Подразделения.Подразделение)) КАК СтрокаПодразделений
    ИЗ
        ВТ_Подразделения КАК ВТ_Подразделения
    // Здесь функция ОбъединитьСтроки(Значение) - это гипотетическая функция,
    // которую СКД может поддержать для объединения строк.
    // В реальных условиях часто приходится сначала выгружать список во временную таблицу,
    // а затем объединять строки через Запрос.Выполнить().ТЗ.ВыгрузитьСтроку().Соединить().
    // Или использовать функции платформы, если они доступны в выражении поля.
    

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

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

    Более реалистичный подход для вычисляемого поля: передача уже преобразованной строки в набор данных "Объект" или как дополнительное поле к основному запросу. Для этого нам все равно потребуется использовать программный код в процедуре ПриКомпоновкеРезультата для формирования этой строки и ее передачи.

  2. Вывод вычисляемого поля: После создания, это поле можно вывести как обычное поле отчета, например, в заголовке или как элемент группировки.

    Преимущества: Минимальные изменения в коде (или их отсутствие, если поле формируется в запросе, что реже). Интегрируется в структуру отчета как обычное поле.

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

Решение 3: Добавление отдельной таблицы для вывода списка параметров

Этот метод предполагает создание в структуре отчета СКД отдельного элемента "Таблица", который будет предназначен исключительно для вывода выбранного списка значений параметра.

  1. Создание дополнительного набора данных:

    Мы можем создать отдельный набор данных типа "Объект" и программно заполнить его в процедуре ПриКомпоновкеРезультата. Этот набор данных будет содержать одну или несколько колонок, в которых будут перечислены значения нашего параметра.

    
    // ... внутри процедуры ПриКомпоновкеРезультата, до компоновки основного отчета
    
    // Создаем временную таблицу для параметров, если ЗначениеПараметра определено
    ПараметрыДляОтчета = Новый ТаблицаЗначений;
    ПараметрыДляОтчета.Колонки.Добавить("Подразделение");
    
    Если ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений") Тогда
        Для Каждого ЭлементСписка Из ЗначениеПараметра Цикл
            НоваяСтрока = ПараметрыДляОтчета.Добавить();
            НоваяСтрока.Подразделение = ЭлементСписка.Значение;
        КонецЦикла;
    КонецЕсли;
    
    // Передаем таблицу значений в параметры СКД для набора данных "Объект"
    // Это требует, чтобы в схеме СКД был параметр с именем "ТаблицаПараметров"
    // и соответствующий набор данных "Объект", привязанный к этому параметру.
    КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ТаблицаПараметров", ПараметрыДляОтчета);
    
    // Дальнейший код для вывода основного отчета
    // ...
    

    В самой схеме СКД создаем набор данных "Объект" с именем, например, "ТаблицаПараметров", и указываем в качестве источника тип ТаблицаЗначений. В списке полей указываем "Подразделение".

  2. Настройка структуры отчета:

    Добавьте в структуру отчета новый элемент "Таблица". В свойствах этой таблицы укажите основной набор данных "ТаблицаПараметров". Добавьте в таблицу группировку по полю "Подразделение" и выведите его в детальных записях. Можно также добавить заголовок для этой таблицы, например, "Выбранные подразделения:".

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

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

Альтернативный подход: Переосмысление работы с большими списками отборов

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

  1. Группировка по общим признакам: Если в списке 12, 50 или 100500 подразделений, возможно, они имеют какой-то общий признак (например, входят в одну группу, относятся к определенному региону, типу деятельности). В таком случае вместо выбора множества отдельных подразделений, мы можем предоставить пользователю возможность выбрать этот общий признак.

    Например, вместо выбора 12 конкретных подразделений, предложить выбрать "Группу подразделений: Отдел продаж". Тогда в параметрах отчета будет отображаться только "Отдел продаж", а не весь список входящих в него подразделений. СКД затем сама развернет эту группу в соответствующий отбор по всем элементам.

    Преимущества: Значительно сокращает объем выводимой информации, делает отбор более высокоуровневым и понятным. Упрощает пользовательский интерфейс для выбора.

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

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

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

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

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

Заключение

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

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

← На главную