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

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

Контекст в 1С: что это и зачем он нужен разработчику

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

Контекст в 1С — это совокупность данных, свойств и методов, доступных в конкретной точке выполнения программного кода. Когда разработчик говорит «переменная недоступна в этом контексте» или «метод работает только в контексте формы», он имеет в виду: исполняемый код «видит» лишь ограниченный набор объектов, и обратиться к чему-то за пределами этого набора напрямую нельзя.

Понимание контекста критично, потому что платформа 1С выполняет код в разных местах: на клиенте (в тонком, толстом или веб-клиенте) и на сервере. У каждой стороны свои возможности и ограничения. Код, который отлично работает на сервере, может вызвать ошибку на клиенте, и наоборот. Именно контекст определяет, какие объекты, реквизиты и методы доступны в каждом конкретном случае.

Ошибки вида «переменная не определена», «метод объекта не обнаружен» или «нельзя изменять поле в данном контексте» — почти всегда следствие непонимания того, в каком контексте выполняется процедура. Разобравшись с видами контекста и директивами компиляции, большинство таких ошибок устраняется за минуты.

Что такое контекст простыми словами

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

В терминах платформы контекст формируется из нескольких слоёв: глобальный контекст (системные функции и свойства, доступные везде), контекст модуля (переменные и процедуры текущего модуля) и контекст объекта (реквизиты и методы конкретного объекта — формы, документа, справочника). Чем «глубже» точка выполнения, тем больше слоёв доступно.

Основные виды контекста в 1С

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

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

Ошибка «Переменная не определена»Код обращается к имени вне своего контекста

Проверить, объявлена ли переменная в этом модуле и не потеряна ли при вызове

«Метод объекта не обнаружен»Метод существует, но недоступен на этой стороне

Проверить директиву компиляции и тип модуля

«Интерактивная операция недоступна»Попытка показать диалог на сервере

Перенести интерактив в клиентскую процедуру

Данные формы «не видны» на сервереСерверный вызов без передачи контекста формы

Передавать данные параметрами, а не обращаться к реквизитам формы напрямую

Директивы компиляции: как управлять контекстом

В модулях форм контекст задаётся директивами, которые ставятся перед объявлением процедуры или функции. Директива определяет, где будет скомпилирован и выполнен код. Без директивы платформа в форме обычно трактует процедуру как серверную, что часто становится источником ошибок.

ДирективаГде выполняетсяТипичное применение
&НаКлиентеКлиентИнтерактив: вопросы, открытие форм, работа с файлами пользователя
&НаСервереСерверЗапросы, обращение к данным, бизнес-логика без контекста формы
&НаСервереБезКонтекстаСервер, без данных формыТяжёлые операции, где реквизиты формы не нужны
&НаКлиентеНаСервереБезКонтекстаОбе стороны, без формыУниверсальные вспомогательные функции (только в модулях форм с соответствующими ограничениями)

Различие «&НаСервере» и «&НаСервереБезКонтекста» принципиально. В первом случае на сервер передаётся весь контекст формы — её реквизиты и данные, что при больших формах даёт заметный трафик между клиентом и сервером. Во втором случае передаются только явно указанные параметры, поэтому вызов работает быстрее, но обратиться к реквизитам формы внутри такой процедуры нельзя.

Как организовать вызовы между клиентом и сервером

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

Порядок действий
  1. 1
    Определите, какие действия требуют базы данных — это серверная часть
  2. 2
    Определите, какие действия требуют диалогов и файлов пользователя — это клиентская часть
  3. 3
    Создайте клиентскую процедуру-обработчик события формы
  4. 4
    Внутри неё вызовите серверную процедуру, передав нужные данные параметрами
  5. 5
    На сервере выполните запрос и верните результат примитивными типами или структурой
  6. 6
    На клиенте обработайте результат и покажите его пользователю

Важное ограничение: между клиентом и сервером можно передавать только сериализуемые данные — примитивные типы, структуры, массивы, ссылки на объекты. Нельзя передать, например, объект запроса или открытое соединение. Если нужно передать сложный результат, соберите его в структуру или массив структур.

Пример разделения контекстов

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

Контекст формы и «БезКонтекста»: что выбрать

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

Сравнение вариантов

&НаСервере

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

&НаСервереБезКонтекста

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

Общий серверный модуль

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

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

Чаще всего проблемы возникают из-за смешения контекстов: разработчик пишет код «как привык», не проверяя, где он будет выполняться. Вторая группа ошибок — попытка передать между клиентом и сервером несериализуемые объекты. Третья — неоправданное использование контекстных серверных вызовов там, где хватило бы вызова без контекста.

Типичные ошибки
01
Вызов запроса в клиентской процедуре — ошибка компиляции или выполнения; запросы переносят на сервер
02
Показ диалога Вопрос() на сервере — интерактив недоступен; диалоги выносят в клиентский код
03
Использование &НаСервере ради одной проверки — лишняя передача всего контекста формы; заменить на &НаСервереБезКонтекста с параметрами
04
Передача объекта Запрос или ТаблицаЗначений на клиент без преобразования — такие типы не сериализуются; возвращать структуры и массивы
05
Обращение к реквизиту формы в процедуре БезКонтекста — переменная не определена; передать значение параметром

Как проверить, что контекст настроен правильно

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

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

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

Проверка модуля в конфигураторе
Норма

Нет ошибок о недоступных методах и переменных

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

Сообщения «Процедура или функция не определена» при проверке

Запуск обработчика в пользовательском режиме
Норма

Действие выполняется, данные обновляются на форме

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

Ошибка «Метод объекта не обнаружен» или интерактивная операция недоступна

Скорость работы формы
Норма

Серверные вызовы редкие и лёгкие

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

Форма «подвисает» при каждом действии — признак лишних контекстных вызовов

Передаваемые данные
Норма

Только примитивы, структуры, массивы, ссылки

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

Попытка передать запрос, СКД-настройки напрямую и подобные объекты

Полезная привычка: называйте серверные процедуры с суффиксом «НаСервере» (например, ЗаполнитьОстаткиНаСервере). По имени сразу видно, где выполняется код, и при чтении чужой формы не нужно каждый раз смотреть директиву.
ПЗ
Практическое замечание

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

Чем контекст формы отличается от контекста объекта?

Контекст формы — это реквизиты, элементы и данные конкретной экранной формы. Контекст объекта — реквизиты и события самого объекта конфигурации (документа, справочника) в его модуле объекта. Форма может редактировать объект, но её контекст шире: там есть и интерфейсные данные, которых у объекта нет.

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

Чаще всего процедура выполняется в контексте, где эта переменная недоступна: например, серверная процедура без контекста обращается к реквизиту формы, или клиентский код обращается к переменной, объявленной только на сервере. Проверьте директиву компиляции и передайте нужное значение параметром.

Можно ли вызвать клиентскую процедуру с сервера?

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

Что даёт флаг «Вызов сервера» в общем модуле?

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

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

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

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

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

Итог

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

Контекст определяет, какие данные и методы доступны коду. Клиент — для интерактива, сервер — для работы с базой, директивы компиляции управляют местом выполнения. Большинство ошибок «не определена» и «не обнаружен» решается правильным выбором контекста и передачей данных параметрами.