Переключение на Главную Страницу Страницы: 1 ... 3 4 [5] 6 7 ... 11 ОтправитьПечать
Очень популярная тема (более 25 ответов) Перехватчик. Для каких событий необходим ручной вызов оригинального? (число прочтений - 71540 )
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #60 - 16. Декабря 2010 :: 07:08
Печать  
Dmitry The Wing писал(а) 16. Декабря 2010 :: 07:03:
Самое странное то, что я не использую перехват событий формы. Добавил включение на будущее ... т.е. на данный момент единственное событие формы, которое перехватываю - это СобытиеГМ_СозданиеКонтекста.

Видимо, придется вернуться к использованию перехвата СобытиеГМ_ПриОткрытии.

1. Кури свой код, явно что-то не так Печаль
Перехватчик используют достаточно много людей, проблемы с явными вылетами из-за ошибок реализации Перехватчика давно не выявлялись..
2. события с префиксом "СобытиеГМ_" - это не события формы, это глобальные события.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #61 - 16. Декабря 2010 :: 07:21
Печать  
artbear писал(а) 16. Декабря 2010 :: 07:08:
1. Кури свой код, явно что-то не так Печаль

Вот список всего, что перехватывает основной перехватчик (Фабрика событий):
  • СобытиеГМ_ПриУдаленииДокумента
  • СобытиеГМ_ПриИзмененииВремениДокумента
  • СобытиеГМ_ПриОтменеПроведенияДокумента
  • СобытиеГМ_ПриЗавершенииРаботыСистемы
  • СобытиеГМ_Событие_НеобработаннаяОшибка
  • СобытиеГМ_Событие_ЗаписьСобытияЖурналаРегистрации
  • СобытиеГМ_Событие_ЗаписьПользовательскогоСобытияЖурналаРегистрации

Реально в работе используются только последние 4.
Глюки с отчетами появляются только при включении перехвата событий СобытиеГМ_СозданиеКонтекста или СобытиеГМ_ПриОткрытии.
Для пробы включал еще перехват событий:
  • Событие_ПриОткрытии
  • Событие_ПослеОткрытия
  • Событие_ПриЗаписи
  • Событие_ПриВыбореЗакладки
  • Событие_ПриИзмененииРазмераОкна
  • Событие_ПриЗакрытии

Все прекрасно работало, кроме глюка с позиционированием при включении перехвата Событие_ПриИзмененииРазмераОкна.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #62 - 16. Декабря 2010 :: 07:49
Печать  
Ну и попробуй понять, в какой момент 1С падает, потестируй, если есть желание.
Кроме тебя, ни у кого подобных вылетов в последнее время не отмечено Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #63 - 16. Декабря 2010 :: 07:54
Печать  
artbear писал(а) 16. Декабря 2010 :: 07:49:
Ну и попробуй понять, в какой момент 1С падает, потестируй, если есть желание.
Кроме тебя, ни у кого подобных вылетов в последнее время не отмечено Улыбка

Оно падает при формировании отчета или при нажатии кнопки "настройка". Т.е. не зная, чего в тот момент происходит внутри - большего сказать не могу ...

При этом может успеть успешно сформироваться до десяти отчетов, но может упасть и на третьем...

Если отчеты не формировать вообще - обычно не падает в течении дня. Дольше я сессию не держу.

Еще меня смущает отсутствие вызовов деструктора перехватчика...
  
Наверх
 
IP записан
 
zk96
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 320
Местоположение: Киев
Зарегистрирован: 15. Ноября 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #64 - 16. Декабря 2010 :: 08:18
Печать  
Пользуюсь перехватчиком, почти всеми событиями, проблем не было.
Выложи тестовую конфигурацию.
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #65 - 16. Декабря 2010 :: 08:22
Печать  
zk96 писал(а) 16. Декабря 2010 :: 08:18:
Пользуюсь перехватчиком, почти всеми событиями, проблем не было.
Выложи тестовую конфигурацию.

Боюсь, что это может зависеть от используемых отчетов, а типовые отчеты в тест запихать будет непросто.
Лучше я покажу свой код данного перехвата:
Код
Выбрать все
Процедура ВключитьПерехватСобытийГК(Конт = "") Экспорт
	Если ТипЗначенияСтр(Конт) = "ГрупповойКонтекст" Тогда
		КонтФормы = Конт;
	КонецЕсли;
	Перехватчик = СоздатьОбъект("Перехватчик");
	Перехватчик.ПерехватитьСобытияГК(КонтФормы, Контекст);
КонецПроцедуры  // ВключитьПерехватСобытийГК

Функция СобытиеГМ_СозданиеКонтекста(Конт) Экспорт
	Сам = Сам(Контекст);
	Рез = 1;

	Если ТипЗначенияСтр(Конт) <> "ГрупповойКонтекст" Тогда
		Возврат 1;
	КонецЕсли;

	ПерехватчикСобытийФормы = СоздатьОбъект(ТипЗначенияСтр(Сам));
	Для Сч = 1 По СписокКлассовПодписчиков.РазмерСписка() Цикл
		КлассПодсистемы = СоздатьОбъект(СписокКлассовПодписчиков.ПолучитьЗначение(Сч));
		КлассПодсистемы.ПодписатьКлассНаСобытияФабрики(ПерехватчикСобытийФормы);
	КонецЦикла;
	ПерехватчикСобытийФормы.ВключитьПерехватСобытийГК(Конт);

	Возврат Рез;
КонецФункции // СобытиеГМ_СозданиеКонтекста
 

Может так будет видна ошибка?
  
Наверх
 
IP записан
 
zk96
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 320
Местоположение: Киев
Зарегистрирован: 15. Ноября 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #66 - 16. Декабря 2010 :: 10:06
Печать  
А попробуй так.
  

_________002.ert ( 55 KB | Загрузки )
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #67 - 16. Декабря 2010 :: 12:39
Печать  
Кстати, тут у кого-то были ошибки, если события формы и события ГМ обрабатываются в одном классе, т.е. как у тебя.
Попробуй разнести по разным классам. У человека ошибки пропадали Улыбка

Лично я считаю, что это на самом деле должны быть разные классы, т.к. решаются разные задачи.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #68 - 17. Декабря 2010 :: 02:01
Печать  
zk96 писал(а) 16. Декабря 2010 :: 10:06:
А попробуй так.

Уловил идею о лишнем создании экземпляра класса Перехватчик и об изменениях в методе ВключитьПерехватСобытийГК, однако изменения в СобытиеГМ_СозданиеКонтекста мне непонятны. Который из перехватчиков вернет ПолучитьПерехватчикСобытийГК?

artbear писал(а) 16. Декабря 2010 :: 12:39:
Кстати, тут у кого-то были ошибки, если события формы и события ГМ обрабатываются в одном классе, т.е. как у тебя.
Попробуй разнести по разным классам. У человека ошибки пропадали Улыбка

Лично я считаю, что это на самом деле должны быть разные классы, т.к. решаются разные задачи.

Суть идеи в том, что перехватом занимается один класс, но при этом он отвечает за раздачу событий всем подписчикам ... причем для каждой открываемой формы создается отдельный экземпляр этого класса (правда я так и не словил ни одного вызова деструктора - почему? - даже пытался снимать перехват в Событие_ПриЗакрытии).
Но идея с разделением услышана и будет опробована сразу после того, как начну перехватывать события формы, т.к. на данный момент они еще не перехватываются - только создание контекста...



Похоже, что разрулил.
1. Не надо доблировать класс фабрики, если он НЕ перехватывает события формы.
2. Класс перехвата событий формы просто обязан перехватывать события открытия и закрытия, контроллируя флаг возврата, т.к. в обоих событиях может возникнуть необходимость снятия перехвата и уничтожения объекта.

Пока проблем с отчетами не обнаружено... хотя стоит еще проверить позиционирование журнала - вдруг и это вылечилось...
Вылечилось! ... думаю, баг все-таки не стоит отменять, но его лечение оказалось простым - не надо путать перехват событий формы с глобальными!
« Последняя редакция: 17. Декабря 2010 :: 04:10 - Dmitry The Wing »  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #69 - 17. Декабря 2010 :: 05:36
Печать  
Dmitry The Wing писал(а) 17. Декабря 2010 :: 02:01:
Похоже, что разрулил.
2. Класс перехвата событий формы просто обязан перехватывать события открытия и закрытия, контроллируя флаг возврата, т.к. в обоих событиях может возникнуть необходимость снятия перехвата и уничтожения объекта.

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

Рад, что мой совет помог.

ИМХО ты не прав, говоря "класс перехвата просто обязан перехватывать события открытия и закрытия" Печаль
это совершенно необязательно Улыбка
Вместо перехвата события ПриОткрытии намного лучше юзать СобытиеГМ_СозданиеКонтекста и уже в нем устанавливать перехват на форму.

При закрытии формы перехват на нее снимается автоматом и если на объект-перехватчик больше нет ссылок, вызывается деструктор этого объекта.
Т.е. если после закрытия формы автоматом не вызвался деструктор перехватчика, значит, ищи где-то лишние ссылки Печаль
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #70 - 17. Декабря 2010 :: 06:34
Печать  
artbear писал(а) 17. Декабря 2010 :: 05:36:
Dmitry The Wing писал(а) 17. Декабря 2010 :: 02:01:
Похоже, что разрулил.
2. Класс перехвата событий формы просто обязан перехватывать события открытия и закрытия, контроллируя флаг возврата, т.к. в обоих событиях может возникнуть необходимость снятия перехвата и уничтожения объекта.

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

Рад, что мой совет помог.

ИМХО ты не прав, говоря "класс перехвата просто обязан перехватывать события открытия и закрытия" Печаль
это совершенно необязательно Улыбка
Вместо перехвата события ПриОткрытии намного лучше юзать СобытиеГМ_СозданиеКонтекста и уже в нем устанавливать перехват на форму.

При закрытии формы перехват на нее снимается автоматом и если на объект-перехватчик больше нет ссылок, вызывается деструктор этого объекта.
Т.е. если после закрытия формы автоматом не вызвался деструктор перехватчика, значит, ищи где-то лишние ссылки Печаль

В том то и дело, что тогда не было больше ссылок ... но деструктор не вызывался ... видимо, отсюда и возникали проблемы с вылетом - объекты накапливались, но пытались контролировать несуществующий контекст.
Но это было раньше, а теперь для раздачи событий и недуплирования списков подписчиков при создании контекста формы создается экземпляр перехватчика формы, который сохраняет ссылку на основной перехватчик, который не следит за формами. Это приводит к появлению перекрестных ссылок, что и требует отслеживания событий открытия и закрытия формы для корректного убиения перехватчика.
  
Наверх
 
IP записан
 
zk96
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 320
Местоположение: Киев
Зарегистрирован: 15. Ноября 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #71 - 17. Декабря 2010 :: 08:01
Печать  
2 Dmitry The Win
Если интересно, вот мой класс-перехватчик,которым я пользуюсь.
  

_______________001.rar ( 14 KB | Загрузки )
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #72 - 20. Декабря 2010 :: 02:16
Печать  
zk96 писал(а) 17. Декабря 2010 :: 08:01:
2 Dmitry The Win
Если интересно, вот мой класс-перехватчик,которым я пользуюсь.

ИМХО: Слишком много кода в глобальнике...
У меня там только 1 строка для фабрики-раздатчика событий:
Код
Выбрать все
ФабрикаСобытий = СоздатьОбъект("ФабрикаСобытий"); 


И по две на каждый перехватчик-подписчик:
Код
Выбрать все
ПерехватчикЖурналаРегистрации = СоздатьОбъект("ПерехватчикЖурналаРегистрации");
ПерехватчикЖурналаРегистрации.ПодписатьКлассНаСобытияФабрики(ФабрикаСобытий); 


Хотя вру Улыбка реально в глобальнике у меня только
Код
Выбрать все
	Если ФС.СуществуетФайл(КаталогИБ() + "ExtForms\start.ert") = 1 Тогда
		ОткрытьФорму("Отчет",, КаталогИБ()+"Extforms\start.ert");
	КонецЕсли; 


А все описанное выше - уже в соотверствующей обработке, ибо менять глобальник - дело неблагодарное...

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

Могу ошибаться, но: из кода видно, что КОП нерабочий, ибо вызов ВыполнитьОригинальноеСобытиеГК из Событие_ВводНового и Событие_ВводНаОсновании дублирует данное событие для документа (на справочнике не проверял), т.е. обработки документа ВводНового и ВводНаОсновании будут вызваны дважды ... сам обжигался...

Я не утверждаю, что класс в целом неправильный, но некоторые моменты совсем не стыкуются с тем, что видел на практике... включая тот момент, который заставил меня разбить перехват на два класса по совету artbear'а.
  
Наверх
 
IP записан
 
zk96
Senior Member
****
Отсутствует


1C++ rocks!

Сообщений: 320
Местоположение: Киев
Зарегистрирован: 15. Ноября 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #73 - 20. Декабря 2010 :: 08:15
Печать  
2 Dmitry The Win
Dmitry The Wing писал(а) 20. Декабря 2010 :: 02:16:
ИМХО: Слишком много кода в глобальнике...
У меня там только 1 строка для фабрики-раздатчика событий:
Код
Выбрать все
ФабрикаСобытий = СоздатьОбъект("ФабрикаСобытий"); 


И по две на каждый перехватчик-подписчик:
Код
Выбрать все
ПерехватчикЖурналаРегистрации = СоздатьОбъект("ПерехватчикЖурналаРегистрации");
ПерехватчикЖурналаРегистрации.ПодписатьКлассНаСобытияФабрики(ФабрикаСобытий); 


Хотя вру Улыбка реально в глобальнике у меня только
Код
Выбрать все
	Если ФС.СуществуетФайл(КаталогИБ() + "ExtForms\start.ert") = 1 Тогда
		ОткрытьФорму("Отчет",, КаталогИБ()+"Extforms\start.ert");
	КонецЕсли; 


А все описанное выше - уже в соотверствующей обработке, ибо менять глобальник - дело неблагодарное...

Мне казалось, что так удобней.И контекст, на мой взгляд лучше получать явно,отдельным методом Но вынести в обработку очень хорошая идея.Спасибо.

Dmitry The Wing писал(а) 20. Декабря 2010 :: 02:16:
...
Непонятно, почему у тебя объявлены практически все события, но СообщитьПодписчикам вызывается не во всех? Поясни...

СообщитьПодписчикам вызивается во всех, перед тем как выложить я из кода удалял
лишнее и, как оказалось, не лишнее тоже удалил.   Улыбка

Dmitry The Wing писал(а) 20. Декабря 2010 :: 02:16:
Могу ошибаться, но: из кода видно, что КОП нерабочий, ибо вызов ВыполнитьОригинальноеСобытиеГК из Событие_ВводНового и Событие_ВводНаОсновании дублирует данное событие для документа (на справочнике не проверял), т.е. обработки документа ВводНового и ВводНаОсновании будут вызваны дважды ... сам обжигался...

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

Dmitry The Wing писал(а) 20. Декабря 2010 :: 02:16:
...который заставил меня разбить перехват на два класса по совету artbear'а.

Мне казалось, что в одном классе удобней обрабатывать, если конечно логика обработки не сильно отличается.

Спасибо за критику. Всегда хорошо послушать мнение со стороны.
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Перехватчик. Для каких событий необходим ручной вызов оригинального?
Ответ #74 - 20. Декабря 2010 :: 08:39
Печать  
zk96 писал(а) 20. Декабря 2010 :: 08:15:
Dmitry The Wing писал(а) 20. Декабря 2010 :: 02:16:
Могу ошибаться, но: из кода видно, что КОП нерабочий, ибо вызов ВыполнитьОригинальноеСобытиеГК из Событие_ВводНового и Событие_ВводНаОсновании дублирует данное событие для документа (на справочнике не проверял), т.е. обработки документа ВводНового и ВводНаОсновании будут вызваны дважды ... сам обжигался...

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

Попробуй включить перехват СобытиеГМ_ВводНаОсновании и НЕ вызывать ВыполнитьОригинальноеСобытиеГК ... увидишь, что ввод на основании документов не сломается ... о чем это говорит? - о том, что ввод уже случился,а потом ты дополнительно насильно его повторяешь вызовом ВыполнитьОригинальноеСобытиеГК.

zk96 писал(а) 20. Декабря 2010 :: 08:15:
Dmitry The Wing писал(а) 20. Декабря 2010 :: 02:16:
...который заставил меня разбить перехват на два класса по совету artbear'а.

Мне казалось, что в одном классе удобней обрабатывать, если конечно логика обработки не сильно отличается.

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

zk96 писал(а) 20. Декабря 2010 :: 08:15:
Спасибо за критику. Всегда хорошо послушать мнение со стороны.

Это не столько критика, сколько обмен опытом, ибо сам с перехватчиком до конца разобрался только по мере развития темы...
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1 ... 3 4 [5] 6 7 ... 11
ОтправитьПечать