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