Разработка и Конфигурация · 11 мин
Контекст в 1С: что это и зачем он нужен разработчику
Что такое контекст в 1С: контекст формы, модуля, клиентский и серверный контекст, директивы компиляции и типичные ошибки разработчика.
Контекст в 1С — это совокупность данных, свойств и методов, доступных в конкретной точке выполнения программного кода. Когда разработчик говорит «переменная недоступна в этом контексте» или «метод работает только в контексте формы», он имеет в виду: исполняемый код «видит» лишь ограниченный набор объектов, и обратиться к чему-то за пределами этого набора напрямую нельзя.
Понимание контекста критично, потому что платформа 1С выполняет код в разных местах: на клиенте (в тонком, толстом или веб-клиенте) и на сервере. У каждой стороны свои возможности и ограничения. Код, который отлично работает на сервере, может вызвать ошибку на клиенте, и наоборот. Именно контекст определяет, какие объекты, реквизиты и методы доступны в каждом конкретном случае.
Ошибки вида «переменная не определена», «метод объекта не обнаружен» или «нельзя изменять поле в данном контексте» — почти всегда следствие непонимания того, в каком контексте выполняется процедура. Разобравшись с видами контекста и директивами компиляции, большинство таких ошибок устраняется за минуты.
Что такое контекст простыми словами
Представьте, что код — это человек, который пришёл в комнату. Контекст — это всё, что находится в этой комнате и чем человек может воспользоваться: инструменты на столе, документы в ящике, телефон на стене. В соседней комнате инструменты другие, и достать их, не выйдя из своей комнаты, нельзя.
В терминах платформы контекст формируется из нескольких слоёв: глобальный контекст (системные функции и свойства, доступные везде), контекст модуля (переменные и процедуры текущего модуля) и контекст объекта (реквизиты и методы конкретного объекта — формы, документа, справочника). Чем «глубже» точка выполнения, тем больше слоёв доступно.
Основные виды контекста в 1С
Практически разработчик сталкивается с четырьмя устойчивыми понятиями. Клиентский контекст — код, выполняемый на компьютере пользователя: здесь доступны интерактивные действия (вопросы пользователю, открытие форм, работа с файлами на локальном диске), но недоступны прямые запросы к базе данных. Серверный контекст — код на сервере 1С: здесь выполняются запросы, транзакции, обращения к данным, но нельзя показать пользователю диалог или открыть окно.
Контекст формы — это данные конкретной формы: её реквизиты, элементы, команды и объект, который форма редактирует. Контекст модуля объекта (например, модуля документа) — это реквизиты самого объекта и его события: ПриЗаписи, ОбработкаПроведения и другие. Общие модули образуют собственный контекст — их процедуры доступны извне, если отмечены как экспортные.
Проверить, объявлена ли переменная в этом модуле и не потеряна ли при вызове
Проверить директиву компиляции и тип модуля
Перенести интерактив в клиентскую процедуру
Передавать данные параметрами, а не обращаться к реквизитам формы напрямую
Директивы компиляции: как управлять контекстом
В модулях форм контекст задаётся директивами, которые ставятся перед объявлением процедуры или функции. Директива определяет, где будет скомпилирован и выполнен код. Без директивы платформа в форме обычно трактует процедуру как серверную, что часто становится источником ошибок.
| Директива | Где выполняется | Типичное применение |
|---|---|---|
| &НаКлиенте | Клиент | Интерактив: вопросы, открытие форм, работа с файлами пользователя |
| &НаСервере | Сервер | Запросы, обращение к данным, бизнес-логика без контекста формы |
| &НаСервереБезКонтекста | Сервер, без данных формы | Тяжёлые операции, где реквизиты формы не нужны |
| &НаКлиентеНаСервереБезКонтекста | Обе стороны, без формы | Универсальные вспомогательные функции (только в модулях форм с соответствующими ограничениями) |
Различие «&НаСервере» и «&НаСервереБезКонтекста» принципиально. В первом случае на сервер передаётся весь контекст формы — её реквизиты и данные, что при больших формах даёт заметный трафик между клиентом и сервером. Во втором случае передаются только явно указанные параметры, поэтому вызов работает быстрее, но обратиться к реквизитам формы внутри такой процедуры нельзя.
Как организовать вызовы между клиентом и сервером
Типовой сценарий в управляемом приложении выглядит так: клиентская процедура собирает данные от пользователя, вызывает серверную процедуру, та выполняет работу с базой и возвращает результат, после чего клиент показывает его пользователю. Нарушение этого порядка — попытка выполнить запрос на клиенте или показать диалог на сервере — приводит к ошибкам компиляции или выполнения.
- 1Определите, какие действия требуют базы данных — это серверная часть
- 2Определите, какие действия требуют диалогов и файлов пользователя — это клиентская часть
- 3Создайте клиентскую процедуру-обработчик события формы
- 4Внутри неё вызовите серверную процедуру, передав нужные данные параметрами
- 5На сервере выполните запрос и верните результат примитивными типами или структурой
- 6На клиенте обработайте результат и покажите его пользователю
Важное ограничение: между клиентом и сервером можно передавать только сериализуемые данные — примитивные типы, структуры, массивы, ссылки на объекты. Нельзя передать, например, объект запроса или открытое соединение. Если нужно передать сложный результат, соберите его в структуру или массив структур.
Пример разделения контекстов
Обработчик команды формы «Заполнить остатки» на клиенте вызывает серверную функцию, которая выполняет запрос к регистру остатков и возвращает таблицу значений, упакованную для передачи. Клиентская часть лишь запускает процесс и при необходимости сообщает пользователю о завершении. Вся работа с данными остаётся на сервере.
Контекст формы и «БезКонтекста»: что выбрать
Выбор между серверными процедурами с контекстом и без него — вопрос производительности и архитектуры. Если процедуре нужно прочитать или изменить реквизиты формы (например, заполнить табличную часть), удобнее &НаСервере: данные формы доступны напрямую. Если процедура работает только с параметрами — например, проверяет контрагента по ИНН — правильнее &НаСервереБезКонтекста: вызов будет легче и быстрее.
Сравнение вариантов
Подходит, когда нужны реквизиты и данные формы. Ограничение: на сервер передаётся весь контекст формы, что дорого на больших формах.
Подходит для независимых операций с параметрами. Ограничение: реквизиты формы недоступны, всё нужное передаётся явно.
Подходит для логики, переиспользуемой из разных форм. Ограничение: для вызова с клиента нужен флаг «Вызов сервера».
Типичные ошибки и как их избежать
Чаще всего проблемы возникают из-за смешения контекстов: разработчик пишет код «как привык», не проверяя, где он будет выполняться. Вторая группа ошибок — попытка передать между клиентом и сервером несериализуемые объекты. Третья — неоправданное использование контекстных серверных вызовов там, где хватило бы вызова без контекста.
Как проверить, что контекст настроен правильно
После изменения директив и структуры вызовов проверьте результат системно, а не только «запустилось — не запустилось». Конфигуратор подсвечивает часть ошибок ещё при проверке модуля, но ошибки передачи данных между клиентом и сервером часто проявляются только в рантайме.
Как проверить результат
Нет ошибок о недоступных методах и переменных
Сообщения «Процедура или функция не определена» при проверке
Действие выполняется, данные обновляются на форме
Ошибка «Метод объекта не обнаружен» или интерактивная операция недоступна
Серверные вызовы редкие и лёгкие
Форма «подвисает» при каждом действии — признак лишних контекстных вызовов
Только примитивы, структуры, массивы, ссылки
Попытка передать запрос, СКД-настройки напрямую и подобные объекты
Полезная привычка: называйте серверные процедуры с суффиксом «НаСервере» (например, ЗаполнитьОстаткиНаСервере). По имени сразу видно, где выполняется код, и при чтении чужой формы не нужно каждый раз смотреть директиву.
Частые вопросы
Чем контекст формы отличается от контекста объекта?
Контекст формы — это реквизиты, элементы и данные конкретной экранной формы. Контекст объекта — реквизиты и события самого объекта конфигурации (документа, справочника) в его модуле объекта. Форма может редактировать объект, но её контекст шире: там есть и интерфейсные данные, которых у объекта нет.
Почему возникает ошибка «Переменная не определена» в модуле формы?
Чаще всего процедура выполняется в контексте, где эта переменная недоступна: например, серверная процедура без контекста обращается к реквизиту формы, или клиентский код обращается к переменной, объявленной только на сервере. Проверьте директиву компиляции и передайте нужное значение параметром.
Можно ли вызвать клиентскую процедуру с сервера?
Напрямую — нет: сервер не имеет доступа к клиентской сессии интерфейса. Правильный путь — вернуть результат с сервера в клиентскую процедуру, которая инициировала вызов, и уже в ней выполнить интерактивные действия. Для длительных операций используют механизм длительных операций с оповещением клиента.
Что даёт флаг «Вызов сервера» в общем модуле?
Он разрешает вызывать экспортные процедуры серверного общего модуля с клиента. Без этого флага модуль доступен только другому серверному коду. Без необходимости флаг лучше не ставить: каждый такой модуль расширяет поверхность клиент-серверных вызовов.
Когда использовать &НаКлиентеНаСервереБезКонтекста?
Для простых вспомогательных функций, которые нужны на обеих сторонах и не требуют ни данных формы, ни доступа к базе: например, форматирование строки или расчёт по переданным числам. Такая функция компилируется и на клиенте, и на сервере, что избавляет от дублирования кода.
Влияет ли контекст на производительность?
Да, напрямую. Каждый контекстный серверный вызов передаёт данные формы между клиентом и сервером. Частые вызовы &НаСервере из цикла или при каждом изменении поля заметно замедляют работу. Оптимизация: группировать действия в один вызов и по возможности использовать вызовы без контекста.
Что важно запомнить
Контекст определяет, какие данные и методы доступны коду. Клиент — для интерактива, сервер — для работы с базой, директивы компиляции управляют местом выполнения. Большинство ошибок «не определена» и «не обнаружен» решается правильным выбором контекста и передачей данных параметрами.