Разработчики конфигураций на платформе 1С:Предприятие 7.7 часто сталкиваются с ситуацией, когда необходимо из глобального модуля или другой формы вызвать экспортную процедуру, расположенную в модуле конкретной открытой обработки. Попытка вызова вида КонтекстФормы.Сформировать() приводит к ошибке: «Поле агрегатного объекта не обнаружено (Сформировать)».
Рассмотрим подробно причины возникновения этой ошибки, выясним, как устроена работа с контекстом в платформах 7-й версии, и разберем все доступные способы решения этой задачи — как штатные, так и с использованием популярных внешних компонент.
Проанализируем поведение платформы 1С 7.7 при работе с контекстом. Когда мы получаем контекст формы (например, через глВзятьКонтекст(Контекст) в процедуре ПриОткрытии() и сохраняем его в глобальную переменную), полученный объект предоставляет доступ к:
Форма.Обновить() или Форма.Закрыть().Важная особенность: встроенный язык 1С 7.7, в отличие от управляемых и обычных форм 1С 8.x, не публикует экспортные процедуры и функции модуля формы в качестве методов объекта контекста. Именно поэтому попытка обратиться к процедуре модуля формы напрямую через точку приводит к ошибке «Поле агрегатного объекта не обнаружено».
Разберем несколько рабочих способов решения этой проблемы.
Наиболее удобным и прямым решением для вызова любой экспортной процедуры модуля формы из внешнего кода является применение внешней компоненты FormEx.
В FormEx доступен объект Сервис и его метод ВыполнитьПроцедуру(), который принимает контекст формы, имя процедуры и список параметров.
Посмотрим на пример вызова экспортной процедуры обработки с помощью FormEx:
// Предварительно загружаем компоненту, если она не была загружена ранее
ЗагрузитьВнешнююКомпоненту("FormEx.dll");
// Вызов процедуры из глобального модуля или другой формы
Перем Конт, Сервис, СписокПараметров;
Сервис = СоздатьОбъект("Сервис");
СписокПараметров = СоздатьОбъект("СписокЗначений");
// Если форма уже открыта и ее контекст сохранен в переменной КонтекстФормыОбработки:
Сервис.ВыполнитьПроцедуру(КонтекстФормыОбработки, "Сформировать", СписокПараметров);
Если вызываемая процедура принимает аргументы, их достаточно добавить в созданный СписокЗначений по порядку передачи.
Если в вашем проекте используется внешняя компонента 1С++ с подключенным модулем TurboBL, механизм обращения к контексту расширяется. В этом случае платформе добавляется возможность обращаться к экспортным процедурам модуля формы напрямую через точку, именно так, как пытался сделать автор вопроса:
// Работает только при подключенном TurboBL из состава 1С++
КонтекстФормыОбработки.Сформировать();
Этот способ удобен тем, что не требует изменения структуры кода и создания дополнительных объектов-списков параметров.
Если задача заключается в периодическом обновлении данных (например, перечитывании таблицы значений раз в несколько секунд), можно воспользоваться недокументированной, но стабильно работающей функцией самого модуля формы Форма.ОбработкаОжидания().
Разберем порядок применения этого метода:
Посмотрим на пример размещения кода в модуле формы:
Процедура Сформировать()
// Логика обновления таблицы значений или перерасчета
ОбновитьТаблицу();
КонецПроцедуры
// Данный код размещается в самом конце модуля формы:
Форма.ОбработкаОжидания("Сформировать", 15); // Запуск процедуры "Сформировать" каждые 15 секунд
Примечание: вызов Форма.ОбработкаОжидания() работает непосредственно в контексте самой формы и не требует передачи контекста в глобальный модуль.
Если вызов процедуры требуется выполнять не по таймеру, а по конкретному событию из глобального модуля или другой формы без использования внешних компонент, проанализируем штатный механизм повторного вызова ОткрытьФорму().
Если форма обработки уже открыта на экране, вызов команды ОткрытьФорму() с передачей параметра не создает вторую копию окна, а активизирует существующую форму и вызывает предопределенную процедуру ПриПовторномОткрытии().
Рассмотрим алгоритм реализации:
ОткрытьФорму("Обработка.ИмяОбработки", "Пересчитать");
Процедура ПриПовторномОткрытии()
ПараметрыОткрытия = Форма.Параметр;
Если ПараметрыОткрытия = "Пересчитать" Тогда
Сформировать();
КонецЕсли;
КонецПроцедуры
Этот подход является полностью штатным, не требует сторонних библиотек и гарантирует корректную работу на любых релизах платформы 1С 7.7.
Мы проанализировали причину ошибки Поле агрегатного объекта не обнаружено при вызове процедур формы в 1С 7.7. Для решения задачи можно выбрать наиболее подходящий вариант:
Сервис.ВыполнитьПроцедуру) или 1С++ с TurboBL;Форма.ОбработкаОжидания() в модуле формы;ПриПовторномОткрытии() с передачей текстового параметра.