зачем нужна директива насерверебезконтекста
&НаКлиенте, &НаСервере, &НаСервереБезКонтекста
Немного теории о стороне выполнения кода. При работе 1С в режиме клиент-сервера, запускается несколько процессов. На компьютере пользователя запускается 1cv8.exe, на сервере 1С запускается rphost.exe, rmngr.exe и ragent.exe.
ragent.exe
Приложение ragent.exe это по сути и есть наша служба агента 1С, которую мы можем посмотреть в списке служб Windows. Данное приложение отвечает за запуск всех остальных приложений и за распределение нагрузки между рабочими rphost.
rphost.exe
Приложение rphost.exe обслуживает подключения пользователей, выполняет код, написанный в конфигурации 1С. В консоли кластера rphost отображается в блоке «Рабочие процессы»
Рабочих процессов может быть несколько. В версии платформы 8.2 их можно было создавать вручную. В версии 8.3 на их количество можно повлиять косвенно, увеличив количество сеансов или информационных баз на один рабочий процесс в свойствах рабочего сервера.
rmngr.exe
В общем случае данное приложение отвечает за выполнение регламентных заданий.
Сторона выполнения кода
После того, как мы в общих чертах описали приложения, выполняющиеся на сервере, перейдем к описанию директив препроцессора, т.е. тех самых &НаКлиенте, &НаСервере. В зависимости от того, на какой стороне выполняется код, мы имеем доступ к файлам либо пользовательского компьютера, либо к файлам на сервере. При этом очень важно понимать, что код &НаКлиенте выполняется с правами пользователя, запустившего 1С. Код &НаСервере выполняется с правами пользователя, под которым запущена служба агента 1С. Как правило, это пользователь USR1CV8, если никто этого не поменял.
&НаКлиенте
Код выполняется на том компьютере, за которым сидит пользователь и под теми правами, которые есть у пользователя. Файлы, созданные в процедурах &НаКлиенте будут созданы на пользовательском компьютере. Есть множество ограничений выполнения кода &НаКлиенте, например, здесь нельзя обращаться к СУБД. Это значит нельзя использовать как прямое создание запроса, так и косвенный запрос при обращении к ссылке через точку. Компьютер клиента может быть медленнее сервера, это следует учитывать при написании кода.
&НаСервере
Код выполняется на сервере 1С, в процессе rphost. Файлы, созданные в процедурах &НаСервере, будут сохранены на сервере и смогут быть записаны только в те папки, на которые у пользователя службы агента 1С есть доступ на запись. &НаСервере уже можно свободно писать запросы, обращаться к предопределенным данным и к реквизитам ссылки через точку.
&НаСервереБезКонтекста
Это самый интересный вариант, разберемся для начала, что такое контекст формы. Управляемая форма представляется на уровне платформы в виде XML файла описания расположения элементов и значения реквизитов формы. Соответственно, чем больше элементов на форме и чем больше данных хранится в реквизитах формы, тем больше будет контекст.
При вызове процедуры без контекста, процедура не видит реквизитов формы и не может к ним обращаться ни для чтения, ни для изменения.
Когда мы вызываем процедуру с директивой &НаСервере, то эта XML уходит с компьютера клиента на сервер. Преимущество этого подхода в том, что мы можем из этой процедуры напрямую менять значения реквизитов. Недостаток — если необходимо исправить один реквизит на форме, приходится перекидывать иногда достаточно крупную XML. Сталкивался однажды с тем, что возврат выполнения с сервера на клиент занимал около минуты.
И вот здесь нам как раз может помочь директива &НаСервереБезКонтекста.
Рассмотрим для примера такую ситуацию: у нас есть форма, в реквизитах формы есть таблица значений с 100 000 строк и реквизит с именем «Реквизит1». Нам необходимо в этот реквизит значение перечисления.
В данном примере произойдет следующее: описание формы, таблица значений с 100000 строк и реквизит1 будут преобразованы в XML, отправлены на сервер. На сервере будет выполнен небольшой неявный запрос к СУБД, в значение реквизит1 будет записан результат этого запроса, все данные опять преобразуются в XML и отправятся на сервер. Учитывая, что таблица значений очень большая, то получится, что мы большой объем данных дважды в холостую передали между клиентом и сервером. Это не оптимально.
Во втором примере мы не стали передавать контекст формы, в итоге произошла только передача ссылки на элемент перечисления с сервера на клиент.
Важно понимать, сколько данных будет передано в холостую, а сколько полезно. Например, если нам нужно заполнить нашу таблицу значения, то есть самый тяжелый элемент формы, то целесообразней будет не усложнять код обходом передачи контекста, а просто передать контекст через &НаСервере.
Пример 3, предположим, у нас есть название для перечисления, которое хранится в реквизите Реквизит2, мы можем его передать в качестве параметра функции:
Ну и напоследок еще один пример, как делать не надо:
Если мы в качестве параметра передаем ЭтаФорма, то по факту мы внеконтекстный вызов превращаем в контекстный. Если без этого не обойтись, то стоит делать контекстный вызов.
Чем отличается &НаСервереБезКонтекста от &НаСервере
Каждая процедура и функция модуля формы, модуля команды и общего модуля управляемого приложения предваряется директивой компиляции, определяющей среду исполнения данной процедуры. Директива предваряется символом «&». Допустимые директивы:
Серверная процедура (функция) исполняется в среде серверного приложения. В такой процедуре доступны данные формы, доступен серверный контекст формы и вызовы серверных и серверных внеконтекстных процедур модуля. При вызове такой процедуры данные формы будут передаваться с клиента на сервер и обратно (по окончанию вызова).
Серверная процедура (функция), исполняемая вне контекста формы, (внеконтекстная) исполняется в среде серверного приложения. В такой процедуре (функции) недоступен контекст формы (включая данные формы). Допустимыми являются вызовы только других внеконтекстных процедур (функций). При вызове этих процедур (функций) не выполняется передача данных формы на сервер и обратно. Применение внеконтекстных процедур (функций) позволяет существенно уменьшить объем передаваемых данных при вызове серверной процедуры (функции) из среды клиентского приложения.
Отсутствие директивы компиляции перед процедурой (функцией) означает использование директивы по умолчанию. Директивой по умолчанию является &НаСервере. Не допускается использование нескольких директив компиляции перед одной процедурой (функцией). Не допускается наличие одноименных процедур (функций), отличающихся только директивами компиляции.
В модуле управляемой формы допускается использование инструкций препроцессору. Рекомендуется использовать инструкции препроцессора только внутри процедур (функций). Для понимания результата при «пересечении» инструкциями препроцессора границ процедур (функций) следует учитывать, что обработка инструкций препроцессора выполняется до обработки директив компиляции.
В модуле команды предопределенная процедура-обработчик ОбработатьКоманду должна предваряться директивой &НаКлиенте, так как выполнение команды происходит в клиентском приложении.
Директивы выполнения кода в модулях управляемых форм 1С 8.3
С появлением управляемых форм в модулях форм 1С 8.3 стали активно использоваться директивы компиляции в модулях форм и объектов:
Дальше речь пойдет о том, как правильно ими пользоваться и как с их помощью можно оптимизировать работу системы.
Необходимо понимать, как работают управляемые формы в тонком режиме, проще всего представить эту модель в виде веб-сайта: сервер отдельно, клиент отдельно. В момент обращения к форме клиент делает обращение к серверу, и вся работа выполняется на сервере. Клиент (Ваша машина) лишь получает результат работы сервера.
Обратите внимание! Если директива не указана, то по умолчанию она выполняется на сервере.
Особенности компиляции этих директив управляемого приложения
&НаКлиенте
Указывает на то, что процедура или функция выполняется на стороне клиента 1C, все переменные существуют лишь на время жизни клиентской части формы. Такой метод выполняется «у Вас на компьютере», никак не затрагивая серверную часть. С клиента доступны все серверные функции.
На клиенте есть доступ к следующим объектам:
&НаСервере
Выполняется на сервере, переменные существуют только на время серверного вызова. С сервера допустим вызов практически любых процедур, кроме клиентских. Если работа происходит в режиме тонкого клиента, вся работа происходит на сервере, а клиент получает лишь результат выполнения.
&НаСервереБезКонтекста
Это процедура выполняется на сервере, вне контекста формы. Т.е. процедура не имеет доступа к реквизитам формы, выполняется на сервере и возвращает желаемый результат. Хорошо подходит для получения статичных данных. Крайне рекомендуется к использованию для оптимизации клиент-серверного взаимодействия.
&НаКлиентеНаСервереБезКонтекста
Используется, когда к процедуре нужно обращаться и с клиента, и с сервера. В остальном аналог &НаСервереБезКонтекста.
Оптимизация клиент-серверного взаимодействия
При разработке функционала необходимо учитывать следующие нехитрые правила:
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
Инструкции препроцессора «&НаСервереНаКлиенте» и «&НаКлиентеНаСервереБезКонтекста»
В курс дела
Процедуры и функции в модулях управляемых форм, а также в общих клиентских модулях управляемого приложения, требуют четкого определения среды выполнения программного кода.
&НаСервереНаКлиенте
Данная директива может применяться только в модуле команды. Сама процедура или функция, объявленная с такой директивой, может быть использована как на клиентской, так и на серверной стороне в модуле команды. Приведу пример использования в команде справочника. Для этого в тестовой конфигурации добавим команду «Тестируем» для справовочника «ПростойСправочник»:
Модуль команды содержит следующий программный код:
Теперь рассмотрим поведение платформы при ее выполнении. Вызовем команду в режиме предприятия и проанализируем количество вызовов сервера. Картина будет следующей:
Таким образом, при вызове процедуры с директивой препроцессора «НаКлиентеНаСервере» с клиентской стороны вызова сервера не происходит. Единственный вызов сервера в нашем прмере происходил при обращении к серверной процедуре «Сервер».
Из всего вышесказанного можно заключить, что процедуры и функции с директивой » НаКлиентеНаСервере» фактически имеет те же возможности, что и клиентские процедуры и функции с директивой «НаКлиенте». Использование директивы «НаКлиентеНаСервере» позволяет вызывать любые процедуры модуля команды, а также получать доступ к клиентскому контексту формы.
На мой взгляд, использование подобных процедур и функций усложняет читабельность программного кода. Если использовать директивы «НаКлиенте», «НаСервере» и «НаСервереБезКонтекста», то код будет более понятным и предсказуемым.
Рассмотрим теперь работу процедур и функций с директивой «&НаКлиентеНаСервереБезКонтекста».
&НаКлиентеНаСервереБезКонтекста
Директива » НаКлиентеНаСервереБезКонтекста» может быть использована в модулях управляемых форм на клиенте и на сервере. При этом такие процедуры и функции не могут получить доступ к контексту формы, всем экспортным переменным формы, но возможен вызов процедур и функций из серверных общих модулей, а тажке не глобальных серверных и клиенских одновременно.
Рассмотрим небольшой пример их использования. В модуле формы элемента справочника «ПростойСправочник» напишем следующий программный код:
Процедура «Тестируем» принадлежит команде формы. При ее запуске осуществляется вызов процедуры «ТестируемКлиентСервер» с директивой «НаКлиентеНаСервереБезКонтекста». Как было сказано выше, данная процедура не сможет получить доступ к контексту формы и другим клиентским процедурам. Но все серверные процедуры модуля формы без контекста будут доступны для вызова, а также серверные процедуры общего модуля.
Вызов сервера будет произведен, что логично, при вызове серверной процедуры со стороны клиента.
Вывод
Подытожим выше сказанное:
За весь опыт работы с управляемыми формами использовать подобные процедуры и функции приходилось очень редко. Как уже говорил выше, считаю, что их исопльзование ухудшает читабельность кода.
Константы, основы клиент-серверного программирования, общие реквизиты
Основы клиент-серверного программирования
Если перед описанием процедуры, функции или переменной в модуле формы отсутствует директива компиляции, по умолчанию считается, что код будет исполняться на сервере. В явном виде это задается указанием директивы &НаСервере.
Здесь мы создали пару функций – одну назвали ПолучитьКонстанту(), при ее описании директиву компиляции мы не указывали. Вторую назвали ПолучитьКонстантуНаСервере() – при ее описании была указана директива &НаСервере. Мы вызвали эти функции для вывода сообщения в клиентской процедуре ПриОткрытии(). У нас уже есть серверная функция в общем модуле СерверныеФункции – здесь показан пример ее использования, в подобном случае, возникшем при реальной разработке, если действия, которые выполняются в серверной функции модуля формы, совпадают с действиями функции, описанной в общем модуле, можно и даже нужно пользоваться функцией общего модуля.
На рис. 2.19. вы можете видеть вывод сообщений, выполненный вышеприведенным кодом.
Вернемся к директивам компиляции. Они могут использоваться не только в модулях форм, но и в общих модулях, и в модулях команд. Таблица 2.1. содержит описание возможности применения директив компиляции в различных модулях
Директивы компиляции | Модули | Переменные | ||
---|---|---|---|---|
Модуль формы | Модуль команды | Общий модуль | ||
&НаКлиенте | Да | Да | Да | Да |
&НаСервере | Да | Да | Да | Да |
&НаКлиентеНаСервере | Нет | Да | Нет | Нет |
&НаСервереБезКонтекста | Да | Нет | Нет | Нет |
&НаКлиентеНаСервереБезКонтекста | Да | Нет | Нет | Нет |
Опишем основные особенности их применения:
&НаКлиенте – эта директива предназначена для клиентских процедур и функций. Из такого метода могут быть вызваны любые процедуры и функции. Кроме того, с данной директивой можно объявлять переменные – их называют клиентскими. Такая переменная существует столько же, сколько существует клиентская часть формы. Из метода с данной директивой доступны другие клиентские переменные модуля формы.
&НаСервере – эта директива предназначена для серверных процедур и функций. Из такой процедуры могут быть вызваны серверные и клиент-серверные внеконтекстные методы, а так же методы неглобальных серверных общих модулей. Допустимо объявление переменных с данной директивой – такие переменные существуют во время выполнения вызова сервера. Из серверных методов доступны серверные переменные, объявленные в модуле формы.
&НаКлиентеНаСервере – предназначена для описания процедур и функций, выполняемых на клиенте и на сервере. Такие процедуры и функции могут вызывать клиентские и серверные процедуры общих модулей. Не подходит для объявления переменных.
&НаСервереБезКонтекста – такая процедура или функция исполняется на сервере вне контекста формы, в модуле которой она описана. Из нее можно вызывать лишь другие внеконтекстные процедуры или функции. Использование этой директивы позволяет сократить объем данных, передаваемых между сервером и клиентом. Не подходит для объявления переменных.
&НаКлиентеНаСервереБезКонтекста – такая процедура или функция может исполняться на клиенте и на сервере, без доступа к контексту формы. Не подходит для объявления переменных.
Помимо директив компиляции в модуле управляемой формы можно пользоваться инструкциями препроцессору. Инструкции препроцессору обрабатываются до того, как будут обработаны директивы компиляции.
Обсудив основы работы с константами и основные положения клиент-серверного программирования, перейдем к работе со справочниками. Обычно разработка системы справочников относится к начальному этапу разработки любой конфигурации, так как на типах данных, заданных справочниками, основываются другие механизмы системы. Но прежде чем начать разговор, о, собственно, справочниках, давайте поговорим об общих реквизитах.
Общие реквизиты
Общие реквизиты являются новой возможностью, которая была добавлена в 14-й релиз платформы 1С:Предприятие 8.2. Общие реквизиты можно использовать двумя способами. Первый из них заключается в использовании их, как, собственно, реквизитов, которые присутствуют у всех (или у достаточно большого количества) объектов конфигурации. Второй способ предусматривает использование общих реквизитов в механизме разделения данных в качестве разделителей данных. В базе, использующей механизм разделения данных, могут работать несколько пользователей, набор данных каждого из которых не пересекается с набором данных других пользователей, то есть – каждый из них считает, что база содержит лишь «его» данные и ничего больше.
Сейчас мы создадим общие реквизиты, которые планируется использовать именно как реквизиты для других объектов конфигурации. В частности, общий реквизит может быть «подключен» к следующим объектам. Правильным будет и утверждение о том, что эти объекты могут «входить в состав» общего реквизита, так как, собственно, от настройки состава общего реквизита зависит его появление в других объектах. Итак, речь идет о следующих объектах:
Прежде чем продолжать работу над общими реквизитами, создадим следующие объекты конфигурации, не настраивая их дополнительных свойств – справочник с именем Организация, и документ с именем ПоступлениеМатериалов. Включим их в подсистему ОперативныйУчетМатериалов.
Создадим новый общий реквизит со следующими параметрами, рис. 2.20.: