Подскажите по использованию &НаСервере и &НаСервереБезКонтекста
Здравствуйте ув. знатоки. Суть вопроса такая. Допустим есть форма на которой есть реквизиты формы "Организация", "Контрагент" и некоторая таблица значений.
1. Вопрос 1. Как правильно выполнить серверную процедуру (допустим остатки получить остатки по регистру)? Что будет более правильным использовать для процедуры &НаСервере и получать значение Организации и Контрагента из контекста формы (+ в контексте передается не используемая в данной процедуре таблица) или же сделать &НаСервереБезКонтекста и Организацию и Контрагента указать в параметрах процедуры?
2. Допустим есть серверная процедура на которую передается контекст форму(&НаСервере). Из этой процедуры вызывается еще одна серверная процедура. Как быть для нее? Ведь по идеи контекст уже есть на сервере, то есть для нее что &НаСервере что &НаСервереБезКонтекста (с передачей параметров) будет по быстродействию одинаково?
1. Вопрос 1. Как правильно выполнить серверную процедуру (допустим остатки получить остатки по регистру)? Что будет более правильным использовать для процедуры &НаСервере и получать значение Организации и Контрагента из контекста формы (+ в контексте передается не используемая в данной процедуре таблица) или же сделать &НаСервереБезКонтекста и Организацию и Контрагента указать в параметрах процедуры?
2. Допустим есть серверная процедура на которую передается контекст форму(&НаСервере). Из этой процедуры вызывается еще одна серверная процедура. Как быть для нее? Ведь по идеи контекст уже есть на сервере, то есть для нее что &НаСервере что &НаСервереБезКонтекста (с передачей параметров) будет по быстродействию одинаково?
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
1) Насколько знаю, в общем случае рекомендация тут такова, что лучше использовать серверный внеконтекстный вызов (т.е. использовать директиву "&НаСервереБезКонтекста"), передав контрагента и организацию в качестве параметров (можно даже не по отдельности двумя параметрами, а запихнуть их в структуру и ее передать). Вроде, с точки зрения производительности это будет быстрее.
Хотя ситуации бывают, наверное, разные. И где-то лучше делать серверный контекстный вызов.
2) Нет. Если вторую процедуру сделаете внеконтекстной, контекст формы там будет недоступен. Т.е. если нужен контекст формы, обе серверные процедуры должны быть контекстными (с директивой "&НаСервере").
P.S. Добавлю еще, что из внеконтекстной процедуры контекстную вызвать вообще нельзя. Ну это Вы и так, наверное, знали )))
Хотя ситуации бывают, наверное, разные. И где-то лучше делать серверный контекстный вызов.
2) Нет. Если вторую процедуру сделаете внеконтекстной, контекст формы там будет недоступен. Т.е. если нужен контекст формы, обе серверные процедуры должны быть контекстными (с директивой "&НаСервере").
P.S. Добавлю еще, что из внеконтекстной процедуры контекстную вызвать вообще нельзя. Ну это Вы и так, наверное, знали )))
(3) Ну я знаю об этих рекомендациях из курса Гилева (то ли в базовом, то ли в продвинутом курсе об этом речь шла...).
Знаете, еще есть такая книга - "Разработка управляемого интерфейса". Вот там отдельная глава посвящена оптимизации клиент-серверного взаимодействия. Но я не дочитал до этого места :))) Поэтому не знаю, о чем там говорится, и рассматриваются ли там данные аспекты.
Ну в любом случае, думаю, почитать будет полезно.))
Знаете, еще есть такая книга - "Разработка управляемого интерфейса". Вот там отдельная глава посвящена оптимизации клиент-серверного взаимодействия. Но я не дочитал до этого места :))) Поэтому не знаю, о чем там говорится, и рассматриваются ли там данные аспекты.
Ну в любом случае, думаю, почитать будет полезно.))
1) В вопросе речь идет о таблице значений. Напрямую таблица значений на клиенте не доступна, а отображается через тип ДанныеФормыКоллекция.
Вариант1 вне контекстный вызов:
Процедура или функция?
Если процедура, то нам нужно передать Организацию, Контрагента и Таблицу (ведь вне контекста мы не сможем нужные нам данные загрузить в реквизит формы) при этом таблицу как ДанныеФормаКоллекция во вне контекстную процедуру мы передать не сможем - получим ошибку передачи данных (или как-то так звучит). Перед отправкой на сервер, нам потребуется преобразовать таблицу на клиенте в доступный для передачи с клиента на сервер вид. В типовых конфигурациях в таких случаях на клиенте формируют массив структур с составом ключей аналогично составу колонок исходной Таблицы, затем отправляют этот массив на сервер, там обрабатывают, после возвращения на клиент массив вновь считывается в ДанныеФормыКоллекция.
Если функция, то передаем в параметрах лишь Организацию и Контрагента. Как будем возвращать данные? ТаблицаЗначений на клиенте в явном виде не доступна, значит вернуть данные в форму "по простому" не получиться. Потребуется вернуть на клиент данные в каком либо "съедобном" виде и затем загрузить их в ДанныеФормыКоллекция. Можно также использовать массив структур.
Вариант2 контекстный вызов:
Тут все просто. Делаем процедуру, в ней имеем все данные и возможность работы с ними. формируем таблицу значений с данными, затем используем ЗначениеВРеквизитФормы(Таблица, "ИмяТаблицыРеквизита") и все...
Таким образом оба варианта допустимы, а какой из них использовать в каждом случае решается отдельно. В случае простой обработки я бы предпочел Вариант2. В случае написания кода для серьезной конфигурации и работы с большими объемами данных - там, где итог применения варианта 1 с процедурой дал бы ощутимый прирост в производительности, конечно, использовал бы Вариант1 - процедуру, если нужно было бы передать таблицу на сервер для обработки; функцию, если достаточно просто возвращаемого значения, например исходная таблица полностью перезатирается и имевшиеся в ней данные не важны.
Если бы речь шла не о таблице значений, а о более простых типах, доступных как на клиенте так и на сервере - тут безусловно обычно все решается с помощью вне контекстных процедур или функций.
2) Тут уже верно ответили - обе процедуры следует объявлять с директивой &НаСервере
Вариант1 вне контекстный вызов:
Процедура или функция?
Если процедура, то нам нужно передать Организацию, Контрагента и Таблицу (ведь вне контекста мы не сможем нужные нам данные загрузить в реквизит формы) при этом таблицу как ДанныеФормаКоллекция во вне контекстную процедуру мы передать не сможем - получим ошибку передачи данных (или как-то так звучит). Перед отправкой на сервер, нам потребуется преобразовать таблицу на клиенте в доступный для передачи с клиента на сервер вид. В типовых конфигурациях в таких случаях на клиенте формируют массив структур с составом ключей аналогично составу колонок исходной Таблицы, затем отправляют этот массив на сервер, там обрабатывают, после возвращения на клиент массив вновь считывается в ДанныеФормыКоллекция.
Если функция, то передаем в параметрах лишь Организацию и Контрагента. Как будем возвращать данные? ТаблицаЗначений на клиенте в явном виде не доступна, значит вернуть данные в форму "по простому" не получиться. Потребуется вернуть на клиент данные в каком либо "съедобном" виде и затем загрузить их в ДанныеФормыКоллекция. Можно также использовать массив структур.
Вариант2 контекстный вызов:
Тут все просто. Делаем процедуру, в ней имеем все данные и возможность работы с ними. формируем таблицу значений с данными, затем используем ЗначениеВРеквизитФормы(Таблица, "ИмяТаблицыРеквизита") и все...
Таким образом оба варианта допустимы, а какой из них использовать в каждом случае решается отдельно. В случае простой обработки я бы предпочел Вариант2. В случае написания кода для серьезной конфигурации и работы с большими объемами данных - там, где итог применения варианта 1 с процедурой дал бы ощутимый прирост в производительности, конечно, использовал бы Вариант1 - процедуру, если нужно было бы передать таблицу на сервер для обработки; функцию, если достаточно просто возвращаемого значения, например исходная таблица полностью перезатирается и имевшиеся в ней данные не важны.
Если бы речь шла не о таблице значений, а о более простых типах, доступных как на клиенте так и на сервере - тут безусловно обычно все решается с помощью вне контекстных процедур или функций.
2) Тут уже верно ответили - обе процедуры следует объявлять с директивой &НаСервере
(8) 1cUserAndrew, действительно, проморгал замыленными глазами :)
Тогда все по тому же (7) выходит: если не хочется заморачиваться и нужен простой код, тогда Вариант2; Если нужна жОООООсткая оптимизация, тогда Вариант1 с функцией, возвращать массив структур и загружать его в таблицу формы :)
Тогда все по тому же (7) выходит: если не хочется заморачиваться и нужен простой код, тогда Вариант2; Если нужна жОООООсткая оптимизация, тогда Вариант1 с функцией, возвращать массив структур и загружать его в таблицу формы :)
(9) xalker, а разве оптимизация не всегда нужна? Простой пример, только что сделал:
5 раз делал вызов того и иного метода. Результат - вне контекстный 36-40 секунд, контекстный 101-110. Разница по быстродействию в 3 раза.
&НаКлиенте
Процедура ВнеконтекстныйВызов(Команда)
НачДата = ТекущаяДата();
Для Й= 1 По 10000 Цикл
ОбработкаБезКонтекста(Число1, Число2);
КонецЦикла;
Секунды = ТекущаяДата() - НачДата;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Внеконтекстный - "+ Секунды;
Сообщение.Сообщить();
КонецПроцедуры
&НаКлиенте
Процедура КонтекстныйВызов(Команда)
НачДата = ТекущаяДата();
Для Й= 1 По 10000 Цикл
ОбработкаСКонтекстом();
КонецЦикла;
Секунды = ТекущаяДата() - НачДата;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "С контекстом - "+ Секунды;
Сообщение.Сообщить();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработкаБезКонтекста(Число1, Число2)
Результат = Число1+Число2;
КонецПроцедуры
&НаСервере
Процедура ОбработкаСКонтекстом()
Результат = Число1+Число2;
КонецПроцедуры
Показать5 раз делал вызов того и иного метода. Результат - вне контекстный 36-40 секунд, контекстный 101-110. Разница по быстродействию в 3 раза.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот