Как передать поле в расшифровку макета СКД, если оно не входит в группировку?

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

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

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

Почему возникает ошибка «Поле не найдено»?

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

Способ 1: Использование ресурсов для полей расшифровки

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

Разберем по шагам, как это реализовать:

  1. Перейдем на вкладку «Ресурсы» в схеме компоновки данных.
  2. Добавим наше поле (например, ИсполнительныйДокумент) в список ресурсов.
  3. В колонке «Выражение» укажем агрегатную функцию. Если мы уверены, что в контексте группировки документ один, используем Максимум(ИсполнительныйДокумент) или Минимум(ИсполнительныйДокумент). Если документов может быть несколько, и нам нужен список для программной обработки, можно использовать функцию СоединитьСтроки(ИсполнительныйДокумент, ";").
  4. В колонке «Рассчитывать по» укажем те группировки, в которых нам нужна расшифровка по этому полю.

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

Способ 2: Настройка параметров расшифровки через структуру

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

В конструкторе макета для ячейки, где выводится сумма, выполним следующие действия:

  1. В свойствах ячейки найдем поле «Параметр расшифровки» и впишем туда произвольное имя, например, ПараметрДеталей.
  2. В нижней части редактора макетов появится таблица параметров. Найдем наш ПараметрДеталей.
  3. В колонке «Выражение» напишем конструктор структуры, который объединит все необходимые данные:

Новый Структура("ФизЛицо, ИсполнительныйДокумент, Сумма", ФизЛицо, ИсполнительныйДокумент, СуммаИспол)

Важный нюанс: Чтобы это выражение работало, поле ИсполнительныйДокумент должно быть доступно в контексте. Для этого его все же придется либо сделать ресурсом (как описано в способе 1), либо добавить в дополнительные поля группировки.

Способ 3: Скрытая группировка или дополнительные поля

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

Рассмотрим вариант с Дополнительными полями:

  1. Выберем нужную группировку в настройках отчета.
  2. Перейдем на вкладку «Дополнительные поля».
  3. Добавим поле ИсполнительныйДокумент.
  4. Установим свойство «Расположение» в значение «Отдельно» (хотя при использовании макета это не всегда критично, это заставляет СКД тянуть данные в выборку).

Если это не помогает, можно применить метод «невидимой» группировки. Мы добавляем ИсполнительныйДокумент в список полей группировки вместе с ФизЛицом, но в макете не рисуем для него отдельную область и в выбранных полях отключаем его отображение. Однако помните, что это может привести к дублированию строк, если у одного физлица несколько документов.

Способ 4: Программная обработка расшифровки в модуле формы

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


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

КонецПроцедуры

&НаСервере
Функция ПолучитьДанныеРасшифровки(ИдентификаторРасшифровки)
    
    // Извлекаем значение параметра из коллекции данных расшифровки компоновки
    ДанныеРасшифровкиОбъект = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
    ПолеРасшифровки = ДанныеРасшифровкиОбъект.Элементы[ИдентификаторРасшифровки].ПолучитьПоля()[0];
    
    Возврат ПолеРасшифровки.Значение;
    
КонецФункции

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

Подведение итогов

Мы выяснили, что ключ к решению проблемы кроется в управлении контекстом данных СКД. Чтобы макет «видел» поле, которое не участвует в группировке, необходимо:

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

← На главную