При разработке отчетов на схеме компоновки данных (СКД) в 1С часто возникает необходимость кастомизировать внешний вид отчета с помощью вкладки «Макеты». Однако при переходе на собственный макет разработчики регулярно сталкиваются с проблемой: стандартная расшифровка перестает работать, а при двойном клике по ячейке (например, с названием организации) система выдает ошибку: «Ошибка при вызове метода контекста (ВыбратьДействие) по причине: Несоответствие типов (параметр номер '1')».
Выясним причину этой ошибки. Она заключается в том, что вместо ожидаемого объектом ОбработкаРасшифровкиКомпоновкиДанных системного идентификатора (тип ИдентификаторРасшифровкиКомпоновкиДанных), в обработчик события передается обычное строковое значение ячейки (например, "ООО ЭКО"). Давайте подробно разберем, как решить эту проблему на обычных формах (на примере конфигурации Управление торговлей 10.3) шаг за шагом.
Когда мы используем стандартный вывод СКД, платформа автоматически генерирует и связывает идентификаторы расшифровки с ячейками табличного документа. Но как только мы задействуем собственный макет, эту связь необходимо настроить вручную. Если мы просто укажем параметр в ячейке макета, система выведет текст, но "забудет", какое именно системное поле за ним стоит.
Рассмотрим, как правильно настроить ячейку макета в конструкторе СКД:
Организация).Организация, то параметру расшифровки зададим имя, например, ОрганизацияРасшифровка.ОрганизацияРасшифровка.Организация (или Организация.Ссылка, чтобы расшифровывался непосредственно ссылочный объект, а не его строковое представление).Открыть значение или оставим его по умолчанию.Благодаря этой несложной настройке платформа поймет, что при клике на ячейку нужно передавать не текст "ООО ЭКО", а уникальный идентификатор этой строки в таблице расшифровки СКД.
Поскольку мы используем собственный макет, отчет практически всегда формируется программно в модуле. На обычных формах крайне важно правильно инициализировать и передавать контейнер ДанныеРасшифровки на всех этапах компоновки макета и вывода результата. Если этого не сделать, идентификаторы расшифровки просто не запишутся в итоговый табличный документ.
Проанализируем правильный шаблон кода для формирования отчета в модуле объекта или формы:
Процедура СформироватьОтчет(ТабличныйДокумент) Экспорт
ТабличныйДокумент.Очистить();
// Инициализируем объект хранения расшифровки.
// На обычных формах это должен быть полноценный объект, а не строка-адрес!
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// КРИТИЧЕСКИ ВАЖНО: передаем ДанныеРасшифровки третьим параметром в метод Выполнить
МакетКомпоновки = КомпоновщикМакета.Выполнить(
СхемаКомпоновкиДанных,
КомпоновщикНастроек.Настройки,
ДанныеРасшифровки
);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// КРИТИЧЕСКИ ВАЖНО: передаем ДанныеРасшифровки третьим параметром при инициализации
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Если мы упустим передачу переменной ДанныеРасшифровки хотя бы в одном из указанных методов, связь между ячейками макета и структурой данных СКД будет полностью утеряна. В результате клик по ячейке снова вернет нам лишь текстовое представление.
Посмотрим на настройки свойств элементов самой формы отчета. В обычных формах за связь таблицы на форме и данных расшифровки отвечают свойства элементов управления. Выполним следующие проверки:
ДанныеРасшифровки (тип значения должен соответствовать типу ДанныеРасшифровкиКомпоновкиДанных).Результат).ДанныеРасшифровки.Это свяжет интерактивные действия пользователя в поле табличного документа с таблицей расшифровки, которую мы сформировали программно на Шаге 2.
Теперь, когда все связи настроены корректно, напишем отказоустойчивый код для события РезультатОбработкаРасшифровки в модуле формы. Обратите внимание, что мы работаем на обычных формах, поэтому директивы компиляции (такие как &НаКлиенте) здесь использовать не нужно.
Добавим обязательную проверку типа получаемого параметра Расшифровка. Это спасет программу от аварийного завершения, если пользователь кликнет по области шапки, подвала или по декоративным элементам макета, где расшифровка не предусмотрена.
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
// Если пользователь кликнул по области без настроенной расшифровки,
// в параметр придет строка, число или Неопределено. Прекращаем обработку.
Если ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Возврат;
КонецЕсли;
// Отменяем стандартное открытие значения платформой, так как мы управляем процессом вручную
СтандартнаяОбработка = Ложь;
// Инициализируем источник настроек на основе схемы компоновки
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникНастроек);
// Формируем список доступных пользователю действий при клике
ДоступныеДействия = Новый Массив;
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение);
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Упорядочить);
Перем ВыполненноеДействие, ПараметрВыполненногоДействия;
// Метод ВыбратьДействие откроет стандартное контекстное меню выбора действия
ОбработкаРасшифровки.ВыбратьДействие(Расшифровка, ВыполненноеДействие, ПараметрВыполненногоДействия, ДоступныеДействия);
// Анализируем выбор пользователя
Если ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
// Открываем карточку значения (например, форму элемента справочника "Организации")
ОткрытьЗначение(ПараметрВыполненногоДействия);
ИначеЕсли ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Упорядочить Тогда
// Здесь можно описать программную сортировку, если это необходимо
КонецЕсли;
КонецПроцедуры
Мы подробно разобрали комплексное решение проблемы некорректной расшифровки при использовании собственных макетов СКД. Главное правило — всегда сопоставлять «Параметр расшифровки» в свойствах ячейки макета СКД с реальным полем набора данных, а также тщательно следить за передачей объекта ДанныеРасшифровки во время программного формирования табличного документа на сервере.