Как правильно программно заполнить табличную часть расчетного документа в 1С:ЗУП 3?

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

При разработке обработок загрузки данных в типовые конфигурации (например, в 1С:ЗУП 3 при заполнении документа Премия) разработчики часто сталкиваются с дилеммой: заполнять ли реквизиты объекта на сервере или программно манипулировать открытой формой документа, пытаясь воспроизвести действия пользователя.

Разберем, почему попытка сымитировать интерактивный ввод через форму приводит к ошибкам, как устроена логика расчетных документов и какими способами следует решать эту задачу.

Почему нельзя сымитировать интерактивный ввод через форму

Попытка открыть форму документа и добавить строку в коллекцию элементов или данных формы выглядит следующим образом:


&НаКлиенте
Процедура ЗаполнитьЧерезФорму()
    ПараметрыФормы = Новый Структура("Ключ", СсылкаНаДокумент);
    Форма = ПолучитьФорму("Документ.Премия.ФормаОбъекта", ПараметрыФормы);
    Форма.Открыть();
    
    НоваяСтрока = Форма.Объект.Начисления.Добавить();
    НоваяСтрока.Сотрудник = СсылкаНаСотрудника;
КонецПроцедуры

При таком подходе возникают серьезные архитектурные и прикладные проблемы:

  1. События формы не генерируются платформой при программном изменении. События элементов управления (ПриИзменении, ОбработкаВыбора, ОкончаниеВводаТекста) платформенно предназначены только для реакции на физические действия пользователя. Программное присвоение значения в свойство строки данных формы не вызывает эти обработчики. В результате зависимые поля (например, Подразделение) остаются пустыми.
  2. Недоступность в фоновых и регламентных процессах. Метод ПолучитьФорму() и клиентские манипуляции работают только в интерактивном сеансе пользователя. Загрузка данных по расписанию, через фоновые задания или веб-сервисы с таким кодом завершится аварийно.
  3. Сложная структура типовых расчетных документов. В конфигурации 1С:ЗУП 3 документы начислений содержат не только видимую пользователю табличную часть, но и скрытые таблицы (показатели расчета, распределения, перерасчеты). Если просто добавить строку в одну таблицу, внутренние связки нарушаются, что приведет к ошибкам при проведении и неверному расчету зарплаты.
  4. Периодичность кадровых данных. Подразделение, должность, график и ставка сотрудника зависят от среза кадровой истории на дату документа. Брать эти значения «напрямую» из реквизитов справочника Сотрудники нельзя — требуется получение данных через специализированные срезы регистров сведений на расчетную дату.

Решение 1: Заполнение объекта на сервере через типовой программный интерфейс

Правильный архитектурный подход заключается в полной изоляции логики на сервере. Мы получаем объект документа, подготавливаем кадровые данные, заполняем табличные части и запускаем серверные процедуры расчета.

Проанализируем пример серверного заполнения документа:


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

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

  1. Изучите модуль менеджера и общие модули подсистемы. Практически вся логика, которую форма выполняет визуально, вынесена в серверные функции конфигурации. Посмотрев код формы документа, определите, какие экспортные процедуры общих модулей отвечают за перерасчет строк и заполнение показателей.
  2. Соблюдайте транзакционность. Все операции по выборке данных, расчету и записи объекта выполняйте в одном серверном вызове, не обращаясь к клиенту на каждой итерации цикла.

Решение 2: Подключение внешней обработки заполнения через БСП

Если требуется встроить загрузку данных непосредственно в форму документа, но конфигурация находится на типовой поддержке, наиболее удобный путь — разработка дополнительной обработки для подсистемы «Дополнительные отчеты и обработки» (БСП).

Разберем по шагам создание такой обработки:

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

В результате кнопка загрузки появится прямо в меню «Заполнить» документа без снятия конфигурации с поддержки.

Решение 3: Доработка логики формы через расширение конфигурации

Если необходимо добавить интерактивную кнопку на форму документа с гарантированным вызовом всех встроенных неэкспортных методов формы, создадим расширение конфигурации:

  1. Подключаем форму документа Премия в расширение.
  2. Добавляем собственную кнопку или команду загрузки.
  3. С помощью аннотаций &После или &Вместо вызываем серверные и клиентские процедуры формы, обеспечивая полную идентичность интерактивному вводу.

Итог: Программная имитация интерактивного ввода через манипуляции с открытой формой ненадежна и противоречит архитектуре 1С. Все операции по загрузке данных в расчетные документы следует выполнять на сервере путем прямой работы с объектом документа, заполнением кадровых срезов и вызовом типовых расчетных процедур.

← На главную