Как с сервера вызвать клиентскую процедуру 1с
Инструкции препроцессора "&НаСервереНаКлиенте" и "&НаКлиентеНаСервереБезКонтекста"
Процедуры и функции в модулях управляемых форм, а также в общих клиентских модулях управляемого приложения, требуют четкого определения среды выполнения программного кода.
Для этих целей, в общей сложности, используются пять директив препроцессора: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста, &НаКлиентеНаСервере. Первые три используются довольно часто при разработке конфигуарции. Последние же две - большая редкость. Именно о них и будет идти речь сегодня в статье.
&НаСервереНаКлиенте
Данная директива может применяться только в модуле команды. Сама процедура или функция, объявленная с такой директивой, может быть использована как на клиентской, так и на серверной стороне в модуле команды. Приведу пример использования в команде справочника. Для этого в тестовой конфигурации добавим команду "Тестируем" для справовочника "ПростойСправочник":
Модуль команды содержит следующий программный код:
Теперь рассмотрим поведение платформы при ее выполнении. Вызовем команду в режиме предприятия и проанализируем количество вызовов сервера. Картина будет следующей:
Таким образом, при вызове процедуры с директивой препроцессора "НаКлиентеНаСервере" с клиентской стороны вызова сервера не происходит. Единственный вызов сервера в нашем прмере происходил при обращении к серверной процедуре "Сервер".
Из всего вышесказанного можно заключить, что процедуры и функции с директивой " НаКлиентеНаСервере" фактически имеет те же возможности, что и клиентские процедуры и функции с директивой "НаКлиенте". Использование директивы "НаКлиентеНаСервере" позволяет вызывать любые процедуры модуля команды, а также получать доступ к клиентскому контексту формы.
На мой взгляд, использование подобных процедур и функций усложняет читабельность программного кода. Если использовать директивы "НаКлиенте", "НаСервере" и "НаСервереБезКонтекста", то код будет более понятным и предсказуемым.
Рассмотрим теперь работу процедур и функций с директивой "&НаКлиентеНаСервереБезКонтекста".
&НаКлиентеНаСервереБезКонтекста
Директива " НаКлиентеНаСервереБезКонтекста" может быть использована в модулях управляемых форм на клиенте и на сервере. При этом такие процедуры и функции не могут получить доступ к контексту формы, всем экспортным переменным формы, но возможен вызов процедур и функций из серверных общих модулей, а тажке не глобальных серверных и клиенских одновременно.
Рассмотрим небольшой пример их использования. В модуле формы элемента справочника "ПростойСправочник" напишем следующий программный код:
Процедура "Тестируем" принадлежит команде формы. При ее запуске осуществляется вызов процедуры "ТестируемКлиентСервер" с директивой "НаКлиентеНаСервереБезКонтекста". Как было сказано выше, данная процедура не сможет получить доступ к контексту формы и другим клиентским процедурам. Но все серверные процедуры модуля формы без контекста будут доступны для вызова, а также серверные процедуры общего модуля.
Вызов сервера будет произведен, что логично, при вызове серверной процедуры со стороны клиента.
Вывод
Подытожим выше сказанное:
- Процедуры и функции с директивой "НаКлиентеНаСервере" используются только в модулях команд и ограничены возможностями клиентской стороны.
- Процедуры и функции с директивой "НаКлиентеНаСервереБезКонтекста" используются только в модулях форм и позволяют работать с серверной стороной без передачи контекста формы (реквизиты формы, экспортные переменные модуля формы и др.).
- Основное различие между двумя рассматриваемыми директивами - это контекст их применения. Одна команда препроцессору используется только в модулях команд, другая в модулях управляемых форм.
За весь опыт работы с управляемыми формами использовать подобные процедуры и функции приходилось очень редко. Как уже говорил выше, считаю, что их исопльзование ухудшает читабельность кода.
Добрый день. Знаю, что из сервера клиент вызвать никак не получится, но посоветуйте, пжл, что-нибудь. В общем модуле есть процедура с директивой компиляции &НаКлиенте. Необходимо обеспечить ее запуск время от времени. С помощью регламентного задания, насколько мне известно, эту проблему не решить, т.к. там можно указывать только процедуры с директивами компиляции &НаСервере.
Подскажите, пжл, выход из ситуации?
(1) Не помогает, при попытке сохранить регламентное задание возникает ошибка "Метод задания не найден"
Знаю, что из сервера клиент вызвать никак не получится, но посоветуйте, пжл, что-нибудь
(3) Проблема в том, что процедура, которая находится в общем модуле, запускает другую клиентскую процедуру. Эту самую другую клиентскую процедуру перенести не получится.
(6) Эта операция должна выполняться периодически, поэтому и сначала решил использовать регл. задания, пока не понял, что они работают только с серверными процедурами.
Похоже, придется решить проблему через виндовый диспетчер заданий, другого пути не вижу.
(9) Так типовую переделай.
Не обязательно переделывать именно эту типовую ф-ю.
Можно ведь свою наваять. Точно такую же, только она будет делаться на сервере и сделать так, чтобы при обновлении она тоже "обновилась".
В общем модуле доступны только две директивы компиляции &НаКлиенте и &НаСервере. Общие директивы для общих модулей не определены.
Вариант следующий:
* общий модуль должен иметь признаки "Клиент (управляемое приложение)", "Сервер", "Вызов сервера".
* в этом общем модуле 3 метода - первый без директивы компиляции, второй с директивой &НаКлиенте, третий с директивой &НаСервере.
Таким образом имеем один метод (первый) как для серверного, так и для клиентского исполнения.
В общем случае достаточно не указывать директивы компиляции в общем методе, и нет необходимости писать заглушки с директивами копиляции. "Вызов сервера" у модуля тоже не особенно нужен.
Разницу поведения потрохов первого метода на клиенте и на сервере можно организовать через инструкции препроцессора.
Проверено для форм, для регл.заданий тестируй сам.
В общем, наиболее лучшим решением для себя я нашел следующее:
1. Создаю внешнюю обработку, в событии открытия формы которой добавляю строку кода запуска необходимой мне процедуры, которая выполняется НаКлиенте в общем модуле. После этого обработка закрывает 1С.
2. Создаю регламентное задание, в котором указываю запуск требуемой базы 1С с обязательным параметром Execute, в котором указываю путь к моей внешней обработке.
(11) ПодключитьОбработчикОжидания - этот способ не подойдет мне по той причине, что постоянно д.б. запущен сеанс 1С.
П.с. База работает в клиент-серверном режиме.
(15) - описанная последовательность действий.
Я создал общий модуль, проставил для него галки Клиент, Сервер, ВызовСервера, создал в нем 3 процедуры: Процедура1 без какой-либо директивы компиляции, Процедура2 с директивой компиляции НаСервере и Процедура3 с директивой компиляции НаКлиенте.
Далее создаю регламентное задание, указываю для запуска Процедура2.
Процедура2 вызывает Процедура1, а та, в свою очередь, должна вызвать Процедура3, но этого не происходит, т.к. Процедура1 не видит Процедура3.
Если я понял (12), то предполагалась именно такая последовательность, разве не так?
В 1С на УФ можно из серверного кода формы передать форму как параметр в серверный общий модуль. И далее из серверного общего модуля в другой серверный общий модуль.
Но из клиенского кода формы и из клиентского модуля невозможно передать форму в серверный общий модуль.
Можно передать форму только из клиентского кода формы в серверный код формы.
Для решения проблемы из клиентского кода формы или клиентского общего модуля вызывают серверный метод формы, который уже передает форму в серверный общий модуль.
Это крайне ужасное решение, которое провоцирует весь код писать в форме, не разнося ее по модулям. Нужно как можно скорее убрать это противоречивое ограничение.
(5) ну вот ты написал некую серверную процедуру Процедура(Форма) в общем модуле МойСервер.
А теперь хочешь эту процедуру вызывать из общего модуля Клиент, куда управление попадает из формы.
и получаешь ошибку невозможности передать форму на сервер.
В этот раз соглашусь с ТС !
Вот ни разу невнятное ограничение. Чем общий модуль хуже серверной процедуры формы . Геноцид.
(10) Нечасто. Но попадалось здоровые штуки делать, и это нелепое (на первый взгляд) ограничение неприлично нервов попортило.
(0) может в каком то частном случае это и нужно, но пока не сталкивался с таким, проблем написать в модуле формы нету
Иногда неудобно, согласен.
Но тут думаю вопрос в целом такой - сложные объекты не передать туда/обратно.
Каждый раз вызывая серверные етоды мы передаем туда весь контекст формы!(а не только ссылку на нее)
теперь первая форма на клиенте закрылась. Если на клиенте нет на нее ссылок, то 1С имеет право ее положить в мусор. Не бегать же за подсчетом ссылок на сервер?
Теперь вызывает так:
ВтораяФорма.ПолучитьРеквизитСудногоДня().Обновить(); //простите что? оно же в мусоре!
+(20) именно поэтому всякие массивы передаются с клиента на сервер как копии своих значений, чтобы не заниматься подсчетом ссылок
(20) в статье я описал, что при вынесении кода в общие модули с этой проблемой встретишься гарантированно. Это не неудобство, это БЕДА 1С
обычно думаешь, как бы оптимизировать: где несколько вызовов в один объединить, где по значению передавать, где без контекста, а то и без серверного вызова
тс думает, как бы сделать, чтобы говнокодить было проще
(24) если кодить проще, то результат лучше получается. Для этого 1с и была задумана, чтобы доступно и всерьез.
как видишь, из-за этой шняги все пишут формы не разбивая ее по модулям.
Что вредит читаемости, повторному использованию кода и т.п.
обрати внимание, что в формах на ОФ было принято использовать модуль формы, в УФ это рудиментом стало.
(32) я вот все хочу посмотреть на этот "нормальный код", но все скрывают, приходится самому статьи писать, просвещать дремучих
Мда уж. "Гении" не пытаются разобраться/почитать мануалы, они сразу, по своим поверхностным представлениям выдают шедевры космической глупости.
"Т.к. данные формы доступны и на клиенте и на сервере, то основным хранилищем всех данных выступает сервер, просто потому что взаимодействие клиента и сервера инициируется только с клиента. Это означает, что в момент работы в памяти сервера находятся все данные формы, и доступ к ним осуществляется напрямую. На клиенте же имеется в общем случае частичное представление этих данных, при необходимости подгружаемое с сервера. При дальнейшей работе с формой изменения данных могут передаваться туда и/или обратно для синхронизации состояний клиента и сервера."
(41) и? любая существующая на клиенте форма существует на сервере. В параметре передается просто ссылка на эту форму. В чем парадокс? Почему эту ссылку нельзя передать с клиента на сервер? Алле? Что за отрицание реальности?
(20) а в чем проблема? Если форма не закрыта, она существует на сервере и следовательно, на нее существует ссылка на клиенте. Даже если все ссылки на клиенте закрыты, если форма открыта, она существует и ее можно получить через коллекцию форм. Проблема надумана и отсосана из пальца
любая ссылка на форму - это ссылка на контекст формы (на клиенте и на сервере). Пока форма жива, эта ссылка имеет смысл, после закрытия формы она обращается в ничто.
(47) при вызове команды закрытия формы она фактически закрывается (т.е. в интерфейсе закрывается). И все ссылки на клиенте и сервере обращаются в Неопределено. В чем проблема?
(47) если ты именно про ссылки на созданные формы, то если форма создана и явно не уничтожена, она должна храниться в памяти. Она будет доступна в коллекции форм, если что.
(48) во первых это не так, никто не будет оббегать все объекты в поисках ссылок, это дорого
во-вторых, для этого понадобилось внезапно бы лезть еще раз на сервер
(49) внезапно мнение поменялось
ты вообще знаешь как устроены системы с управляемой памятью и сборщиком мусора?
Способ вызывать форму из клиента через функцию-посредник формы есть. значит, платформа может это делать, но не делает.
В итоге провоцируется длинный монокод формы.
(52) ты что-то не уловил. Никакого подсчета ссылок. Нет явной команды уничтожения формы - форма хранится.
(52) как сборщики мусора устроены. знаю. Теперь расскажи, как ты это применяешь для форм.
(53) да, но только в контексте одной формы, ты войдешь в этом контексте на сервере и выйдешь из него в нем же, другие формы на сервере ты так не изменишь
Подключили на форме 2 обработчика ожидания. В них передаем форму в разные методы (или даже модули) на сервер. Там параллельно с формой что-то делается.
Как синхронизировать потом на клиенте эти изменения?
(58) платформа стандартно все делает, в чем проблема? Для тебя удивительно, что все формы синхронизируются на клиенте и сервере.
Мы передаем не форму, а ссылку на нее. Форма всегда есть на клиенте и сервере.
С сервера вызвать клиента
очень очень нужно вызвать из процедуры в модуле объекта открыть форму нужно, т.е. совершить.
Отличаются версии клиента и сервера
всем привет. ставлю платформу 1с 8.3.6.7( кажется) устанавливаю все тонкий клиент, сервер.
Обратный вызов клиента
Может кто доступно объяснить принцип действия обратного вызова клиента и метода.
определение и вызов Почтового клиента
Подскажите каким образом возможно из программы на Visual C, определить почтового клиента по.
С сервера нельзя вызвать клиента (клиентов может быть много и сервер не знает о их существовании)
Добавлено через 22 секунды
На самом деле это и не нужно
Добавлено через 1 минуту
Наверное логично, чтобы получить доступ к методу какого-то объекта, необходимо получить сам ОБЪЕКТ
тогда такой вопрос-если в общем модуле стоят галки клиент и сервер(обычные формы),в таком случае доступно ли получитьформу()?
StaLL1n, смотря где исполняется код
Добавлено через 24 секунды
Если на сервере, то НЕТ
Если на Клиенте, то ДА
не совсем понял,как это.Процедура в том модуле запускается рег.заданием(которое,кстати,фиг поймешь как работает).Можно ли как-то программно открыть обработку в вышеуказанном модуле?
Решение
StaLL1n, читать литературу. Читать, читать, Много читать.
Галочки у модуля только говорят о том где должен компилироваться модуль! (не исполняться. ) т.е. ОМ с галками Сервер и Клиент будет скомпилирован 2 раза для клиента и отдельно для сервера + компиляцией так же управляют инструкции препроцессору
Если вызвать функцию Этого модуля например с формы (с клиента), то код будет выполняться на клиенте
Если вызвать эту же функцию например из ОМ с галкой Сервер или из Регламентного задания то код будет исполняться на сервере
В этой статье мы покажем, как взаимодействуют клиентская и серверная части платформы и какие есть особенности в использовании директив компиляции.
Это будет полезно начинающим разработчикам и тем, у кого есть пробелы в области клиент-серверного взаимодействия – всё объясним «на пальцах» :)
Клиент-серверная архитектура заложена в платформе изначально – со времен «1С:Предприятие 8.0».
Однако при разработке на 8.0 и 8.1 о разделении кода на клиентскую и серверную часть можно было не заботиться, поскольку на клиенте (на толстом клиенте) был доступен тот же функционал, что и на сервере.
Всё изменилось с выходом платформы «1С:Предприятие 8.2», когда появился тонкий клиент. Теперь на клиенте доступен один функционал, на сервере – другой. Клиент и сервер «общаются» между собой с помощью серверного вызова.
Конечно, это усложнило процесс разработки, но с другой стороны – можно создавать более оптимальные (быстрые) решения, поскольку все сложные задачи выполняются на сервере.
Немного базовой теории
Перед тем, как перейти к содержательной части, договоримся о некоторых ограничениях:
- Мы подразумеваем, что Вы знаете о существовании четырёх директив компиляции, доступных в модулях формы: «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста».
- Все примеры будут опираться на работу «1С:Предприятие 8» в клиент-серверном режиме. Файловый вариант по сути является эмуляцией клиент-серверного режима, с небольшими отклонениями (для данной статьи это не критично)
- В рамках этого материала рассматривается исключительно взаимодействие клиента и сервера 1С. Работа с базой данных, преобразование данных и прочие нюансы работы системы – это темы других статей.
Далее, освежим в памяти немного теории.
Директивы, в имени которых упоминается «Клиент», устанавливают ограничение на обращение к базе данных.
Процедуры или функции, написанные под директивой «Без контекста», не имеют доступа к контексту (данным) формы. Исходя из этой информации, легко представить ограничения директив по доступу к данным в виде следующей таблицы:
Опережая вопрос «Для чего же директива с самым длинным названием, если она ограничивает и использование контекста форм, и обращения к базе данных?», напомню: любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.
Отсюда делаем вывод: у методов, описанных под директивой «&НаКлиентеНаСервереБезКонтекста», единственным источником данных являются эти самые переданные параметры.
Не стоит забывать и про доступность вызова одних процедур и функций из других. Для этого стоит запомнить, что можно вызывать только те процедуры и функции, которые находятся под одноимённой (с родительским методом) директивой или под директивой, находящейся ниже (чем у родительского метода) согласно списку:
- &НаКлиенте
- &НаСервере
- &НаСервереБезКонтекста
- &НаКлиентеНаСервереБезКонтекста.
То есть из метода, описанного под директивой «&НаКлиенте», можно вызывать процедуры и функции, описанные под любой директивой. А вот «из-под» директивы «&НаСервереБезКонтекста» можно вызывать только то, что описано под директивой «&НаСервереБезКонтекста» или «&НаКлиентеНаСервереБезКонтекста».
Теперь про серверный вызов
Серверный вызов – это передача какой-то информации с клиентской части «1С:Предприятие 8» на серверную часть с целью вернуть обратно некий набор данных.
Самый первый серверный вызов инициализируется в момент начала сеанса работы 1С. То есть когда пользователь выполняет вход в информационную базу:
«Оу! При чём тут Библиотека?!» – спросите Вы.
Всё очень просто:
Обратите внимание, что доступ к базе данных есть только на серверной части, а соединение между клиентом и сервером имеет ограниченную пропускную способность. Это и неудивительно – ведь соединение между клиентской и серверной частью может быть установлено даже по нестабильному низкоскоростному каналу связи (например, посредством мобильного интернета).
Кроме этого, передача данных между клиентом и сервером возможна только посредством серверного вызова.
Но, для того чтобы перейти к основной теме данной статьи, необходимо сначала разобраться – где будет выполняться программный код, написанный под определенными директивами. То есть на какой части приложения «1С:Предприятие 8» будут доступны процедуры и функции, описанные под директивами «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста»:
Видим, что на стороне клиента у нас будут доступны процедуры и функции, написанные под двумя директивами из четырёх, а на стороне сервера – под тремя из четырёх.
Сразу возникают вопросы: «Зачем такое многообразие и чем оно полезно?», «Как метод, описанный под директивой «&НаКлиентеНаСервереБезКонтекста» может выполняться и на клиенте, и на сервере?».
Сейчас мы постараемся понять особенности работы системы при использовании директив и почему необходимо уметь правильно использовать каждую из существующих директив компиляции.
И в этом нам помогут наши новые друзья, знакомьтесь!
Это процесс клиентской части приложения «1С:Предприятие 8». Он запускается на компьютере пользователя и сожительствует в оперативной памяти с другими процессами (38 вкладок браузера, поток аудио из социальной сети, telegram и другие). Может порождать серверный вызов.
Это процесс серверной части приложения «1С:Предприятие 8». Он существует на сервере 1С. Знает, какие клиентские сеансы в данный момент запущены, но самостоятельно не может инициировать взаимодействие с ними. Работает с клиентской частью только через полученный от неё серверный вызов.
А это серверный вызов. Как было сказано выше, он порождается процессом клиентской части и призван «прислуживать» ему. Он передает запросы со стороны клиента на сторону сервера, а также занимается транспортировкой данных с клиента на сервер и обратно.
Итак, давайте рассмотрим несколько особенностей работы программного кода в «1С:Предприятие 8», написанного под разными директивами.
Действие 1. Открытие пользователем формы с данными.
В момент нажатия Пользователем кнопки открытия формы из интерфейса, происходит передача управления на Сервер. По переданным параметрам получаются необходимые для построения данные из БД и происходит формирование контекста формы, который затем отправляется на клиентскую часть. У пользователя на экране отображается запрошенная форма.
Действие 2. Получение из открытой Пользователем формы дополнительных данных из Базы данных.
Получение этих данных может быть описано под двумя директивами – «&НаСервере» и «&НаСервереБезКонтекста». Рассмотрим оба случая.
Явление 1. Директива «&НаСервере»
При вызове процедуры или функции под директивой «&НаСервере» из формы со стороны клиента происходит «упаковка» всего контекста формы и отправка его на сторону сервера.
После выполнения метода на сервере, весь этот «пакет» транспортируется обратно. Таким образом, форма со всеми элементами и данными дважды проходит через самое узкое место системы.
Явление 2. Директива «&НаСервереБезКонтекста»
При вызове процедуры или функции под директивой «&НаСервереБезКонтекста» из формы со стороны клиента происходит передача на сторону сервера только тех данных, которые были указаны в качестве параметров. Обратно же передаётся только необходимая информация в уже подготовленном виде.
Таким образом, серверный вызов не несёт лишней нагрузки, и для передачи данных между клиентом и сервером потребуется меньше ресурсов.
Из примеров видно, что далеко не всегда оправдано указание директивы компиляции «&НаСервере» с точки зрения использования контекста (данных) формы на сервере.
Если возможно решить возникшую задачу путём отправки на сервер только определённого набора данных, то надо эту возможность использовать и описывать метод под директивой «&НаСервереБезКонтекста». Это позволит уменьшить нагрузку на серверный вызов, а также не занимать сервер обработкой и хранением ненужной в текущий момент информации.
Кстати, именно поэтому до версии платформы 8.3.7.1759 на сложных формах для управления видимостью элементов рекомендовалось использовать панели со страницами, а не свойство «Видимость». Только начиная с этого релиза отработка изменения видимости элементов стала выполняться на стороне клиента.
До этого момента при каждом изменении свойства «Видимость» происходил серверный вызов, как при использовании директивы «&НаСервере».
Но использование директивы «&НаСервереБезКонтекста» не является панацеей. Помимо нагрузки на серверный вызов, всегда необходимо задумываться ещё над одним параметром.
Действие 3. Обработка данных табличной части формы с получением дополнительной информации из Базы данных.
Явление 1. Построчная обработка табличной части на стороне клиента с организацией серверного вызова для получения дополнительной информации из базы данных.
Мы уже знаем – лучше использовать директиву «&НаСервереБезКонтекста».
При таком построении программного кода происходит множественное обращение со стороны клиента на сервер – по количеству элементов цикла, запущенного на стороне клиента.
Явление 2. Предварительная обработка табличной части на стороне клиента с целью подготовки требуемых к обработке на сервере данных и «упаковки» их в набор параметров. Затем передача этого набора на сервер для получения дополнительной информации из базы данных.
Используем всё ту же директиву «&НаСервереБезКонтекста».
В данном случае количество серверных вызовов сведено к минимуму за счёт предварительной подготовки параметров.
Большое количество текущих серверных вызовов может свидетельствовать о неоптимальном программном коде.
Избегайте создания серверных вызовов внутри цикла. Подготовьте набор параметров и единожды выполните его передачу для обработки на сервер. Если предполагается сложная обработка большого количества данных формы – передайте её полностью на сервер (при помощи директивы «&НаСервере») и выполните все действия на стороне сервера.
Если цель серверного вызова, созданного внутри цикла – получить какую-либо информацию из базы данных, то данная операция включает в себя запрос в цикле. А это очень негативно влияет на производительность всей системы в целом.
С директивой «&НаСервереБезКонтекста» вроде бы разобрались. Она нужна для того, чтобы уменьшить объем информации, передаваемой в рамках одного серверного вызова. Дополнительно разобрались с количеством текущих серверных вызовов – необходимо стремиться к их минимизации.
Давайте теперь попробуем разобраться, для чего нужна директива «&НаКлиентеНаСервереБезКонтекста».
Действие 4. Выполнение обработки данных.
Когда предполагается выполнение одной и той же обработки данных из нескольких участков программного кода, разумно этот код поместить в самостоятельную процедуру или функцию. Остаётся только решить, под какой директивой её написать.
Та-дам!
Для копирования у нас есть ксерокс. Но куда его поставить? На сторону клиента или сервера? Под какой директивой его разместить?
Как было озвучено ранее – любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.
Давайте для начала попробуем разместить копировальный аппарат на стороне клиента. Для этого описываем процедуру или функцию «Ксерокс» под директивой «&НаКлиенте». Тогда процесс клиентской части в любой момент сможет без проблем обратиться к ней и все действия будут выполнены в соответствии с программным кодом.
Но что произойдёт, если потребность в копировании возникнет на стороне сервера? Например, для подготовки данных, передаваемых на сторону клиента, потребуется сделать копию? Напомню – процесс серверной части не имеет возможности самостоятельно инициировать клиентские вызовы.
Получается, что использовать директиву «&НаКлиенте» неправильно, а директиву «&НаСервере», как мы изучили ранее – нежелательно. Давайте посмотрим поведение системы при использовании директивы «&НаСервереБезКонтекста».
Вроде бы результат достигнут – и с сервера, и с клиента доступно копирование. Но для того, чтобы получить копию данных, используемых на клиенте, приходится делать серверный вызов. А это опять ведет к лишней нагрузке на соединение и временным затратам.
Избавиться от излишней передачи на сервер при сохранении возможности копирования на клиенте и на сервере можно при помощи директивы «&НаКлиентеНаСервереБезКонтекста».
Не углубляясь в детали, отметим, что метод, описанный под данной директивой управления, создаётся в двух копиях – и на стороне клиента, и на стороне сервера. Это позволяет выполнить необходимые действия там, где появилась потребность в них (клиент/сервер), без лишних серверных вызовов.
Конечно, вместо того чтобы выделять повторяющийся программный код, описывать его в отдельном методе под директивой «&НаКлиентеНаСервереБезКонтекста», можно поступить по-другому. Просто взять и написать один и тот же участок кода и в клиентской, и в серверной процедуре.
С точки зрения выполнения программы результат будет одинаков. Но объяснение «почему так не надо делать» – это уже совершенно другая тема…
Вместо заключения
В данной статье мы на наглядных примерах рассмотрели влияние различных директив компиляции на такое явление системы «1С:Предприятие 8», как серверный вызов. Как видно, основная причина для выбора правильной директивы – производительность транспортировки данных между клиентской и серверной частью.
Придерживайтесь при разработке следующих правил:
- По возможности не передавайте контекст формы на сторону сервера
- Минимизируйте количество текущих серверных вызовов
- Длительные и ресурсоёмкие задачи запускайте на выполнение на стороне сервера (при возможности – в фоновом режиме).
Учитывайте потребность в доступности тех или иных видов данных, обоснованность передачи управления и не стесняйтесь при необходимости дробить процедуры и функции. И будет Вашему серверному вызову всегда легко, а Вы от пользователей Вашей программы получите «молчаливую благодарность»!
Программист Иван при доработке 1С на своём предприятии сделал ошибку в выборе директивы компиляции. Из-за неё длительность одного из серверных вызовов была больше возможной на полсекунды.
Пользователей, применяющих этот функционал, – 25 человек, и каждый из них за рабочий день в среднем совершает 110 таких операций. Всего впустую за рабочий месяц потрачено 28875 секунд (21 рабочий день * 25 человек * 110 операций * 0,5 секунды) = 8,02 часов.
Иван, каково тебе осознавать, что за месяц ты задолжал своему предприятию целый рабочий день?
Об авторе
Автор статьи – Павел Ванин
PDF-версия статьи для участников группы ВКонтакте
Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.
Если Вы уже участник группы – нужно просто повторно авторизоваться в ВКонтакте, чтобы скрипт Вас узнал. В случае проблем решение стандартное: очистить кэш браузера или подписаться через другой браузер.
Комментарии / обсуждение (158):
Всё предельно понятно, спасибо за статью!
Хотелось бы увидеть правильные практические примеры с директивой &НаКлиентеНаСервереБезКонтекста
Добрый день, Ruby!
Много примеров использования директив находится в типовых конфигурациях.
Например, в 1С:УНФ есть вот такая функция под директивой «&НаКлиентеНаСервереБезКонтекста»:
&НаКлиентеНаСервереБезКонтекста
Функция ПолучитьЗаголовокНастроек(ТекущийРежим, НовыйЗаголовок)
Результат = “Настройки”;
Если НЕ ТекущийРежим Тогда
Результат = НовыйЗаголовок;
КонецЕсли;
C какой радости “Отсюда делаем вывод: у методов, описанных под директивой «&НаКлиентеНаСервереБезКонтекста», единственным источником данных являются эти самые переданные параметры.” ? С этой директивой можно сделать с базой все что угодно, если код реально будет выполняться в серверном контексте или в толстом клиенте. В тонком просто синтаксический контроль может не пройти. И что за 5 лет никто этого не заметил? Табличка выше этой цитаты тоже вдохновляет. База недоступна. Дальше читать не стал.
Добрый день, . Хочется вам сказать “Браво!” и поаплодировать! (сарказм)
Вы правы – технологических ограничений на доступ к базе данных при серверном исполнении процедуры или функции под директивой «&НаКлиентеНаСервереБезКонтекста» нет. Можно ли считать этот факт опровержением всей статьи? Я считаю – нет, и давайте поясню почему.
В сути данной директивы заложена возможность исполнения одного и того-же кода как на стороне клиента, так и на стороне сервера. И если мы в ней напишем, например, запрос к базе данных, то при компиляции формы возникнет ошибка. Так как со стороны клиентского экземпляра программного модуля формы доступа к базе данных нет.
Про директиву «&НаКлиентеНаСервереБезКонтекста».
Ваши оговорки про толстый клиент и возможность выполнения запроса к базе данных на сервере (игнорируя ошибки, возникающие при компиляции формы) ничто иное, как исключения из правил. Это все равно, что пассатижами гвозди заколачивать – в принципе возможно, но молотком удобнее.
Примеры про доступ к Access и COM-объектам тоже больше похожи на частный случай. Напомню – в ограничениях статьи (которые вы должны были по-идее прочитать, так как они выше описания директив приведены) указано, что рассматривается клиент-серверный вариант работы системы. А это означает, что доступность ресурсов (файлы, объекты, оборудование, …) со стороны клиента и со стороны сервера может иметь существенные отличия.
P.S.
Давайте поясню причину агрессии в своем предыдущем комментарии. Вы не удосужились прочитать статью, но повесили на нее ярлык «плохой контент». В наше время часто перед тем как читать длинный текст, люди пробегаются по комментариям – понять, стоит ли тратить свое время на материал. Увидев ваш комментарий, кто-то может засомневаться в пользе статьи и уйти со страницы. А мне, как автору материала, хотелось бы принести пользу максимальному количеству людей.
Читайте также: