Как вызвать серверный метод из модуля команды в 1С 8.3 для получения реквизитов объекта

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

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

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

Выясняем причину: почему нельзя получить «реквизит реквизита» на тонком клиенте?

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

Если мы попытаемся написать на клиенте конструкцию вида:


Организация = ПараметрКоманды.Договор.Организация; // Ошибка или скрытый тяжелый вызов!

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

Золотое правило разработки 1С: любое обращение к реквизитам ссылочных типов должно выполняться строго на стороне сервера.


Разбираем проблему: почему платформа ругается на «без контекста» (&НаСервереБезКонтекста)

Пытаясь исправить ситуацию и вызвать серверный метод, разработчики часто пробуют применить директиву компиляции &НаСервереБезКонтекста в модуле команды. При попытке сохранить модуль платформа выдает ошибку компиляции. Давайте разберем, почему так происходит.

Директива &НаСервереБезКонтекста предназначена исключительно для модулей управляемых форм. В модулях команд (как и в общих модулях) её использование синтаксически запрещено.

В модуле команды разрешено использовать только три директивы компиляции:

При этом важно понимать: сам модуль команды не имеет собственного контекста данных (в отличие от модуля формы, у которого есть реквизиты формы, элементы и т.д.). Поэтому вызов обычной процедуры с директивой &НаСервере в модуле команды по своей сути является «внеконтекстным» — он максимально легковесный и не передает на сервер лишние данные.


Решение 1. Реализация собственного серверного метода в модуле команды

Рассмотрим классический способ решения задачи, если мы разрабатываем функционал в самописной конфигурации без использования Библиотеки Стандартных Подсистем (БСП).

Разберем по шагам, как настроить вызов:

  1. Основной метод команды ОбработкаКоманды выполняется на клиенте. В него в качестве первого параметра (ПараметрКоманды) передается ссылка на текущий документ.
  2. Из этого метода мы вызываем сопредельную функцию, расположенную в этом же модуле, но с директивой &НаСервере.
  3. В серверной функции мы спокойно обращаемся к любым реквизитам объекта «через точку» и возвращаем результат обратно на клиент.

Посмотрим на пример готового кода в модуле команды:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    // ПараметрКоманды хранит ссылку на документ. Передаем её на сервер.
    ОрганизацияДоговора = ПолучитьОрганизациюДоговораНаСервере(ПараметрКоманды);
    
    // Дальнейшая логика работы на клиенте с полученным значением
    ПоказатьПредупреждение(, "Организация по договору документа: " + ОрганизацияДоговора);
    
КонецПроцедуры

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

Решение 2. Оптимальный вариант с использованием БСП

Если вы работаете в типовой конфигурации 1С (например, 1С:ERP, 1С:Комплексная автоматизация, 1С:Управление торговлей или 1С:Бухгалтерия), то в них уже встроена Библиотека Стандартных Подсистем (БСП). В этом случае писать собственный серверный метод в модуле команды нет никакой необходимости.

Проанализируем встроенный инструмент БСП — функцию ЗначениеРеквизитаОбъекта из общего модуля ОбщегоНазначения. Эта функция позволяет получить реквизиты (в том числе через точку) за один быстрый и оптимизированный серверный запрос без необходимости написания лишних строк кода.

Посмотрим, как лаконично будет выглядеть модуль команды в данном случае:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    // Используем готовый метод БСП. 
    // Нам не нужно писать собственную серверную функцию в модуле команды.
    Организация = ОбщегоНазначенияКлиентСервер.ЗначениеРеквизитаОбъекта(ПараметрКоманды, "ДоговорКонтрагента.Организация");
    
    // Используем полученное значение в клиентском сценарии
    Если ЗначениеЗаполнено(Организация) Тогда
        // Выполняем действия
    КонецЕсли;
    
КонецПроцедуры

Важное примечание: При вызове функций общего назначения непосредственно с клиента убедитесь, что у используемого общего модуля установлены флаги «Клиент (управляемое приложение)» и «Вызов сервера», либо используйте специализированный клиентский аналог модуля.

Использование готовых механизмов БСП существенно ускоряет разработку, минимизирует количество ошибок и делает код более стандартизированным и легко читаемым для других разработчиков.

← На главную