При разработке внешних обработок заполнения для конфигураций на платформе 1С:Предприятие 8.3 (таких как «Управление торговлей», «ERP Управление предприятием» или «Комплексная автоматизация») программисты часто сталкиваются с необходимостью не просто изменить данные объекта, но и сразу же обновить их визуальное отображение на форме. Одной из типичных задач является вызов процедур пересчета, например, РассчитатьИтоговыеПоказателиПоступления(ЭтаФорма), непосредственно из кода внешней обработки.
В этой статье мы подробно разберем, как правильно получить контекст управляемой формы документа во внешней обработке, работающей по технологии БСП (Библиотека Стандартных Подсистем), проанализируем архитектурные ограничения платформы и рассмотрим три эффективных способа вызова процедур пересчета итогов.
Для того чтобы внешняя обработка имела доступ к контексту формы, а не просто к объекту базы данных, необходимо правильно настроить параметры ее регистрации в справочнике «Дополнительные отчеты и обработки». В БСП за это отвечает функция СведенияОВнешнейОбработке().
Выясним ключевой нюанс: стандартный тип команды ВидОбработкиЗаполнениеОбъекта() по умолчанию работает напрямую с объектом на сервере и не передает контекст формы. Чтобы обойти это ограничение, мы должны использовать тип команды «Заполнение формы». В этом случае БСП передает управление обработке, предоставляя полноценную ссылку на активную форму в параметрах выполнения.
Рассмотрим пример реализации функции регистрации обработки в модуле объекта:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Версия = "1.0";
// Указываем назначение обработки (например, документ ПоступлениеТоваровУслуг)
ПараметрыРегистрации.Назначение.Добавить("Документ.ПриобретениеТоваровУслуг");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Заполнить документ и пересчитать итоги (без записи)'");
НоваяКоманда.Идентификатор = "ЗаполнитьИПересчитать";
// КРИТИЧЕСКИ ВАЖНО: Используем тип команды заполнения формы
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы();
Возврат ПараметрыРегистрации;
КонецФункции
После такой регистрации при вызове команды БСП передаст управление в экспортную процедуру ВыполнитьКоманду. Именно в ней через структуру ПараметрыВыполнения мы получаем доступ к текущей активной форме документа.
Посмотрим на пример серверного обработчика выполнения команды:
Процедура ВыполнитьКоманду(ИмяКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
Если ИмяКоманды = "ЗаполнитьИПересчитать" Тогда
// Получаем форму документа из параметров БСП
ЭтаФорма = ПараметрыВыполнения.ЭтаФорма;
// Изменяем данные объекта напрямую через реквизит формы "Объект"
ТекущийОбъект = ЭтаФорма.Объект;
// Пример заполнения реквизита
ТекущийОбъект.Комментарий = "Заполнено внешней обработкой " + ТекущаяДатаСеанса();
// Устанавливаем признак модифицированности формы, чтобы пользователь видел изменения
ЭтаФорма.Модифицированность = Истина;
// Сообщаем пользователю об успешном завершении операции
ШаблонСообщения = Новый СообщениеПользователю();
ШаблонСообщения.Текст = "Данные успешно заполнены. Требуется пересчет итогов.";
ШаблонСообщения.Сообщить();
КонецЕсли;
КонецПроцедуры
Итак, форму документа мы успешно получили в переменную ЭтаФорма. Однако при попытке вызвать процедуру расчета итогов напрямую, например, написав ЭтаФорма.РассчитатьИтоговыеПоказателиПоступления(ЭтаФорма), платформа выдаст ошибку: «Метод объекта не обнаружен».
Проанализируем причину этой проблемы:
РассчитатьИтоговыеПоказателиПоступления в типовых конфигурациях расположена в модуле формы документа.Экспорт.Экспорт, она должна находиться в соответствующем контексте выполнения (серверном или клиентском), который совпадает с контекстом выполнения внешней обработки.Как решить эту дилемму, не снимая типовую конфигурацию с поддержки? Рассмотрим три практических варианта решения.
Если в вашей системе разрешено использование расширений конфигурации, этот способ является самым элегантным и надежным. Мы создадим небольшое расширение, которое сделает неэкспортный метод формы доступным для внешней обработки.
Разберем процесс реализации по шагам:
ПриобретениеТоваровУслуг).
&НаСервере
Процедура ИмяПрефикса_РассчитатьИтоговыеПоказателиЭкспорт() Экспорт
// Вызываем оригинальную неэкспортную процедуру типовой формы
РассчитатьИтоговыеПоказателиПоступления(ЭтаФорма);
КонецПроцедуры
Теперь из кода нашей внешней обработки мы можем напрямую и безопасно обратиться к этой процедуре через полученную форму:
// В модуле внешней обработки в процедуре ВыполнитьКоманду
ЭтаФорма = ПараметрыВыполнения.ЭтаФорма;
// Вызываем экспортный метод из расширения
ЭтаФорма.ИмяПрефикса_РассчитатьИтоговыеПоказателиЭкспорт();
Этот метод гарантирует, что все визуальные декорации, подписи, расчеты НДС, валютные показатели и итоги на форме обновятся мгновенно и корректно, в точном соответствии с логикой типового решения.
В случаях, когда использование расширений невозможно (например, база данных развернута в сервисе 1cfresh с жесткими ограничениями или у вас нет прав на администрирование расширений), нам придется имитировать интерактивные действия пользователя программным путем на сервере.
В современных конфигурациях 1С (ERP, УТ 11, КА) математические расчеты в строках табличных частей вынесены в специализированные серверные общие модули. Мы можем обойти непосредственный вызов процедур формы и рассчитать строки табличной части программно.
Рассмотрим пример пересчета строк табличной части «Товары» с использованием механизмов конфигурации «Управление торговлей 11»:
// Получаем форму и объект
ЭтаФорма = ПараметрыВыполнения.ЭтаФорма;
ДокументОбъект = ЭтаФорма.Объект;
// Подготавливаем кэш для расчета (требуется для ускорения работы серверных процедур)
КэшированныеЗначения = ОбработкаТабличнойЧастиКлиентСервер.ПолучитьСтруктуруКэшируемыхЗначений();
// Настраиваем структуру действий для пересчета колонок
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить("ПересчитатьСумму");
СтруктураДействий.Вставить("ПересчитатьСуммуНДС");
СтруктураДействий.Вставить("ПересчитатьСуммуСНДС");
// Обходим строки табличной части документа
Для Каждого СтрокаТовара Из ДокументОбъект.Товары Цикл
// Вызываем типовой серверный пересчет для каждой строки
ОбработкаТабличнойЧастиСервер.ОбработатьСтрокуТЧ(
СтрокаТовара,
СтруктураДействий,
КэшированныеЗначения
);
КонецЦикла;
Важное примечание: при использовании этого варианта данные внутри табличной части ЭтаФорма.Объект.Товары будут рассчитаны абсолютно верно математически. Однако общие итоги в подвале формы (визуальные текстовые декорации) могут не обновиться мгновенно на экране пользователя. Они обновятся автоматически, как только пользователь совершит любое интерактивное действие на форме (например, добавит или удалит строку, изменит количество товара или просто запишет документ).
Если для бизнес-процесса критически важно, чтобы расчет происходил исключительно на клиенте и сопровождался немедленной перерисовкой интерфейса без дополнительных действий пользователя, мы можем зарегистрировать команду внешней обработки с типом «Вызов клиентского метода».
Для этого в функции регистрации укажем следующий тип использования:
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
При таком подходе в модуле формы нашей внешней обработки создается клиентский обработчик. БСП передает в него управление и контекст клиентской формы документа. На клиенте разработчик получает возможность имитировать изменение реквизитов формы. Например, мы можем вызвать стандартное событие ПриИзменении для ключевых элементов, что автоматически запустит всю цепочку встроенных обработчиков формы, включая обновление итоговых показателей в подвале документа.
Мы подробно проанализировали особенности взаимодействия внешних обработок заполнения БСП с управляемыми формами документов в системе 1С. Получение формы через структуру ПараметрыВыполнения.ЭтаФорма при использовании типа команды «Заполнение формы» открывает разработчику широкие возможности по управлению интерфейсом. Выбор конкретного метода пересчета показателей (через расширение, серверные общие модули или клиентские команды) зависит от технических требований проекта и политики администрирования вашей информационной системы.