&НаКлиенте, &НаСервере, &НаСервереБезКонтекста

На клиенте на сервере

Немного теории о стороне выполнения кода. При работе 1С в режиме клиент-сервера, запускается несколько процессов. На компьютере пользователя запускается 1cv8.exe, на сервере 1С запускается rphost.exe, rmngr.exe и ragent.exe.

ragent.exe

Приложение ragent.exe это по сути и есть наша служба агента 1С, которую мы можем посмотреть в списке служб Windows. Данное приложение отвечает за запуск всех остальных приложений и за распределение нагрузки между рабочими rphost.

rphost.exe

Приложение rphost.exe обслуживает подключения пользователей, выполняет код, написанный в конфигурации 1С. В консоли кластера rphost отображается в блоке «Рабочие процессы»

Рабочий сервер 1с rphost

Рабочих процессов может быть несколько. В версии платформы 8.2 их можно было создавать вручную. В версии 8.3 на их количество можно повлиять косвенно, увеличив количество сеансов или информационных баз на один рабочий процесс в свойствах рабочего сервера.

Количество ИБ на процесс rphost

rmngr.exe

В общем случае данное приложение отвечает за выполнение регламентных заданий.

Сторона выполнения кода

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

&НаКлиенте

Код выполняется на том компьютере, за которым сидит пользователь и под теми правами, которые есть у пользователя. Файлы, созданные в процедурах &НаКлиенте будут созданы на пользовательском компьютере. Есть множество ограничений выполнения кода &НаКлиенте, например, здесь нельзя обращаться к СУБД. Это значит нельзя использовать как прямое создание запроса, так и косвенный запрос при обращении к ссылке через точку. Компьютер клиента может быть медленнее сервера, это следует учитывать при написании кода.

&НаСервере

Код выполняется на сервере 1С, в процессе rphost. Файлы, созданные в процедурах &НаСервере, будут сохранены на сервере и смогут быть записаны только в те папки, на которые у пользователя службы агента 1С есть доступ на запись. &НаСервере уже можно свободно писать запросы, обращаться к предопределенным данным и к реквизитам ссылки через точку.

&НаСервереБезКонтекста

Это самый интересный вариант, разберемся для начала, что такое контекст формы. Управляемая форма представляется на уровне платформы в виде XML файла описания расположения элементов и значения реквизитов формы. Соответственно, чем больше элементов на форме и чем больше данных хранится в реквизитах формы, тем больше будет контекст.

При вызове процедуры без контекста, процедура не видит реквизитов формы и не может к ним обращаться ни для чтения, ни для изменения.

Когда мы вызываем процедуру с директивой &НаСервере, то эта XML уходит с компьютера клиента на сервер. Преимущество этого подхода в том, что мы можем из этой процедуры напрямую менять значения реквизитов. Недостаток — если необходимо исправить один реквизит на форме, приходится перекидывать иногда достаточно крупную XML. Сталкивался однажды с тем, что возврат выполнения с сервера на клиент занимал около минуты.

И вот здесь нам как раз может помочь директива &НаСервереБезКонтекста.

Рассмотрим для примера такую ситуацию: у нас есть форма, в реквизитах формы есть таблица значений с 100 000 строк и реквизит с именем «Реквизит1». Нам необходимо в этот реквизит значение перечисления.

Пример 1:

&НаКлиенте
Процедура ВыполнитьКод(Команда)
ЗаписатьЗначение();
КонецПроцедуры
&НаСервере
Процедура ЗаписатьЗначение()
     Реквизит1 = Перечисления.ПеречислениеДляПримера.Пример;
КонецПроцедуры

В данном примере произойдет следующее: описание формы, таблица значений с 100000 строк и реквизит1 будут преобразованы в XML, отправлены на сервер. На сервере будет выполнен небольшой неявный запрос к СУБД, в значение реквизит1 будет записан результат этого запроса, все данные опять преобразуются в XML и отправятся на сервер. Учитывая, что таблица значений очень большая, то получится, что мы большой объем данных дважды в холостую передали между клиентом и сервером. Это не оптимально.

Пример 2:

&НаКлиенте
Процедура ВыполнитьКод(Команда)
     Реквизит1 = ПолучитьЗначение();
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьЗначение()
     Возврат Перечисления.ПеречислениеДляПримера.Пример;
КонецФункции

Во втором примере мы не стали передавать контекст формы, в итоге произошла только передача ссылки на элемент перечисления с сервера на клиент.

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

Пример 3, предположим, у нас есть название для перечисления, которое хранится в реквизите Реквизит2, мы можем его передать в качестве параметра функции:

&НаКлиенте
Процедура ВыполнитьКод(Команда)
     Реквизит1 = ПолучитьЗначение(Реквизит2);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьЗначение(ИмяЭлементаПеречисления)
     Возврат Перечисления.ПеречислениеДляПримера[ИмяЭлементаПеречисления];
КонецФункции

Ну и напоследок еще один пример, как делать не надо:

&НаКлиенте
Процедура ВыполнитьКод(Команда)
     Реквизит1 = ПолучитьЗначение(ЭтаФорма);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьЗначение(Форма)
     Возврат Перечисления.ПеречислениеДляПримера[ИмяЭлементаПеречисления];
КонецФункции

Если мы в качестве параметра передаем ЭтаФорма, то по факту мы внеконтекстный вызов превращаем в контекстный. Если без этого не обойтись, то стоит делать контекстный вызов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *