gifts2017

Клиент- серверные вызовы

Опубликовал Татьяна К (tanka495) в раздел Программирование - Практика программирования

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

 

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

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

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

 

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

 

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

 

 

 

 

 

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

 

 

 

 

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

 


 

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

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

 

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

 

 

 

 

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

 

 

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

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

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

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

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

 

 

 

 

См. также

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

Комментарии

1. Алексей Роза (DoctorRoza) 02.07.11 09:40
.. Рассмотрим возможности вызова различных процедур и функции из процедур, компилируемых на стороне сервера, и процедур, компилируемых на стороне клиента ...

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

Cкажите, будет являтся ошибкой следующий код, выполняемый в модуле формы документа Приходная:
&НаКлиенте
Процедура СписокНоменклатурыКоличествоПриИзменении(Элемент)
РассчитатьСумму();
КонецПроцедуры

Процедура РассчитатьСумму()
НомерСтр = Элементы.СписокНоменклатуры.ТекущаяСтрока;
Стр = Объект.СписокНоменклатуры[НомерСтр];
Стр.Сумма = Стр.Цена * Стр.Количество;
КонецПроцедуры // РассчитатьСумму()

:)

Мыслю, что все верно! Поэтому, поправьте маленько, что директива компиляции &НаСервере не всегда является обязательной. Процедура/функция без этой директивы работает всегда на сервере!

2. BigB (BigB) 04.07.11 08:20
А где же директивы &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста?
3. Дмитрий Шерстобитов (DitriX) 06.07.11 11:53
BigB пишет:

А где же директивы &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста?


Вот это было бы интересно
4. Дмитрий Гомзин (plevakin) 07.07.11 14:13
Существует задача после проведения документа из формы документа обновлять его форму (после проведения изменяется например долг клиента, отобразим это изменение на форме). Можно ли получить на сервере элементы формы документа?
5. Денис Яковлев (iceflash) 12.12.11 22:26
(4) plevakin, Может не так понял, а зачем? Провели документ - изменились остатки\обороты, делаем запрос. Вычисленное значение записываем в реквизит формы, который отображается на форме.
6. Денис Яковлев (iceflash) 12.12.11 22:28
(2) BigB, Ага, было бы интересно, точнее там вроде как все понятно, то же самое все, но единственное - "Без контекста" =) Вот что есть сам контекст, еще не разбирался, но как я понял не передается информация о форме/реквизитах формы, но с примерчиком было бы полезно, да.
7. Сергей Ожерельев (Поручик) 13.04.12 00:46
Никогда этого не понимал в 8.2. Фактически функции компилятора или транслятора возложили на программиста и назвали удобством для разработчика.
8. Михаил Лыков (Miha.L) 13.04.12 01:03
Полезная статья.
И наглядно.
Это хорошо.
9. Сергей Толмачев (sss999) 13.06.12 08:45
Да ну,ниче не понятно.Плохая статья,итогов нет.
10. Сергей Толмачев (sss999) 13.06.12 10:21
слышал такое,что если указано #насервере то все что после доступно только серверу,отсюда вопрос,как работает вызов процедур с клиента т.е.#наклиенте,если фактически на клиенте не видно что внутри директивы #насервере ?
11. Игорь Богданов (avz_1C) 20.06.12 13:06
Большое спасибо, реально помогло :-)
12. Филин (Филин) 10.07.12 22:49
(10) sss999, Не надо путать # и & ))
& -- это директива компиляции, определяет, где будет работать процедура или функция. Заметьте, что директивы ставятся сразу на всю процедуру или функцию, но не на части кода внутри них.
# -- это инструкции препроцессору. Уже из названия видно, что они работают еще до компиляции. Причем работают очень просто: если условие инструкции не выполняется, то текст после этого условия будет просто выкинут из модуля.
Получается, если очень захотеть, можно делать такие безобразия, и ничего за это не будет:

&НаКлиенте
Процедура ЗдрасвтвуйБесконечность()
перем рез;

#Если Сервер тогда
рез = 1/0;
#Иначе
сообщить("ничего не случилось");
#КонецЕсли

КонецПроцедуры
...Показать Скрыть
13. Александр Лыткин (TrinitronOTV) 08.12.13 17:58
а вот мне не понятен такой момент: у меня файловый вариант базы данных и следовательно мне не понятно, как в этом случает будут работать вызовы "на сервере" и "на клиенте" в управляемом приложении? кто-нибудь подскажите, пожалуйста
14. Алексей Белоусов (AllexSoft) 08.12.13 19:23
(13) TrinitronOTV, точно так же как и в клиент-северном варианте работы базы, дело в том что запускается некая искусственная среда исполнения "сервер", которая работает с данными, ну а тонкий клиент подключается к этому "искусственному серверу" и работает как обычно в клиент-сервере... ну просто в случае файловой базы сервер и клиент существуют в рамках одного процесса 1С предприятия)
15. Александр Лыткин (TrinitronOTV) 10.12.13 05:33
(14) спасибо,AllexSoft, т.е. получается, что всё выполняется на клиентской машине?
16. Алексей Белоусов (AllexSoft) 10.12.13 11:01
(15) TrinitronOTV, в файловой базе - да
TrinitronOTV; +1 Ответить
17. Александр Пономарев (silvermilion) 21.08.14 07:59
Подскажите, при вызове процедур/функций общего модуля с клиента, идет обращение к серверу?
Т.е. меня интересует, если я в общем модуле опишу функцию с директивой &НаКлиенте и буду её вызывать из формы тоже с клиента, то все действия будут выполняться на клиенте, никак сервер не затрагивая или все же 1ска в любом случае обратится к серверу для того, чтобы вызвать процедуру общего модуля?
18. Алексей Белоусов (AllexSoft) 22.08.14 16:25
(17) silvermilion, смотря что за общий модуль, если в свойствах модуля стоит флаг "Клиент" тогда разумеется ваш модуль будет размещен и выполнен на стороне клиента, без участия сервера. Если стоит флаг "Вызов сервера" то платформа обратиться на сервер...
19. Сергей Толмачев (sss999) 09.10.14 13:25
такая ситуация нужно из процедуры насервере вызвать процедуру на клиенте можно как то нет?Дело в том что нужно передать форму объекта а я не знаю как ее получить на сервере
20. Алексей Белоусов (AllexSoft) 10.10.14 11:06
(19) sss999, на сервере не могут существовать форменные (визуальные) объекты.. их типов там просто нет.. точно так же как в клиентских процедурах не могут существовать чисто серверные типы данных, ну скажем запрос на клиенте вы не сделаете по тем же причинам. Так что не сможете никак (
21. Ольга Ковалева (volha-77) 17.03.15 23:42
Подскажите пожалуйста: есть две функции. 1-я исполняется на клиенте, 2-я вызывается из 1-ой. Нужно решить, какую директиву компиляции ставить для 2-й функции. Возможны оба варианта - на клиенте и на сервере. Если выбрать НаКлиенте, то все равно нужно будет вставлять туда пару-тройку серверных вызовов. С точки зрения быстродействия и оптимальности - лучше сразу поставить НаСервере или все-таки НаКлиенте? Как будет более правильно?
22. Алексей Белоусов (AllexSoft) 18.03.15 17:12
(21) volha-77, лучше все по максимум выносить на сервер, а НаКлиенте делать только самое необходимое (то есть оставлять только интерфейсную работу)
23. Ольга Ковалева (volha-77) 18.03.15 20:33
24. 12e3 1sd (mymyka) 18.03.15 21:46
(20)Процедура ПриСозданииНаСервере так не думает )
(19)Зачем вам на сервере форма? на сервер передается контекст формы(если не указан &НаСервереБезКонтекста). Любые данные(не значения выводимые в элементы, а именно данные) можно получить через РеквизитФормыВЗначение(), поменять, а затем поместить обратно через ЗначениеВРеквизитФормы().
25. Алексей Белоусов (AllexSoft) 19.03.15 09:59
(24) mymyka,
(20)Процедура ПриСозданииНаСервере так не думает )

ПриСозданииНаСервере выполняется с контекстом клиента, то есть на сервере с контекстом доступно управление интерфесныими элементами! но отображение не доступно!
26. Ольга Ковалева (volha-77) 19.03.15 21:07
(22) AllexSoft, подскажите пожалуйста еще один вопрос.
В документах, содержащих табличную часть ТаблицаТоваров при внесении в табличную часть значений требуется выполнять однотипные действия - получение цены, суммы и т.д. (причем документ может быть и не записан, т.е. ссылка на него пустая). Поэтому нужно такие действия оформить как функции в общем модуле. Например, при вводе товара в модуле формы я пишу

&НаКлиенте
Процедура ТаблицаТоваровТоварПриИзменении(Элемент)
МодульОбслуживанияДокументов.ПриВводеТовара(ЭтаФорма);
КонецПроцедуры

В функции МодульОбслуживанияДокументов.ПриВводеТовара() нужно обращаться, как к данным текущей строки, так и к реквизитам шапки документа, также данные текущей строки должны изменяться в этой функции, поэтому я передаю туда ЭтаФорма.

&НаКлиенте
Процедура глПриВводеТовара(Форма) Экспорт

ОбъектФормы = Форма.Объект;
ТекущиеДанныеТЧ = Форма.Элементы.ТаблицаТоваров.ТекущиеДанные;

....
другие клиентские вызовы
серверные вызовы, получение цены, партии и т.д.
...

ТекущиеДанныеТЧ.Сумма = Сумма;

КонецПроцедуры

В общей функции глобального модуля происходят клиентские вызовы, куда также передается форма, и серверные вызовы, куда передается Форма.Объект.
Все работает, но у меня терзают сомнения, правильно ли так делать - передавать Форму и совершать много отдельных серверных вызовов - не будет ли это в реальной базе сильно тормозить работу.
Может правильно при изменении строки в форме документа выгружать табличную часть в таблицу значений и написать серверную функцию глобального модуля, туда передавать Форма.Объект (для получения реквизитов шапки) и таблицу значений, все действия совершать на сервере, а потом измененную таблицу значений загружать в таблицу формы? В таком варианте тоже сомневаюсь, при каждом изменении получается будет заново загружаться вся таблица.
Заранее большое спасибо.
27. Алексей Белоусов (AllexSoft) 20.03.15 11:49
(26) volha-77, нужно стараться как можно меньше тягать туда-сюда весь контекст с клиента на сервер и обратно, это все отражается на работе форм.. так же нужно стараться избегать модулей с флагом "вызов сервера", так как они так же загружаются в память клиента.
В функции МодульОбслуживанияДокументов.ПриВводеТовара() нужно обращаться, как к данным текущей строки, так и к реквизитам шапки документа, также данные текущей строки должны изменяться в этой функции, поэтому я передаю туда ЭтаФорма.

Вот тут лучше бы вы передавали необходимые параметры, а не все кучей, например так:
МодульОбслуживанияДокументов.ПриВводеТовара(Объект, Элементы.Товары.ТекущиеДанные)
а еще лучше не передавать целиком объект, а передавать необходимые данные шапки.. ну например
МодульОбслуживанияДокументов.ПриВводеТовара(Объект.Контрагент, Объект.Организация, Элементы.Товары.ТекущиеДанные)
+ еще можно указать платформе какие параметры будут изменены, а какие передаются по значению (чтобы при возврате на клиент из серверного вызова 1с-ка не тащила назад кучу хлама, которую вы не изменяли и не хотели). Например так может выглядеть бы объявление вашей процедуры правильно:
Процедура ПриВводеТовара(знач Контрагент, знач Организация, ТекущиеДанныеСтроки) Экспорт
+ можно преобразовать в функцию с минимальными возвратами на клиент, например так:

Функция ПриВводеТовара(знач Контрагент, знач Организация, знач ТекущиеДанныеСтроки) Экспорт
// получаем цену и сумму
возврат Новый Структура("Цена, Сумма", Цена, Сумма)
КонецФункции;

ну а вызов превращается в
ЗаполнитьЗначенияСвойств(Элементы.Товары.ТекущиеДанные, МодульОбслуживанияДокументов.ПриВводеТовара(Объект.Контрагент, Объект.Организация, Элементы.Товары.ТекущиеДанные));

Вот тогда вы будете таскать с клиента на сервер и обратно только гарантированно нужные данные, а не всю бесполезную кучу
28. Ольга Ковалева (volha-77) 20.03.15 14:25
(27) AllexSoft, большое спасибо за Ваши советы.
29. Ольга Ковалева (volha-77) 20.03.15 18:25
(27) AllexSoft, Вы пишете "так же нужно стараться избегать модулей с флагом "вызов сервера" , так как они так же загружаются в память клиента". А если в модуле формы вызывается клиентская функция общего модуля, в которой уже идет вызов серверной функции другого общего модуля с флагом "сервер", то тоже она будет загружать память?

&НаКлиенте
Процедура ТаблицаТоваровТоварПриИзменении(Элемент)
МодульОбслуживанияДокументов.ПриВводеТовара(Объект.Контрагент, Объект.Организация, Элементы.ТаблицаТоваров.ТекущиеДанные);
КонецПроцедуры

МодульОбслуживанияДокументов (с флагом Клиент)
&НаКлиенте
Функция ПриВводеТовара(знач Контрагент, знач Организация, ТекущиеДанныеСтроки) Экспорт
...
МодульОбслуживанияДокументовСервер.ПриВводеТовараСервер(...);
ТекущиеДанныеСтроки.Сумма = Сумма
КонецФункции;

МодульОбслуживанияДокументовСервер - с флагом Сервер
30. Алексей Белоусов (AllexSoft) 23.03.15 10:33
(29) volha-77, если только флаг "сервер" тогда не загружается в клиентскую рабочую память, если "сервер" и "вызов сервера" - то загружается.. так что "вызов сервера" лучше не ставить "на всякий случай" просто так, и стараться разделять функции и процедуры где он действительно нужен, а где нет.. Обычно я делаю функции-переходники на чисто серверные модули, например так:

//в модуле с флагом "вызов сервера"
Функция МояФункция(параметр1) Экспорт
 //вызов функции в "серверном" модуле без флага "вызов сервера"
 возврат  МойМодульСервер.МояФункция(параметр1);
КонецФункции 
...Показать Скрыть
31. Михаил Кончаренко (Anchoret) 15.11.16 15:23
Возник вопрос
В модуле формы есть следующий код:
&НаКлиенте
Процедура КнопкаВыполнитьНажатие(Команда)
КнопкаВыполнитьНажатиеНаСервере()
КонецПроцедуры

Процедура КнопкаВыполнитьНажатиеНаСервере()
//что-то происходит
КонецПроцедуры
...Показать Скрыть


Где будет выполнятся процедура КнопкаВыполнитьНажатиеНаСервере? На клиенте или на сервере?
32. Виктор Григоренко (JohnGalt) 18.11.16 13:26
(31) Anchoret, На клиенте, потому что наследуется предыдущее указание выполнения до тех пор, пока не будет другого указания.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа