В процессе разработки интеграций, загрузок данных из внешних систем (например, из файлов Excel) или при автоматизации рутинных операций в программе 1С:Зарплата и управление персоналом 3.1 часто возникает необходимость программно создавать и заполнять документы выплаты. Один из таких документов — ВедомостьНаВыплатуЗарплатыПеречислением (в интерфейсе программы — "Ведомость на счета").
В этой статье мы подробно разберем, с какими трудностями сталкиваются разработчики при решении этой задачи, почему стандартные «клиентские» методы заполнения через форму являются грубой ошибкой, и как правильно реализовать заполнение ведомости полностью на стороне сервера, используя штатный программный интерфейс (API) конфигурации.
Давайте проанализируем ситуацию, описанную в теме форума. Разработчик пытается создать документ на сервере, записывает его пустым, затем получает его форму на клиенте с помощью метода ПолучитьФорму и пытается вызвать типовую клиентскую процедуру заполнения:
&НаКлиенте
Процедура СформироватьДокумент(Команда)
Структура = ПодготовитьСписокСотрудников;
Док = СформироватьДокументВедомостьНаСервере(Структура.мФизЛица, СсылкаДН);
Парам = Новый Структура("Ключ", Док);
Форма = ПолучитьФорму("Документ.ВедомостьНаВыплатуЗарплатыПеречислением.Форма.ФормаДокумента", Парам);
Если Форма.Объект.Основания.Количество > 0 Тогда
ВедомостьНаВыплатуЗарплатыКлиент.Заполнить(Форма);
КонецЕсли;
КонецПроцедуры
В процессе выполнения этого кода автор столкнулся с тем, что отладчик не заходил в процедуру ВедомостьНаВыплатуЗарплатыКлиент.Заполнить, а система выдавала ошибку «Обращение к процедуре объекта как к функции». Автор сделал ошибочный вывод, что проблема заключалась в лишней точке с запятой ; в конце строки.
Важное техническое уточнение: с точки зрения синтаксиса встроенного языка 1С, наличие или отсутствие точки с запятой перед ключевым словом КонецЕсли не влияет на компиляцию и не может вызывать ошибку обращения к процедуре как к функции. Подобный сбой обычно происходит, если имя процедуры совпадает с локальной переменной, или если вызов случайно был помещен внутрь условия. Истинная же проблема кроется гораздо глубже — в самой архитектуре выбранного решения.
Попытка открыть форму документа в памяти на клиенте только ради того, чтобы сымитировать нажатие кнопки «Заполнить», ведет к серьезным проблемам:
ПолучитьФорму вернет ошибку.Начиная с версии ЗУП 3.1.5, разработчики «1С» перенесли всю бизнес-логику расчета и заполнения ведомостей в специализированные общие модули. Теперь нам не нужно эмулировать работу формы. Конфигурация предоставляет готовый серверный API для расчета зарплаты и налогов к выплате.
Выясним, как выглядит правильный алгоритм программного создания и заполнения ведомости на счета на сервере:
ЗагрузитьВыплаты.Рассмотрим подробный пример реализации этого алгоритма на встроенном языке 1С:
&НаСервере
Функция СоздатьИЗаполнитьВедомостьНаСервере(ДанныеЗаполнения) Экспорт
// Шаг 1. Создание нового документа
НовыйДокумент = Документы.ВедомостьНаВыплатуЗарплатыПеречислением.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.ПериодРегистрации = НачалоМесяца(ДанныеЗаполнения.ДатаДокумента);
НовыйДокумент.Организация = ДанныеЗаполнения.Организация;
// Задаем способ выплаты (например, Начисления по договорам ГПХ)
НовыйДокумент.СпособВыплаты = Справочники.СпособыВыплатыЗарплаты.НайтиПоНаименованию("Начисления по договорам");
НовыйДокумент.Округление = Справочники.СпособыОкругленияПриРасчетеЗарплаты.НайтиПоНаименованию("Без округления");
НовыйДокумент.ПроцентВыплаты = 100;
НовыйДокумент.Ответственный = ПараметрыСеанса.ТекущийПользователь;
НовыйДокумент.Комментарий = "Создан автоматически " + ТекущаяДата();
// Добавляем документ-основание (например, Начисление по договорам)
СтрокаОснования = НовыйДокумент.Основания.Добавить();
СтрокаОснования.Документ = ДанныеЗаполнения.ДокументОснование;
// Записываем документ для получения ссылки (обязательно для расчета выплат)
НовыйДокумент.Записать();
СсылкаНаДокумент = НовыйДокумент.Ссылка;
// Шаг 2. Подготовка параметров заполнения через Менеджер документа
МенеджерВедомости = Документы.ВедомостьНаВыплатуЗарплатыПеречислением;
ПараметрыЗаполнения = МенеджерВедомости.ПараметрыЗаполненияПоОбъекту(НовыйДокумент);
// При необходимости накладываем жесткий отбор по конкретным сотрудникам
// ПараметрыЗаполнения.ОтборСотрудников.Вставить("Сотрудники", ДанныеЗаполнения.МассивСотрудников);
// Шаг 3. Расчет сумм к выплате (зарплата)
ТаблицаЗарплаты = ВедомостьНаВыплатуЗарплаты.ЗарплатаКВыплате(
ПараметрыЗаполнения.ОписаниеОперации,
ПараметрыЗаполнения.ОтборСотрудников,
ПараметрыЗаполнения.ПараметрыРасчетаЗарплаты,
ПараметрыЗаполнения.Финансирование,
СсылкаНаДокумент
);
// Шаг 4. Расчет сумм удерживаемого НДФЛ
ТаблицаНДФЛ = ВедомостьНаВыплатуЗарплаты.НалогиКУдержанию(
ТаблицаЗарплаты,
ПараметрыЗаполнения.ОписаниеОперации,
ПараметрыЗаполнения.ПараметрыРасчетаНДФЛ,
ПараметрыЗаполнения.Финансирование,
СсылкаНаДокумент
);
// Шаг 5. Загрузка результатов расчетов в объект документа
НовыйДокумент.ЗагрузитьВыплаты(ТаблицаЗарплаты, ТаблицаНДФЛ);
// Шаг 6. Итоговая запись и проведение документа
Попытка
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
Возврат СсылкаНаДокумент;
Исключение
ВызватьИсключение "Ошибка при проведении ведомости: " + ОписаниеОшибки();
КонецПопытки;
КонецФункции
Этот способ полностью безопасен, работает в транзакции на сервере и не требует открытия диалоговых окон. Он отрабатывает в разы быстрее клиентских методов и гарантирует целостность данных.
Даже при использовании абсолютно верного программного кода ведомость может заполняться пустой табличной частью. Проанализируем основные методические причины, по которым это может происходить:
ЗарплатаКВыплате, которые формируются именно в момент проведения начислений.Применяя предложенный серверный подход к заполнению ведомостей, вы сможете создавать надежные, быстродействующие интеграции, устойчивые к обновлениям конфигурации 1С:ЗУП 3.1.