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