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