gifts2017

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

Опубликовал Игорь Пашутин (Alien_job) в раздел Программирование - Практика программирования

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

См. также

Подписаться Добавить вознаграждение

Комментарии

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

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

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

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

	КонецЦикла;

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


Оцените! )))
8. Игорь Пашутин (Alien_job) 28.08.15 15:48
9. Игорь Пашутин (Alien_job) 26.10.15 11:08
(4) Новиков, не получается разобраться с этим элегантным и простым методом. Не нашел примеров работы с "ПараметрРасшифровки" в контексте СКД. Помоему этот подход работает только при самостоятельном выводе отчета (через ТабДок.Вывести(Область))
10. megatrend - (megatrend) 21.12.15 00:01
Это только для неуправляемых форм? В управляемой форме возникает ошибка на первой же строке :

Значение не является значением объектного типа (Элементы)
Поле = ДанныеРасшифровки.Элементы[Расшифровка];
11. Игорь Пашутин (Alien_job) 21.12.15 06:09
(10) megatrend, На управляемых формах не проверял
12. Viktor M (it-tk-sibir) 14.01.16 15:19
13. Poopkeen (Poopkeen) 08.02.16 15:14
(7) ikar-nikolay,

Камрад, а можно текст соответствующих функций из модуля автРаботаСФормами ?
14. Ирина Мухачева (moli_i_n) 07.04.16 08:03
Спасибо, интересное решение проблемы.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа