Как программно загрузить разовые показатели в документ «Данные для расчета зарплаты» в 1С:ЗУП 3.1?

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

Анализ проблемы и особенности работы документа

При переходе на 1С:ЗУП 3.1 с прошлых версий разработчики часто сталкиваются с изменением логики работы разовых показателей. В 1С:ЗУП 3.1 показатели расчета зарплаты хранятся в подчинённых регистрах сведений (например, Значения разовых показателей расчета зарплаты (для сотрудников)), а единственным регистратором этих записей выступает документ Данные для расчета зарплаты.

Рассмотрим распространенную проблему: при попытке программного заполнения табличных частей ЗначенияПоказателей и ФизическиеЛица открытого документа данные при сохранении очищаются. Проанализируем причину такого поведения платформы.

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

Решение проблемы: программная запись объекта на сервере

Чтобы корректно загрузить показатели и избежать их затирания формой, необходимо выполнять программное создание и проведение документа напрямую через серверный объект Документы.ДанныеДляРасчетаЗарплаты.СоздатьДокумент() без использования формы документа.

Разберем по шагам правильную последовательность действий:

  1. Создаем новый объект документа на сервере.
  2. Заполняем реквизиты шапки: Дата, Организация, Ответственный, Период и ВидДокумента (элемент справочника ВидыДокументовВводДанныхДляРасчетаЗарплаты).
  3. Обходим загружаемые данные и добавляем строки в табличную часть ЗначенияПоказателей.
  4. Вызываем метод Записать(). При записи или проведении документа платформа автоматически сформирует строки табличной части ФизическиеЛица и создаст записи в подчинённых регистрах.

Примеры программного кода

Рассмотрим пример функции, создающей документ и заполняющей разовый показатель по массиву сотрудников:


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

Рассмотрим еще один вариант: заполнение существующего объекта документа из внешнего XML-файла с поиском действующего сотрудника по физическому лицу:


// Заполнение табличной части ЗначенияПоказателей из источника XML
ДокОбъект.ЗначенияПоказателей.Очистить();

Пока ЧтениеXML.Прочитать() Цикл        
    Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "Строка" Тогда
        
        КодСотрудника = ЧтениеXML.ПолучитьАтрибут("КодСотрудника");   
        СуммаПремии = ЧтениеXML.ПолучитьАтрибут("Сумма");
        
        ФизЛицо = Справочники.ФизическиеЛица.НайтиПоКоду(КодСотрудника);
        Если ФизЛицо.Пустая() Тогда
            Сообщить("Физлицо с кодом " + КодСотрудника + " не найдено");
            Продолжить;
        КонецЕсли;
        
        // Поиск активного сотрудника организации
        Запрос = Новый Запрос;
        Запрос.Текст = 
        "ВЫБРАТЬ
        |   СотрудникиОрганизаций.Ссылка КАК Ссылка
        |ИЗ
        |   Справочник.Сотрудники КАК СотрудникиОрганизаций
        |   ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ТекущиеКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанныеСотрудников
        |   ПО СотрудникиОрганизаций.Ссылка = ТекущиеКадровыеДанныеСотрудников.Сотрудник
        |       И (ЕСТЬNULL(ТекущиеКадровыеДанныеСотрудников.ДатаУвольнения, ДАТАВРЕМЯ(1, 1, 1)) = ДАТАВРЕМЯ(1, 1, 1))
        |       И (ТекущиеКадровыеДанныеСотрудников.ОсновноеРабочееМестоВОрганизации)
        |       И (ТекущиеКадровыеДанныеСотрудников.ТекущийВидЗанятости = ЗНАЧЕНИЕ(Перечисление.ВидыЗанятости.ОсновноеМестоРаботы))
        |ГДЕ
        |   СотрудникиОрганизаций.ФизическоеЛицо = &Физлицо
        |   И СотрудникиОрганизаций.ГоловнаяОрганизация = &Организация
        |   И НЕ СотрудникиОрганизаций.ПометкаУдаления";
        
        Запрос.УстановитьПараметр("Организация", ДокОбъект.Организация);
        Запрос.УстановитьПараметр("Физлицо", ФизЛицо);
        
        Выборка = Запрос.Выполнить().Выбрать();
        
        Если Выборка.Следующий() Тогда
            Сотрудник = Выборка.Ссылка;
            
            ПараметрыОтбора = Новый Структура("Объект", Сотрудник);
            МассивСтрок = ДокОбъект.ЗначенияПоказателей.НайтиСтроки(ПараметрыОтбора);
            
            Если МассивСтрок.Количество() = 0 Тогда
                НоваяСтрока = ДокОбъект.ЗначенияПоказателей.Добавить();
                НоваяСтрока.Объект = Сотрудник;                   
            Иначе
                НоваяСтрока = МассивСтрок[0];
            КонецЕсли;
            
            НоваяСтрока.Период = ДокОбъект.Период;
            НоваяСтрока.Показатель = ДокОбъект.ВидДокумента.Показатели.Получить(0).Показатель;
            НоваяСтрока.Значение = СуммаПремии;
            
        КонецЕсли;
        
    КонецЕсли; 
КонецЦикла;

ДокОбъект.Записать(РежимЗаписиДокумента.Запись);

Ключевые технические детали

Выясним основные особенности заполнения реквизитов, о которых важно помнить:

  1. Тип реквизита Объект: Реквизит Объект в табличной части ЗначенияПоказателей имеет составной тип. Если показатель задается по сотрудникам, необходимо передавать ссылку на справочник Сотрудники. Для показателей подразделения передается ПодразделенияОрганизаций, для организации — Организации.
  2. Соответствие показателя виду документа: Указываемый элемент справочника ПоказателиРасчетаЗарплаты должен входить в табличную часть Показатели выбранного ВидДокумента (шаблона ввода исходных данных).
  3. Период: Значение реквизитов Период в шапке и табличной части должно соответствовать первому числу месяца начисления.
← На главную