Зачем в модуле менеджера 1С используется конструкция #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При изучении типовых конфигураций или создании собственных объектов в 1С:Предприятии 8.3 программисты часто сталкиваются с тем, что весь код в Модуле менеджера (справочника, документа, обработки) обернут в специфическую инструкцию препроцессора. На первый взгляд может показаться, что это ограничивает функциональность, например, запрещая печать из Тонкого клиента. Однако это не так. В данной статье мы подробно разберем архитектурные причины использования этой конструкции, проанализируем поведение различных клиентских приложений и выясним, как обеспечить стабильную работу системы.

Понятие контекста исполнения в модуле менеджера

Для начала рассмотрим, что представляет собой модуль менеджера. В отличие от модуля объекта, который отвечает за конкретный экземпляр (ссылку) данных, модуль менеджера предназначен для управления всем классом объектов. Здесь располагаются методы печати, обработчики выбора, переопределение получения форм и другие функции, не привязанные к конкретной ссылке.

Важно понимать ключевое различие между Тонким клиентом и Толстым клиентом в управляемом приложении:

  1. Тонкий клиент: Модуль менеджера на стороне клиента физически отсутствует. Весь код, написанный в нем, исполняется строго на сервере. Когда вы вызываете метод менеджера из тонкого клиента, платформа автоматически выполняет серверный вызов.
  2. Толстый клиент (управляемое приложение): Это "гибридный" режим. Модуль менеджера здесь доступен и на клиенте, и на сервере. Именно в этом кроется главная опасность и причина использования обсуждаемой директивы.

Проблема компиляции в Толстом клиенте

Проанализируем ситуацию: что произойдет, если мы уберем инструкции препроцессора и оставим код "голым"? Рассмотрим пример типичного метода в модуле менеджера:


Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ * ИЗ Документ.РеализацияТоваровУслуг ГДЕ Ссылка В (&МассивОбъектов)";
    Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
    // ... логика формирования табличного документа
КонецПроцедуры

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

Таким образом, конструкция #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда выступает в роли "защитного экрана", который говорит компилятору: "Не пытайся читать этот код, если ты не сервер, не старое обычное приложение и не внешнее соединение".

Разбор составляющих директивы препроцессора

Выясним, за что отвечает каждая часть этой сложной конструкции, которая является стандартом разработки фирмы "1С":

  1. #Если Сервер: Обеспечивает работу кода на стороне сервера приложений 1С или в файловом варианте при имитации серверного вызова. Это основной контекст для работы с базами данных, запросами и метаданными.
  2. ТолстыйКлиентОбычноеПриложение: Эта часть необходима для обратной совместимости. В старых конфигурациях (на обычных формах) вся логика часто исполнялась именно на клиенте (в толстом клиенте). Без этой директивы код в режиме "Обычного приложения" просто не будет виден, и функции менеджера перестанут работать.
  3. ВнешнееСоединение: Крайне важный флаг для интеграционных задач. Когда другая программа подключается к вашей базе через COM-соединение (Automation), контекст не идентифицируется как "Сервер" в чистом виде. Если исключить этот флаг, внешняя система не сможет вызвать методы модуля менеджера, что приведет к ошибкам интеграции.

Будет ли работать печать в Тонком клиенте?

Рассмотрим вопрос автора темы: не "отвалятся" ли команды печати при использовании Тонкого клиента?

Ответ: Нет, не отвалятся. Когда пользователь в Тонком клиенте нажимает кнопку "Печать", вызывается клиентская команда, которая внутри себя обращается к серверному методу (например, в общем модуле), а тот, в свою очередь, обращается к методу модуля менеджера. Так как вызов происходит на сервере, условие #Если Сервер выполняется, код успешно компилируется и отрабатывает.

Для Тонкого клиента модуль менеджера — это "черный ящик", который доступен только через серверный контекст. Проблем с доступностью процедур не возникает, так как обращение идет "сверху вниз" (Клиент -> Сервер -> Модуль менеджера).

Почему нельзя использовать &НаСервере вместо инструкций препроцессора?

Проанализируем разницу между аннотациями и инструкциями препроцессора. В модулях форм или команд мы привыкли использовать &НаСервере или &НаКлиенте. Однако в Модулях объектов и Модулях менеджеров использование этих аннотаций (инструкций-атрибутов) запрещено синтаксисом языка.

В этих модулях управление видимостью кода осуществляется только через инструкции препроцессора, начинающиеся с символа решетки #. Это более низкоуровневый механизм, который управляет не просто видимостью процедуры для вызова, а самим фактом включения этого куска текста в скомпилированный бинарный код для конкретного сеанса.

Особенности мобильной платформы и мобильного клиента

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

Однако для типовых "десктопных" конфигураций стандартное обрамление является избыточным, но необходимым для стабильности в Толстом клиенте (управляемое приложение).

Итоги и рекомендации

Подводя итог, использование конструкции препроцессора в модуле менеджера — это не прихоть, а необходимость, продиктованная архитектурой 1С. Рассмотрим основные выводы:

  1. Всегда оборачивайте содержимое модуля менеджера в #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда ... #КонецЕсли, если внутри есть серверные объекты (Запросы, Таблицы значений, Метаданные).
  2. Это никак не мешает работе Тонкого клиента — он всегда работает с менеджером через сервер.
  3. Это спасает от критических ошибок при запуске системы в режиме Толстого клиента (в котором часто работают разработчики в процессе отладки).
  4. Это обеспечивает доступ к методам базы данных для внешних систем через COM.

Если вы хотите, чтобы определенная функция была доступна везде (включая клиентский контекст толстого клиента) и она не содержит серверного кода, вы можете вынести ее за пределы блока #Если. Но на практике для модуля менеджера такая потребность возникает крайне редко, так как почти любая полезная работа менеджера связана с данными БД.

← На главную