Имя: Пароль:
1C
1С v8
8.2 УФ множественный вызов ПриАктивацииСтроки
0 Aswed
 
20.09.12
12:17
Уже пару лет сталкиваюсь с подобной проблемой и всё жду когда её решит 1С.

Когда вешаешь обработку на предопределенную процедуру ПриАктивацииСтроки, то если в этом обработчике делать процедуру на сервере система уходит в бесконечный цикл. Вызвано тем что если происходит выполнение какой либо процедуры на сервере то происходит перерисовка формы и опять вызывается процедура при активации строки и так до бесконечности.

Вот тема год назад была.

v8: ПриАктивизацииСтроки в УФ.

Собственно кто как обходит такую проблему?
1 Жан Пердежон
 
20.09.12
12:21
сохранять номер ранее активированной строки и сверяться с ним?
2 Aswed
 
20.09.12
12:23
Можно, но где сверяться тогда?

Если опять в той же при активации то опять зацикливание.
3 aleks-id
 
20.09.12
12:24
в СП даже написали "В обработчике данного события нельзя использовать серверные методы формы с директивой компиляции &НаСервере."
4 Aswed
 
20.09.12
12:25
(3) ну да.
А альтернативу не предложили.
5 ChAlex
 
20.09.12
12:26
(0) - решение: в обработчике ПриАктивацииСтроки вешаете ПодклчитьОбработчикОжидания - в котором указываете процедуру, которую надо выполнить. В таком режиме не получал циклов
6 Aswed
 
20.09.12
12:26
Я обработчик ожидания даже вешать пытался
всё равно сволочь при срабатывании обработчика опять проскакивает процедура ПриАктивацииСтроки
7 Aswed
 
20.09.12
12:27
(5)

&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
   
   Если Элементы.Список.ТекущиеДанные <> Неопределено Тогда
       ПодключитьОбработчикОжидания("ОбработчикФормированияЦенКомплектаций", 0.1, Истина);
   КонецЕсли;
           
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикФормированияЦенКомплектаций()
   
   Если Элементы.Список.ТекущаяСтрока <> Неопределено Тогда
       ПрочестьКомплектацииМодели(Элементы.Список.ТекущаяСтрока);
   КонецЕсли;
   
КонецПроцедуры

&НаСервере
Процедура ПрочестьКомплектацииМодели(ТекущаяМодель);
   
   Если НЕ ТекущаяМодель.ЭтоГруппа() Тогда
       
   КонецЕсли;
       
КонецПроцедуры


У меня зацикливается с таким кодом.
Где накосячил?
8 Aswed
 
20.09.12
12:29
(5) Поделись кодом
9 aleks-id
 
20.09.12
12:30
давай для начала разберемся что ты хочешь вывести
открой УНФ и погляди как там реализовали в ЗаказеПокупателя в ФормаСпискаДокументов заполнение и вывод различной информации по заказу
10 ChAlex
 
20.09.12
12:30
а вот нафиг повторно проверять

&НаКлиенте
Процедура ОбработчикФормированияЦенКомплектаций()
   
   Если Элементы.Список.ТекущаяСтрока <> Неопределено Тогда
       ПрочестьКомплектацииМодели(Элементы.Список.ТекущаяСтрока);
   КонецЕсли;
   
КонецПроцедуры


достаточно

&НаКлиенте
Процедура ОбработчикФормированияЦенКомплектаций()
   
   ПрочестьКомплектацииМодели(Элементы.Список.ТекущаяСтрока);
   
КонецПроцедуры

только вод передавать нужно бы не текущую строку а ссылку
11 ChAlex
 
20.09.12
12:31
Элементы.Список.ТекущаяСтрока - номер текущей строки, боюсь потом еще на сервере ей значение присваивается
12 ChAlex
 
20.09.12
12:32
на сервере не должно быть перепозиционирования текущейстроки таблицы
13 ChAlex
 
20.09.12
12:32
иначе - да вечный цикл.
14 Aswed
 
20.09.12
12:33
(11) Кстати да, возможно дело в этом, сейчас попробую.
15 Aswed
 
20.09.12
12:34
(12) да я на сервере вообще ещё ничего не писал)
16 aleks-id
 
20.09.12
12:36
(15) что ты хочешь получить на выходе? задачу озвучь!
17 Aswed
 
20.09.12
12:37
(16) Есть справочник.
Надо что бы при позиционированнии на каждом элементе этого справочника внизу выводились цены для этого элемента.
18 ChAlex
 
20.09.12
12:39
(17) - ну чего тут военного, все работает для такого режима как надо
19 ChAlex
 
20.09.12
12:40
даже если память не изменяет в видеокурсе Гилева - точь в точь такой пример приводится
20 aleks-id
 
20.09.12
12:40
(17) смотри как в УНФ сделано!!!
там на форме списка таблица - динамический список. запросом тянет все нужные данные. в твоем случае еще и цену. рядом лежит реквизит формы, у которого путь к данным = колонка дин.списка с ценой. все!
21 Aswed
 
20.09.12
12:40
(19) Да в том то и дело, что делал такое уже.
А вот сейчас не могу вспомнить как сотворил))))
22 Aswed
 
20.09.12
12:40
(20) Ок, после обеда гляну)
23 aleks-id
 
20.09.12
12:41
(22) не пользуй обработчики событий. сделай по феншую
24 ChAlex
 
20.09.12
12:47
(20) решение спорное - вернее вопрос, данные по ценам уже получены, их можно видеть в колонке, зачем еще раз отдельно отображать цену? - ну да можно извращаться, ради некой красоты, вот функциональность такого решения как-то не совсем интуитивно понятна. Другой вопрос если цены не получаются сразу в динамическом списке( скажем экономим какое-то время на поддержание их получения в запросе или по иным причинам) - тогда вот как раз и решение - отображать только тогда, когда спозиционируешь на нужную строку. Но - это дело вкуса. Второе решение: тот же реквизит на форме с отображением цены, вызов функции на сервере для получения цены и запись в реквизит - и все.
25 aleks-id
 
20.09.12
12:49
(24) сейчас открыл базу с курсов по УФ - там такое же решение. динамический список и реквизит формы с данными из ДС
26 ChAlex
 
20.09.12
12:59
(25) - да я ж не спорю по поводу того что так можно сделать, именно в данном случае у меня больше вопрос а зачем? еще отдельно показывать цену. Ну может где-то это и акцентирует внимание, но как-то не очень эргономично - приходится отвлекаться - то на строчку поиска, то в место где отображается цена, может просто разместит колонку в нужном месте (например после наименования) - как-то такое решение мне личнео ближе.
27 ChAlex
 
20.09.12
13:03
+(26) - то есть если цены получаются динамическим списком - то их можно сразу видеть в списке и ничего больше можно не предпринимать (нет необходимости отображать отдельно) , а если данные по ценам не получаются в динамическом списке - то тут как раз уместно решение с отображением цены по текущей позиции отдельно на форме.
28 toypaul
 
гуру
20.09.12
13:04
использовал все советы из перечисленных здесь запоминал обработанную строку и подключал обработчик ожидания
29 acsent
 
20.09.12
13:05
1с говорить что нужно запоминать сосотяние и уже повторный раз не вызывать действий при активизации
30 Aswed
 
20.09.12
14:03
(26) Тут подход другой. У модели автомобиля может быть множество комплектаций(полчиненный справочник) и для каждой из них уникальная цена. Вот и хочу выводить в отдельном окне все комплектации данной модели и цену этой комплектации.
31 ChAlex
 
20.09.12
14:08
(30) - лишний раз убеждаюсь в том что раньше писал: ваши же слова "Вот и хочу выводить в отдельном окне все комплектации данной модели и цену этой комплектации." - логика сразу ломается "все комплектации" и "цену это комплектации" - как комплектации - то множественное число, а как цену то почему-то применительно к комплектации - единственное. А не лучше ли вывести и комплектации и цены сразу в одной таблице и не надо при этом бегать по таблице, что бы видеть цену конкретной. А кроме того и сравнивать лучше. Разве нет?
32 Aswed
 
20.09.12
14:11
(31) ))))
там два справочника, для обоих хочу сделать такую плюшку
Один Автомобили - у него только одна комплектация
Второй Модели - у него их неограниченное количество

Делать для одного один вид для второго другой не хочется.
33 Aswed
 
20.09.12
17:08
(20) А где такое в УНФ?
Я что то не найду.
34 Rounder
 
20.09.12
17:15
(33) Может я не совсем понял задачу.
А где цены хранятся на ту номенклатуру, при активизации строки с которой нужно ее отображать (цену в смысле)?
35 Йюхйюх
 
20.09.12
17:16
Странно, у меня все работает и никакого зацикливания нет.

&НаКлиенте
Процедура ОбъектыНедвижимостиПриАктивизацииСтроки(Элемент)                              
   
   Если НЕ Элементы.ОбъектыНедвижимости.ТекущаяСтрока = Неопределено Тогда
       
       ПрочитатьОбщуюИнформациюПоОбъектуСделкиНаСервереШапка();
       
   КонецЕсли;

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

&НаСервере
Процедура ПрочитатьОбщуюИнформациюПоОбъектуСделкиНаСервереШапка()
........
КонецПроцедуры
36 Aswed
 
20.09.12
17:17
(34) В регистре сведений конечно
37 Йюхйюх
 
20.09.12
17:20
+(35) 1С:Предприятие 8.2 (8.2.15.301)
38 Rounder
 
20.09.12
17:20
(36) Ну тогда что мешает сделать в форме списка справочника еще и динамический список с основной таблицей ТвойРегистрСведений.
А при активизации строки просто на него накладывать определенный отбор?
39 Стальная Крыса
 
20.09.12
17:20
(0) я решил с применением "флага" (булевый реквизит формы).

Процедура ПроцПриАктивизацииСтроки(Элемент)

 Если ФлагОбработкаАктивизацииСтроки тогда
   Возврат;
 КонецЕсли;
   
 ФлагОбработкаАктивизацииСтроки = Истина;

 // здесь любой код обработчика

 ФлагОбработкаАктивизацииСтроки = Ложь;

КонецПроцедуры
40 Йюхйюх
 
20.09.12
17:20
(36)(38) Ребята, в чем проблема?
Тупо читаю заголовок темы, смотрю у себя в конфе - все работает без зацикливаний.
Что у меня не так?
41 Aswed
 
20.09.12
17:22
(38) Ну я это же и хочу сделать))))
а мешает то что постоянно идёт зацикливание ПриАктивацииСтроки
42 Rounder
 
20.09.12
17:22
(40) Нет у меня с этим проблем. Просто пытаюсь помочь человеку
43 Aswed
 
20.09.12
17:22
(39) Ну я так же сейчас сделал, но как то не нравится мне такое решение)
Не по феншую оно))))
44 Йюхйюх
 
20.09.12
17:23
Почему вот это работает и нет никаких зацикливаний?

&НаКлиенте
Процедура ОбъектыНедвижимостиПриАктивизацииСтроки(Элемент)                                  
   
   Если НЕ Элементы.ОбъектыНедвижимости.ТекущаяСтрока = Неопределено Тогда
       
       ПрочитатьОбщуюИнформациюПоОбъектуСделкиНаСервереШапка();
       
   КонецЕсли;

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

&НаСервере
Процедура ПрочитатьОбщуюИнформациюПоОбъектуСделкиНаСервереШапка()
   
   АктивнаяСтрока = Объект.ОбъектыНедвижимости.НайтиПоИдентификатору(Элементы.ОбъектыНедвижимости.ТекущаяСтрока);
   
   СсылкаНаНедвижимость = АктивнаяСтрока.ОбъектНедвижимости;
                             
   Запрос = Новый Запрос;
   Запрос.УстановитьПараметр("Ссылка", СсылкаНаНедвижимость);
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ПлощадиОбъектовНедвижимости.ОбщаяПлощадь,
   |    ПлощадиОбъектовНедвижимости.ЖилаяПлощадь,
   |    ПлощадиОбъектовНедвижимости.ПлощадьКухни,
   |    ПлощадиОбъектовНедвижимости.КоличествоЖилыхКомнат,
   |    ПлощадиОбъектовНедвижимости.ПлощадиЖилыхКомнат,
   |    УсловияПродажиОбъектов.КоличествоКомнатДляПродажиАренды,
   |    ПравообладателиОбъектов.Контрагент КАК КонтрагентПравообладатель
   |ИЗ
   |    Справочник.УПН_ОбъектыНедвижимости КАК ОбъектыНедвижимости
   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.УПН_ПлощадиОбъектовНедвижимости.СрезПоследних(, ОбъектНедвижимости = &Ссылка) КАК ПлощадиОбъектовНедвижимости
   |        ПО (ПлощадиОбъектовНедвижимости.ОбъектНедвижимости = ОбъектыНедвижимости.Ссылка)
   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.УПН_УсловияПродажиОбъектов.СрезПоследних(, ОбъектНедвижимости = &Ссылка) КАК УсловияПродажиОбъектов
   |        ПО ОбъектыНедвижимости.Ссылка = УсловияПродажиОбъектов.ОбъектНедвижимости
   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.УПН_ПравообладателиОбъектов.СрезПоследних(, ОбъектНедвижимости = &Ссылка) КАК ПравообладателиОбъектов
   |        ПО ОбъектыНедвижимости.Ссылка = ПравообладателиОбъектов.ОбъектНедвижимости
   |ГДЕ
   |    ОбъектыНедвижимости.Ссылка = &Ссылка";
   
   Результат = Запрос.Выполнить();
   Выборка = Результат.Выбрать();
   
   Если Выборка.Следующий() Тогда
               
       ОбщаяПлощадь                     = Выборка.ОбщаяПлощадь;
       ЖилаяПлощадь                     = Выборка.ЖилаяПлощадь;
       ПлощадьКухни                     = Выборка.ПлощадьКухни;
       КоличествоЖилыхКомнат             = Выборка.КоличествоЖилыхКомнат;
       ПлощадиЖилыхКомнат                 = Выборка.ПлощадиЖилыхКомнат;
       КонтрагентПравообладатель         = Выборка.КонтрагентПравообладатель;
       КоличествоКомнатДляПродажиАренды = Выборка.КоличествоКомнатДляПродажиАренды;        
       
   Иначе
       ОбщаяПлощадь                     = "";
       ЖилаяПлощадь                     = "";
       ПлощадьКухни                     = "";
       КоличествоЖилыхКомнат             = "";
       ПлощадиЖилыхКомнат                 = "";
       КонтрагентПравообладатель         = "";
       КоличествоКомнатДляПродажиАренды = "";

   КонецЕсли;
   
   ЗаполнитьЗдание();
   
КонецПроцедуры
45 Rounder
 
20.09.12
17:23
Вот это работает у меня - без зацикливаний.

&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
   УстановитьОтборТЧ(СоответствиеПодразделений, "Подразделение", Элемент.ТекущаяСтрока, ВидСравненияКомпоновкиДанных.Равно);
КонецПроцедуры

&НаКлиенте
Процедура УстановитьОтборТЧ(ТЧ, ЛевоеЗначение, ПравоеЗначение, СравнениеВид)
   ТЧ.Отбор.Элементы.Очистить();
   ЭлементОтбора = ТЧ.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
   ЭлементОтбора.Использование = Истина;
   ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ЛевоеЗначение);
   ЭлементОтбора.ПравоеЗначение = ПравоеЗначение;
   ЭлементОтбора.ВидСравнения = СравнениеВид;
КонецПроцедуры
46 Aswed
 
20.09.12
17:23
(44) Это и пытаюсь выяснить))))
47 Стальная Крыса
 
20.09.12
17:25
Ну может версия 1С ?

я еще живу на 8.2.13...
48 Aswed
 
20.09.12
17:26
думаю над этим как раз
я на 8.2.16.362
49 Aswed
 
20.09.12
17:27
Кстати что лучше сделать.
Набор записей регистра и ставить отбор или лучше динамический список с условием сделать?
50 Aswed
 
20.09.12
17:27
+49 что быстрее работать будет?
51 Rounder
 
20.09.12
17:27
Если сделать как в (45) - тоже циклит?
52 Йюхйюх
 
20.09.12
17:27
(48) не знаю в чем у тебя проблема.
Я даже не знал, что если в при активизации вызвать сервер, то должно быть зацикливание )))))

И написал вызов сервера и все работает :)))
53 Aswed
 
20.09.12
17:28
(51) Да
И через обработчик ожидания циклит и просто так тоже циклит.
54 Aswed
 
20.09.12
17:28
(52) )))))
55 _Demos_
 
20.09.12
17:29
а может дело в том что не надо трогать данные на форме и никаких зацикливаний не будет?
56 Йюхйюх
 
20.09.12
17:31
(54)(55) правда реквизиты на форме, которые заполняет ПрочитатьОбщуюИнформациюПоОбъектуСделкиНаСервереШапка из ПриАктивизации, не являются реквизитами, имеющими ссылки на объект. Это просто реквизиты формы.
57 Стальная Крыса
 
20.09.12
17:32
(55) это конечно так, но в том-то и закавыка, что нужно данные "трогать"
58 Aswed
 
20.09.12
17:33
(57) +1
а именно обновлять один из списков на этой форме)
59 ChAlex
 
20.09.12
18:19
(58)- а что значит обновлять один из списков? и попутно зачем?
60 Стальная Крыса
 
20.09.12
18:27
(59) например есть некий "инструмент" - очень пользователям пришелся по душе.
окно разделено на 3 области (некая "студийность")
1. левая вертикальная область (узкая), "статьи бюджета";
2. правая область:
 верхняя часть "мероприятия" выбранной статьи,
 нижняя часть: "детализация" выбранного мероприятия.

получается мне в двух местах "активизацию строки" нужно отработать.

когда нарвался на "залипы" долго не мог сообразить - в чем собака порылась...
61 Cervantes
 
20.09.12
18:37
Добавлю немного маслица.
У меня работает в УТ 11 начиная с 15.301 точно...В списке заказов поставщикам снизу выводится информация о номенклатуре заказа при активизиции строки. Ничего не зацикливается.


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
   Элементы.СоставНоменклатуры.Заголовок = ПолучитьСписокНоменклатурыЗаказа(Элемент.ТекущиеДанные.Ссылка)
КонецПроцедуры

&НаСервере
Функция  ПолучитьСписокНоменклатурыЗаказа(ЗаказСсылка)
   СтрокаНоменклатуры = "";
   ОбъектЗаказ = ЗаказСсылка.ПолучитьОбъект();
   Для каждого стр из ОбъектЗаказ.Товары Цикл
       СтрокаНоменклатуры = СтрокаНоменклатуры + СокрЛП(Стр.Номенклатура)+ ", ";
   КонецЦикла;    
   Если СтрокаНоменклатуры <> "" Тогда
       СтрокаНоменклатуры = Лев(СтрокаНоменклатуры,СтрДлина(СтрокаНоменклатуры)-2);
   КонецЕсли;
   Возврат СтрокаНоменклатуры;
КонецФункции
62 ChAlex
 
20.09.12
18:41
(60) - вообще-то в такой схеме легче нарваться на неотработку актвизации строки, чем на зацикливания
63 ChAlex
 
20.09.12
18:46
Работает все без всякого зацикливания 100 пудов. Если в форме несколько таблиц и вызовы сервера и еще какая нибудь хрень с формами, то достаточно просто отсечь лишние вызовы неактивных таблиц при перерисовках форм таким кодом:

&НаКлиенте
Процедура СписокОтбораОрганизацияПриАктивизацииСтроки(Элемент)
   Если ЭтаФорма.ТекущийЭлемент=Элемент Тогда
       ПодключитьОбработчикОжидания("УстановитьОтборОрганизация",0.1,Истина);
   КонецЕсли;
КонецПроцедуры
64 Aswed
 
21.09.12
09:25
Вопрос решился удалением одной строки
Как она влияла на это зацикливание не представляю.
Удалил проверку на группу

Если НЕ ТекущаяМодель.ЭтоГруппа() Тогда
       
   КонецЕсли;


Работающий код

&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
   
   Если Элементы.Список.ТекущиеДанные <> Неопределено Тогда
       ПодключитьОбработчикОжидания("ОбработчикФормированияЦенКомплектаций",0.1, Истина);
   КонецЕсли;
           
КонецПроцедуры

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

&НаСервере
Процедура ОбновитьСписокКомплектаций()
   
   КомплектацииИЦены.Параметры.УстановитьЗначениеПараметра("Модель", Модель);
   Элементы.КомплектацииИЦены.Обновить();
       
КонецПроцедуры
65 IamAlexy
 
21.09.12
09:31
(0) ее не будут решать..
обсасывали же уже 100500 раз

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

http://partners.v8.1c.ru/forum/thread.jsp?id=751564#751564

от официалов:

"Я писал в другой теме. Запомните в модуле переменную (&НаКлиенте) со значением свойства ТекущаяСтрока для которого Вы в последний раз вызывали обработчик. Если при новом вызове значение не поменялось, то ничего делать не надо. Я уже писал выше, что платформа не может это сделать автоматически, поскольку тому же самому значению ТекущаяСтрока могут соответствовать уже другие данные. Если Вы как разработчик знаете что список не изменился, то этот простой приём решает проблему."



"Да, мы не считаем возможно лишние вызовы данного события проблемой. Мы считаем большей проблемой отсутствие вызовов когда они могут понадобиться. В принципе, платформа могла бы автоматически не генерировать событие для таблицы после возврата с сервера нового описания формы, если предыдущий вызов осуществлялся для той же самой строки. Но это не всегда будет корректно. Платформа не может отследить и правильно интерпретировать все те изменения, которые произошли в форме в процессе серверного вызова. Возможно поменялся источник данных таблицы, возможно тому же самому идентификатору, содержащемуся в свойстве ТекущаяСтрока соответствуют совсем другие данные.  Мы считаем более правильным предоставить разработчику возможность обработки этого события при пересоздании формы."

ну и еще есть сотня веток на подобную тему
66 IamAlexy
 
21.09.12
09:35
а вот еще про бесконечную рекурсию вызовов которая в (0):

http://partners.v8.1c.ru/forum/thread.jsp?id=812317#812317


"От жеж Фома неверующий... :) Читаем синтакс-помощник. Там русским по белому написано:
--------------------------------------------------------------
ТаблицаФормы.ПриАктивизацииСтроки (FormTable.OnActivateRow)
ТаблицаФормы (FormTable)
ПриАктивизацииСтроки (OnActivateRow)
Синтаксис:
ПриАктивизацииСтроки()

Описание:
Вызывается при активизации строки таблицы.

Примечание:
В обработчике данного события нельзя использовать серверные методы формы с директивой компиляции &НаСервере.
--------------------------------------------------------------
Если на это забить - то как раз и получим целый букет разнообразнейших глюков,  среди которых может быть и постоянный вызов обработчика. Проверено на свей шкуре. :) Так что дело совершенно точно в этом. Только сформулировано пожалуй не совсем корректно, точнее несколько туманно: из того, что указана директива &НаСервере следует не то, что запрещены вообще серверные вызовы, а то что запрещены именно контекстные серверные вызовы, но бесконтекстные не запрещены. Весьма неочевидная тонкость."
67 IamAlexy
 
21.09.12
09:36
(66) кстати о бесконтекстных  - собственно как раз таки очевидная тонкость ибо форма не передергивается и  события формы не возникают...
AdBlock убивает бесплатный контент. 1Сергей