1с скд расшифровка
Сегодня ковырялся с одним отчетом на ‘скд’ (система компоновки данных), где нужно было программно по алгоритму заказчика обработать расшифровку одного ресурса, так как типовая расшифровка его не устраивала. Так вот, потратив немного времени, я открыл для себя новые возможности по работе с расшифровкой в ‘скд’ программно. Ну конечно решил добавить себе это в заметку! Ссылка на обработку в конце статьи – палец вверх там же!
Итак, у меня есть отчет на ‘скд’ (запрос написан в самом макете!), в котором данные выводится в виде таблицы. Это иерархия договоров, с суммами документов за период (месяц):
Теперь самое важное: что бы мы могли обрабатывать расшифровку ‘скд’ у нас должны быть добавлена форма отчета с использованием системы компоновки данных (в случае если еще нет формы отчета):
В этом случае у нас будет полностью подготовленная форма со всеми данными: в данном случае нас интересуют реквизиты ‘ДанныеРасшифровки’ и ‘Результат’:
Важно: Если систему компоновки данных мы формируем программным способом, то обязательно нужно определить ‘ДанныеРасшифровкиКомпоновкиДанных‘ и передать их в компоновщик макета:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; //Получаем наш внешний набор данных ТЗ ТЗИтог = ПолучитьВнешнийНаборДанных(); //Получаем наш внешний набор данных ТЗ Настройки = КомпоновщикНастроек.ПолучитьНастройки(); ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки); ВнешнийНаборДанных = Новый Структура("НашаВнешняяТаблица", ТЗИтог); ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешнийНаборДанных, ДанныеРасшифровки); ДокументРезультат.Очистить(); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(ДокументРезультат); ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных); КонецПроцедуры |
Супер! Теперь у нас все есть, что бы полностью читать расшифровка отчета на ‘скд’. Задача: Убрать стандартную расшифровку ресурса ‘Сумма’ и получить все возможные связанные с ней значения: контрагента, договор и период и т.д.
Создаем событие ‘ОбработкаРасшифровки’ у нашего табличного поля ‘Результат’:
1 2 3 4 5 6 |
&НаКлиенте Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка) СтруктураЗначений = ПолучитьРасшифровкуНаСервере(Расшифровка); КонецПроцедуры |
Прежде чем писать процедуру ‘ПолучитьРасшифровкуНаСервере‘ отметим несколько моментов:
- Параметр ‘Расшифровка’ – это у нас число;
- Сама расшифровка хранится у нас во временном хранилище по адресу, которое хранится в реквизите формы ‘ДанныеРасшифровки’.
Зная это, мы легко сможем понять какое поле мы обрабатываем по данным параметрам расшифровки. В нашем случае нам интересно только нажатие по ресурсу ‘сумма‘ (но обратите внимание, что значение ресурса ‘сумма’ в отладке у нас будет NULL) и все связанные с ним значения по всем группировкам:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
&НаКлиенте Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка) РезультатСтруктура = РаботаемСРасшифровкойНаСервере(Расшифровка); КонецПроцедуры &НаСервере Функция РаботаемСРасшифровкойНаСервере(Расшифровка) РезультатСтруктура = Новый Структура; Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки); Поля = Данные.Элементы.Получить(Расшифровка).ПолучитьПоля(); //Сообщить("Поле: " + Поля[0].Поле + ", значение: " + Поля[0].Значение); Если Поля[0].Поле = "Сумма" Тогда РезультатСтруктура.Вставить(Поля[0].Поле, Поля[0].Значение); Иначе Возврат РезультатСтруктура; КонецЕсли; //РасшифровкаГоризонталь = Данные.Элементы[Расшифровка].ПолучитьРодителей()[0]; //РасшифровкаДиоганаль = Данные.Элементы[Расшифровка].ПолучитьРодителей()[1]; ВывестиЗначениеГруппировки(Данные, Расшифровка, РезультатСтруктура); Возврат РезультатСтруктура; КонецФункции Процедура ВывестиЗначениеГруппировки(п_Данные, ТекРасшифровка, РезультатСтруктура) МассивРодителей = п_Данные.Элементы[ТекРасшифровка].ПолучитьРодителей(); Для Сч = 1 По МассивРодителей.Количество() Цикл ПолеРодитель = МассивРодителей[Сч-1]; Если ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда //Выведем значения текущей расшифровки Поле = ПолеРодитель.ПолучитьПоля()[0]; //Сообщить("Поле: " + Поле.Поле + ", значение: " + Поле.Значение); РезультатСтруктура.Вставить(Поле.Поле, Поле.Значение); //Рекурсивный вызов процедуры. РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей()[0].Идентификатор; ВывестиЗначениеГруппировки(п_Данные, РасшифровкиВыше, РезультатСтруктура); ИначеЕсли ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") тогда Попытка Поле = ПолеРодитель.ПолучитьРодителей()[0].ПолучитьПоля()[0] ; //Сообщить("Поле: " + Поле.Поле + ", значение: " + Поле.Значение); РезультатСтруктура.Вставить(Поле.Поле, Поле.Значение); //Рекурсивный вызов процедуры. РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей()[0].Идентификатор; ВывестиЗначениеГруппировки(п_Данные, РасшифровкиВыше, РезультатСтруктура); Исключение КонецПопытки; КонецЕсли; КонецЦикла; КонецПроцедуры |
С помощью метода ‘ПолучитьРодителей()’ – мы можем получить массив расшифровок как по горизонтали, так и по вертикале (группировки, колонки). В итоге имеем структуру со всеми необходимыми данными (ну почти!):
То есть получается, что мы смогли определить все связанные значения расшифровки для ячейки ‘сумма’, но само значение ресурса у нас пустое! Хотя оно мне так же было нужно!
И спустя некоторое время я все-таки откопал почему же оно не доступно! А все просто! Необходимо задать макет поля для нашего ресурса ‘Сумма’ и указать в нем параметр расшифровки:
О том как это можно сделать, есть статья: ‘Макет СКД расшифровка’.
Итак, теперь запускаем отладчик и смотрим что в итоге у нас есть программная расшифровка всех необходимых значений:
Думаю что теперь, имя эту заметку, для меня не будет проблем организовать любой алгоритм расшифровки в макете ‘скд’.
А да, кстати, не забывайте что если вы в дальнейшем хотите расшифровывать свои значения, после обработки расшифровки, то ставьте параметр ‘СтандартнаяОбработка’ = Ложь:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
&НаКлиенте Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка) РезультатСтруктура = РаботаемСРасшифровкойНаСервере(Расшифровка); Если РезультатСтруктура.Свойство("Сумма") И ЗначениеЗаполнено(РезультатСтруктура.Сумма) Тогда //пишем любые свои алгоритмы с полученными данными... СтандартнаяОбработка = Ложь; ОткрытьЗначение(РезультатСтруктура.Сумма); КонецЕсли; КонецПроцедуры |
Надеюсь всем все было понятно – уж мне то точно. Я не говорю что процедура получения расшифровки данных идеальная. Скорее всего её можно дорабатывать и улучшать! Но она рабочая и имеет право на жизнь!
Ребят, нашел еще один вариант получения данных расшифровки – более универсальный (он так же есть в обработке). Внимание! Значение своего ресурса обрабатывайте отдельно, так в нижеуказанной процедуре в итоге он может сброситься в NULL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
&НаСервере Функция РаботаемСРасшифровкойНаСервере(Расшифровка) РезультатСтруктура = Новый Структура; Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки); Поля = Данные.Элементы.Получить(Расшифровка).ПолучитьПоля(); //Сообщить("Поле: " + Поля[0].Поле + ", значение: " + Поля[0].Значение); //Ресурс, который нас интересует. Если Поля[0].Поле = "Сумма" Тогда РезультатСтруктура.Вставить(Поля[0].Поле, Поля[0].Значение); Иначе Возврат РезультатСтруктура; КонецЕсли; //РасшифровкаГоризонталь = Данные.Элементы[Расшифровка].ПолучитьРодителей()[0]; //РасшифровкаДиоганаль = Данные.Элементы[Расшифровка].ПолучитьРодителей()[1]; //1-ый вариант получения всех поле //ВывестиЗначениеГруппировки(Данные, Расшифровка, РезультатСтруктура); //2-ой вариант получения всех полей - более рабочий вариант, так как получает все данные //Внимание! Ресурс сумма может быть перезаписан в значение NULL - поэтому его значение лучше получать выше. ЗаполнитьСтруктуруПолейРасшифровки(Расшифровка, РезультатСтруктура); Возврат РезультатСтруктура; КонецФункции //2-ой вариант получения всех полей &НаСервере Процедура ЗаполнитьСтруктуруПолейРасшифровки(Знач Расшифровка, СтруктураПолей, Знач Данные = "") Если Данные = "" Тогда Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки); Если ТипЗнч(Данные.Элементы[Расшифровка]) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда Поля = Данные.Элементы[Расшифровка].ПолучитьПоля(); Для каждого Поле Из Поля Цикл СтруктураПолей.Вставить(ПреобразоватьИмяПоляГруппировки(Поле.Поле), Поле.Значение); КонецЦикла; Индекс = Число(Расшифровка); Попытка Пока Индекс Цикл ЭлементРасшифровки = Данные.Элементы[Индекс]; Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда Прервать; КонецЕсли; Индекс = Индекс + 1; КонецЦикла; Исключение КонецПопытки; Индекс = Индекс - 1; Пока Индекс Цикл ЭлементРасшифровки = Данные.Элементы[Индекс]; Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда Поля = ЭлементРасшифровки.ПолучитьПоля(); Для каждого Поле Из Поля Цикл Если Не ТипЗнч(Поле.Значение) = Тип("Число") Тогда СтруктураПолей.Вставить(ПреобразоватьИмяПоляГруппировки(Поле.Поле), Поле.Значение); КонецЕсли; КонецЦикла; Индекс = Индекс - 1; Иначе Прервать; КонецЕсли; КонецЦикла; КонецЕсли; ЗаполнитьСтруктуруПолейРасшифровки(Данные.Элементы[Расшифровка], СтруктураПолей, Данные); Иначе МассивРодителей = Расшифровка.ПолучитьРодителей(); Для каждого ПолеРодитель из МассивРодителей Цикл Если Число(ПолеРодитель.Идентификатор) > 0 Тогда Если ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда МассивПолей = ПолеРодитель.ПолучитьПоля(); ИначеЕсли ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда МассивПолей = ПолеРодитель.ПолучитьРодителей()[0].ПолучитьПоля(); КонецЕсли; Для каждого Поле из МассивПолей Цикл СтруктураПолей.Вставить(ПреобразоватьИмяПоляГруппировки(Поле.Поле), Поле.Значение); РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей(); Для каждого РодительВыше Из РасшифровкиВыше Цикл ЗаполнитьСтруктуруПолейРасшифровки(РодительВыше, СтруктураПолей, Данные); КонецЦикла; КонецЦикла; КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры Функция ПреобразоватьИмяПоляГруппировки(п_Поле) Возврат СокрЛП(п_Поле); КонецФункции |
Как обычно, обработка с готовым решением для вас и для меня! Всем удачи!
Скачать файлы craft1c_RasshifrovkaSKD.erf
Внимание, добавил еще один вариант получения данных расшифровки!
Учитывайте, что если в отчете ресурсы дублируются, т.е. допустим идет разбивка по месяцам (колонки), а в них ресурс сумма – то данные процедуры в итоге вам вернут значения первых колонок. Не смотря на то, что вы щелкнули по декабрю, а сумма вернется с первого месяца (к примеру с января). Поэтому эти значения обрабатывайте до вызова процедур получения всех расшифровок. В общем разберетесь.