В процессе разработки в конфигурации 1С:Бухгалтерия государственного учреждения 2.0 (БГУ 2.0) программисты часто сталкиваются с необходимостью автоматизировать создание документов. Одной из специфических задач является копирование настроек Типовой операции из документа-образца в новый документ. Попытка решить эту задачу «в лоб», имитируя интерактивные действия пользователя через получение формы программно и передачу её в типовые общие модули, приводит к ошибке отображения типов ФормаКлиентскогоПриложения. Разберем, почему это происходит и как правильно реализовать программное заполнение данных.
Рассмотрим причину возникновения ошибки. Когда мы вызываем метод ПолучитьФорму() на клиенте, платформа создает объект ФормаКлиентскогоПриложения. Этот объект предназначен исключительно для работы в контексте клиентского сеанса. Типовые процедуры БГУ 2.0, такие как БухгалтерскиеОперацииСервер.СформироватьСтруктуруРеквизитов(Форма, ...), ожидают в качестве параметра контекст формы, который доступен только тогда, когда процедура вызывается из модуля самой формы.
Проанализируем ситуацию: если мы пытаемся передать форму, полученную по ссылке, в серверный метод, система пытается сериализовать (передать) этот объект на сервер. Однако объект «Форма» (не текущая) не подлежит такой передаче. В 1С:Предприятии 8 разделение на клиент и сервер реализовано строго: сервер «не знает» ничего об интерфейсных объектах, которые не являются его текущим контекстом выполнения. Поэтому использование методов, предназначенных для обслуживания интерактивной работы, в групповых обработках или фоновых заданиях невозможно.
Выясним причину, по которой разработчики типовых конфигураций создают методы, завязанные на форму. Это делается для удобства интерактивной работы: чтобы при изменении реквизитов на экране система сразу могла пересчитать структуру операции. Но для программной обработки нам нужно обращаться напрямую к данным. В БГУ 2.0 настройки типовой операции хранятся не в самом документе (за исключением ссылки на саму операцию), а в независимом хранилище.
Посмотрим на ключевые составляющие механизма типовых операций:
ТиповыеОперации.Для реализации задачи по заполнению документов «по образцу» в групповом режиме, нам необходимо выполнить последовательность действий с данными регистра, полностью игнорируя формы документов.
Сначала проанализируем объект документа. Нам нужно установить саму выбранную операцию, чтобы механизмы проведения понимали, по какому алгоритму формировать проводки.
НовыйОбъект = ДокументСсылка.ПолучитьОбъект();
НовыйОбъект.ТиповаяОперация = ОбразецСсылка.ТиповаяОперация;
// Предварительная запись важна, если документ новый, чтобы получить ссылку для регистра
НовыйОбъект.Записать(РежимЗаписиДокумента.Запись);
Рассмотрим подробнее работу с регистром ЗначенияПараметровТиповыхОпераций. Нам нужно прочитать все записи, где измерение Объект равно нашему документу-образцу, и создать такие же записи для нашего нового документа.
Выполним это с помощью запроса или набора записей:
НаборЗаписейОбразца = РегистрыСведений.ЗначенияПараметровТиповыхОпераций.СоздатьНаборЗаписей();
НаборЗаписейОбразца.Отбор.Объект.Установить(ОбразецСсылка);
НаборЗаписейОбразца.Прочитать();
НаборЗаписейНовый = РегистрыСведений.ЗначенияПараметровТиповыхОпераций.СоздатьНаборЗаписей();
НаборЗаписейНовый.Отбор.Объект.Установить(НовыйОбъект.Ссылка);
Для Каждого ЗаписьИзОбразца Из НаборЗаписейОбразца Цикл
НоваяЗапись = НаборЗаписейНовый.Добавить();
ЗаполнитьЗначенияСвойств(НоваяЗапись, ЗаписьИзОбразца, , "Объект");
НоваяЗапись.Объект = НовыйОбъект.Ссылка;
КонецЦикла;
НаборЗаписейНовый.Записать();
Система БГУ 2.0 при проведении обращается к ДополнительныеСвойства объекта. Если мы просто вызовем Записать(РежимЗаписиДокумента.Проведение), система может не увидеть параметров, если они еще не подтянуты в память. Разберем, как принудительно инициализировать эти данные.
Для этого воспользуемся серверным методом типового общего модуля:
// Подготавливаем структуру параметров, чтобы проведение прошло корректно
БухгалтерскиеОперацииБГУ.ПодготовитьСтруктуруПараметровДляПроведения(НовыйОбъект);
// Теперь можно проводить
НовыйОбъект.Записать(РежимЗаписиДокумента.Проведение);
Рассмотрим дополнительные инструменты, которые предоставляет БГУ 2.0 для программиста, чтобы не изобретать велосипед при работе с данными типовых операций:
БухгалтерскиеОперацииСервер.ПолучитьПараметрыТиповойОперации(СсылкаНаДокумент): Этот метод возвращает структуру всех заполненных параметров. Это крайне удобно, если вам нужно не просто скопировать записи регистра, а проанализировать их программно перед записью.БухгалтерскиеОперацииБГУ.ЗаписатьПараметрыТиповойОперации(Объект, СтруктураПараметров): Этот метод позволяет передать объект документа и структуру (где Ключ — имя параметра, Значение — его значение) и автоматически обновит регистр сведений. Это более «чистый» способ, чем ручная работа с набором записей регистра.Проанализируем пример использования метода ЗаписатьПараметрыТиповойОперации:
Параметры = БухгалтерскиеОперацииСервер.ПолучитьПараметрыТиповойОперации(ОбразецСсылка);
// Если нужно что-то подправить в параметрах перед копированием:
Параметры.Вставить("ДатаПлатежа", ТекущаяДата());
БухгалтерскиеОперацииБГУ.ЗаписатьПараметрыТиповойОперации(НовыйОбъект, Параметры);
Подведем итог нашего анализа ситуации. Ошибка с формой — это лишь сигнал системы о том, что вы пытаетесь использовать интерфейсный слой там, где должен работать слой данных.
Запомним основные правила:
ПолучитьФорму() для передачи её в серверные процедуры обработки данных.ДополнительныеСвойства объекта документа и регистром ЗначенияПараметровТиповыхОпераций.БухгалтерскиеОперацииБГУ, так как они инкапсулируют в себе сложную логику проверки типов и связей параметров, специфичную для государственных учреждений.Используя этот подход, вы сможете реализовать любые задачи по групповому созданию, изменению или копированию документов с типовыми операциями, обеспечив при этом высокую производительность и отсутствие ошибок отображения типов.