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