Получение значений всех полей в иерархии структуры отчета

28.02.20

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

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

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

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

Сподвигло меня оставить этот алгоритм здесь отсутствие его уже готового на просторах интернета при небольшой, но востребованности, и вполне универсальное его назначение.

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

&НаСервере
Процедура ПоляРасшифровки(ДанныеРасшифровки, Расшифровка, Поля, ОбработанныеЭлементы, ОбрабатыватьБратьев = Истина)
    
    Если ОбработанныеЭлементы.Найти(Расшифровка) = Неопределено Тогда
        ОбработанныеЭлементы.Добавить(Расшифровка);
    Иначе
        Возврат;
    КонецЕсли;
    
    ЭлементРасшифровки = ДанныеРасшифровки.Элементы.Получить(Расшифровка);
    
    Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
        ПоляЭлемента = ЭлементРасшифровки.ПолучитьПоля();
        ДополнитьПоляРасшифровки(ПоляЭлемента, Поля);
    ИначеЕсли ТипЗнч(ЭлементРасшифровки) = Тип("ЗначенияПолейРасшифровкиКомпоновкиДанных") Тогда
        ДополнитьПоляРасшифровки(ЭлементРасшифровки, Поля);
        Возврат;
    КонецЕсли;
    
    Родители = ЭлементРасшифровки.ПолучитьРодителей();
    Для каждого Родитель Из Родители Цикл
        
        Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда
            
            РодителиТекущегоУзла = РодителиУзлаВМассив(ЭлементРасшифровки);
            
            Инд = Число(ЭлементРасшифровки.Идентификатор) - 1;
            Пока Инд >= 0 Цикл
                
                РодителиПроверяемогоУзла = РодителиУзлаВМассив(ДанныеРасшифровки.Элементы.Получить(Инд));
                
                Если МассивыСовпадают(РодителиТекущегоУзла, РодителиПроверяемогоУзла) Тогда
                    ПоляРасшифровки(ДанныеРасшифровки, Инд, Поля, ОбработанныеЭлементы, Ложь);
                Иначе
                    Прервать;
                КонецЕсли;
                
                Инд = Инд - 1;
                
            КонецЦикла;
            
        Иначе
            
            Если ОбрабатыватьБратьев  Тогда
                
                Братья = НайтиБратьев(ДанныеРасшифровки, Родитель.Идентификатор, Расшифровка);
                Для каждого Брат Из Братья Цикл
                    ПоляРасшифровки(ДанныеРасшифровки, Брат, Поля, ОбработанныеЭлементы, Ложь);
                КонецЦикла;
                
            КонецЕсли;
            
        КонецЕсли;
        
        ПоляРасшифровки(ДанныеРасшифровки, Родитель.Идентификатор, Поля, ОбработанныеЭлементы, Истина);
        
    КонецЦикла;
    
КонецПроцедуры

&НаСервере
Функция РодителиУзлаВМассив(Узел)
    
    Результат = Новый Массив;
    
    СписокРодителей = Узел.ПолучитьРодителей();
    
    Для каждого Родитель Из СписокРодителей Цикл
        Результат.Добавить(Число(Родитель.Идентификатор));
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

&НаСервере
Функция МассивыСовпадают(Массив1, Массив2)
    
    Если Массив1.Количество() <> Массив2.Количество() Тогда
        Возврат Ложь;
    КонецЕсли;
    
    Для каждого ИД Из Массив1 Цикл
        Если Массив2.Найти(ИД) = Неопределено Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Истина;
    
КонецФункции

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

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

 

Вступайте в нашу телеграмм-группу Инфостарт

СКД Расшифровка Значения

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    250852    1390    421    

1145

Инструментарий разработчика СКД Программист 1С 8.3 Бесплатно (free)

В этой статье представлен СКДБилдер — общий модуль-обёртка над объектной моделью СКД, который сокращает код в 3-4 раза и делает его читаемым.

29.01.2026    5834    310    shapa_pro    25    

67

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Статья написана по результатам проведенного внутреннего обучающего вебинара для разработчиков ГК «СофтБаланс». Если осилить 25 000 знаков - задача для вас непосильная, где-то на бескрайних просторах интернета видео есть (или будет). Но здесь информация точнее. Разберем, чем запрос для СКД принципиально отличается от обычного запроса и как модифицируется в зависимости от настроек. Изучим «базовый рецепт» написания запроса для СКД, сформируем чек-лист. Полезно будет всем – от стажеров до тех. лидов. Всем, кто не снимает галку «автозаполнение» и пишет запросы для отчетов в консоли запросов – читать (вдумчиво) обязательно.

29.10.2025    17377    ovetgana    112    

107

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Описан способ заполнения списка доступных значений для полей наборов данных и параметров в схеме компоновки данных для любых конфигураций (с использованием БСП или без).

01.07.2025    10116    krasnoshchekovpavel    5    

68

СКД Программист Стажер 1С:Предприятие 8 Россия Бесплатно (free)

Несколько способов управления формами выбора параметров и отборов СКД.

10.04.2025    9402    Neti    0    

41

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Хорошая отчетная форма - сродни искусству. Есть какое-то невероятное эстетическое удовольствие в том, чтобы разобраться в логике учета и анализируемых показателях, спроектировать архитектуру хранения данных так, чтобы оптимально собрать эти показатели вместе с аналитическими разрезами в запросе, а затем настроить отображение так, чтобы, глядя на результат, сразу было понятно, что это за отчет и какие задачи он призван решать. Система компоновки данных - это моя первая, главная и, наверное, единственная "рабочая" любовь. Ее я использую везде, где только можно и где нельзя тоже. Хочу поделиться с вами некоторыми практическими приемами в работе с отчетами на СКД, которые, надеюсь, будут полезны.

27.02.2025    16015    ovetgana    50    

93

СКД Программист 1С:Предприятие 8 Бесплатно (free)

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

24.12.2024    13666    Akcium    17    

46

СКД Механизмы типовых конфигураций Запросы Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

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

20.08.2024    10275    AlexeyPROSTO_1C    1    

32
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. VmvLer 28.02.20 17:47 Сейчас в теме
неплохо, правда метод

Функция НайтиБратьев() - не толерантно, девочки могут засудить.
Предлагаю переименовать в
НайтиОтпрысков() или
НайтиПотомков()

пора пора создавать новый раздел "О боже, как я прекрасен"
2. Jenya78 24.04.23 10:54 Сейчас в теме
Спасибо тебе добрый человек!
3. wing 29 14.03.24 12:42 Сейчас в теме
Не работает, однако.
У меня есть таблица:
а1, б1, в1
а2, б2, в2
При клике по ячейке б2 данный код возвращает: а1, б2, в1
4. Гость 29.12.25 13:25
(3) Мне кажется что описанный в статье алгоритм некорректен (или же произошли какие-то изменения со стороны платформы, которые привели к его некорректности). "Братья" здесь определяются по совпадению родителя, что для детальных записей приводит к попаданию вообще всех детальных записей в текущей группировке в "братья". В результат в итоге попадают значения из первого попавшегося "брата".
На приложенной картинке наглядно это видно (в отчете цифры в скобах - ИД расшифровки; таблица справа - слегка обработанные для наглядности ДанныеРасшифровки)

Тут же видно, что гарантированно найти нужные данные невозможно, можно только придумывать костыли (например, искать "назад" первое значение с основным действием "открыть значение"), которые также могут перестать работать при изменениях платформы.
Прикрепленные файлы:
Для отправки сообщения требуется регистрация/авторизация