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

28.07.15

Разработка - СКД

Скорее заметка на память, чем статья. Прошелся по форумам и не нашел решения данной проблемы. Везде предлагается получить значения только группировок, в которые входит эта ячейка. Был еще способ создать свой макет и там в параметрах ячейки указать параметры расшифровки, но мне показалось такое решение слишком сложным. Предлагаю другой путь - обойти ячейки строки, для каждой ячейки получить реквизит "Расшифровка" и данные расшифровки.

Код должен располагаться в модуле формы отчета. У поля табличного документа событие "ОбработкаРасшифровки" должно ссылаться на процедуру РезультатОбработкаРасшифровки

Решение, которое предлагают на форумах для получения значений группировок:

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

Функции для передвижения по строке: разбирается имя ячейки и увеличивается или уменьшается номер колонки:

Функция РаспарситьИмяПоля(ИмяПоля)
	
	ИндексСи = Найти(ИмяПоля, "C");
	БазаИмени = Лев(ИмяПоля, ИндексСи);
	НомерКолонкиСтрокой = СтрЗаменить(ИмяПоля, БазаИмени, "");
	НомерКолонки = Число(НомерКолонкиСтрокой);
	
	Возврат Новый Структура (
		"БазаИмени, НомерКолонки",
		БазаИмени,
		НомерКолонки
		);
		
	
КонецФункции
 
Функция ИмяПредыдущегоПоляВСтроке(ИмяПоля)

	Данные = РаспарситьИмяПоля(ИмяПоля);
	
	Если Данные.НомерКолонки = 1 Тогда
		Возврат "";
	КонецЕсли;
	
	Результат = Данные.БазаИмени + (Данные.НомерКолонки - 1);
	
	Возврат Результат;
	
КонецФункции
 
Функция ИмяСледующегоПоляВСтроке(ИмяПоля, МаксНомерКолонки = 100)

	Данные = РаспарситьИмяПоля(ИмяПоля);
	
	Если Данные.НомерКолонки = МаксНомерКолонки Тогда
		Возврат "";
	КонецЕсли;
	
	Результат = Данные.БазаИмени + (Данные.НомерКолонки + 1);
	
	Возврат Результат;
	
КонецФункции

Собственно функции, которые собирают значения ячеек строки и добавляют их к переданной структуре

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

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

Функция ПолучитьДанныеРасшифровкиЯчеекСтроки(Элемент, СтруктураОтбора = Неопределено)
	
	Если СтруктураОтбора = Неопределено Тогда
		СтруктураОтбора = Новый Структура;
	КонецЕсли; 

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

Теперь в обработке расшифровки мы можем получить структуру со значениями группировок и ячеек нашей строки

Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
	
	Поле = ДанныеРасшифровки.Элементы[Расшифровка];
	СтруктураОтбора = ПолучитьРекурсивноСтруктуруОтбора(Поле);
	СтруктураОтбора = ПолучитьДанныеРасшифровкиЯчеекСтроки(Элемент, СтруктураОтбора);
	
КонецПроцедуры

 

Расшифровка СКД

См. также

SALE! 15%

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    159447    872    399    

861

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    8684    implecs_team    6    

47

Инструментарий разработчика СКД Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

По выбранной схеме компоновки данных генерирует программный код, который генерирует СКД, аналогичную исходной схеме. Есть дополнительные инструменты для просмотра дерева схемы, сравнение исходной схемы и полученной по коду, а также сравнение изменений в сгенерированном коде для исходной схемы и для измененной.

3 стартмани

05.02.2024    6996    56    obmailok    21    

79

Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    3148    5    Yashazz    1    

34

СКД WEB-интеграция Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

11.12.2023    10805    23    John_d    25    

124

СКД Программист Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

Рассмотрим еще не получивший широкого распространения способ работы с внешними данным в СКД. В процессе обсуждения работы с СКД выяснилось, что многие не знакомы со способом помещения туда временной таблицы, полученной предварительно. Статья будет полезна разработчикам, знакомым с программным созданием СКД.

05.12.2023    8017    PROSTO-1C    15    

68
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Aleksey81 1186 28.07.15 21:19 Сейчас в теме
Спасибо, что нашел время изложить этот метод в инфостарте. Идея великолепна!!!! Респект!!!
2. 7OH 70 29.07.15 09:44 Сейчас в теме
Если в группировке есть поле через точку - вылетает.
Например "Контрагент.ИНН".
3. Alien_job 190 29.07.15 09:53 Сейчас в теме
(2) 7OH, Спасибо за репорт, к вечеру посмотрю, поправлю.
5. Alien_job 190 29.07.15 13:04 Сейчас в теме
(2) 7OH, Очень неожиданное поведение 1с - в структуру вообще нельзя вставить ключ, содержащий точку.
Решение - использовать вместо структуры соответствие.
4. Новиков 292 29.07.15 10:47 Сейчас в теме
За статью спасибо. Самого интересовал вопрос, как получить данные строки, без группировок и без макета. На курсах сказали - никак :)

Был еще способ создать свой макет и там в параметрах ячейки указать параметры расшифровки, но мне показалось такое решение слишком сложным

На самом деле этот способ гораздо проще и понятнее, чем вот такой спагетти-образный код. Я уже года два как только таким способом и пользуюсь, оглядываясь на разработчиков типовых. И Вам рекомендую разобраться с этим способом. Когда разберетесь, улыбнетесь насколько он элегантен и прост.
9. Alien_job 190 26.10.15 11:08 Сейчас в теме
(4) Новиков, не получается разобраться с этим элегантным и простым методом. Не нашел примеров работы с "ПараметрРасшифровки" в контексте СКД. Помоему этот подход работает только при самостоятельном выводе отчета (через ТабДок.Вывести(Область))
6. Жолтокнижниг 259 30.07.15 10:46 Сейчас в теме
Улыбнуло
Очень неожиданное поведение 1с
7. ikar-nikolay 104 28.08.15 15:12 Сейчас в теме
Ха! Решал такой вопрос, тоже столкнулся с отсутствием описания данного метода.
Я заметил, что коды расшифровки идут по порядку, поэтому обычной пробежкой по значениям вперед и назад, пока не встретим отсутствие значения группировки, находим данные строки
Вот мой код:
&НаСервере
Функция ПолучитьСписокПолейВСтрокеСКД(КодРасшифровки, ДанныеРасшифровки) Экспорт
	
 	// Получаем поля группировки
	ЭлементРасшифровки = ПолучитьИзВременногоХранилища(ДанныеРасшифровки).Элементы[КодРасшифровки];
	ПоляГруппировки = автРаботаСФормами.ПолучитьСтруктуруПолейРасшифровки(ЭлементРасшифровки);

	// Делаем проверку Влево и Вправо от значения, которое хотят расшифровать
	// и проверяем - есль поля из ТЗПолейРасшифровки (в ней остались только поля с данными и без текущего расшифровываемого поля)
	КодРасшифровкиВлево 	= КодРасшифровки;
	КодРасшифровкиВправо 	= КодРасшифровки;
	
	ПоляВСтроке	= Новый Структура; 
	Пока Истина Цикл
		КодРасшифровкиВлево 	= КодРасшифровкиВлево - 1;
		Если Не КодРасшифровкиВлево < 0 Тогда // если вылезли за диапазон возможных расшифровок
			ИДЭлементаРасшифровки 	= ПолучитьИзВременногоХранилища(ДанныеРасшифровки).Элементы[КодРасшифровкиВлево];
		Иначе
			Прервать;
		КонецЕсли;
		
		ЗначениеГруппировки = автРаботаСФормами.ПолучитьИмяРасшифровываемогоПоля(ИДЭлементаРасшифровки);
		Если ЗначениеГруппировки = Неопределено Тогда
			Прервать;
		КонецЕсли;
		
		Если  ПоляГруппировки.Свойство(ЗначениеГруппировки) Тогда 
			Прервать;
		КонецЕсли;
		
		ПоляГруппировкиТекущие = автРаботаСФормами.ПолучитьСтруктуруПолейРасшифровки(ИДЭлементаРасшифровки);
		РезультатСравненияГруппировок = СравнитьСоответствияГруппировок(ПоляГруппировкиТекущие, ПоляГруппировки);
		Если РезультатСравненияГруппировок Тогда
			 ПоляВСтроке.Вставить(автРаботаСФормами.ПолучитьИмяРасшифровываемогоПоля(ИДЭлементаРасшифровки), автРаботаСФормами.ПолучитьЗначениеРасшифровки(ИДЭлементаРасшифровки));
		Иначе
			 Продолжить;
		КонецЕсли;
		
	КонецЦикла;
	
	Пока Истина Цикл
		КодРасшифровкиВправо 	= КодРасшифровкиВправо + 1;
		
		Если ПолучитьИзВременногоХранилища(ДанныеРасшифровки).Элементы.Количество() < КодРасшифровкиВправо Тогда // если вылезли за диапазон возможных расшифровок
			ИДЭлементаРасшифровки 	= ПолучитьИзВременногоХранилища(ДанныеРасшифровки).Элементы[КодРасшифровкиВправо];
		Иначе
			Прервать;
		КонецЕсли;
			
		ЗначениеГруппировки = автРаботаСФормами.ПолучитьИмяРасшифровываемогоПоля(ИДЭлементаРасшифровки);
		Если ЗначениеГруппировки = Неопределено Тогда
			Прервать;
		КонецЕсли;
		
		Если  ПоляГруппировки.Свойство(ЗначениеГруппировки) Тогда 
			Прервать;
		КонецЕсли;
		
		ПоляГруппировкиТекущие = автРаботаСФормами.ПолучитьСтруктуруПолейРасшифровки(ИДЭлементаРасшифровки);
		РезультатСравненияГруппировок = СравнитьСоответствияГруппировок(ПоляГруппировкиТекущие, ПоляГруппировки);
		Если РезультатСравненияГруппировок Тогда
			 ПоляВСтроке.Вставить(автРаботаСФормами.ПолучитьИмяРасшифровываемогоПоля(ИДЭлементаРасшифровки), автРаботаСФормами.ПолучитьЗначениеРасшифровки(ИДЭлементаРасшифровки));
		Иначе
			 Продолжить;
		КонецЕсли;

	КонецЦикла;

	Возврат ПоляВСтроке;
	
КонецФункции
Показать


Оцените! )))
8. Alien_job 190 28.08.15 15:48 Сейчас в теме
(7) ikar-nikolay, тоже вариант
13. Poopkeen 08.02.16 15:14 Сейчас в теме
(7) ikar-nikolay,

Камрад, а можно текст соответствующих функций из модуля автРаботаСФормами ?
10. megatrend 131 21.12.15 00:01 Сейчас в теме
Это только для неуправляемых форм? В управляемой форме возникает ошибка на первой же строке :

Значение не является значением объектного типа (Элементы)
Поле = ДанныеРасшифровки.Элементы[Расшифровка];
11. Alien_job 190 21.12.15 06:09 Сейчас в теме
(10) megatrend, На управляемых формах не проверял
15. HEKPOH 76 16.05.17 12:24 Сейчас в теме
(10)
Для УФ нужно использовать конструкцию:

ДанныеРасшифровкиКомпоновки = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
ПоляРасшифровки = ДанныеРасшифровкиКомпоновки.Элементы.Получить(Расшифровка).ПолучитьПоля();
user1430860; neo-ti; AngV; Alien_job; +4 Ответить
12. viktor_v 14.01.16 15:19 Сейчас в теме
14. moli_i_n 07.04.16 08:03 Сейчас в теме
Спасибо, интересное решение проблемы.
16. mrm1212 36 05.04.18 14:57 Сейчас в теме
Спасибо за код, только пришлось структуру на соответствие заменить и все заработало!
18. idw 344 03.12.21 16:05 Сейчас в теме
(16) а что конкретно сделали? У меня тоже код не работает.
17. qazaz2 17 31.01.20 18:18 Сейчас в теме
Спасибо автору, ни в жисть бы не допер
19. ignorant 29.06.22 12:40 Сейчас в теме
Спасибо, пригодилось.
Чуть подправил РаспарситьИмяПоля для случая, когда поле отформатировано как объединение ячеек.
Тогда НомерКолонкиСтрокой выглядит как "1:4" и значение находится в колонке 1.
Функция РаспарситьИмяПоля(ИмяПоля)
    
    ИндексСи = Найти(ИмяПоля, "C");
    БазаИмени = Лев(ИмяПоля, ИндексСи);
    НомерКолонкиСтрокой = СтрЗаменить(ИмяПоля, БазаИмени, "");
	
	//	Объединение ячеек
	Если Найти (НомерКолонкиСтрокой, ":") > 0 Тогда
		
		ТекСтр = СтрЗаменить (НомерКолонкиСтрокой, ":", Символы.ПС); 
		КвоСлов = СтрЧислоСтрок (ТекСтр);
		Если КвоСлов > 0 Тогда
			НомерКолонкиСтрокой = Врег (СтрПолучитьСтроку ( ТекСтр, 1));
		Иначе
			//	ХЗ что такое
			НомерКолонкиСтрокой = "1";
		КонецЕсли;
	КонецЕсли;
	
	НомерКолонки = Число(НомерКолонкиСтрокой);
    
    Возврат Новый Структура (
        "БазаИмени, НомерКолонки",
        БазаИмени,
        НомерКолонки
        );
    
КонецФункции
Показать
Alien_job; +1 Ответить
20. shanginre 01.12.23 06:59 Сейчас в теме
Для управляемых форм работает вот так. Сразу скажу, код делал под мою задачу с выводом плоской таблицы. В варианте с хитрыми группировками могут быть нюансы :)

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



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

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

&НаСервере
Функция ЭтоЭлементРасшифровкиКомпоновкиДанныхПоля(ЭлементРасшифровки)

	Возврат ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля");

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

&НаСервере
Функция ИдентификаторНачалаДанныхВГруппировке(ДанныеРасшифровкиОтчета, ТекущийИдентификаторРасшифровки)

	ДанныеРодителейРасшифровки = ДанныеРасшифровкиОтчета.Элементы.Получить(ТекущийИдентификаторРасшифровки).ПолучитьРодителей();
	
	Возврат ДанныеРодителейРасшифровки[0].Идентификатор + 1;
	
КонецФункции

&НаСервере
Функция КоличествоПолейВСтрокеОтчета(ДанныеРасшифровкиОтчета, ТекущийИдентификаторРасшифровки)

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

&НаСервере
Функция ДанныеПоляРасшифровки(ДанныеРасшифровкиОтчета, ИдентификаторРасшифровки)
	
	ПоляЭлементаРасшифровки = ДанныеРасшифровкиОтчета.Элементы.Получить(ИдентификаторРасшифровки).ПолучитьПоля()[0];
	
	Возврат Новый Структура("Поле, Значение", ПоляЭлементаРасшифровки.Поле, ПоляЭлементаРасшифровки.Значение);
	
КонецФункции

&НаСервере
Функция ИдентификаторНачалаТекущейСтрокиОтчета(ДанныеРасшифровкиОтчета, ТекущийИдентификаторРасшифровки, КоличествоПолейВСтрокеОтчета)

	ИдентификаторНачалаДанныхВГруппировке = 
		ИдентификаторНачалаДанныхВГруппировке(ДанныеРасшифровкиОтчета, ТекущийИдентификаторРасшифровки);
		
	СмещениеНачалаТекущейСтроки = КоличествоПолейВСтрокеОтчета 
		* Цел((ТекущийИдентификаторРасшифровки - ИдентификаторНачалаДанныхВГруппировке) / КоличествоПолейВСтрокеОтчета);
		
	Возврат ИдентификаторНачалаДанныхВГруппировке + СмещениеНачалаТекущейСтроки;

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

&НаСервере
Функция ИдентификаторОкончанияТекущейСтрокиОтчета(ИдентификаторНачалаТекущейСтрокиОтчета, КоличествоПолейВСтрокеОтчета)

	Возврат ИдентификаторНачалаТекущейСтрокиОтчета + КоличествоПолейВСтрокеОтчета - 1;

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


Показать
Оставьте свое сообщение