Как вызвать экспортную процедуру модуля менеджера из клиентского кода в 1С?

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

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

Анализируем причину ошибки: почему модуль менеджера недоступен на клиенте?

Для начала выясним причину возникновения ошибки. В режиме управляемого приложения (Тонкий клиент, Веб-клиент) существует жесткое разделение между клиентской и серверной средой исполнения. Глобальные контекстные переменные, такие как Документы, Справочники, ПланыВидовХарактеристик и другие менеджеры объектов, существуют только на сервере.

Когда мы пишем код &НаКлиенте и пытаемся обратиться к Документы.ПоступлениеТоваров, клиентское приложение просто «не знает» о существовании такой коллекции. С точки зрения архитектуры это оправдано: клиент не должен иметь прямого доступа к объектной модели базы данных из соображений безопасности и производительности. Модуль менеджера компилируется на сервере, и его экспортные методы могут быть вызваны только в серверном контексте.

Решение №1: Использование серверной процедуры-посредника в модуле формы

Самый распространенный и простой способ обойти это ограничение — создать в модуле формы промежуточную процедуру с директивой компиляции &НаСервере или &НаСервереБезКонтекста. Эта процедура будет выступать своего рода «мостом» между клиентом и модулем менеджера.

Рассмотрим по шагам, как это реализовать на примере вызова процедуры ДобавитьЗапись из модуля менеджера документа ПоступлениеТоваров:

Шаг 1. В модуле формы документа создаем клиентскую процедуру (например, обработчик команды), из которой нам нужно инициировать действие.

Шаг 2. Создаем серверную процедуру в этом же модуле формы.

Шаг 3. Вызываем серверную процедуру из клиентской, а уже внутри серверной обращаемся к модулю менеджера.

Пример кода будет выглядеть следующим образом:


&НаКлиенте
Процедура КомандаВыполнитьДействие(Команда)
    
    // Передаем необходимые данные с клиента на сервер
    ВызватьДобавлениеЗаписиНаСервере(Объект.Организация, НоменклатураСсылка);
    
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВызватьДобавлениеЗаписиНаСервере(ПараметрОрганизация, ПараметрНоменклатура)
    
    // На сервере нам доступна коллекция "Документы"
    Документы.ПоступлениеТоваров.ДобавитьЗапись(ПараметрОрганизация, ПараметрНоменклатура);
    
КонецПроцедуры

Обратите внимание, что мы использовали директиву &НаСервереБезКонтекста. Это лучшая практика, если для работы вызываемого метода менеджера нам не нужно обращаться ко всем реквизитам формы целиком. Это значительно ускоряет работу программы, так как на сервер не передаются все данные формы (контекст), а только конкретные параметры.

Решение №2: Вынос логики в общий модуль

Если логика, которую вы вызываете, используется в нескольких формах или разных объектах, архитектурно правильнее будет использовать общий модуль. Это позволяет избежать дублирования кода «процедур-посредников» в каждой форме.

Разберем этот вариант подробнее:

  1. Создайте (или выберите существующий) общий модуль, например, РаботаСДокументамиСервер.
  2. В свойствах модуля должны быть установлены флаги «Сервер» и «Вызов сервера».
  3. Внутри общего модуля напишите экспортную процедуру, которая будет вызывать метод модуля менеджера.

Пример кода в общем модуле:


// В общем модуле РаботаСДокументамиСервер (флаги Сервер, Вызов сервера)
Процедура ДобавитьЗаписьВПоступление(Организация, Номенклатура) Экспорт
    
    Документы.ПоступлениеТоваров.ДобавитьЗапись(Организация, Номенклатура);
    
КонецПроцедуры

Теперь из любой клиентской процедуры в любой форме вы сможете напрямую вызвать этот метод:


&НаКлиенте
Процедура ВыполнитьНаКлиенте()
    
    РаботаСДокументамиСервер.ДобавитьЗаписьВПоступление(ОрганизацияКнопка, НоменклатураКнопка);
    
КонецПроцедуры

Важный нюанс: флаг «Вызов сервера» позволяет обращаться к серверному общему модулю непосредственно из клиентского кода. Платформа сама осуществит переход между контекстами.

Анализируем использование препроцессора в модуле менеджера

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

На самом деле, модуль менеджера и так компилируется только на сервере (за исключением режима толстого клиента). Однако такие инструкции часто вставляются автоматически или вручную для обеспечения совместимости кода. Если вы работаете исключительно в управляемом приложении, эти инструкции можно считать избыточными, но их наличие не мешает работе, если вы правильно организовали вызов через серверную процедуру-посредник.

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

Особенности передачи параметров между клиентом и сервером

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

Подведение итогов

Для успешного вызова экспортной процедуры модуля менеджера из клиента необходимо соблюдать следующую цепочку вызовов:

Клиент (Обработка нажатия кнопки) -> Серверная процедура (в модуле формы или общем модуле) -> Модуль менеджера.

Использование этого паттерна не только устраняет ошибку «Переменная не определена (Документы)», но и соответствует стандартам разработки фирмы «1С», обеспечивая стабильную работу приложения как в тонком клиенте, так и в веб-клиенте.

← На главную