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