Как программно заполнить период и создать документ в 1С без обращения к реквизитам управляемой формы?

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

При разработке обработок пакетной загрузки данных в типовые конфигурации (например, 1С:Зарплата и управление персоналом 3.1, 1С:ERP или 1С:Комплексная автоматизация) разработчики нередко сталкиваются с ситуацией, когда на форме документа отображаются удобные для пользователя строковые поля (например, МесяцРегистрацииСтрокой), а попытка получить форму программно через ПолучитьФорму на клиенте или сервере приводит к ошибкам либо очистке табличных частей.

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

Архитектурная разница между реквизитами формы и реквизитами объекта

Проанализируем природу клиент-серверного взаимодействия в платформе 1С:Предприятие 8.3 на управляемых формах:

  1. Реквизиты формы — существуют исключительно в контексте сеанса пользователя в оперативной памяти конкретной открытой формы. Они не сохраняются в базе данных и служат только для удобства визуального отображения (например, вывод месяца в виде строки «Октябрь 2017» со стрелочками выбора). При закрытии формы эти значения уничтожаются.
  2. Реквизиты объекта — хранятся непосредственно в таблицах базы данных (в объекте метаданных документа). Именно они считываются механизмами проведения и модулями объекта при вызове метода Записать().

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

В чем заключается ошибка при установке периода в документах кадрового учета и расчета зарплаты

В документе ИндивидуальныйГрафик, как и во многих других расчетных документах ЗУП, строковое поле МесяцРегистрацииСтрокой на форме не является реквизитом документа. Оно динамически формируется событиями формы (например, ПриСозданииНаСервере или ПриЧтенииНаСервере) из настоящего реквизита объекта — ПериодРегистрации.

Реквизит ПериодРегистрации имеет тип Дата и всегда хранит дату, приведенную к первому числу соответствующего расчетного месяца (например, 01.10.2017 0:00:00 для октября 2017 года).

Если при открытии документа поле месяца подсвечивается красным или документ не проводится с ошибкой «Не указан период», это означает, что в самом объекте не заполнен реквизит ПериодРегистрации, либо не заполнены связанные служебные реквизиты (например, дата начала и окончания периода, перечисление периода ввода данных).

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

Рассмотрим по шагам, как правильно создать и провести документ ИндивидуальныйГрафик полностью в серверном коде без вызова формы:

  1. Создаем экземпляр объекта через менеджер документа.
  2. Инициализируем базовые реквизиты через метод Заполнить() или явным присвоением.
  3. Приводим дату расчетного месяца к первому числу с помощью функции НачалоМесяца() и записываем ее в ПериодРегистрации.
  4. Заполняем табличную часть данными графика.
  5. Записываем документ с проведением.

Посмотрим на пример серверной процедуры создания документа:


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

Как передать параметры в управляемую форму при интерактивном открытии

Если задача требует не пакетной фоновой загрузки, а открытия нового документа для пользователя с уже предзаполненными реквизитами, использовать ПолучитьФорму и напрямую менять реквизиты формы также не рекомендуется. В управляемом интерфейсе для этого используется механизм передачи параметров формы через метод ОткрытьФорму.

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


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

При таком подходе платформа передаст структуру ЗначенияЗаполнения в обработчик ОбработкаЗаполнения модуля объекта и в событие ПриСозданииНаСервере формы. Типовой код формы автоматически преобразует ПериодРегистрации в строковое представление МесяцРегистрацииСтрокой без ошибок и с сохранением всех связанных данных.

← На главную