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