Как работают процедуры и функции в управляемых формах 1С без директив НаКлиенте и НаСервере?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Правила компиляции по умолчанию в управляемых формах

Рассмотрим, как именно платформа 1С определяет контекст исполнения методов, если разработчик не указал директиву компиляции:

  1. Модуль управляемой формы: все процедуры, функции и переменные модуля, перед которыми не указана директива, по умолчанию всегда компилируются на сервере с контекстом (эквивалентно директиве &НаСервере).
  2. Модуль команды: метод без явной директивы по умолчанию компилируется на клиенте (эквивалентно директиве &НаКлиенте).
  3. Общие модули: в них директивы компиляции перед методами не используются вовсе — контекст определяется флагами в свойствах самого общего модуля (Сервер, Клиент, Внешнее соединение, Вызов сервера).

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

Почему выводятся сообщения через метод Сообщить() с сервера

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

Ограничения и риски отсутствия явных директив

Хотя формально платформа позволяет опускать директиву &НаСервере, на практике это порождает серьезные архитектурные проблемы. Разберем основные из них:

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

Использование директивы &НаКлиентеНаСервереБезКонтекста

Нередко возникает задача выполнить один и тот же несложный алгоритм (например, математический расчет суммы по строке табличной части) как на клиенте, так и на сервере, не дублируя код. Для этого в модуле управляемой формы применяется директива &НаКлиентеНаСервереБезКонтекста:


&НаКлиентеНаСервереБезКонтекста
Функция РассчитатьСуммуСтроки(Количество, Цена)
    Возврат Количество * Цена;
КонецФункции

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

Жизненный цикл переменных и передача данных между клиентом и сервером

Сервер 1С работает по принципу отсутствия сохранения состояния (stateless). Это означает, что между отдельными серверными вызовами в памяти сервера не сохраняются никакие глобальные переменные модуля. Рассмотрим жизненный цикл переменных:

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

Для корректной передачи и сохранения данных между клиентом и сервером используются:

  1. Реквизиты формы: штатный механизм хранения данных, доступный в контексте формы как на клиенте, так и на сервере.
  2. Параметры процедур и функций: явная передача структур и значений в процедуры &НаСервереБезКонтекста.
  3. Временное хранилище: использование методов ПоместитьВоВременноеХранилище() и ПолучитьИзВременногоХранилища() с привязкой к уникальному идентификатору формы для передачи больших массивов данных или файлов.

Реализация сценария «проверить, записать и закрыть при открытии»

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

Если форму не нужно открывать вовсе при несоблюдении условий, логику реализуют в обработчике ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Не ПроверитьДанныеСервер() Тогда
        Отказ = Истина; // Окно формы даже не откроется на клиенте
        Возврат;
    КонецЕсли;
КонецПроцедуры

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Выполняем серверную операцию записи
    ЗаписатьДанныеНаСервере();
    
    // Возвращаем управление на клиент и закрываем форму
    ЭтаФорма.Закрыть();
КонецПроцедуры

&НаСервере
Процедура ЗаписатьДанныеНаСервере()
    // Логика проверки и записи данных объекта
    ОбъектМодифицирован = Ложь;
КонецПроцедуры

Соблюдение стандартов разработки 1С и явное указание директив компиляции перед каждым методом делает код прозрачным, исключает неожиданные ошибки контекста и обеспечивает оптимальную производительность системы.

← На главную