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