Почему в расширении не видно процедуру общего модуля и как это исправить

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

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

Причина проблемы: контекстные ограничения и безопасность

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

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

Решение 1: Создание промежуточного «прокси-модуля» в расширении

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

Разберем этот процесс по шагам:

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

Проанализируем пример кода для такого модуля:


// В новом модуле расширения с флагом "Вызов сервера"
Функция ВызватьНужнуюПроцедуруНаСервере(Параметр1, Параметр2) Экспорт
    
    // Здесь мы уже находимся на сервере, поэтому нам доступны 
    // любые серверные модули основной конфигурации
    Возврат ОбщийМодульОсновнойКонфигурации.ЦелеваяПроцедура(Параметр1, Параметр2);
    
КонецФункции

Теперь в клиентском коде (например, в модуле формы или в клиентском общем модуле расширения) мы вызываем наш новый модуль:


&НаКлиенте
Процедура КомандаВыполнить(Команда)
    
    Результат = Расш_ПромежуточныйСерверныйМодуль.ВызватьНужнуюПроцедуруНаСервере(Данные1, Данные2);
    
КонецПроцедуры

Решение 2: Использование серверного контекста формы (методы-обертки)

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

Рассмотрим пример реализации:


&НаКлиенте
Процедура Расш_ПриИзмененииРеквизита(Элемент)
    // Напрямую вызвать серверный модуль без "Вызова сервера" нельзя
    // Вызываем свою серверную обертку
    Результат = ВыполнитьЛогикуНаСервере(Объект.Ссылка);
КонецПроцедуры

&НаСервере
Функция ВыполнитьЛогикуНаСервере(Ссылка)
    // В серверном контексте формы нам доступны серверные общие модули
    Возврат ОбщийМодульТиповой.РассчитатьЗначение(Ссылка);
КонецФункции

Важно помнить, что в новых версиях платформы вызов серверных методов формы извне (например, из общего клиентского модуля) для заимствованных форм может быть ограничен. Если вы сталкиваетесь с тем, что Форма.ИмяСерверногоМетода() не работает, используйте первый способ с общим модулем-прокси.

Особенности работы с заимствованными и новыми объектами

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

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

Рекомендации по стандартам разработки (Стандарт №679)

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

Если вам приходится дорабатывать типовой механизм, постарайтесь следовать этим правилам:

Заключение

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

← На главную