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