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