Расшифровка отчета на СКД: свое меню и открытие документа

Дата: 19.09.2026 09:47:59
Отчеты
СКД
Расшифровка
Табличный документ
Управляемые формы
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Управляемые

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

Как работает расшифровка отчета на СКД

При выводе результата процессор компоновки кладет в ячейку табличного документа не значения полей, а только идентификатор — объект типа ИдентификаторРасшифровкиКомпоновкиДанных. Сами значения хранятся отдельно, в объекте ДанныеРасшифровкиКомпоновкиДанных, который заполняется при формировании отчета. Если с устройством схемы вы пока на «вы», начните со статьи о схеме компоновки данных.

Данные расшифровки — это набор связанных элементов двух типов:

  • ЭлементРасшифровкиКомпоновкиДанныхГруппировка — выведенная группировка отчета;
  • ЭлементРасшифровкиКомпоновкиДанныхПоля — значения полей: для группировки это поля, по которым она сгруппирована, для ячейки — поля, попавшие в ее расшифровку.

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

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

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

Когда стандартной расшифровки мало

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

Своя расшифровка СКД: код формы отчета

Пример рассчитан на отчет с основной схемой компоновки и управляемой формой, созданной конструктором; обычный это отчет или внешний — неважно. В схеме есть поля Номенклатура и Регистратор. Если в ячейке есть документ или товар, двойной щелчок показывает стандартное меню плюс пункты «Открыть документ» и «Движения по товару». В остальных ячейках все работает как раньше. Платформа 8.3, тонкий и веб-клиент, без модальных вызовов. Полный модуль формы — в поле «Код» ниже, здесь он разобран по частям.

Шаг 1. Значения полей ячейки

Функция работает на сервере без контекста формы: туда уходят адрес данных, идентификатор ячейки и список нужных полей, данные формы не передаются. Рекурсия поднимается по родителям и собирает в соответствие «путь к полю → значение» только перечисленные поля. У ячейки широкого отчета их бывают десятки, и гонять все на клиент при каждом двойном щелчке незачем.

&НаСервереБезКонтекста
Функция ЗначенияПолейРасшифровки(АдресДанныхРасшифровки, Расшифровка, ИменаПолей)

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

	Возврат ЗначенияПолей;

КонецФункции

&НаСервереБезКонтекста
Процедура ДобавитьЗначенияПолей(ЭлементРасшифровки, ЗначенияПолей, ИменаПолей)

	Если ЭлементРасшифровки = Неопределено Тогда
		Возврат;
	КонецЕсли;

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

	// У ячейки кросс-таблицы два родителя: группировка строк и колонок.
	Для Каждого Родитель Из ЭлементРасшифровки.ПолучитьРодителей() Цикл
		ДобавитьЗначенияПолей(Родитель, ЗначенияПолей, ИменаПолей);
	КонецЦикла;

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

Шаг 2. Перехват события ОбработкаРасшифровки

Обработчик назначайте из палитры свойств элемента Результат (событие «Обработка расшифровки»): конструктор подставит сигнатуру, которую ждет ваша версия платформы. В актуальных релизах 8.3 у процедуры четыре параметра.

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

	Если ПустаяСтрока(ДанныеРасшифровки)
		Или ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
		Возврат;
	КонецЕсли;

	ЗначенияПолей = ЗначенияПолейРасшифровки(ДанныеРасшифровки, Расшифровка,
		СтрРазделить("Регистратор,Номенклатура", ","));
	ДокументЯчейки = ЗначенияПолей.Получить("Регистратор");
	ТоварЯчейки = ЗначенияПолей.Получить("Номенклатура");

	ДополнительныеПункты = Новый СписокЗначений;
	Если ЗначениеЗаполнено(ДокументЯчейки) Тогда
		ДополнительныеПункты.Добавить("ОткрытьДокумент", НСтр("ru = 'Открыть документ'"));
	КонецЕсли;
	Если ЗначениеЗаполнено(ТоварЯчейки) Тогда
		ДополнительныеПункты.Добавить("ДвиженияТовара", НСтр("ru = 'Движения по товару'"));
	КонецЕсли;

	Если ДополнительныеПункты.Количество() = 0 Тогда
		Возврат; // в ячейке нет нужных полей - работает стандартная расшифровка
	КонецЕсли;

	СтандартнаяОбработка = Ложь;

	КонтекстВыбора = Новый Структура;
	КонтекстВыбора.Вставить("Расшифровка", Расшифровка);
	КонтекстВыбора.Вставить("ДокументЯчейки", ДокументЯчейки);
	КонтекстВыбора.Вставить("ТоварЯчейки", ТоварЯчейки);
	Оповещение = Новый ОписаниеОповещения("ВыборДействияРасшифровкиЗавершение", ЭтотОбъект, КонтекстВыбора);

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

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

Шаг 3. Обработка выбранного пункта меню

&НаКлиенте
Процедура ВыборДействияРасшифровкиЗавершение(ВыполненноеДействие, ПараметрВыполненногоДействия, КонтекстВыбора) Экспорт

	Если ВыполненноеДействие = "ОткрытьДокумент" Тогда
		ПоказатьЗначение(, КонтекстВыбора.ДокументЯчейки);

	ИначеЕсли ВыполненноеДействие = "ДвиженияТовара" Тогда
		ОткрытьОтчетПоТовару(КонтекстВыбора.ТоварЯчейки);

	ИначеЕсли ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
		ПоказатьЗначение(, ПараметрВыполненногоДействия);

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

	КонецЕсли;
	// Действие "Нет" или Неопределено - пользователь закрыл меню.

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

Шаг 4. Другой отчет с отбором по ячейке

&НаКлиенте
Процедура ОткрытьОтчетПоТовару(Товар)

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Отбор", Новый Структура("Номенклатура", Товар));
	ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
	ОткрытьФорму("Отчет.ДвиженияТоваров.Форма", ПараметрыФормы, ЭтотОбъект, Новый УникальныйИдентификатор);

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

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

Разбор ключевых строк

  • Проверка типа параметра Расшифровка. В ячейку табличного документа можно положить расшифровку любого типа, от СКД приходит ИдентификаторРасшифровкиКомпоновкиДанных. Остальное пропускаем без изменений.
  • СтрРазделить("Регистратор,Номенклатура", ",") — пути к полям, которые нужны обработчику. Функция есть с версии 8.3.6, в более старых релизах соберите массив через Добавить.
  • СтандартнаяОбработка = Ложь только там, где меню показываем сами. Ячейки без нужных полей (например, строка общего итога) уходят в стандартную расшифровку, и привычное поведение не ломается.
  • Новый ИсточникДоступныхНастроекКомпоновкиДанных(Отчет). Обработке расшифровки нужны схема и доступные поля, в форме отчета их источник — основной реквизит Отчет.
  • ПоказатьВыборДействия выводит то же меню, что и платформа, плюс пункты из списка ДополнительныеПункты. Значение элемента списка вернется в оповещение параметром ВыполненноеДействие, представление станет текстом пункта. Третий параметр (доступные действия) пропущен, поэтому стандартные пункты доступны все. Если передать массив значений ДействиеОбработкиРасшифровкиКомпоновкиДанных, меню можно урезать.
  • Стандартные пункты в оповещении. Раз стандартную обработку отключили, стандартные пункты тоже обрабатываем сами. Для них в ПараметрВыполненногоДействия приходят готовые настройки расшифровки. Их вместе с адресом данных и идентификатором упаковываем в ОписаниеОбработкиРасшифровкиКомпоновкиДанных и открываем эту же форму (свойство ИмяФормы) с параметром Расшифровка.
  • Новый УникальныйИдентификатор в ОткрытьФорму — ключ уникальности: каждая расшифровка открывается в своем окне и не подменяет уже открытое.
  • Параметр формы Отбор — структура «имя поля → значение». Форма второго отчета установит отбор, если поле с таким именем есть в его схеме.

Дополнительная расшифровка отчета 1С и типовые конфигурации

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

В конфигурациях на БСП (УТ 11, КА 2.0, ERP) большинство отчетов не имеет своей формы: они открываются в общей форме подсистемы «Варианты отчетов», и обработчик в форму отчета добавить некуда. В БП 3.0 основные бухгалтерские отчеты (оборотно-сальдовая ведомость, анализ и карточка счета) устроены иначе: у них собственные формы со своей обработкой расшифровки, поэтому обработчик добавляют в форму конкретного отчета через расширение. Для отчетов в общей форме путей два. Первый — дать отчету собственную форму; для внешнего отчета это обычно самый короткий путь, и код выше подходит без изменений. Второй — перехватить событие в клиентском переопределяемом модуле БСП ОтчетыКлиентПереопределяемый (процедура ОбработкаРасшифровки) через расширение, обязательно с проверкой, какой отчет открыт, чтобы не задеть остальные. Реквизиты в общей форме называются иначе, поэтому адрес данных расшифровки берите из переданной в процедуру формы отчета, а сигнатуру и имена сверяйте со своей редакцией БСП.

Типичные ошибки

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

Частые вопросы

Как открыть документ из отчета СКД без программирования?

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

Можно ли совсем отключить расшифровку в отчете?

Да. В обработчике ОбработкаРасшифровки установите СтандартнаяОбработка = Ложь и больше ничего не делайте. Если запретить нужно только часть ячеек, проверяйте их поля функцией из шага 1 и для остальных выходите раньше.

Будет ли код работать в веб-клиенте и в обычных формах?

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

Как передать во второй отчет не только отбор, но и период?

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

&НаСервере
Процедура ПриЗагрузкеВариантаНаСервере(Настройки)
	ПрименитьПереданныйПериод();
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеПользовательскихНастроекНаСервере(Настройки)
	ПрименитьПереданныйПериод();
КонецПроцедуры

&НаСервере
Процедура ПрименитьПереданныйПериод()

	Если ТипЗнч(Параметры.Период) <> Тип("СтандартныйПериод") Тогда
		Возврат; // отчет открыт без периода, например из меню
	КонецЕсли;

	Компоновщик = Отчет.КомпоновщикНастроек;
	ПараметрНастроек = Компоновщик.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
		Новый ПараметрКомпоновкиДанных("Период"));
	Если ПараметрНастроек = Неопределено Тогда
		Возврат; // в схеме нет параметра Период
	КонецЕсли;
	ПараметрНастроек.Значение = Параметры.Период;
	ПараметрНастроек.Использование = Истина;

	// Параметр в пользовательских настройках: значение берется оттуда.
	Если ЗначениеЗаполнено(ПараметрНастроек.ИдентификаторПользовательскойНастройки) Тогда
		ПользовательскийПараметр = Компоновщик.ПользовательскиеНастройки.Элементы.Найти(
			ПараметрНастроек.ИдентификаторПользовательскойНастройки);
		Если ПользовательскийПараметр <> Неопределено Тогда
			ПользовательскийПараметр.Значение = Параметры.Период;
			ПользовательскийПараметр.Использование = Истина;
		КонецЕсли;
	КонецЕсли;

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

Когда проще заказать

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

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

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


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.