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