gifts2017

Варианты получения значения элементарного (серверного) выражения на клиентской стороне (в том числе с использованием функций ПредопределенноеЗначение и ВычислитьФормулу). Плюсы, минусы.

Опубликовал mxm2 mxm2 (mxm2) в раздел Программирование

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

Допустим на форме нужно в зависимости от интерактивного изменения флажка устанавливать значение какого-либо реквизита, это можно сделаеть так:

Вариант 1:
&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
      ФлажокПриИзмененииНаСервере();
КонецПроцедуры

 &НаСервере
Процедура ФлажокПриИзмененииНаСервере()
      Объект.Статус = Перечисления.СтатусыЗаказовКлиентов.КОбеспечению;
      // или так: Объект.Статус = Перечисления.СтатусыЗаказовКлиентов.ПустаяСсылка; 
КонецПроцедуры 

Или так: 

Вариант 2:
&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
       Объект.Статус = ВернутьСтатусНаСервере();
КонецПроцедуры

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

Строго говоря, оба эти варианта "неправильные", т.е. работать они конечно же будут, но неэффентивно, так же неэффективен следующий вариант (есть в УТ11):

Вариант 3:
&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
       Объект.Статус = РаботаСФомулами.ВычислитьФормулу("Перечисления.СтатусыЗаказовКлиентов.КОбеспечению");
КонецПроцедуры

Здесь производится вывов стандартной серверной функции, реализованной в общем модуле УТ11 РаботаСФомулами.ВычислитьФормулу. Её реализация:

Функция ВычислитьФормулу(ТекстРасчета) Экспорт
       Возврат Вычислить(ТекстРасчета);
КонецФункции

Эта "фича", которая позволяет не описывать процедуры/функции исполняемой на сервере, а использует уже готовую "универсальную", но существует и "пара но", а именно:
   - уже есть функция платформы, которая может выполнять, почти тоже самое(об этом позднее);
   - если у вас есть РаботаСФомулами.ВычислитьФормулу, а база опубликована в веб, то любой человек может выполнять на вашем сервере произвольный 1С-код, просто передавая туда HTTP-запросы (Evil Beaver)

Функция платформы, которая позволяет сделать тоже самое, но с одной стороны без привязки к конфигурации, с другой кэшируя полученное значение:

Вариант 4:
&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
       Объект.Статус = ПредопределенноеЗначение("Перечисление.СтатусыЗаказовКлиентов.КОбеспечению");
КонецПроцедуры

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

&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
       Объект.Группа = РаботаСФомулами.ВычислитьФормулу("Справочники.Партнеры.НайтиПоКоду(""00002"")");
КонецПроцедуры

Такое значение нельзя вычислить используя Вариант 4, но правильнее в этом случае использовать предопределенный элемент справочника, тогда Вариант 4 вполне применим, например так:

&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
       Объект.Группа = ПредопределенноеЗначение("Справочник.Партнеры.НашеПредприятие");
КонецПроцедуры

 

Кратко преимущества(+)/недостатки(-) каждого варианта
+/- Возможность \ Вариант Вариант 1 Вариант 2 Вариант 3 Вариант 4
  Количество вызовов сервера при первоначальном использовании одного значения формы 1 1 1 1
  Количество вызовов сервера при первоначальном использовании N значений формы  1 N N N
  Количество вызовов сервера при повторном использовании уже полученного одного значения  1 1 1 0
  Количество вызовов сервера при повторном использовании уже полученных N значений 1 N N 0
+ Контекстная подсказка при написании кода Есть Есть Нет Есть
+ Возможность использования предопределенных и пустых значений объектов Есть Есть Есть Есть
+ Использование функций типа НайтиПоКоду, НайтиПоНаименованию... Есть Есть Есть Нет
+ Нагладность кода Есть Есть Есть Есть
+ Возможность проверки, используя синтаксис контроль Есть Есть Нет Нет
+ Возможность проверки, используя контроль при сохранении (со словами "Возможно ошибочный параметр") Нет Нет Нет Есть
- Необходимость написания процедуры/функции исполняемой на сервере  Есть Есть Нет Нет

Исходя из данной таблицы, наиболее выигрышными являются варианты 1 и 4, причем Вариант 1 лучше использовать когда нужно установить несколько значений формы, возможно со сложными вычислениями (например, Запросами), Вариант 4 - в простейших случаях, к которым можно сводить конструкции типа НайтиПоКоду, НайтиПоНаименованию, через предопределенные значения.

Вариант 2 - вообще желательно не употеблять ввиду его недостатков и возможность замещения другими, более эффективными вариантами.

Вариант 3 - можно рекомендовать только как временное решение (если база не опубликована в веб), до добавления предопределенного значения.

ЗЫ: Особое спасибо Magisterу, Поручику и Evil Beaver, за то что наставили на "путь истины", критикой в комментариях (изначально статья имела совсем другое содержание и выводы).

См. также

Подписаться Добавить вознаграждение

Комментарии

1. mxm2 mxm2 (mxm2) 06.02.13 12:30
Применять удобно при взаимодействии с пользователем, например, при изменении реквизита на форме, - заполнять нужным значением, какой-либо другой реквизит. Если же нужно заполнить несколько реквизитов применение указанного метода будет приводить к нескольким вызовам сервера, что нежелательно.
2. Misha ⁠ (Magister) 06.02.13 22:55
Вот за это:
РаботаСФомулами.ВычислитьФормулу("Перечисления.СтатусыЗаказовКлиентов.КОбеспечению");

минус!
нужно писать так:
ПредопределенноеЗначение("Перечисление.СтатусыЗаказовКлиентов.КОбеспечению");

Это, как минимум, кэшируется на уровне платформы - так что при втором и следующих вызовах обращения к серверу не будет.
Evil Beaver; mxm2; +2 Ответить 1
3. Сергей Ожерельев (Поручик) 07.02.13 01:00
Тоже самое касается и получения пустой ссылки для перечисления и справочника или предопределённых элементов справочника.
4. mxm2 mxm2 (mxm2) 07.02.13 11:57
(2) Magister, (3) Поручик, спасибо за критику, принял к сведению, изменил статью.
5. Модератор раздела Артур Аюханов (artbear) 08.02.13 11:32
Вариант 4 сильно ограниченный и не такой универсальный, как другие варианты :(
Для задачи установки фиксированных значений подходит, а вот для других задач уже нет.
Да и предопределенные значения не всегда можно юзать :(
6. mxm2 mxm2 (mxm2) 08.02.13 12:04
(5) artbear, Для простейших 4 для более сложных (без взаимодействия с пользователем) - 1. К предопределенным можно сводить НайтиПоКоду, НайтиПоНаименованию.
7. Misha ⁠ (Magister) 08.02.13 15:40
(5) Зато он по скорости оптимальнее, т.к. значения кешируются платформой.
8. Алексей Роза (DoctorRoza) 09.02.13 17:32
Хм, а ведь интересная тема поднята на самом деле. Использование функции глобального контекста маленько, но сократит код! Автору респект! :)
9. борян петров (TODD22) 18.02.13 13:24
Автор купи себе учебник по стилистике русского языка. Твой заголовок ужасен.
10. mxm2 mxm2 (mxm2) 18.02.13 13:58
(9) TODD22, заголовок неказист, но суть отражает верно ).
11. Андрей Овсянкин (Evil Beaver) 19.04.13 17:28
Обожымой! Зачем эта статья? Сообщить миру, чтобы прежде, чем городить костыли с ОбщийМодуль.ВычислитьНаСервере почитали документацию про ПредопределенноеЗначение?
12. Андрей Овсянкин (Evil Beaver) 19.04.13 17:31
И еще. Если у вас есть СерверныйМодуль.ВычислитьНаСервере, а база опубликована в веб, то любой человек может выполнять на вашем сервере произвольный 1С-код, просто передавая туда HTTP-запросы. Вас это не пугает?
13. mxm2 mxm2 (mxm2) 19.04.13 22:36
(12) Evil Beaver, вебом не пользуюсь, но пугает, такая интересная особенность... а ведь она в стандарте УТ11...
14. mxm2 mxm2 (mxm2) 19.04.13 23:04
(11) Evil Beaver,
Зачем эта статья? Сообщить миру, чтобы прежде, чем городить костыли с ОбщийМодуль.ВычислитьНаСервере почитали документацию про ПредопределенноеЗначение?

эта статья прежде всего для себя, даже читая документацию (чего, что скрывать, я делать не люблю) часто очень важные моменты остаются "не у дел", т.к. всасывается все именно на практике. А тут открыл - подсмотрел - и все ок. Не говоря уже о том, что взаимодействие с сообществом is позволяет находить новые тонкие моменты.
15. Андрей Овсянкин (Evil Beaver) 22.04.13 09:45
(13) mxm2,
а ведь она в стандарте УТ11...

Что-то не нашел. Подскажете модуль, номер строки и версию конфы?
16. mxm2 mxm2 (mxm2) 22.04.13 10:15
(15) Evil Beaver,
11.0.9.15: ОбщиеМодули.РаботаСФормулами.ВычислитьФормулу (стр. 85) (актуальная на момент написания статьи версия).
11.1.1.11: ОбщиеМодули.РаботаСФормуламиКлиентСервер.ПроверитьФормулу (стр. 32) - правда здесь добавлен код обработки, (который может не позволить использовать само вычисление, но передать на запуск выражение возможно).

Вопрос: какой должен быть HTTP запрос к веб-базе, чтобы выполнить произвольный код на 1С (обходящий права доступа, или вообще вредоносный)?
17. Андрей Овсянкин (Evil Beaver) 22.04.13 12:37
(16) mxm2 нет под рукой редакции 11.0, чтобы проверить. Но в 11.1 в модуле РаботаСФормуламиКлиентСервер нет вызова сервера. То есть, формула будет исполнена там, где вызван данный модуль. Перехода на сервер нет, а значит исполнения внешнего (по отношению к серверу) кода тоже нет. Все чисто.
Беда, если у модуля стоит флаг ВызовСервера, а внутри выполнение переданного извне кода. В 11.1 такого нет.
18. mxm2 mxm2 (mxm2) 22.04.13 12:44
(17) Evil Beaver, 11.0.9.15: таки да...)
Прикрепленные файлы:
19. Сергей Маслов (LexSeIch) 22.04.13 13:21
Мир этому дому!
В споре рождается истина. Интересно читать полемику - что то новое узнаешь, иногда даже и не в теме: "а база опубликована в веб, то любой человек может выполнять на вашем сервере произвольный 1С-код, просто передавая туда HTTP-запросы" (Evil Beaver) - второй раз за день читаю об очередной дырке... Сколько же их?
20. Андрей Овсянкин (Evil Beaver) 22.04.13 13:56
(19) LexSeIch, ну в случае модуля РаботаСФормулами, могу ошибаться, но там, насколько мне известно передается не чистый код, а некий псевдокод, который еще и синтаксическую проверку проходит. То есть, прямого выполнения нет. Так что вроде бы не все так печально.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа