Как получить значения (процент, сумма) из соответствия в функции ТекущиеДанныеОплатыТруда в ЗУП 3.1

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При разработке в конфигурации 1С:Зарплата и управление персоналом 3.1 программисты часто сталкиваются с необходимостью программного получения текущих плановых начислений сотрудника. Одной из самых эффективных функций для этого является КадровыйУчетРасширенный.ТекущиеНачисленияСотрудника. Однако результат, который она возвращает, представляет собой сложную многоуровневую структуру (Соответствие), «распаковка» которой может вызвать затруднения.

В этой статье мы подробно разберем, как устроены возвращаемые данные, и рассмотрим несколько способов извлечения из них конкретных показателей: вида начисления, суммы (размера) и процентных показателей.

Анализируем структуру данных функции ТекущиеНачисленияСотрудника

Прежде чем приступать к написанию кода, проанализируем, что именно возвращает функция КадровыйУчетРасширенный.ТекущиеНачисленияСотрудника(Сотрудник, ТекущаяДата). Это знание критически важно для правильного обращения к объектам.

Функция возвращает объект типа Соответствие (Map), структура которого выглядит следующим образом:

  1. Ключ: Ссылка на объект ПланВидовРасчета.Начисления. Это конкретный вид расчета, например, «Оклад» или «Надбавка за вредность».
  2. Значение: ТаблицаЗначений. В этой таблице содержатся подробные сведения о начислении.

Внутри ТаблицыЗначений (значения соответствия) обычно присутствуют следующие колонки:

Таким образом, мы имеем «матрешку»: Соответствие -> Таблица Значений -> Соответствие. Именно такая глубина вложенности часто сбивает с толку начинающих разработчиков.

Способ 1: Прямое обращение (если известен вид начисления)

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


// Определяем вид начисления, который нас интересует
КлючНачисления = ПланыВидовРасчета.Начисления.НайтиПоНаименованию("Надбавка за стаж");

// Получаем общие данные оплаты труда
ТекущиеДанныеОплатыТруда = КадровыйУчетРасширенный.ТекущиеНачисленияСотрудника(СотрудникСсылка, ТекущаяДата);

// Извлекаем таблицу значений для конкретного начисления
ТаблицаНачисления = ТекущиеДанныеОплатыТруда.Получить(КлючНачисления);

Если ТаблицаНачисления <> Неопределено И ТаблицаНачисления.Количество() > 0 Тогда
    // Берем первую строку из таблицы (обычно начисление одно)
    СтрокаДанных = ТаблицаНачисления[0];
    
    // Получаем сумму из колонки "Размер"
    СуммаНачисления = СтрокаДанных.Размер;
    
    // Если нужно получить показатель (например, процент), лезем во вложенное соответствие "Показатели"
    ПоказательПроцент = Справочники.ПоказателиРасчетаЗарплаты.НайтиПоНаименованию("Процент");
    ЗначениеПроцента = 0;
    СтрокаДанных.Показатели.Выяснить(ПоказательПроцент, ЗначениеПроцента);
    
    Сообщить("Сумма: " + СуммаНачисления + ", Процент: " + ЗначениеПроцента);
КонецЕсли;

Способ 2: Конвертация соответствия в таблицу значений (универсальный обход)

Если нам нужно обработать все начисления сотрудника и представить их, например, в отчете или форме, удобнее всего перегнать Соответствие в плоскую ТаблицуЗначений. Разберем, как это сделать с помощью цикла.


Функция ПреобразоватьДанныеНачисленийВТЗ(СоотвДанных)
    
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("ВидНачисления");
    ТЗ.Колонки.Добавить("Сумма");
    ТЗ.Колонки.Добавить("Процент");

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

Способ 3: Рекурсивный обход для сложных вложенных структур

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


Процедура РазобратьСоответствиеРекурсивно(ИсточникДанных, ИтоговаяТЗ)
    
    Для Каждого Элемент Из ИсточникДанных Цикл
        
        Если ТипЗнч(Элемент.Значение) = Тип("Соответствие") Тогда
            // Если внутри опять соответствие - проваливаемся глубже
            РазобратьСоответствиеРекурсивно(Элемент.Значение, ИтоговаяТЗ);
            
        ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("ТаблицаЗначений") Тогда
            // Если внутри таблица значений - перебираем её строки
            Для Каждого СтрокаИзТЗ Из Элемент.Значение Цикл
                // Если в строке есть колонка-соответствие (как "Показатели"), обрабатываем и её
                Для Каждого Колонка Из Элемент.Значение.Колонки Цикл
                    Если ТипЗнч(СтрокаИзТЗ[Колонка.Имя]) = Тип("Соответствие") Тогда
                         РазобратьСоответствиеРекурсивно(СтрокаИзТЗ[Колонка.Имя], ИтоговаяТЗ);
                    КонецЕсли;
                КонецЦикла;
            КонецЦикла;
            
        КонецЕсли;
        
        // Здесь можно добавить логику проверки Ключа и заполнения ИтоговойТЗ
        // Например: Если Элемент.Ключ = СсылкаНаНужныйПоказатель Тогда ...
        
    КонецЦикла;
    
КонецПроцедуры

Важное замечание: Рекурсия — мощный инструмент, но в случае с ТекущиеНачисленияСотрудника структура достаточно детерминирована (фиксирована). Поэтому чаще всего достаточно двойного цикла: по самому соответствию и по строкам вложенной таблицы значений.

Использование стандартных функций БСП

Выясним, можно ли упростить задачу с помощью стандартных библиотек. В Библиотеке стандартных подсистем (БСП) существует метод ОбщегоНазначения.ВыгрузитьКолонку(). Хотя он не решает задачу «распаковки» вложенных ТЗ, он может быть полезен, если вам нужно быстро получить список всех Видов расчета (ключей соответствия) или всех Таблиц значений (значений соответствия) в массив для дальнейшей обработки.

Пример использования:


// Получаем массив всех Таблиц Значений из соответствия
МассивТЗ = ОбщегоНазначения.ВыгрузитьКолонку(ТекущиеДанныеОплатыТруда, "Значение");

Практические советы по работе с начислениями

Проанализируем несколько нюансов, которые помогут избежать ошибок при разработке:

  1. Проверка на пустые значения: Всегда проверяйте результат функции ТекущиеНачисленияСотрудника на Неопределено или Количество() > 0. Если у сотрудника нет действующих начислений на указанную дату, попытка обращения к ключу вызовет ошибку.
  2. Несколько строк одного вида: Помните, что для одного ключа (вида начисления) в таблице может быть несколько строк. Это случается, если сотруднику назначено два одинаковых начисления с разными показателями (например, две разные надбавки, использующие один и тот же вид расчета).
  3. Показатели: Ключом во вложенном соответствии Показатели всегда является Ссылка на справочник ПоказателиРасчетаЗарплаты. Использование поиска по наименованию внутри цикла — плохая практика. Рекомендуется один раз получить нужные ссылки перед началом цикла.
  4. Дата среза: Функция учитывает данные регистров сведений (ПлановыеНачисления и др.) именно на ту дату, которую вы передаете в параметрах. Убедитесь, что дата указана корректно, особенно если начисления начинаются с первого числа месяца.

Рассмотренные методы позволяют гибко извлекать любые данные об оплате труда сотрудников в ЗУП 3.1, превращая сложные вложенные объекты в понятные и удобные для использования структуры.

← На главную