При разработке функционала в управляемых формах платформы 1С:Предприятие 8.3 начинающие разработчики нередко сталкиваются с ситуацией, когда процедуры и функции успешно компилируются и отрабатывают даже без явного указания директив &НаКлиенте или &НаСервере. Разберем по шагам, по каким правилам платформа исполняет такой код, почему сообщения доходят до пользователя и к каким скрытым проблемам производительности может привести игнорирование директив.
Рассмотрим, как именно платформа 1С определяет контекст исполнения методов, если разработчик не указал директиву компиляции:
&НаСервере).&НаКлиенте).Таким образом, если в модуле формы написать процедуру без директивы, платформа создаст серверный метод с передачей полного контекста формы.
Проанализируем, почему функция Сообщить(), вызванная внутри серверного метода без директивы, успешно показывает текст пользователю на экране. Сервер 1С накапливает все отправленные сообщения во внутреннем буфере на протяжении всего времени выполнения серверного вызова. Как только серверная процедура завершает свою работу и управление возвращается на тонкий клиент, накопленный стек сообщений передается обратно и отображается в окне сообщений пользовательского интерфейса.
Хотя формально платформа позволяет опускать директиву &НаСервере, на практике это порождает серьезные архитектурные проблемы. Разберем основные из них:
Нажатие кнопки, ПриИзменении поля ввода) были объявлены исключительно с директивой &НаКлиенте. Процедура без директивы будет скомпилирована на сервере, и выбрать ее в палитре свойств элемента формы не удастся.Форма.ИмяМетода().Нередко возникает задача выполнить один и тот же несложный алгоритм (например, математический расчет суммы по строке табличной части) как на клиенте, так и на сервере, не дублируя код. Для этого в модуле управляемой формы применяется директива &НаКлиентеНаСервереБезКонтекста:
&НаКлиентеНаСервереБезКонтекста
Функция РассчитатьСуммуСтроки(Количество, Цена)
Возврат Количество * Цена;
КонецФункции
Обратите внимание: в управляемой форме нельзя использовать директиву &НаКлиентеНаСервере (она доступна только в модулях команд). В форме доступен только вариант без контекста, где все необходимые исходные данные должны передаваться исключительно через параметры функции.
Сервер 1С работает по принципу отсутствия сохранения состояния (stateless). Это означает, что между отдельными серверными вызовами в памяти сервера не сохраняются никакие глобальные переменные модуля. Рассмотрим жизненный цикл переменных:
&НаКлиенте в шапке модуля формы, существуют все время, пока открыта форма на клиенте.&НаСервере инициализируются заново при каждом серверном вызове и сразу уничтожаются после его завершения.Для корректной передачи и сохранения данных между клиентом и сервером используются:
&НаСервереБезКонтекста.ПоместитьВоВременноеХранилище() и ПолучитьИзВременногоХранилища() с привязкой к уникальному идентификатору формы для передачи больших массивов данных или файлов.Посмотрим на практический пример: как связать клиентскую логику закрытия формы с серверной логикой записи данных. Серверный код не может напрямую вызвать закрытие окна на клиенте, так как поток управления всегда инициируется клиентом.
Если форму не нужно открывать вовсе при несоблюдении условий, логику реализуют в обработчике ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Не ПроверитьДанныеСервер() Тогда
Отказ = Истина; // Окно формы даже не откроется на клиенте
Возврат;
КонецЕсли;
КонецПроцедуры
Если же форму необходимо открыть, выполнить запись и закрыть, поток управления строится через клиентский обработчик ПриОткрытии:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Выполняем серверную операцию записи
ЗаписатьДанныеНаСервере();
// Возвращаем управление на клиент и закрываем форму
ЭтаФорма.Закрыть();
КонецПроцедуры
&НаСервере
Процедура ЗаписатьДанныеНаСервере()
// Логика проверки и записи данных объекта
ОбъектМодифицирован = Ложь;
КонецПроцедуры
Соблюдение стандартов разработки 1С и явное указание директив компиляции перед каждым методом делает код прозрачным, исключает неожиданные ошибки контекста и обеспечивает оптимальную производительность системы.