Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

17 Май 2022, 04:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Вы можете задать вопрос по LibreOffice или Apache OpenOffice без регистрации, используя форму
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: « 1 2 3 4 »   Вниз
  Печать  
Автор Тема: Как работает ChartDataChangeEventListener?  (Прочитано 3250 раз)
0 Пользователей и 1 Гость смотрят эту тему.
eeigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 1 071


« Ответ #30: 15 Январь 2022, 12:54 »

@Kadet, в ответе #15 в коде есть небольшая неточность:
ячейка не имеет метода queryIntersection, поэтому надо использовать диапазон из одной ячейки (в прилагаемом примере это учтено).

Цитата: eeigor от Сегодня в 10:41
Макрос Sheet_OnChange подключается вручную щелчком ПКМ по ярлычку листа >> Sheet Events...
Вот этот момент совсем не годится.
Прилагаю пример с программным подключением события листа, как Вы просили.
Однако как всё просто!  Улыбка

* example-connect-sheet-event.ods (60.15 Кб - загружено 8 раз.)
« Последнее редактирование: 15 Январь 2022, 13:21 от eeigor » Записан

Ubuntu 18.04 LTS • LibreOffice 7.3.2.2 Community
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #31: 15 Январь 2022, 14:40 »

Прилагаю пример с программным подключением события листа, как Вы просили.
Однако как всё просто!  Улыбка
Хорошо. Я посмотрю. Спасибо!

Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #32: 15 Январь 2022, 14:42 »

Вы проверяли, помогает ли addActionLock/removeActionLock вокруг кода, меняющего большие массивы данных?
Да. Заморозку использую.
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #33: 15 Январь 2022, 14:50 »

Однако как всё просто!
Посмотрел. Подвязку событий макросом делать умею. Это мы уже проходили и rimi помог с этим.
Вопрос стоит ли это делать. (см. выше).
« Последнее редактирование: 15 Январь 2022, 14:51 от Kadet » Записан
eeigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 1 071


« Ответ #34: 15 Январь 2022, 14:58 »

А вот Вы и попробуйте на реальных данных, а нам потом расскажете
Записан

Ubuntu 18.04 LTS • LibreOffice 7.3.2.2 Community
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #35: 15 Январь 2022, 15:00 »

Однако, если вернуться к нашим "баранам".

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

Код:
Type TListener
ra As New com.sun.star.table.CellRangeAddress 'RangeAdress
ltr As New com.sun.star.chart.XChartDataChangeEventListener 'объект Listener
End Type

'*****************************************************
Global ANListener(0) As New TListener
'******************************************************
Sub ANListenerSUB(oRange)
Dim n%
n =UBound(ANListener)
If NOT IsNull(ANListener(n).ra) Then
n = n+1
ReDim preserve ANListener(n) As New TListener
End If

ANListener(n).ra = oRange.RangeAddress
ANListener(n).ltr = CreateUnoListener( "AN_", "com.sun.star.chart.XChartDataChangeEventListener" )
oRange.addChartDataChangeEventListener(ANListener(n).ltr)
End Sub

'******************************************************
Sub AN_disposing(oEvent)
End Sub

'******************************************************
Sub AN_chartDataChanged(oEvent)
ANSet(oEvent)
End Sub

'******************************************************
Sub UnregisterANlistener(n%)
Dim oDoc, oSheet, oRange, iSh%, iStCl%, iStRw%, iEnCl%, iEnRw%
' ON LOCAL ERROR resume next
oDoc = ThisComponent

iSh = ANListener(n).ra.Sheet
iStCl = ANListener(n).ra.StartColumn
iStRw = ANListener(n).ra.StartRow
iEnCl = ANListener(n).ra.EndColumn
iEnRw = ANListener(n).ra.EndRow

oSheet = oDoc.Sheets(iSh)

oRange = oSheet.getCellRangeByPosition(iSh, iStCl, iStRw, iEnCl, iEnRw)
oRange.removeChartDataChangeEventListener(ANListener(n).ltr)
' ON LOCAL ERROR GOTO 0
End Sub

Делаю тип TListener. В ra записываю RangeAddress, а в ltr объект листенера.
При отключении достаю всё это и получаю диапозон, к которому привязываю листенер и пытаюсь отключить листенер, привязанный к нему.
Проходит гладко.
Но когда после отключения всех листенеров снова пытаюсь создать или удалить лист - все листенеры срабатывают.
Получается, что, несмотря на то, что команда removeChartDataChangeEventListener прошла гладко, листенеры всё одно продолжают работать.

* tttt_t.ods (12.66 Кб - загружено 5 раз.)
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #36: 15 Январь 2022, 15:00 »

А вот Вы и попробуйте на реальных данных, а нам потом расскажете
Хорошо. Попробую.
Записан
eeigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 1 071


« Ответ #37: 15 Январь 2022, 15:09 »

Ну, про слушатели Вам пояснил Михаил. Потому и срабатывают. И на моем облегчённом примере в ответе #5 это лучше демонстрировать.
Записан

Ubuntu 18.04 LTS • LibreOffice 7.3.2.2 Community
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #38: 15 Январь 2022, 16:11 »

Ну, прежде всего я допустил ошибку в строчке:
Код:
oRange = oSheet.getCellRangeByPosition(iSh, iStCl, iStRw, iEnCl, iEnRw)

Нужно так:
Код:
oRange = oSheet.getCellRangeByPosition(iStCl, iStRw, iEnCl, iEnRw)

Но, и это видимо не помогает. Срабатывают.
Записан
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 721


« Ответ #39: 15 Январь 2022, 16:35 »

Вроде бы при remove ошибок не выдаёт. Но, сдаётся, мне, что эти листенеры так и не отключаются.
...
При отключении достаю всё это и получаю диапозон, к которому привязываю листенер и пытаюсь отключить листенер, привязанный к нему.
Проходит гладко.

Вы создаёте новый объект. Не тот же объект, который использовали при регистрации слушателя, а такой же, для того же диапазона, но не тот же самый. Это и есть проблема.
Записан

С уважением,
Михаил Каганский
sokol92
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 900


WWW
« Ответ #40: 15 Январь 2022, 18:17 »

Раньше не смотрел  XChartDataChangeEventListener. Для "обычных" диапазонов ячеек он при изменении любой ячейки диапазона порождает событие, в котором источником (Source) является диапазон, а в структуре ChartDataChangeEvent возвращается адрес диапазона (а не измененной ячейки).
На мой взгляд, проще использовать старый испытанный XModifyListener.

Событие листа "OnChange" отлавливает не все изменения ячеек листа (например, если ячейки меняются в результате пересчета формул). В Excel ситуация не лучше.

Что касается остановки слушателя, то замечание Михаила носит универсальный характер: лучше в глобальных переменных сохранять как сам слушатель, так и "вещатель" - объект, к которому слушатель добавляется.

Насколько я понимаю, методы removeXXXXListener нормально завершаются при попытке удалить слушатель, который ранее к вещателю не подключался.
« Последнее редактирование: 15 Январь 2022, 21:12 от sokol92 » Записан

Владимир.
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #41: 15 Январь 2022, 22:06 »

Вы создаёте новый объект. Не тот же объект, который использовали при регистрации слушателя, а такой же, для того же диапазона, но не тот же самый. Это и есть проблема.
"Интересное кино"?! А как же тогда получить "тот же самый"?
Вроде бы логически должно быть всё верно. Я сохраняю создаваемый листенер в массиве и сохраняю адрес диапазона, к которому его привязываю.

А как же тогда достать "тот самый"? Чего-то я окончательно запутался. По вашему получается - "те самые" листенеры просто недосягаемы.
Записан
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 721


« Ответ #42: 15 Январь 2022, 22:10 »

А как же тогда получить "тот же самый"?

Сохранять в ANListener(n) не oRange.RangeAddress, а oRange.
Записан

С уважением,
Михаил Каганский
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #43: 15 Январь 2022, 22:10 »

Что касается остановки слушателя, то замечание Михаила носит универсальный характер: лучше в глобальных переменных сохранять как сам слушатель, так и "вещатель" - объект, к которому слушатель добавляется.
Ага. Кажется начинаю догонять. Вы предлагаете в массиве сохранять не адрес диапазона, а сам диапазон как объект.
Интересная идея. Попробую.

Кстати, "обходной манёвр" реализовал. Вроде бы стало работать правильно.
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #44: 15 Январь 2022, 22:11 »

Сохранять в ANListener(n) не oRange.RangeAddress, а oRange.
Да, да. Я уже понял предыдущие объяснения. Спасибо!
Записан
Страниц: « 1 2 3 4 »   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!