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

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

Как обратиться к процедуре формы в 1С

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

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

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

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

Вызов процедуры внутри модуля формы

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

&НаКлиенте

Процедура КнопкаРассчитатьНажатие(Элемент)

РассчитатьИтоги(ТаблицаТоваров);

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

&НаКлиенте

Процедура РассчитатьИтоги(Таблица)

Для Каждого Строка Из Таблица Цикл

Строка.Сумма = Строка.Количество * Строка.Цена;

КонецЦикла;

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

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

Из процедуры &НаСервере нельзя вызвать процедуру &НаКлиенте напрямую — на сервере нет доступа к клиентскому контексту. Если нужно выполнить действие на клиенте после серверной обработки, серверная процедура должна завершиться, а клиентский код продолжить работу с результатом.

Экспортные процедуры и обращение извне

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

&НаКлиенте

Процедура ОбновитьДанныеФормы(ПараметрыОбновления) Экспорт

// логика обновления

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

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

ФормаОбработки = ПолучитьФорму("Обработка.ЗагрузкаДанных.Форма.ФормаЗагрузки");

ФормаОбработки.УстановитьПараметрыЗагрузки(Параметры);

ФормаОбработки.Открыть();

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

Вызов процедуры формы из другой формы

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

Рекомендуемый современный способ — механизм оповещений. При открытии формы указывается ОписаниеОповещенияОЗакрытии, и после закрытия вызывается указанная экспортная процедура формы-владельца:

&НаКлиенте

Процедура ВыбратьКонтрагента(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтотОбъект);

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , , Оповещение);

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

&НаКлиенте

Процедура ПослеВыбораКонтрагента(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

Объект.Контрагент = Результат;

КонецЕсли;

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

Этот подход предпочтительнее прямого обращения через ВладелецФормы.ИмяПроцедуры(), потому что он не создаёт жёсткой связи между формами и корректно работает в режиме блокирования окна владельца.

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

Обращение к процедуре формы из общего модуля

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

// Общий модуль РаботаСФормами

Процедура ЗаполнитьШапкуДокумента(Форма, Данные) Экспорт

Форма.Объект.Дата = ТекущаяДатаСеанса();

Форма.ПослеЗаполненияШапки(Данные); // экспортная процедура формы

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

Из модуля формы такой вызов выглядит как РаботаСФормами.ЗаполнитьШапкуДокумента(ЭтотОбъект, Данные). Ключевой момент — передаётся именно ЭтотОбъект, то есть текущий экземпляр формы.

Учитывайте контекст исполнения общего модуля. Если общий модуль серверный, переданная форма будет доступна как объект ФормаКлиентскогоПриложения только при вызове с клиента через серверную процедуру формы с контекстом. Вызов серверного общего модуля из клиентского кода напрямую невозможен, если у модуля не установлен признак «Вызов сервера».

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

Директива компиляции определяет, где исполняется процедура и откуда она доступна. Несоответствие директив — главный источник ошибок при обращении к процедурам формы.

ДирективаГде исполняетсяДоступ к данным формыОткуда можно вызвать
&НаКлиентеКлиентЕстьИз клиентских процедур формы, извне через объект формы
&НаСервереСерверЕстьИз клиентских и серверных процедур той же формы
&НаСервереБезКонтекстаСерверНетИз любых процедур формы, данные передаются параметрами
&НаКлиентеНаСервереБезКонтекстаИ там, и тамНетИз любого контекста формы

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

Сравнение способов вызова

Прямой вызов по имени

Только внутри своего модуля формы. Самый быстрый и простой вариант, недоступен извне.

Через объект формы (ПолучитьФорму, ВладелецФормы)

Для обращения из другой формы. Требует Экспорт у процедуры и живого экземпляра формы.

Через ОписаниеОповещения

Рекомендуется для возврата результата из дочерней формы. Не создаёт жёстких связей, работает с модальными окнами.

Через общий модуль с передачей формы параметром

Для общей логики над разными формами. Требует дисциплины в объявлении экспортных процедур.

Типичные ошибки и их диагностика

Ошибка «Процедура или функция с указанным именем не определена» означает, что процедура либо не объявлена, либо недоступна в текущем контексте компиляции. Проверьте написание имени, наличие процедуры в модуле формы и совместимость директив: клиентский код не видит процедуры, объявленные только на сервере вне контекста, если вызов идёт не через форму.

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

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

Типичные ошибки
01
Вызов процедуры без Экспорт из другой формы — ошибка «Метод объекта не обнаружен»
02
Вызов клиентской процедуры из серверного кода — ошибка компиляции или выполнения
03
Обращение к данным формы из &НаСервереБезКонтекста — данные недоступны, нужны параметры
04
Вызов процедуры закрытой формы без проверки Открыта() — ошибка выполнения
05
Частые серверные вызовы из клиентского цикла — резкое падение производительности

Как проверить корректность вызова

После внесения изменений проверьте модуль через конфигуратор: меню «Конфигурация — Проверка конфигурации» с включённой проверкой модулей. Ошибки несоответствия директив и отсутствующие процедуры будут показаны до запуска.

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

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

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

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

Проверка конфигурации проходит без ошибок по модулю формы

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

Сообщения «процедура не определена» или «несоответствие директив»

Выполнение вызова
Норма

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

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

Точка не срабатывает или параметры равны Неопределено

Состояние формы после вызова
Норма

Данные и элементы формы изменились как ожидалось

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

Форма не изменилась или появилось окно ошибки

Часто задаваемые вопросы

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

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

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

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

Нужно ли слово Экспорт, если процедура вызывается только внутри своей формы?

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

Как передать параметры при вызове процедуры другой формы?

Параметры передаются в скобках как при обычном вызове: ОбъектФормы.ИмяПроцедуры(Параметр1, Параметр2). Следите за типами: через клиент-серверную границу передаются только сериализуемые значения, поэтому сложные объекты лучше заменять структурами.

Чем ОписаниеОповещения лучше прямого вызова через ВладелецФормы?

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

Можно ли вызвать процедуру формы по имени, хранящемуся в строке?

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

Итог

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

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