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

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

НаСервереБезКонтекста в 1С: для чего нужна и как применять

Разбираем директиву НаСервереБезКонтекста в 1С: зачем нужна, чем отличается от НаСервере, когда применять, типичные ошибки и проверка результата.

Директива &НаСервереБезКонтекста в управляемых формах 1С указывает, что процедура или функция выполняется на сервере, но при этом ей недоступен контекст формы: данные реквизитов, элементы формы, объект формы. На первый взгляд это выглядит как ограничение, но именно оно делает такие вызовы быстрее и дешевле по ресурсам, чем обычные серверные методы формы.

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

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

Как устроен вызов сервера из управляемой формы

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

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

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

Чем НаСервереБезКонтекста отличается от НаСервере

Ключевое отличие — доступ к данным формы. В методе &НаСервере можно обратиться к реквизиту формы напрямую, изменить табличную часть, работать с объектом через РеквизитФормыВЗначение(). В методе без контекста всё это недоступно: попытка обратиться к реквизиту формы вызовет ошибку компиляции модуля.

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

КритерийНаСервереНаСервереБезКонтекста
Доступ к реквизитам формыЕстьНет
Доступ к элементам формыЕстьНет
РеквизитФормыВЗначение()ДоступенНедоступен
Передача контекста по сетиПолная сериализация формыТолько параметры метода
Типичное применениеИзменение данных формы на сервереПолучение данных из БД, расчёты, проверки

Когда применять директиву

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

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

Маршрут решения

Как выбрать директиву

Методу нужно читать или менять реквизиты и элементы формыИспользуйте &НаСервере — без контекста доступ к форме невозможен
Методу достаточно параметров-ссылок и примитивных значенийИспользуйте &НаСервереБезКонтекста — вызов будет легче и быстрее
Метод не зависит от конкретной формы и нужен в нескольких местахВынесите его в общий серверный модуль вместо модуля формы
Код может выполняться и на клиенте, и на сервереРассмотрите &НаКлиенте или общий модуль с флагом Клиент (управляемое приложение)

Ограничения и подводные камни

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

Второй момент — передаваемые параметры должны быть сериализуемыми. Ссылки, примитивные типы, структуры и массивы из них передаются без проблем. А вот объекты типа ДанныеФормыСтруктура, элементы формы или несериализуемые значения передать нельзя. Если нужно передать набор данных формы, соберите их в структуру на клиенте и передайте её.

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

Пример практической реализации

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

bsl
&НаКлиенте
Процедура НоменклатураПриИзменении(Элемент)
    Инфо = ПолучитьДанныеНоменклатуры(Объект.Номенклатура);
    Остаток = Инфо.Остаток;
    Цена = Инфо.Цена;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьДанныеНоменклатуры(НоменклатураСсылка)
    Результат = Новый Структура("Остаток, Цена", 0, 0);
    // запрос к регистрам остатков и цен
    Возврат Результат;
КонецФункции

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

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

Типичные ошибки и как их избежать

Самая частая ошибка — обращение к реквизиту формы внутри метода без контекста. Модуль не скомпилируется, и разработчик либо возвращает директиву &НаСервере, либо начинает передавать десяток параметров по одному. Правильнее оформить данные в структуру на клиенте — так сигнатура останется читаемой.

Вторая ошибка — ожидание, что изменения в базе данных сразу видны в форме. Метод без контекста записал документ, а форма продолжает показывать старые данные. Решение — вернуть признак успеха на клиент и там вызвать обновление данных или оповещение других форм через Оповестить().

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

Типичные ошибки
01
Обращение к реквизитам формы внутри метода без контекста — ошибка компиляции модуля
02
Серверный вызов в цикле по строкам — лавина обращений к серверу и зависание формы
03
Передача несериализуемых значений (ДанныеФормы, элементы формы) как параметров
04
Ожидание автообновления формы после записи данных на сервере — форму нужно обновлять явно
05
Дублирование одинаковых функций без контекста в нескольких формах вместо общего модуля

Проверка результата и влияние на производительность

Убедиться, что оптимизация сработала, можно через технологический журнал или замер времени вызова до и после смены директивы. В формах с тяжёлым контекстом — большими табличными частями, динамическими списками — разница между вызовом с контекстом и без него заметна невооружённым глазом, особенно в клиент-серверном режиме.

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

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

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

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

Модуль компилируется, ошибок обращения к контексту нет

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

Ошибки вида «Переменная не определена» на реквизиты формы

Поведение формы после вызова
Норма

Клиент получает возвращаемое значение и обновляет нужные поля

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

Данные на форме не меняются, хотя на сервере операция выполнилась

Количество серверных вызовов
Норма

Один вызов на логическую операцию

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

Вызовы идут в цикле или на каждое изменение поля

Частые вопросы

Можно ли вызвать метод НаСервереБезКонтекста из клиентской процедуры?

Да, именно так он и используется. Из процедуры с директивой &НаКлиенте серверный метод без контекста вызывается напрямую по имени, как обычная функция. Платформа сама выполнит удалённый вызов и вернёт результат.

Что быстрее: НаСервереБезКонтекста или обращение к общему модулю?

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

Почему метод без контекста не видит реквизит формы, хотя он объявлен?

Это штатное поведение, а не ошибка платформы. Директива специально исключает контекст формы из вызова. Передайте нужное значение параметром или смените директиву на &НаСервере, если доступ к форме действительно необходим.

Можно ли передать таблицу значений в метод без контекста?

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

Нужна ли директива, если вся логика уже в общих модулях?

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

Итог

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

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