Имя: Пароль:
1C
1С v8
Не модальный вопрос в цикле о прерывании загрузки прайса
, ,
0 kobzon2
 
12.03.20
10:56
Коллеги, натолкните на решение.
Есть обработка загрузки большого прайса. В цикле на клиенте добавлен код с возможностью в каждые нн шагов прервать загрузку.
Сделано все старинным методом Ответ=Вопрос("Прервать загрузку?",....
Понятно что напрашивается не модальный метод ПоказатьВопрос(Оповещение,...
Но тогда я же по-любому выхожу из цикла. Плюс окно с сообщением видимо не успевает закрыться и тоже зацикливается, хотя таймаут 2 секунды.
Что еще можно придумать, кроме оповещения, с добавлением процедуры ЗавершениеОповещения?
1 ДенисЧ
 
12.03.20
10:57
А ОбработкаПрерыванияПОльзователя() не катит?
2 kobzon2
 
12.03.20
11:04
(1) Катит в принципе. Правда вопрос о прерывании задается именно в определенные моменты, когда закончилась грузиться последняя строчка одной номенклатуры и готовится первая строчка другой.
А тут я получается обрываю там где получится. Последняя номенклатура наверное наполовину только загрузится.
3 Sasha_H
 
12.03.20
11:06
ПоказатьВопрос - не прекратит действие цикла, поскольку тело цикла продолжит свою работу - учим мат.часть!
4 Sasha_H
 
12.03.20
11:07
это делается совершенно иначе! Через оповещение событий  - к примеру обработка ожиданий длительных операций
5 Cthulhu
 
12.03.20
11:08
ПЕРЕД циклом: "ПоказатьВопрос(...)" и переменная модуля(!) "мОтвет = Ложь;"
В цикле проверять "Если мОтвет Тогда Прервать КонецЕсли;"
В обработчике ответа "Да" на выведенный вопрос - "мОтвет = Истина;"
6 Cthulhu
 
12.03.20
11:10
(+) если нужно - в цикле внутри "Если мОтвет Тогда ..." - доп.обработка ситуации без прерывания пока не выполнится это самое доп.условие.
7 pechkin
 
12.03.20
11:14
однако задача "вызвать асинхронную процедуру в цикле" - это практически задача олимпиадного уровня сложности
8 pechkin
 
12.03.20
11:15
по идее нужно из оповещения вызывать основную процедуру и передавать туда индекс с которого нужно начинать
9 Sasha_H
 
12.03.20
11:20
(5) - это ересь!!! Во-первых интерфейс зависнет и вопрос выйдет только в конце поскольку это асинхронная модель! Во-вторых даже если бы вопрос вышел то тело цикла будет продолжать загрузку.
10 Sasha_H
 
12.03.20
11:21
Да прекратите вы заниматся ерундой!!! Для этого есть обработки оповещений. Посмотри как работают загрузки. Это надо создавать фоновое задание и делать обработку оповещения!
11 kobzon2
 
12.03.20
11:23
(10) Какие загрузки посмотреть? Какие то типовые?
12 Sasha_H
 
12.03.20
11:24
(11) Открой БСП. Смысл в том. что тебе необходимо создавать ФоновоеЗадание у которого есть ответ и на форме объявляется обработка оповещения. Есть еще через взаимодействие делают (но я так не практиковал)
13 Sasha_H
 
12.03.20
11:25
на инфостарте полно обработок по типу. Прогресс бар при загрузке!
14 pechkin
 
12.03.20
11:27
(13) прогресс бар - это не вопрос
15 Sasha_H
 
12.03.20
11:29
учти тот факт, что эта модель совершенно другая! То есть у тебя будет идти загрузка и состояние процентов. Сделать модель по типу рандомный вопрос я во-первых не вижу смысла на хрена!!!! Поскольку прогрес бар это лучше вопроса и ты в любой момент можешь прервать загрузку!
16 pechkin
 
12.03.20
11:29
вот лови обработку с возможностью прерывания
17 pechkin
 
12.03.20
11:29
18 Sasha_H
 
12.03.20
11:29
в чем смысл вопроса? чтобы он как-то рандомно открылся, а если я хочу прервать загрузку уже!? как это сделать ждать вопроса!?
19 Sasha_H
 
12.03.20
11:32
Не накладывайте алгоритм обычных форм (не управляемых) на новую парадигму. Тут совершенно иначе все. Ненужно выдумывать костыль, когда логика приложения задумана по-другому!
20 pechkin
 
12.03.20
11:34
можно еще через фоновые делать, но тут сложнее будет
21 Sasha_H
 
12.03.20
11:34
(20) нужно делать черезз фоновые. В чем сложность !?
22 Sasha_H
 
12.03.20
11:34
(20) ответ в (12)
23 kobzon2
 
12.03.20
11:35
(15) Да понятно, что процесс будет в любом случае продолжаться, а оповещение только после этой процедуры отработает.
Будем значит обработкой прерывания делать.
Фоновое задание, оно же должно вызываться как можно чаще?
24 Александр Б
 
12.03.20
11:35
(2) Так ты вместо вопроса поставь обработку прерывания. И он тебе как раз и будет прерывать именно в этих местах. Никакой проблемы.
25 Sasha_H
 
12.03.20
11:35
(23) во-первых в такси интерфейсе не существует обработки прерывания
26 Александр Б
 
12.03.20
11:36
(25) Существует на клиенте.
27 Sasha_H
 
12.03.20
11:37
Примечание:
Прерывание работы встроенного языка возможно не во всех клиентских обработчиках управляемой формы.
28 Sasha_H
 
12.03.20
11:37
Доступность:
Тонкий клиент, веб-клиент, толстый клиент.
29 Sasha_H
 
12.03.20
11:38
загрузка делается где на сервере, что он там прерывать то собрался
30 Sasha_H
 
12.03.20
11:38
вообще что за интерфейс ОФ, УФ, Такси. тонкий или толстый клиент
31 unenu
 
12.03.20
11:39
(18) допустим есть загрузка неких данных в количестве 10 000 000 строк
каждые 100 000 грузятся час
хотелось бы поле загрузки очередных 100 000 спрашивать
"Если еще не вечер, то продолжим?"

как решить такой алгоритм на УФ?
Думаю реально если сначала нарисовать цикл и вызов оповещений на листике, учитывая что обработчики оповещения содержат доппараметры.
32 Александр Б
 
12.03.20
11:39
(29) Вопрос же рабоатет. Значит обработка выполняется на клиенте.
33 kobzon2
 
12.03.20
11:44
(32) Обработка делается на клиенте, читается excel файл. Далее уже передается структура на сервер.
Мне еще не нравится что каждая строка структуры гоняется на сервер. Это же замедляет работу. Или по фиг?
34 pechkin
 
12.03.20
11:45
держи на фоновых (требуется БСП)
http://catalog.mista.ru/public/943888/
35 Sasha_H
 
12.03.20
11:45
(34) На хрена там БСП!??? Читаем СП и все дела!
36 Sasha_H
 
12.03.20
11:47
(33) позвольте уточнить,  а как происходит отчитка ексель?
37 pechkin
 
12.03.20
11:47
(35) без бсп не запустишь код в фоновом из внешней обработки
38 Александр Б
 
12.03.20
11:48
(33) У тебя в чём вопрос сабжа стоит? Как уйти от вопроса. Обработка прерывания решает этот вопрос. Если нужно прервать - контрл брейк. Если не нужно - процедура будет крутиться до завершения.
Вопрос же не стоит в оптимизации самого алгоритма, а лишь в том, чтобы убрать эти интерактивные паузы.
39 Sasha_H
 
12.03.20
11:49
Так ведь в сотню раз проще все сделать. Правда код только на сервере и файл придется в хранилище на сервер передать

ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать("C:\My Documents\Таблица1.xls");
40 Sasha_H
 
12.03.20
11:49
(38) не будет он там ничего прерывать
41 Александр Б
 
12.03.20
11:50
(40) Учи матчасть.
42 Sasha_H
 
12.03.20
11:51
&НаСервереБезКонтекста
Процедура ЗагружаюДанныЕксельВБазу()

ОбработкаПрерыванияПользователь() // вызвет ошибку компиляциИ!!!
43 Sasha_H
 
12.03.20
11:51
(41) сам поучи прежде чем людям ахенею предлагать
44 Александр Б
 
12.03.20
11:52
(42) Какой сервер? Чтение из экселя на клиенте выполняется. Не пиши ахинею.
45 kobzon2
 
12.03.20
11:52
(36) Забыл, что уже переделал загрузку. Теперь копирую эксель таблицу и вставляю в табличное поле на форму обработки. Дальше циклом перебираю строки.
46 Александр Б
 
12.03.20
11:52
(43) Тебе в сабже написано, что обработка выполняется на клиенте. Пользователю вызывается вопрос, который тоже доступен только на клиенте. А значит замена вопроса на обработку прерывания будет гарантированно работать.
47 Sasha_H
 
12.03.20
11:53
(44) высер свой не предлагай людям, как ты на клиенте собрался сделать Номенклатура.Записать()?!
48 Александр Б
 
12.03.20
11:54
(47) Ты свой высер при себе оставь. Где ты видишь в сабже Номенклатура.Записать()?
49 kobzon2
 
12.03.20
11:54
(38) Если как вы пишите, будет прерывание в том месте, куда вставить вызов процедуры прерывания, тогда мне этот вариант вполне подходит. Просто останется объяснить пользователем, что кнопочки теперь не будет, а нужно нажать сочетание клавиш.
50 Garykom
 
гуру
12.03.20
11:55
(0) Делай по умному на фоновых задания.
51 kobzon2
 
12.03.20
11:55
(47) На сервер с клиента передается прочитанная строка в виде структуры, а там уже все записывается в базу.
52 Sasha_H
 
12.03.20
11:57
мда обработка мега оптимальная посмотрю
53 Sasha_H
 
12.03.20
11:58
Вам надо все переделать если эта обработка запускается в тонком клиенте
54 Александр Б
 
12.03.20
11:58
(51) Я бы порекомендовал сперва добавить таблицу на форму. Сперва на клиенте в неё все считать без обращений на сервер. А уже после чтения одним вызовом сервера обработать таблицу и записать все нужные данные.
55 pechkin
 
12.03.20
11:59
(52) разницы нет - весь файл ты стразу передаешь или частями по строкам
56 pechkin
 
12.03.20
11:59
если вызов безконтекстный то вполне норм
57 Garykom
 
гуру
12.03.20
12:01
(0)

1. файл с клиента отправляется на сервер
2. получается на сервер
3. на сервере грузится в нечто типа ТабДок или ТЗ
4. обрабатывается на сервере построчно или запросами

На каком этапе ты хочешь получить свое "прерывание" ?
58 Александр Б
 
12.03.20
12:02
(57) С чего ты взял, что у ТС файл с клиента отправляется на сервер?
59 Garykom
 
гуру
12.03.20
12:05
(58) Если он построчно дергает сервер то не понял в чем проблема?
60 Sasha_H
 
12.03.20
12:09
(57)  +
Я пытаюсь объяснить но не слушают!
61 Sasha_H
 
12.03.20
12:10
ЖЖЕСТь отчитать файл на форму и сожрать память сервера на форму  - мега круто для ПТушников самое оно!
62 Sasha_H
 
12.03.20
12:11
(0) Автор у Вас это тонкий клиент!?
63 kobzon2
 
12.03.20
12:42
(62) Тонкий
64 Sasha_H
 
12.03.20
12:49
(63) Тогда сделайте по уму. как я и (57) говорили!
65 kobzon2
 
12.03.20
12:51
(64) Попробую. Прирост скорости загрузки прайса обеспечен?
66 dezss
 
12.03.20
12:58
(65) Но учти, что тогда прерывания не будет.
Хотя я сам не понимаю, в каком случае оно нужно.
67 Sasha_H
 
12.03.20
12:58
(65) Смотри сделай так:
1. передаеь файл на серевер потом
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать("C:\My Documents\Таблица1.xls");

вот тебе твой ексель весь в Табличном документе.

Если тебе принципиально важен вопрос тогда придется помахаться.

Для этого необходимо табличный документ поместить в таблицу значений. Дальше во время загрузки в процедурах загрузки через параметры ты передаешь например задать вопрос через Н строк.
Когда счетчки доходит перебирая ТЗ до этой строки  - сохраняешь это все дело во временное хранилище. ТЗ и параметры на какой строке ты остановился. Обрываешь код тем самым отслежываешь выход из процедуры и задаешь вопрос. Но тут следует немножко круче сделать. А именно не ПоказатьВопрос, а открытьФорму, где у тебя будет параметр Продолжить загрузку на n-строк и вывести вопрос или Прервать вообще или продолжить загрузку до конца не задавая больше вопросов. Все это упаковываешь в параметры.
68 Sasha_H
 
12.03.20
13:03
При этом у тебя процедуры/функции разделяться на отдельные.
ПрочитатьЭксель() возвращает адрес временного хранилища.

ОбработатьТаблицуДанных()  
в которой ты отчитываешь адрес во временном хранилище где у тебя там структура ЗадатьВопросЧерезНСтрок, ТекущийСчетчик, ТаблицаЗначений
69 Sasha_H
 
12.03.20
13:04
это просто я навожу на мысли в процессе реализации все это закрутится и усовершенствуется
70 Sasha_H
 
12.03.20
13:06
Можно попробовать сэконоимить память и ТаблицуЗначений не получать, а именно работать с табличным документом и его помещать во временное хранилище. И уже с помошью счетчиков перемещаться по областям
71 kobzon2
 
12.03.20
13:07
(69) Ага, спасибо за наводки. Код давно пора оптимизировать, а то колхоз какой то..
72 Sasha_H
 
12.03.20
13:07
Только помещаешь во временное хранилище РАЗОВО, а счетчиик можно через параметры функции ганять
73 pechkin
 
12.03.20
13:11
(68) реализация подобного в (17)
74 Sasha_H
 
12.03.20
13:13
(73) только уходит большая потеря на индикацию это дергать сервер-клиент плохая идея
75 pechkin
 
12.03.20
13:14
(74) тесты говорят об обратоном.
безконтекстный вызов достаточно легко дается
76 Garykom
 
гуру
12.03.20
13:39
(74) Зато можно во много потоков данные грузить если строчки независимы в прайсе.
И если сервер 1С это дело поддерживает с много потоков на много rphost.
77 kobzon2
 
13.04.20
09:11
Столкнулся с похожей задачей, в которой нужно в цикле, давать выбор пользователю.
Только я смирился с асинхронностью оповещений, раздробленных несколько процедур, как вдруг понял что с циклом у меня ничего не получается в таком контексте.

Посмотрел реализации прогресс бара с использованием обработок оповещения и фоновым заданием, но так и не понял как это можно применить в моём случае. И возможно ли это?
Объявление глобальных переменных и возврат вновь в первичную процедуру, тоже результата особого не дает. Сначала проходит весь цикл, а потом только отрабатывают оповещения с вопросом выбора.

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

&НаКлиенте
Процедура1()

/// какие то действия

Для Каждого Артикул Из СписокТоваров Цикл //перебираем список необходимых товаров
   ВыгрузкаОписания(Артикул)
КонецЦикла;

/// еще какие то действия

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

//////////////////

&НаКлиенте
Процедура ВыгрузкаОписания(Артикул)

СписокОписаний = ПолучитьОписанияТовара(Артикул); // получаем список описаний. На каждый товар может быть одно, а может и несколько
Если СписокОписаний.Количество()  > 1 Тогда

   Для Каждого Элемент Из СписокОписаний Цикл
         Товары = Новый СписокЗначений;        
     Товары.Добавить(Элемент);        
   КонецЦикла;    
    
ОповещениеПослеВыбораЭлемента = Новый ОписаниеОповещения("СоздатьШаблон", ЭтотОбъект);
Товары.ПоказатьВыборЭлемента(ОповещениеПослеВыбораЭлемента,"Выберите товар для артикула " + Артикул); // Спрашиваем пользователя какое описание выбрать

КонецЕсли;

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

///////////////

&НаКлиенте
Процедура СоздатьШаблон(Элемент, Параметры) Экспорт)
Если Элемент <> Неопределено Тогда
///  выгружаем выбранное описание
КонецЕсли;
КонецПроцедуры
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой