СКД. Добавление собственного пункта расшифровки.

Потребовалось как-то создать отчет, который выводит информацию об оплате товара: не оплачен (сумма оплаты = 0), частично оплачен (сумма оплаты < суммы товара), оплачен (сумма оплаты = сумма товара). Сумма оплаты формируется по неким условиям, и требуется предоставлять пользователю информацию о том, каким образом была сформирована сумма, выражаясь терминами СКД: расшифровать сумму оплаты товара.

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

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

К сожалению, дальше требуется написание программного кода, как говорится: "Без труда не вынешь и рыбку из пруда". Второй пункт реализации данной задачи - это задание собственной обработки расшифровки для табличного документа, делается это в модуле формы (см. рисунок 3):
  • для обычной формы - в событии ОбработкаРасшифровки;
  • для управляемой формы - в событии ОбработкаДополнительнойРасшифровки.
Рисунок 3. Определение процедуры для события табличного документа ОбработкаРасшифровки
На заметку для отчетов, работающих под управляемыми формами! Переопределять действия по расшифровке отчета, вызываемой при нажатии правой кнопки мыши, нужно в обработчике события ОбработкаДополнительнойРасшифровки. А в обработчике события ОбработкаРасшифровки нужно переопределять действия, происходящие при двойном щелчке мыши на поле отчета.

Так как собственная расшифровка должна выполняться для детальной записи, написал функцию по определению такой записи:
Функция ЭтоДетальнаяЗапись(ДанныеРасшифровки, Расшифровка)
ЭтоДетальнаяЗапись = Ложь;
Элемент = ДанныеРасшифровки.Элементы[Расшифровка];
Если ТипЗнч(Элемент) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
Элементы = Элемент.ПолучитьРодителей();
Если Элементы.Количество() > 0 Тогда
Элемент = Элементы[0];
Если ТипЗнч(Элемент) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда
ЭтоДетальнаяЗапись = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ЭтоДетальнаяЗапись;
КонецФункции


Далее в процедуре события обработки расшифровки задал собственный алгоритм обработки расшифровки для поля СуммаОплаты:

// 0. Процедура выполняет расшифровку обработки. Параметры: Элемент; Расшифровка (Произвольный) - значение расшифровки; СтандартнаяОбработка (Булево) - признак выполнения стандартной операции.
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
Перем ВыбранноеДействие;
Перем ПараметрыВыбранногоДействия;


// 1. Получаем имя поля, для которого пользователь хочет применить расшифровку.
ИмяПоля = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[0].Поле;

// 2. Определяем тип записи, детальная она или группировочная, т.к. расшифровку необходимо выполнять для детальной записи.
ЭтоДетальнаяЗапись = ЭтоДетальнаяЗапись(ДанныеРасшифровки, Расшифровка);

// 3. Выполняем проверку, если это поле СуммаОплаты и запись является детальной, то применяем собственный обработчик расшифровки.
Если ИмяПоля = "СуммаОплаты" И ЭтоДетальнаяЗапись Тогда

// 4. Отменяем стандартную обработку расшифровки.
СтандартнаяОбработка = Ложь;

// 5. Задаем список стандартных действий расшифровки, которые будут доступны пользователю.
ДоступныеДействия = Новый Массив;
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение);
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Отфильтровать);
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Расшифровать);


// 6. Задаем собственный список действий расшифровки, в моем случае это единственный пункт под названием "Расшифровать сумму".
ДополнительныеДействия = Новый СписокЗначений;
ДополнительныеДействия.Добавить("РасшифроватьСумму", "Расшифровать сумму");


// 7. Создаем объект, обрабатывающий расшифровку.
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));

// 8. Интерактивный выбор действий обработки расшифровки. Для управляемой формы нужно использовать метод ВыбратьДействие, если для конфигурации свойство РежимИспользованияМодальности установлено в НеИспользовать, следует использовать метод ПоказатьВыборДействия.
ПараметрыВыбранногоДействия = ОбработкаРасшифровки.Выполнить(Расшифровка, ВыбранноеДействие, , ДополнительныеДействия);

// 9. Проверим обработку расшифровки на изменение настроек.
Если ПараметрыВыбранногоДействия <> Неопределено Тогда

// 10. Если настройки изменены, значит пользователь выбрал стандартную расшифровку, которую мы определили в 5 пункте. Так как мы уже отменили выполнение стандартной операции в 4 пункте, то выполним стандартную обработку расшифровки программно.

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

// Открытие нового отчета с выводом результата для обычной формы.
//Отчет = Отчеты[Метаданные().Имя].Создать();
//Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(ПараметрыВыбранногоДействия);
//Форма = Отчет.ПолучитьФорму();
//Отчет.СкомпоноватьРезультат(Форма.ЭлементыФормы.Результат);
//Форма.Открыть();

// Выводим результат в текущий отчет.
ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(ПараметрыВыбранногоДействия);
ЭлементыФормы.Результат.Очистить();
ОтчетОбъект.СкомпоноватьРезультат(ЭлементыФормы.Результат, ДанныеРасшифровки);

Иначе


// 10. Получим значение полей для собственной расшифровки см. рисунок 2, под 0 индексом получаем значение поля Реализация в текущей строке, а под 1 индексом значение поля СуммаОплаты.
ДокРеализация = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[0].Значение;
СуммаОплаты = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[1].Значение;


// 11. Реализация собственной расшифровки и вывод результата (собственный алгоритм расшифровки приводить не буду, т.к. он громоздкий).
Сообщить("Сумма оплаты  = " + СуммаОплаты + " по документу " + Строка(ДокРеализация));

КонецЕсли;
КонецЕсли;
КонецПроцедуры


Итоговый программный код:
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

Перем ВыбранноеДействие;
Перем ПараметрыВыбранногоДействия;

ИмяПоля = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[0].Поле;
ЭтоДетальнаяЗапись = ЭтоДетальнаяЗапись(ДанныеРасшифровки, Расшифровка);

Если ИмяПоля = "СуммаОплаты" И ЭтоДетальнаяЗапись Тогда

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

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

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

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

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

КонецЕсли;

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


Комментарии

  1. Массив ДоступныеДействия определяется, но не используется в меню расшифровки

    ОтветитьУдалить
  2. У меня в событии 'ОбработкаРасшифровки' не доступна переменная 'ДанныеРасшифровки'. Не могу понять почему?

    ОтветитьУдалить
    Ответы
    1. Возможно, вы используете произвольную форму для отчета. Попробуйте создать отчет с максимальным использованием стандартных механизмов.

      Удалить
  3. Подскажите пожалуйста почему у меня отладчик не заходит в РезультатОбработкаРасшифровки

    ОтветитьУдалить

Отправить комментарий