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