К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как вызвать экспортную процедуру модуля формы в 1С

Как вызвать экспортную процедуру модуля формы в 1С: синтаксис, контекст клиент и сервер, директивы &НаКлиенте и &НаСервере, типовые ошибки и способы их исправить.

Экспортная процедура модуля формы — это процедура, объявленная с ключевым словом Экспорт, которую можно вызвать извне формы: из модуля объекта, общего модуля, другой формы или внешней обработки. Без слова Экспорт процедура доступна только внутри своего модуля, и попытка обратиться к ней снаружи завершится ошибкой «Процедура или функция с указанным именем не определена».

Главная сложность вызова состоит не в синтаксисе, а в понимании контекста: модуль формы в управляемом приложении компилируется и на клиенте, и на сервере, а директивы &НаКлиенте, &НаСервере, &НаСервереБезКонтекста определяют, откуда процедура доступна. Неверно выбранная директива — самая частая причина ошибок компиляции и «падений» вызова в режиме предприятия.

Ниже разобраны объявление экспортной процедуры, способы обращения к форме извне, ограничения контекста, вызов серверных процедур с клиента и типовые ошибки с проверкой результата.

Объявление экспортной процедуры в модуле формы

Экспортная процедура объявляется как обычная, но с ключевым словом Экспорт после списка параметров. Директива компиляции ставится перед ключевым словом Процедура и задаёт сторону исполнения.

&НаКлиенте

Процедура ОбновитьНадписьИтога(НовыйТекст) Экспорт

Элементы.НадписьИтог.Заголовок = НовыйТекст;

КонецПроцедуры

&НаСервере

Процедура ПересчитатьИтогиНаСервере() Экспорт

// работа с данными формы, запросы, обращения к реквизитам

КонецПроцедуры

Обратите внимание: директива &НаСервереБезКонтекста для экспортных процедур формы почти бесполезна — такой метод нельзя вызвать через объект формы с клиента, потому что у него нет доступа к данным формы. Для логики без контекста формы правильнее использовать общий серверный модуль.

Имя процедуры должно быть уникальным в пределах модуля формы и не совпадать с именами предопределённых обработчиков, если вы не переопределяете их осознанно. После добавления слова Экспорт обязательно проверьте модуль через «Конфигурация → Проверка конфигурации» или синтаксический контроль модуля — ошибка директивы всплывёт именно там.

Вызов процедуры через объект формы

Чтобы вызвать экспортную процедуру формы, нужна ссылка на объект формы — УправляемаяФорма или Форма (для обычных форм). Получить её можно несколькими способами в зависимости от того, откуда выполняется вызов.

Из модуля объекта (например, документа) форма доступна, только если она передана туда явно — напрямую «добраться» до открытой формы из серверного модуля объекта нельзя. На практике чаще используются два сценария: вызов из другой формы и вызов из внешнего кода, где форма получена функцией ПолучитьФорму().

// Получение формы и вызов её экспортной процедуры

ПараметрыФормы = Новый Структура("Ключ", НоменклатураСсылка);

ФормаЭлемента = ПолучитьФорму("Справочник.Номенклатура.ФормаОбъекта", ПараметрыФормы);

ФормаЭлемента.Открыть();

ФормаЭлемента.ОбновитьНадписьИтога("Итог пересчитан");

Если форма уже открыта и вызов идёт из другой формы, объект формы-источника обычно передают через параметры открытия или через ВладелецФормы / РодительскаяФорма. Например, подчинённая форма может обратиться к владельцу: ВладелецФормы.ОбновитьНадписьИтога("Готово").

Важное ограничение: вызов Форма.ИмяПроцедуры() выполняется в контексте вызывающей стороны. Если вызывающий код работает на клиенте, доступны только клиентские экспортные процедуры формы (&НаКлиенте). Обратиться с клиента напрямую к процедуре &НаСервере другой формы нельзя.

Порядок вызова из другой формы
  1. 1
    В модуле целевой формы объявите процедуру с Экспорт и директивой &НаКлиенте
  2. 2
    В вызывающей форме получите объект целевой формы (через параметры открытия, ВладелецФормы или ПолучитьФорму)
  3. 3
    Вызовите метод: ОбъектФормы.ИмяПроцедуры(Параметры)
  4. 4
    Проверьте в отладчике, что управление вошло в процедуру и данные формы изменились

Вызов серверной процедуры формы с клиента

Типовая задача: по кнопке на форме выполнить серверную обработку — запрос к базе, пересчёт, запись данных. Прямой вызов серверной процедуры с клиента запрещён платформой, поэтому используется цепочка: клиентский обработчик вызывает серверную процедуру той же формы.

&НаКлиенте

Процедура КомандаПересчитать(Команда)

ПересчитатьНаСервере();

КонецПроцедуры

&НаСервере

Процедура ПересчитатьНаСервере()

// запрос, пересчёт, изменение реквизитов формы

КонецПроцедуры

Здесь серверная процедура не обязана быть экспортной, если вызывается только внутри модуля формы. Но если та же серверная логика нужна снаружи (например, из модуля объекта при программной записи), правильнее вынести её в общий серверный модуль, а не делать форму «точкой входа» для бизнес-логики.

При каждом серверном вызове с клиента происходит сериализация контекста формы и обратно — это сетевой и серверный вызов. Не помещайте такие вызовы в циклы: сто вызовов сервера из цикла ощутимо медленнее одного вызова, обрабатывающего всю коллекцию целиком.

Директивы компиляции и ограничения контекста

Директива определяет, где компилируется метод и откуда он виден. Ошибки вида «Процедура или функция с указанным именем не определена» при внешне корректном коде почти всегда означают несовпадение директив вызывающего и вызываемого методов.

ДирективаГде выполняетсяКто может вызвать
&НаКлиентеТонкий/толстый клиентКлиентский код этой и других форм (через объект формы)
&НаСервереСервер, есть контекст формыКлиентские методы этой же формы; серверный код
&НаСервереБезКонтекстаСервер, без данных формыКлиентские методы этой же формы; данные передаются параметрами
&НаКлиентеНаСервереБезКонтекстаОбе стороны, без контекстаЛюбой код формы; только в толстом клиенте для обычных форм

Из серверной процедуры формы нельзя вызвать клиентскую процедуру той же формы — на сервере нет клиентского контекста. Если после серверной обработки нужно обновить интерфейс (например, показать предупреждение), делайте это в клиентском коде после возврата из серверного вызова.

Для обычных форм (неуправляемое приложение) разделения директив нет: модуль формы целиком исполняется на клиенте, а экспортные процедуры вызываются через объект формы напрямую. Серверная логика там выносится в общие модули с флагом «Сервер».

Передача параметров и возврат значений

Параметры экспортной процедуры передаются по стандартным правилам встроенного языка: по умолчанию — по ссылке внутри одного контекста, с модификатором Знач — по значению. При вызове между клиентом и сервером все параметры сериализуются, поэтому изменения параметров внутри серверной процедуры не вернутся на клиент автоматически.

Если нужно вернуть результат с сервера, используйте функцию с возвращаемым значением или заполняйте реквизиты формы на сервере — после завершения вызова клиент увидит обновлённые данные формы. Для больших структур данных предпочтительнее вернуть сериализуемое значение (структуру, массив, таблицу значений), чем многократно дёргать сервер.

&НаКлиенте

Функция ПолучитьОстатокПоТовару(Товар) Экспорт

Возврат ПолучитьОстатокНаСервере(Товар);

КонецФункции

&НаСервереБезКонтекста

Функция ПолучитьОстатокНаСервере(Товар)

// запрос к регистру остатков

Возврат Остаток;

КонецФункции

Проверка результата: поставьте точку останова в экспортной процедуре и убедитесь, что отладчик входит в неё, параметры заполнены ожидаемыми значениями, а после возврата вызывающий код получил результат. Если процедура «молчит», первым делом сверьте директивы и наличие слова Экспорт.

Контрольные точки

Как проверить результат

Компиляция модуля
Норма

Синтакс-контроль проходит без ошибок, процедура видна в списке методов модуля

Тревожный признак

Ошибка «Процедура не определена» у вызывающего кода

Вход в процедуру в отладчике
Норма

Точка останова срабатывает, параметры заполнены

Тревожный признак

Отладчик не заходит — неверный объект формы или директива

Изменение данных формы
Норма

После вызова реквизиты и элементы формы обновлены

Тревожный признак

Данные не меняются — изменения делались в другом контексте или в копии данных

Типовые ошибки и альтернативные подходы

Большинство проблем с вызовом экспортных процедур формы сводится к нескольким повторяющимся причинам. Их удобно проверять в первую очередь, прежде чем углубляться в отладку.

Типичные ошибки
01
Забыто слово Экспорт — вызывающий код получает «Процедура или функция не определена»
02
Вызов серверной процедуры с клиента напрямую — ошибка компиляции или выполнения; нужна клиентская обёртка
03
Обращение к закрытой форме — объект формы уничтожен, вызов приводит к ошибке; проверяйте, открыта ли форма
04
Бизнес-логика помещена в экспортные методы формы и дублируется — правильнее вынести её в общий модуль и вызывать отовсюду
05
Вызов в цикле серверных процедур формы — резкое падение производительности из-за сериализации контекста

Если экспортная процедура формы нужна только для того, чтобы «достучаться» до общей логики, остановитесь и пересмотрите архитектуру. Форма — это интерфейсный слой; переиспользуемая логика должна жить в общих модулях. Экспортные методы формы оправданы для операций именно с формой: обновить элементы, установить заголовок, активизировать страницу, обработать оповещение.

Альтернатива прямому вызову — механизм оповещений: Оповестить("ИмяСобытия", Параметры, Источник) в одной форме и обработчик ОбработкаОповещения в другой. Это слабее связывает формы между собой и не требует хранить ссылку на объект чужой формы, что снижает риск ошибок при закрытии форм.

Сравнение подходов

Прямой вызов Форма.Метод()

Подходит, когда вызывающий код гарантированно имеет живой объект формы и нужен синхронный результат. Ограничение: жёсткая связь форм и риск обращения к закрытой форме.

Оповестить + ОбработкаОповещения

Подходит для уведомления открытых форм об изменениях данных. Ограничение: нет возвращаемого значения, обработчик должен быть явно написан в целевой форме.

Общий серверный модуль

Подходит для бизнес-логики, нужной из разных мест. Ограничение: нет доступа к элементам и реквизитам конкретной формы.

FAQ

Почему возникает ошибка «Процедура или функция с указанным именем не определена»?

Три типовые причины: отсутствует ключевое слово Экспорт у процедуры; директива компиляции не соответствует контексту вызова (например, клиент вызывает серверный метод другой формы); опечатка в имени или вызов идёт не к тому объекту. Проверьте модуль синтакс-контролем и убедитесь, что переменная содержит именно объект нужной формы.

Можно ли вызвать экспортную процедуру формы из модуля объекта документа?

Напрямую — нет: модуль объекта выполняется на сервере и не имеет доступа к открытым формам. Если нужно отреагировать на запись из формы, используйте обработчик ПослеЗаписи в модуле формы или оповещение ОповеститьОЗаписи, которое перехватят открытые формы.

Чем отличается вызов в обычной и управляемой форме?

В обычной форме нет разделения на клиент и сервер: модуль исполняется на клиенте, экспортные процедуры вызываются через объект формы без директив. В управляемой форме обязательно учитывать директивы компиляции и сериализацию контекста при серверных вызовах.

Как вызвать процедуру формы, которая ещё не открыта?

Получите объект формы функцией ПолучитьФорму() с нужными параметрами, затем вызывайте её экспортные методы — форму при этом можно даже не открывать, если метод не работает с элементами интерфейса. Учтите, что каждая ПолучитьФорму с уникальным ключом создаёт новый экземпляр формы.

Стоит ли делать серверную экспортную процедуру формы для вызова извне?

Как правило, нет. Снаружи до серверного метода чужой формы всё равно не добраться, а для переиспользуемой логики правильное место — общий серверный модуль. Экспорт в модуле формы оправдан для клиентских методов, управляющих самой формой.

Итог

Что важно запомнить

Экспортная процедура формы объявляется со словом Экспорт и вызывается через объект формы. Клиент может вызывать только клиентские методы; серверная логика вызывается через клиентскую обёртку внутри той же формы. Для переиспользуемой логики используйте общие модули, а для связи между формами — оповещения.