Форум на Kuban.ru (http://forums.kuban.ru/)
-   Территория 1С (http://forums.kuban.ru/f1040/)
-   -   Доступность ТЗ в серверных процедурах (http://forums.kuban.ru/f1040/dostupnost-_tz_v_servernyh_procedurah-6898079.html)

denisv 05.06.2015 09:19

Доступность ТЗ в серверных процедурах
 
Приветствую всех!
Только начинаю осваивать управляемые формы, прочитал много интересного в интернете, но вот в голове не сложилось общей концепции как правильно сделать взаимодействие серверной и клиентской части.
Вот сейчас нужно решить задачу, к примеру, процедура на клиенте запускает серверную процедуру, которая делает вычисления и получает множество таблиц значений, задача состоит в том, чтобы можно было на форме отображать текущий процесс (скажем, через поле индикатора) обхода таблицы значений и выполнения дальнейших вычислений в другой серверной процедуре:
&НаКлиенте
Процедура ЗагрузитьДанные(Команда)
КолвоСтрок = ЗаполнитьТЗНаСервере();
Для i=0 По КолвоСтрок-1 Цикл
Счетчик = Счетчик + 1; //отображаем процесс через индикатор
ОбновитьОтображениеДанных();
ОбработкаСтрокиТЗНаСервере(i);
КонецЦикла;
КонецПроцедуры

вопрос в том, как сделать так, чтобы в процедуре ОбработкаСтрокиТЗНаСервере были доступны все ТЗ, сформированные и заполненные в серверной процедуре ЗаполнитьТЗНаСервере. Описывать все ТЗ в реквизитах объекта??? Проясните ситуацию знающие люди...

VZ 05.06.2015 10:42

ТЗ вообще на клиенте недоступна...
Отображение текущего состояния можно организовать разными способами. Например, разбить серверный модуль на куски, каждый раз возвращаясь в клиент, отображать промежуточное сообщение, и вызывать следующий серверный кусочек.
Можно еще использовать Состояние(), которое организует на клиенте собственную форму. Можно организовать прогрессор с пояснением, и даже с картинкой ;)

На инфостарте есть примеры. У Душелова, в частности.

Советую держать в уме, что все красивости, связанные с беганьем от сервера к клиенту и обратно, жрут связанные с этим ресурсы. Особо впечаляюще проявится когда серверная часть не на том же самом железе, что и клиент.

denisv 05.06.2015 10:53

Все таки вопрос остался не открытым, то как вывести текущее состояние в этом вопроса нет, я по сути так и делаю, вызываю из клиента серверные процедуры с выводом текущего прогресса, но вопрос в том, как сделать чтобы вторая серверная процедура имела доступ ко всем ТЗ, которые были порождены первой серверной процедурой? Если обработка достаточно длинная, порождает порядка 10 тысяч документов, оставлять пользователя перед статическим экраном считаю безрассудно.

denisv 05.06.2015 10:55

сорри, вопрос остался открытым...

VZ 05.06.2015 11:08

2-DenisV > Прогрессор уже не "статический экран": в правом нижнем углу всплывает форма, в котором отображается текст состояния. Возможно, и с полоской прогрессора.

"[em]как сделать чтобы вторая серверная процедура имела доступ ко всем ТЗ, которые были порождены первой серверной процедурой?[/em]" - передачу "всех ТЗ" через параметр не предлагать?

denisv 05.06.2015 11:11

4-VZ >Предлагать всё, а можно подробнее, про передачу параметром?

VZ 05.06.2015 11:33

5-DenisV > Не понял, "подробнее" это как? Цитировать Дональда Кнута? :)

denisv 05.06.2015 11:49

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

VZ 05.06.2015 11:57

7-DenisV > Верно. Клиент не может передать ТЗ, ибо на Клиенте не доступна (если Клиент не толстый). Да, ТЗ можно спрятать в Структуру, Массив. Во Временное Хранилище, опять же.

denisv 05.06.2015 13:07

Спасибо, тогда вопрос:
если передавать через параметр, и таблицы будут немаленькие по объему, а вызов процедуры будет большое количество раз, то передавать в качестве параметра одни и те же таблицы немалого размера с точки зрения оптимальности кода - не совсем изящное решение?
а если ТЗ реализовать через реквизиты обработки - это совсем кривое решение? Зато не потребуется одни и те же таблицы тягать между сервером и клиентом.

roma n 05.06.2015 13:57

[url]http://its.1c.ru/db/v8std#content:2149184291[/url]

denisv 05.06.2015 14:24

10-roma n >Спасибо, очень познавательно!

roma n 05.06.2015 15:22

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

USSR 08.06.2015 14:28

(1)А что за состояние(), которое организует собственную форму? Про форму не нашел ничего. Да и все равно с сервера состояние передаст только после окончания серверной процедуры, или я что-то пропустил?
(12)в порции данных далеко не все просто вписать
Могли бы разработчики платформы предусмотреть некий механизм обмена индикатором между сервером и клиентом, или это очень сложно технически ? я в этом просто мало понимаю

denisv 08.06.2015 14:47

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

roma n 08.06.2015 15:01

(12) а зачем "всё"? Для индикатора вполне достаточно одного значения, и нет никакой разницы на стороне клиента или сервера это значение вычисляется: обработал сотню записей, освежил значение в хранилище; обработал очередную сотню - опять в хранилище.
(14) [em]Процедура будет вызываться ТОЛЬКО в период ожидания системы[/em] - так когда исполнение идёт по технологии (10) - клиентская часть именно что находится в ожидании. И можно пользоваться как "родным" обработчиком ожидания, опрашивающим готовность результата длительной операции, так и отдельным собственным. Да, индикатор будет "дёргаться", а не плавно бежать, но это всяко лучше чем дёргать сервер для каждой итерации

denisv 08.06.2015 15:20

15-roma n >Ну если по технологии (10), то да, я думал обработкой ожидания в стандартном понимании

VZ 08.06.2015 22:36

13-USSR > Смотри в СП.

USSR 09.06.2015 07:49

(17)Говорю же, не нашел я. Только вот это

Состояние(<ТекстСообщения>, <Прогресс>, <Пояснение>, <Картинка>)
И формы тут нет никакой, и выполняется на клиенте

VZ 09.06.2015 09:38

18-USSR > Конечно, на клиенте. Кому на сервере нужны картинки? Форма - собственная, поделенная вот на эти четыре области:
ТекстСообщения - первая сверху область
Прогресс - область прогресса, под сообщением
Пояснение - самая нижняя область, под прогрессом
Картинка - крайняя левая область. Можешь собственную гифку.

Пример у Душелова на инфостарте.

Суть:
[em]&НаКлиенте
Функция ПолучитьИндикаторПроцесса(КоличествоПроходов, ПредставлениеПроцесса = "Выполнено", ВнутреннийСчетчик = Истина,
КоличествоОбновлений = 100, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина) Экспорт

Индикатор = Новый Структура;
Индикатор.Вставить("КоличествоПроходов", КоличествоПроходов);
Индикатор.Вставить("ДатаНачалаПроцесса", ТекущаяДата());
Индикатор.Вставить("ПредставлениеПроцесса", ПредставлениеПроцесса);
Индикатор.Вставить("ЛиВыводитьВремя", ЛиВыводитьВремя);
Индикатор.Вставить("РазрешитьПрерывание", РазрешитьПрерывание);
Индикатор.Вставить("ВнутреннийСчетчик", ВнутреннийСчетчик);
Индикатор.Вставить("Шаг", КоличествоПроходов / КоличествоОбновлений);
Индикатор.Вставить("СледующийСчетчик", 0);
Индикатор.Вставить("Счетчик", 0);
Возврат Индикатор;

КонецФункции

&НаКлиенте
Процедура ОбработатьИндикатор(Индикатор, Счетчик = 0) Экспорт

Если Индикатор.ВнутреннийСчетчик Тогда
Индикатор.Счетчик = Индикатор.Счетчик + 1;
Счетчик = Индикатор.Счетчик;
КонецЕсли;
Если Индикатор.РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;

Если Счетчик > Индикатор.СледующийСчетчик Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Если Индикатор.ЛиВыводитьВремя Тогда
ПрошлоВремени = ТекущаяДата() - Индикатор.ДатаНачалаПроцесса;
Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1);
Часов = Цел(Осталось / 3600);
Осталось = Осталось - (Часов * 3600);
Минут = Цел(Осталось / 60);
Секунд = Цел(Цел(Осталось - (Минут * 60)));
ОсталосьВремени = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
+ Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
+ Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН=");
ТекстОсталось = "Осталось: ~" + ОсталосьВремени;
Иначе
ТекстОсталось = "";
КонецЕсли;

Если Индикатор.КоличествоПроходов > 0 Тогда
ТекстСостояния = ТекстОсталось;
Иначе
ТекстСостояния = ""+Счетчик;
КонецЕсли;

Состояние(Индикатор.ПредставлениеПроцесса, Счетчик / Индикатор.КоличествоПроходов * 100, ТекстСостояния);
КонецЕсли;

Если Счетчик = Индикатор.КоличествоПроходов Тогда
Состояние(Индикатор.ПредставлениеПроцесса, 100, ТекстСостояния);
КонецЕсли;

КонецПроцедуры[/em]

В теле цикла делаешь так:
[em] ОчиститьСообщения();
Индикатор = ПолучитьИндикаторПроцесса(ЗаполненоСтрок,"Выполнено",,ЗаполненоСтрок,Ложь);
сч = 0;
Для Каждого строкаДанных Из ТабличнаяЧастьВладельца Цикл
//Обрабатываем строку как хотим
сч = сч+1;
ОбработатьИндикатор(Индикатор, сч);
КонецЦикла;[/em]

denisv 09.06.2015 10:17

19-VZ >Все эти методы клиентские, в строчке
Для Каждого строкаДанных Из ТабличнаяЧастьВладельца Цикл
здесь можно обрабатывать только объекты, доступные на клиенте
Все таки более универсально делать через (10)

VZ 09.06.2015 10:46

20-DenisV > Не спорю. Вообще что-то выводить можно только на клиенте.
Но у нас штатно с сервера есть только Сообщить(), СообщениеПользователю().
Т.е., хочешь что-то на экран - вылазь из сервера.

USSR 09.06.2015 13:01

"Т.е., хочешь что-то на экран - вылазь из сервера." - увы, это и так понятно. Ни в отладке толком посмотреть,ни пользователю хотя бы хоть что-то показать, чтобы он не нервничал. Как то не по человечески

VZ 09.06.2015 13:49

22-USSR > По человечески. по человечески :)
Племя декстопов с полным фаршем софта и приватными БД скукоживается, и это необратимо. Время виртуальных сетей, виртуальных серверов, и виртуальных БД. С легкими планшетами у конечных пользователей.

Привыкай.

USSR 09.06.2015 15:14

(23)Я уже столько раз ко всему привыкал ) Такие могучие усилия были потрачены, чтобы в конечном счете лечь под интернет. А через n-ое количестов лет опять случится виток эволюции, все сети станут сверх быстрыми и опять софт с серверов полезет на клиента. А потом обратно ) Огромные приложения ради того, чтобы сделать проводку Дт41.01 Кт60.01. Это как катерпиллером маленький огород прополоть ) Прогресс, мать его )

USSR 09.06.2015 15:22

Давайте все-таки вернемся к теме.
1 - какие есть реальные способы индикации на форме серверного процесса, кроме его "порционного" выполнения ?
2 - если по окончании процесса надо выдать отчет (табличный документ), то как лучше это организовать ? В серверных процедурах можно что-либо выводить в макет?

VZ 09.06.2015 16:23

1.(мысль) поискать методы генерации внешнего события. На клиенте ловить процедурой ВнешнееСобытие(Источник, Событие, Данные)
2. Можно. Ведь всяческие текстовые документы (из СФ, например) формируются на сервере.

roma n 09.06.2015 16:28

25-USSR > по поводу (2): табличный документ нормально мигрирует между клиентом и сервером.
Из существенных проблем с табдоком помню только одну: глюки с отображением на клиенте табличного документа сформированного на сервере если документ содержит группы строк/столбцов,- содержимое могло не отображаться до тех пор, пока не "передёрнуть" (свернуть-развернуть) какую-либо блокировку.

USSR 09.06.2015 16:54

С табличным уже документом разобрался, попробовал, но все равно спасибо всем ) Но вот увы (10) не могу прочесть, не партнер )

Reaper 09.06.2015 17:07

Коллеги, посмотрите как реализовано обновление данных ИБ после обновления конфигурации в БСП. Используется в любом актуальном релизе конфигураций 1С на управляемых формах.

Morrison 13.06.2015 13:15

2(29) Вот. Только собрался это написать, а уже есть :)

VZ 15.06.2015 13:10

29-Reaper > Хм... На форму повесить Обработку оповещения? А оповещать-то кто будет? Серверная процедура неспособна.
Но серверная процедура может видеть ЭтотОбъект...
ПодключитьОбработчикОжидания, чтоб реквизиты формы щупал периодически7

Reaper 16.06.2015 22:28

31-VZ > Обработчик ожидания должен щупать адрес во временном хранилище.


Текущее время: 11:28. Часовой пояс GMT +3.