1С вызвать клиентскую процедуру из серверной

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1.1. Разработку управляемого приложения необходимо вести с контролем количества вызовов серверных процедур и функций из клиентского кода (серверных вызовов), а в некоторых случаях – также объем передаваемых данных между клиентом и сервером (трафик).

Общее количество серверных вызовов складывается из

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

1.2. Отдельно для режима с низкой скоростью соединения следует оптимизировать не только количество вызовов, но и объем передаваемых данных между клиентом и сервером (трафик). Отладку клиент-серверного взаимодействия в этом режиме работы рекомендуется проводить в режиме имитации задержек серверных вызовов.

Ниже рассмотрены типовые действия пользователя и даны рекомендации по организации клиент-серверного взаимодействия.

Запуск клиентского приложения

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

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

// Фрагмент общего серверного модуля СтандартныеПодсистемыПереопределяемый с повторным использованием возвращаемых значений
Функция ПараметрыРаботыКлиента()
Параметры = Новый Структура();
Параметры.Вставить("ИнформационнаяБазаФайловая", ОбщегоНазначения.ИнформационнаяБазаФайловая());
// Инициализация других параметров, необходимых на клиенте при запуске приложения
// Параметры.Вставить(имя параметра, значение параметра);
Возврат Параметры;
КонецФункции

Пример клиентского кода, использующего функцию ПараметрыРаботыКлиента :

ИнформационнаяБазаФайловая = СтандартныеПодсистемыПереопределяемый. ПараметрыРаботыКлиента().ИнформационнаяБазаФайловая;
Если ИнформационнаяБазаФайловая Тогда
// обработка этого случая в клиентском коде
//…

Открытие управляемой формы

3.1. В случае если открытие формы выполняется из кода, следует открывать форму за один вызов с помощью метода глобального контекста ОткрытьФорму (при использовании версии платформы 1С:Предприятие 8.2 и более ранних версий – также ОткрытьФормуМодально ). Для передачи параметров в форму следует использовать параметр этих методов Параметры .

3.2. При открытии формы не допускается выполнять обращений к серверу из кода модуля формы в обработчиках клиентских событий формы, таких как ПриОткрытии и ПриПовторномОткрытии . При необходимости обращения из них к серверным данным, следует размещать эти данные в реквизитах формы в ПриСозданииНаСервере .

НастройкаПроксиСервера = СерверныйМодуль.НастройкаПроксиСервера();
ОткрытьФорму("ОбщаяФорма.ПараметрыПроксиСервера", Новый Структура("Настройка", НастройкаПроксиСервера));

при этом получение значения константы выполнять в обработчике ПриСозданииНаСервере формы ПараметрыПроксиСервера .

Выполнение локальной команды управляемой формы

4.1. Выполнение локальной команды формы должно приводить не более чем к одному вызову сервера.

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

Пример:
При выборе товаров из списка номенклатуры требуется запретить для пользователя выбор групп номенклатуры: при попытке выбрать группу программа должна выдавать останавливающее сообщение. Для проверки, является ли выбранный элемент номенклатуры группой, неправильно вызывать отдельную серверную функцию. Следует добавить в таблицу значений, которая связана с полем списка на форме, реквизит ЭтоГруппа и заполнять его в обработчике события формы ПриСозданииНаСервере . Тогда проверка на клиенте выполняется без дополнительного серверного вызова и имеет вид:

ТекущаяСтрока = Элемент.ТекущиеДанные;
Если ТекущаяСтрока.ЭтоГруппа Тогда
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = НСтр("ru = ‘Выбор группы запрещен.’");
Сообщение.Сообщить();
Возврат;
КонецЕсли;

  • Если команда связана с выполнением бизнес-логики, которую возможно отработать только на сервере, то вся она должна выполняться за один серверный вызов.

Выбор из справочника

4.2. В общем случае, при выборе из справочника допускается выполнять только один серверный вызов из кода, к которому приводит вызов метода глобального контекста ОткрытьФорму (или ОткрытьФормуМодально ).

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

Выполнение глобальной команды

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

Выполнение команды формирования отчета

6.1. При выполнении команды формирования отчета не допускается выполнять дополнительных серверных вызовов из кода конфигурации.

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

Например, неправильно выполнять формирование отчета, использующего систему компоновки данных, из обработчика формы ПриОткрытии :

Читайте также:  Устройство подсветки жк телевизора

&НаСервере
Процедура ВывестиОтчет()
// код по формированию отчета…
КонецПроцедуры

  • открывать форму отчета с параметром СформироватьПриОткрытии = Истина , либо
  • установить параметр формы СформироватьПриОткрытии в значение Истина в обработчике ПриСозданииНаСервере .

Выполнение подбора элементов

7.1. Особенность клиент-серверного взаимодействия при выполнении подбора элементов состоит в необходимости передавать список выбранных элементов между формой объекта и формой подбора. При этом объем передаваемых данных может быть достаточно большим.

В этом случае не рекомендуется передавать потенциально большой массив данных в качестве параметра формы подбора. Потенциально большой массив данных, хранимый в форме подбора в параметре типа ДанныеФормыКоллекция , может оказаться на клиенте не полным за счет оптимизации работы управляемой формы. Как результат – для передачи параметра будет выполнено дополнительное "дочитывание" данных формы с сервера.

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

Проиллюстрируем методику использования формы подбора на примере подбора элементов справочников Товары в табличную часть Товары документа РасходТовара . (Из демонстрационной конфигурации по платформе 1С:Предприятие ).

Открытие формы подбора из клиентского кода должно приводить не более чем к двум обращениям на сервер. С этой целью локальная команда открытия формы подбора в модуле формы документа РасходТовара помещает список товаров из табличной части во временное хранилище (первый вызов) и открывает форму подбора (второй вызов), передавая адрес временного хранилища:

&НаКлиенте
Процедура ОбработчикКомандыПодбора()
АдресТоваровВХранилище = ПоместитьТоварыВХранилище();
ПараметрыПодбора = Новый Структура("АдресТоваровДокумента, ВидЦен, Склад", АдресТоваровВХранилище, Объект.ВидЦен, Объект.Склад);
ФормаПодбора = ОткрытьФорму("Документ.РасходТовара.Форма.ФормаПодбора", ПараметрыПодбора, ЭтотОбъект);
КонецПроцедуры

Форма подбора получает список выбранных товаров из временного хранилища в обработчике ПриСозданииНаСервере :

Закрытие формы подбора должно приводить не более чем к двум обращениям на сервер. При закрытии форма подбора помещает список выбранных товаров во временное хранилище (первый вызов):

Затем форма документа восстанавливает список товаров из временного хранилища (второй вызов на сервер):

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

Это будет полезно начинающим разработчикам и тем, у кого есть пробелы в области клиент-серверного взаимодействия – всё объясним «на пальцах» 🙂

Клиент-серверная архитектура заложена в платформе изначально – со времен «1С:Предприятие 8.0».

Однако при разработке на 8.0 и 8.1 о разделении кода на клиентскую и серверную часть можно было не заботиться, поскольку на клиенте (на толстом клиенте) был доступен тот же функционал, что и на сервере.

Всё изменилось с выходом платформы «1С:Предприятие 8.2», когда появился тонкий клиент. Теперь на клиенте доступен один функционал, на сервере – другой. Клиент и сервер «общаются» между собой с помощью серверного вызова.

Конечно, это усложнило процесс разработки, но с другой стороны – можно создавать более оптимальные (быстрые) решения, поскольку все сложные задачи выполняются на сервере.

Немного базовой теории

Перед тем, как перейти к содержательной части, договоримся о некоторых ограничениях:

  • Мы подразумеваем, что Вы знаете о существовании четырёх директив компиляции, доступных в модулях формы: «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста».
  • Все примеры будут опираться на работу «1С:Предприятие 8» в клиент-серверном режиме. Файловый вариант по сути является эмуляцией клиент-серверного режима, с небольшими отклонениями (для данной статьи это не критично)
  • В рамках этого материала рассматривается исключительно взаимодействие клиента и сервера 1С. Работа с базой данных, преобразование данных и прочие нюансы работы системы – это темы других статей.

Далее, освежим в памяти немного теории.

Директивы, в имени которых упоминается «Клиент», устанавливают ограничение на обращение к базе данных.

Процедуры или функции, написанные под директивой «Без контекста», не имеют доступа к контексту (данным) формы. Исходя из этой информации, легко представить ограничения директив по доступу к данным в виде следующей таблицы:

Директива Данные формы База данных
&НаКлиенте +
&НаСервере + +
&НаСервереБезКонтекста +
&НаКлиентеНаСервереБезКонтекста

Опережая вопрос «Для чего же директива с самым длинным названием, если она ограничивает и использование контекста форм, и обращения к базе данных?», напомню: любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Отсюда делаем вывод: у методов, описанных под директивой «&НаКлиентеНаСервереБезКонтекста», единственным источником данных являются эти самые переданные параметры.

Не стоит забывать и про доступность вызова одних процедур и функций из других. Для этого стоит запомнить, что можно вызывать только те процедуры и функции, которые находятся под одноимённой (с родительским методом) директивой или под директивой, находящейся ниже (чем у родительского метода) согласно списку:

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

То есть из метода, описанного под директивой «&НаКлиенте», можно вызывать процедуры и функции, описанные под любой директивой. А вот «из-под» директивы «&НаСервереБезКонтекста» можно вызывать только то, что описано под директивой «&НаСервереБезКонтекста» или «&НаКлиентеНаСервереБезКонтекста».

Теперь про серверный вызов

Серверный вызов – это передача какой-то информации с клиентской части «1С:Предприятие 8» на серверную часть с целью вернуть обратно некий набор данных.

Самый первый серверный вызов инициализируется в момент начала сеанса работы 1С. То есть когда пользователь выполняет вход в информационную базу:

Читайте также:  Устранение дребезга контактов кнопки

«Оу! При чём тут Библиотека?!» – спросите Вы.

Всё очень просто:

Обратите внимание, что доступ к базе данных есть только на серверной части, а соединение между клиентом и сервером имеет ограниченную пропускную способность. Это и неудивительно – ведь соединение между клиентской и серверной частью может быть установлено даже по нестабильному низкоскоростному каналу связи (например, посредством мобильного интернета).

Кроме этого, передача данных между клиентом и сервером возможна только посредством серверного вызова.

Но, для того чтобы перейти к основной теме данной статьи, необходимо сначала разобраться – где будет выполняться программный код, написанный под определенными директивами. То есть на какой части приложения «1С:Предприятие 8» будут доступны процедуры и функции, описанные под директивами «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста»:

Видим, что на стороне клиента у нас будут доступны процедуры и функции, написанные под двумя директивами из четырёх, а на стороне сервера – под тремя из четырёх.

Сразу возникают вопросы: «Зачем такое многообразие и чем оно полезно?», «Как метод, описанный под директивой «&НаКлиентеНаСервереБезКонтекста» может выполняться и на клиенте, и на сервере?».

Сейчас мы постараемся понять особенности работы системы при использовании директив и почему необходимо уметь правильно использовать каждую из существующих директив компиляции.

И в этом нам помогут наши новые друзья, знакомьтесь!

Итак, давайте рассмотрим несколько особенностей работы программного кода в «1С:Предприятие 8», написанного под разными директивами.

Действие 1. Открытие пользователем формы с данными.

Действие 2. Получение из открытой Пользователем формы дополнительных данных из Базы данных.

Получение этих данных может быть описано под двумя директивами – «&НаСервере» и «&НаСервереБезКонтекста». Рассмотрим оба случая.

Явление 1. Директива «&НаСервере»

После выполнения метода на сервере, весь этот «пакет» транспортируется обратно. Таким образом, форма со всеми элементами и данными дважды проходит через самое узкое место системы.

Явление 2. Директива «&НаСервереБезКонтекста»

Таким образом, серверный вызов не несёт лишней нагрузки, и для передачи данных между клиентом и сервером потребуется меньше ресурсов.

Из примеров видно, что далеко не всегда оправдано указание директивы компиляции «&НаСервере» с точки зрения использования контекста (данных) формы на сервере.

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

До этого момента при каждом изменении свойства «Видимость» происходил серверный вызов, как при использовании директивы «&НаСервере».

Но использование директивы «&НаСервереБезКонтекста» не является панацеей. Помимо нагрузки на серверный вызов, всегда необходимо задумываться ещё над одним параметром.

Действие 3. Обработка данных табличной части формы с получением дополнительной информации из Базы данных.

Явление 1. Построчная обработка табличной части на стороне клиента с организацией серверного вызова для получения дополнительной информации из базы данных.

Мы уже знаем – лучше использовать директиву «&НаСервереБезКонтекста».

Явление 2. Предварительная обработка табличной части на стороне клиента с целью подготовки требуемых к обработке на сервере данных и «упаковки» их в набор параметров. Затем передача этого набора на сервер для получения дополнительной информации из базы данных.

Используем всё ту же директиву «&НаСервереБезКонтекста».

Большое количество текущих серверных вызовов может свидетельствовать о неоптимальном программном коде.

Избегайте создания серверных вызовов внутри цикла. Подготовьте набор параметров и единожды выполните его передачу для обработки на сервер. Если предполагается сложная обработка большого количества данных формы – передайте её полностью на сервер (при помощи директивы «&НаСервере») и выполните все действия на стороне сервера.

С директивой «&НаСервереБезКонтекста» вроде бы разобрались. Она нужна для того, чтобы уменьшить объем информации, передаваемой в рамках одного серверного вызова. Дополнительно разобрались с количеством текущих серверных вызовов – необходимо стремиться к их минимизации.

Давайте теперь попробуем разобраться, для чего нужна директива «&НаКлиентеНаСервереБезКонтекста».

Действие 4. Выполнение обработки данных.

Когда предполагается выполнение одной и той же обработки данных из нескольких участков программного кода, разумно этот код поместить в самостоятельную процедуру или функцию. Остаётся только решить, под какой директивой её написать.

Та-дам!

Для копирования у нас есть ксерокс. Но куда его поставить? На сторону клиента или сервера? Под какой директивой его разместить?

Как было озвучено ранее – любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Давайте для начала попробуем разместить копировальный аппарат на стороне клиента. Для этого описываем процедуру или функцию «Ксерокс» под директивой «&НаКлиенте». Тогда процесс клиентской части в любой момент сможет без проблем обратиться к ней и все действия будут выполнены в соответствии с программным кодом.

Но что произойдёт, если потребность в копировании возникнет на стороне сервера? Например, для подготовки данных, передаваемых на сторону клиента, потребуется сделать копию? Напомню – процесс серверной части не имеет возможности самостоятельно инициировать клиентские вызовы.

Получается, что использовать директиву «&НаКлиенте» неправильно, а директиву «&НаСервере», как мы изучили ранее – нежелательно. Давайте посмотрим поведение системы при использовании директивы «&НаСервереБезКонтекста».

Читайте также:  Фантомное питание 48 вольт

Вроде бы результат достигнут – и с сервера, и с клиента доступно копирование. Но для того, чтобы получить копию данных, используемых на клиенте, приходится делать серверный вызов. А это опять ведет к лишней нагрузке на соединение и временным затратам.

Избавиться от излишней передачи на сервер при сохранении возможности копирования на клиенте и на сервере можно при помощи директивы «&НаКлиентеНаСервереБезКонтекста».

Не углубляясь в детали, отметим, что метод, описанный под данной директивой управления, создаётся в двух копиях – и на стороне клиента, и на стороне сервера. Это позволяет выполнить необходимые действия там, где появилась потребность в них (клиент/сервер), без лишних серверных вызовов.

С точки зрения выполнения программы результат будет одинаков. Но объяснение «почему так не надо делать» – это уже совершенно другая тема…

Вместо заключения

В данной статье мы на наглядных примерах рассмотрели влияние различных директив компиляции на такое явление системы «1С:Предприятие 8», как серверный вызов. Как видно, основная причина для выбора правильной директивы – производительность транспортировки данных между клиентской и серверной частью.

Придерживайтесь при разработке следующих правил:

  • По возможности не передавайте контекст формы на сторону сервера
  • Минимизируйте количество текущих серверных вызовов
  • Длительные и ресурсоёмкие задачи запускайте на выполнение на стороне сервера (при возможности – в фоновом режиме).

Учитывайте потребность в доступности тех или иных видов данных, обоснованность передачи управления и не стесняйтесь при необходимости дробить процедуры и функции. И будет Вашему серверному вызову всегда легко, а Вы от пользователей Вашей программы получите «молчаливую благодарность»!

Программист Иван при доработке 1С на своём предприятии сделал ошибку в выборе директивы компиляции. Из-за неё длительность одного из серверных вызовов была больше возможной на полсекунды.

Пользователей, применяющих этот функционал, – 25 человек, и каждый из них за рабочий день в среднем совершает 110 таких операций. Всего впустую за рабочий месяц потрачено 28875 секунд (21 рабочий день * 25 человек * 110 операций * 0,5 секунды) = 8,02 часов.

Иван, каково тебе осознавать, что за месяц ты задолжал своему предприятию целый рабочий день?

Об авторе

Автор статьи – Павел Ванин

В платформе 8.2 в управляемом приложении для оптимизации работы приложений предлагается разделение функции клиента и сервера. На клиенте, например, нельзя обращаться к данным БД. А на стороне сервера не доступны данные формы, в модуле которой находится процедура с директивой &НаСервереБезКонтекста. Программный код в 1С располагается в различных модулях, модуле объекта, модуле формы, общих модулях и т.д. Процедуры и функции каждого модуля могут компилироваться как на сервере, так и на клиенте. Рассмотрим возможности вызова различных процедур и функции из процедур, компилируемых на стороне сервера, и процедур, компилируемых на стороне клиента.

Итак, со стороны клиента можно вызывать

1) клиентские процедуры данного модуля, с директивой &НаКлиенте;

2) серверные процедуры данного модуля, с директивой &НаСервере;

4) все процедуры клиентского общего модуля , в свойствах общего модуля должно быть только свойство «Клиент(управляемое приложение)». Директиву &НаКлиенте в общем модуле в этом случае не пишут;

5) процедуры серверного общего модуля, но с дополнительным свойством «Вызов сервера», причем важно чтобы общий модуль имел только свойство компиляции на сервере.

Со стороны сервера можно вызывать

1) серверные процедуры данного модуля, с директивой компиляции &НаСервере;

2) все процедуры серверного общего модуля, причем в свойствах общего модуля должно быть только свойство «Сервер». Директиву &НаСервере в общем модуле в этом случае не пишут;

3) процедуры общего модуля, с директивой &НаСервере (при условии наличия в свойствах доступности в нескольких контекстах, «Сервер» обязателен и др).

Кроме того, если в свойствах общего модуля указаны несколько мест компиляции «Клиент, Сервер», а в процедуре не указана никакая директива компиляции, то в этом случае процедура будет скомпилирована и на стороне сервера, и на стороне клиента. И ее можно вызывать соответственно и из клиентских методов, и из серверных. В этом случае нужно внимательно использовать процедуру, необходимо чтобы ее код мог выполняться и на сервере, и на клиенте.

Существует еще одна особенность. В одном общем модуле, имеющем несколько мест компиляции («Сервер, клиент») нельзя вызывать из клиентской процедуры серверную того же модуля, даже если поставить галку «вызов сервера». Свойство «вызов сервера» имеет смысл при наличии только одного свойства общего модуля «компиляции на Сервере».

Существуют рекомендации использовать общие модули, скомпилированные только на сервере или только на клиенте. Соответственно использовать в модуле со свойством «Клиент» все клиентские модули, а в модуле со свойством «сервер» использовать все серверные методы.

Еще одно удобное свойство общего модуля. Если в свойствах общего модуля активировать свойство «Глобальный», то процедуры этого модуля можно вызывать напрямую, без имени общего модуля.

Но не стоит увлекаться использованием этого свойства, так как в таком случае модуль будет компилироваться при запуске системы, что увеличивает время запуска.

Оцените статью
Добавить комментарий

Adblock
detector