&НаСервереБезКонтекста: когда серверный вызов не тащит за собой форму
Содержание
Директива &НаСервереБезКонтекста нужна, чтобы выполнить код 1С на сервере, не передавая туда данные формы. Сервер получает только параметры процедуры и возвращает только результат. Вызов получается лёгким: меньше трафика, меньше времени на упаковку формы, нет риска случайно поменять её реквизиты.
Типичная ситуация: в документе на 300 строк пользователь выбирает контрагента, а форма полсекунды «думает». Разработчик открывает модуль и видит &НаСервере у функции, которой нужен только ИНН. Достаточно сменить директиву на «без контекста» и передать ссылку параметром — задержка уходит. Это не отдельный режим запуска программы, а способ компиляции конкретной процедуры в модуле управляемой формы.
Как устроен вызов сервера и чем мешает контекст формы
Управляемая форма живёт в двух местах. На клиенте — её отображение и клиентские процедуры. На сервере — реквизиты формы и серверные процедуры. При обычном серверном вызове платформа синхронизирует эти две половины.
Что происходит при вызове процедуры с &НаСервере:
- 📤 Клиент упаковывает данные формы:
Объект, табличные части, реквизиты формы. - 🔄 Данные уходят на сервер, там восстанавливается серверный контекст формы.
- ⚙️ Выполняется процедура. Ей доступны
ЭтотОбъект,Объект,Элементы, реквизиты. - 📥 Изменённые данные упаковываются и возвращаются на клиент, форма перерисовывается.
С &НаСервереБезКонтекста шаги 1, 2 и 4 почти исчезают. На сервер уходят параметры, обратно приходит возвращаемое значение. Формы на сервере в этот момент как бы нет.
Сравнение директив модуля формы
| Директива | Где выполняется | Данные формы доступны | Когда применять |
|---|---|---|---|
&НаКлиенте | Клиент | Да, клиентская часть | Обработчики событий, интерактив, диалоги |
&НаСервере | Сервер | Да, полностью | Нужно читать или менять реквизиты, табличные части, элементы |
&НаСервереБезКонтекста | Сервер | Нет | Нужны данные базы по ссылке, запрос, расчёт по параметрам |
&НаКлиентеНаСервереБезКонтекста | Там, откуда вызвали | Нет | Общие вычисления без обращения к базе: формат строки, проверка числа |
Если процедура не использует ни одного реквизита формы, это почти всегда кандидат на «без контекста». Проверка простая: смените директиву и сохраните модуль. Компилятор сам покажет, что функция всё-таки трогала форму.
Что доступно, а что нет
Внутри процедуры на сервере без контекста работают:
- ✅ параметры процедуры и её локальные переменные;
- ✅ запросы, менеджеры объектов, обращение к реквизитам по ссылке (
Контрагент.ИНН); - ✅ серверные общие модули, параметры сеанса, константы;
- ✅ другие процедуры этой же формы с директивой
&НаСервереБезКонтекста.
Недоступны:
- ❌
Объект,ЭтотОбъект(ЭтаФорма),Элементы, реквизиты формы; - ❌ процедуры формы с директивой
&НаСервере— им нужен контекст, которого нет; - ❌ переменные модуля формы.
Пример. Клиентский обработчик берёт ИНН выбранного контрагента:
&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
ИНН = ИННКонтрагента(Объект.Контрагент);
Если ЗначениеЗаполнено(ИНН) Тогда
Сообщить("ИНН контрагента: " + ИНН);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ИННКонтрагента(Контрагент)
Если Не ЗначениеЗаполнено(Контрагент) Тогда
Возврат "";
КонецЕсли;
Возврат Контрагент.ИНН;
КонецФункции
Ссылку передали параметром, строку получили обратно. Табличная часть документа на сервер не поехала.
Какие значения можно передавать
Параметры и результат проходят между клиентом и сервером, поэтому тип значения должен это позволять:
- ✅ примитивы: строка, число, дата, булево,
Неопределено; - ✅ ссылки на объекты базы;
- ✅
Структура,Массив,Соответствие, если внутри тоже передаваемые значения; - ❌
ТаблицаЗначений,ДеревоЗначений,РезультатЗапроса, объект документа (ДокументОбъект).
Если нужно вернуть табличные данные, переложите их в массив структур. Вот функция, которая собирает несколько реквизитов договора за один вызов:
&НаСервереБезКонтекста
Функция ДанныеДоговора(Договор)
Результат = Новый Структура("ВидДоговора, ВалютаВзаиморасчетов");
ЗаполнитьЗначенияСвойств(Результат, Договор);
Возврат Результат;
КонецФункции
Один вызов вместо двух отдельных: каждый серверный вызов — это круг по сети, их число важнее объёма кода.
Фоновые задания и регламентная обработка без формы
Фоновое и регламентное задание по своей природе работает без контекста. Ни формы, ни клиента у него нет. Метод такого задания — экспортная процедура серверного общего модуля, а не процедура формы.
Отсюда частый приём: из формы через &НаСервереБезКонтекста запускают фоновое задание и сразу возвращают клиенту его идентификатор. Форма не висит, пользователь продолжает работать.
&НаСервереБезКонтекста
Функция ЗапуститьПересчет(Организация, Период)
Параметры = Новый Массив;
Параметры.Добавить(Организация);
Параметры.Добавить(Период);
Задание = ФоновыеЗадания.Выполнить("ПересчетОстатковСервер.Пересчитать",
Параметры, , "Пересчёт остатков");
Возврат Задание.УникальныйИдентификатор;
КонецФункции
&НаСервереБезКонтекста
Функция ЗаданиеВыполняется(Идентификатор)
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(Идентификатор);
Возврат Задание <> Неопределено
И Задание.Состояние = СостояниеФоновогоЗадания.Активно;
КонецФункции
На клиенте состояние проверяют через ПодключитьОбработчикОжидания("ПроверитьЗадание", 2, Истина). Каждая проверка — лёгкий вызов без контекста, поэтому опрос раз в 2 секунды почти не нагружает сервер.
В типовых конфигурациях на БСП для этого есть готовый общий модуль ДлительныеОперации. Он берёт на себя запуск, опрос и вывод результата. Если пишете доработку для типовой — используйте его, а не собственный велосипед.
Код, который вы отладили в процедуре «без контекста», почти без правок переносится в общий модуль для фонового задания. Это ещё одна причина держать серверную логику независимой от формы.
Отладка серверного кода без контекста
Точку останова в процедуре &НаСервереБезКонтекста ставят так же, как в любой другой. Разница в том, где этот код выполняется.
Файловая база. Серверный код выполняется в процессе клиента. Отладка работает сразу: запустили 1С:Предприятие из конфигуратора, точка останова сработала.
Клиент-серверная база
. Код выполняется в рабочем процессе rphost на сервере 1С. Чтобы отладчик его видел:
- Сервер 1С должен быть запущен с разрешённой отладкой — ключ
-debugв строке запуска службы агентаragent. Изменение строки запуска требует перезапуска службы. - В конфигураторе откройте
Отладка → Подключениеи проверьте, что в списке предметов отладки есть серверные. - В настройке автоматического подключения отметьте сервер, а для фоновых заданий — и их.
Перезапуск службы сервера 1С обрывает сеансы всех пользователей. Включайте отладку на рабочем сервере только в нерабочее время, а лучше — на тестовом.
Что смотреть в отладчике:
- 🔍 значения параметров на входе: часто приходит пустая ссылка, а не ожидаемое значение;
- 🔍 тип возвращаемого значения — нельзя вернуть то, что не передаётся на клиент;
- 🔍 права: серверный код без привилегированного режима работает с правами текущего пользователя.
Для ошибок, которые не воспроизводятся под отладчиком, пишите диагностику в журнал регистрации через ЗаписьЖурналаРегистрации. Журнал смотрят в Администрирование → Обслуживание → Журнал регистрации или через конфигуратор.
Настройки кластера, которые влияют на серверные вызовы
Сама директива никаких настроек кластера не требует. Но код на сервере без контекста выполняется в среде сервера, и это даёт несколько практических следствий.
Файлы и пути — на сервере
Процедура «без контекста» видит диск сервера, а не компьютер пользователя. Путь C:\Выгрузка\прайс.xlsx в такой процедуре ищется на сервере 1С. Права на папку нужны пользователю, под которым работает служба (по умолчанию USR1CV8).
Файл с компьютера пользователя на сервер передают через временное хранилище: ПоместитьФайл на клиенте, затем ПолучитьИзВременногоХранилища на сервере. Адрес хранилища — обычная строка, её спокойно передают параметром без контекста.
Регламентные задания
В консоли кластера в свойствах информационной базы есть флажок «Блокировка регламентных заданий включена». Если он стоит, регламентные задания этой базы не стартуют. Фоновые задания, запущенные из кода через ФоновыеЗадания.Выполнить, при этом работают. Блокировку часто ставят на копиях баз и забывают снять при переносе в рабочую.
Рабочие процессы
Серверные вызовы и фоновые задания обслуживают рабочие процессы rphost. Их количество и нагрузку настраивают в свойствах рабочего сервера в консоли кластера. Тяжёлый фоновый пересчёт делит процессор с интерактивными пользователями, поэтому длинные операции ставят по расписанию на ночь.
Ошибки при вызове без контекста и как их разбирать
Часть ошибок ловит компилятор при сохранении модуля, часть проявляется только при работе.
Исключения на сервере и потеря соединения
Исключение в процедуре без контекста долетает до клиента как ошибка вызова. Если её не перехватить, пользователь увидит окно с текстом ошибки, а клиентская процедура прервётся.
Правильная схема:
- На сервере оберните рискованный участок в
Попытка … Исключение. - В блоке исключения запишите
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())в журнал регистрации. - Верните клиенту понятный признак:
Ложьили структуру с полем «ТекстОшибки».
Если транзакцию начали явно через НачатьТранзакцию(), в блоке исключения обязательно вызовите ОтменитьТранзакцию(). Иначе база останется в незавершённой транзакции до конца серверного вызова, и следующие записи в нём упадут.
При обрыве соединения с сервером (перезапуск рабочего процесса, сбой сети) клиент пытается переподключиться сам. Для вызовов без контекста это менее болезненно: форма на сервере не хранит промежуточного состояния, всё нужное лежит на клиенте. Повторный вызов просто передаст те же параметры.
Ускорение форм за счёт вызовов без контекста
Самый быстрый серверный вызов — тот, которого нет. Второй по скорости — без контекста. Порядок работы такой:
- Измерьте. Запустите 1С:Предприятие с ключом
/DisplayPerformance. В строке состояния появится число серверных вызовов и объём переданных данных. Откройте форму, повторите действие пользователя и запишите цифры. - Найдите лишние вызовы. Замер производительности в конфигураторе (
Отладка → Замер производительности) покажет, какие строки кода выполнялись и сколько времени заняли. - Переведите процедуры. Всё, что не трогает реквизиты формы, переводите в
&НаСервереБезКонтекста. - Объедините вызовы. Три функции подряд, каждая за своим реквизитом, превращаются в одну, возвращающую структуру.
- Уберите обращения к серверу из клиента. Обращение
Объект.Контрагент.ИННна клиенте неявно ходит на сервер. Такие места заменяют явным вызовом без контекста или заранее подготовленными данными формы.
Пример из практики. Документ реализации на 200 строк, при выборе номенклатуры в строке форма делала вызов &НаСервере, чтобы получить цену. Каждый раз на сервер уходила вся табличная часть. После перевода на «без контекста» с параметрами «номенклатура, вид цены, дата» объём передаваемых данных на одном изменении упал в десятки раз, а задержка перестала быть заметной.
Не переводите в «без контекста» всё подряд. Если процедуре нужны пять реквизитов формы и она меняет табличную часть, &НаСервере честнее и проще: передавать всё параметрами и собирать результат вручную выйдет сложнее и медленнее.
Частые вопросы
Работает ли &НаСервереБезКонтекста в файловой базе?
Чем процедура без контекста отличается от общего модуля с флажком «Вызов сервера»?
Можно ли из процедуры без контекста записать документ?
ПолучитьОбъект(), измените и вызовите Записать(). Открытая форма этого документа при этом сама не обновится — её нужно перечитать.