Как расшифровать ресурс макета СКД до документов-регистраторов и избежать ошибок?

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

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

Понимание проблемы: Расшифровка ресурсов и собственные макеты

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

Основная задача состоит в том, чтобы при двойном клике на числовое значение (ресурс) в отчете СКД открыть список документов, которые внесли свой вклад в это агрегированное значение. Рассмотрим, с какими трудностями сталкиваются разработчики.

Типичные ошибки при настройке расшифровки

Ошибка 1: "Ошибка компоновки макета по причине: Ошибка в выражении по причине: Синтаксическая ошибка"

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

Почему это происходит?

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

Ошибка 2: "Несоответствие типов (параметр номер '2')" в обработчике расшифровки

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

Почему это происходит?

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

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

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

Шаг 1: Подготовка запроса СКД

Прежде всего, убедимся, что в вашем запросе СКД присутствуют все необходимые поля, включая само поле Регистратор. Если ресурс группируется по каким-либо полям (например, Номенклатура, Подразделение), то эти поля также должны быть доступны в запросе. Поле Регистратор должно быть ссылочного типа (например, ДокументСсылка.ПоступлениеТоваровУслуг).

Шаг 2: Настройка реквизитов формы отчета

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

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

Шаг 3: Программное заполнение объекта ДанныеРасшифровкиКомпоновкиДанных

В процедуре ПриКомпоновкеРезультата (или аналогичной процедуре, где происходит выполнение компоновки данных) необходимо создать и заполнить объект ДанныеРасшифровкиКомпоновкиДанных, а затем поместить его во временное хранилище и передать его адрес в реквизит формы.

Рассмотрим пример кода:


// В модуле объекта отчета
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровкиПараметр, СтандартнаяОбработка)

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

Пояснения к коду:

Шаг 4: Настройка параметров расшифровки в собственном макете

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

  1. Для обычных полей (не ресурсов):

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

    Пример:

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

  2. Для ресурсов (агрегированных значений):

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

    Обычно это достигается одним из следующих способов:

    • Указание поля группировки: Если ваш ресурс сгруппирован, например, по Номенклатура и Подразделение, то в ПараметрахРасшифровки для ячейки ресурса можно указать выражение, которое возвращает идентификатор этой группировки. Например, если в запросе есть поле Номенклатура.Ссылка, то вы можете указать Номенклатура. Это позволит в обработчике расшифровки понять, для какой именно номенклатуры был запрошен ресурс.
    • Использование специально вычисленного поля-идентификатора: Вы можете добавить в запрос СКД вычисляемое поле, которое будет содержать уникальный идентификатор для каждой группы или для каждой детальной записи. Например, "ВЫБОР КОГДА ИСТИНА ТОГДА НОВЫЙ УНИКАЛЬНЫЙИДЕНТИФИКАТОР() КОНЕЦ" КАК ИДРасшифровки. Затем это поле можно указать в ПараметрахРасшифровки.
    • Обобщенный подход: Наиболее гибким является подход, когда ПараметрыРасшифровки для ячейки ресурса содержит имя поля, которое уникально идентифицирует контекст текущей строки (группировки) отчета. Например, если в вашем запросе есть поле ИдентификаторСтроки, которое уникально для каждой строки отчета, то в ПараметрахРасшифровки укажите ИдентификаторСтроки. В обработчике расшифровки мы сможем по этому идентификатору получить все поля текущей строки (включая группировки) и уже на их основе сформировать запрос к регистраторам.

    Пример для ресурса (настройка в собственном макете):

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

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

Шаг 5: Обработка расшифровки в форме отчета

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

Рассмотрим пример обработчика:


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

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

Пояснения к коду:

Дополнительные рекомендации

  1. Тестирование выражений макета: Если вы столкнулись с "Синтаксической ошибкой", попробуйте упростить выражение в ПараметрахРасшифровки до минимума или временно убрать его, чтобы убедиться, что проблема именно в выражении. Затем постепенно усложняйте его.
  2. Проверка типов полей: Убедитесь, что поле, которое вы ожидаете получить в обработчике расшифровки (например, Регистратор), имеет ожидаемый тип данных (например, ДокументСсылка).
  3. Использование стандартной расшифровки: Если ваша логика расшифровки не требует уникального меню, вы можете попробовать использовать стандартный механизм расшифровки 1С. Для этого в обработчике расшифровки табличного документа установите СтандартнаяОбработка = Истина;. Однако, для расшифровки ресурса до регистраторов, как правило, требуется ручная обработка.
  4. Работа с объединением наборов данных: Если ваш отчет СКД состоит из нескольких наборов данных, объединенных в один, будьте внимательны. Иногда пустой запрос в одном из наборов может приводить к неожиданным ошибкам расшифровки, таким как "Ожидается выражение ВЫБРАТЬ". Проверяйте все запросы.

Заключение

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

← На главную