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

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




