Как работает ChartDataChangeEventListener?

Автор Kadet, 14 января 2022, 21:07

0 Пользователи и 1 гость просматривают эту тему.

eeigor

#15
Цитата: eeigor от 15 января 2022, 01:13Я использую событие листа "Content changed", и мне хватает...
Кажется, я уже отвечал Вам на Ваш вопрос...
Цитата: Kadet от 15 января 2022, 10:30Возможно я использую не тот листенер, но... другого способа не придумал.
Именно так.

''''''''''''''''''''''''''''' Sheet Event Procedure ''''''''''''''''''''''''''''
Sub Sheet_OnChange(oTarget As Object)  '<- ScCellObj, ScCellRangeObj, ScCellRangesObj
''' Called by: OnChange (Content changed) event of this sheet.

   On Local Error GoTo HandleErrors
   Dim oCell As Object
   oCell = <Ваша ячейка со списком выбора>
   If oCell.queryIntersection(oTarget.RangeAddress).Count > 0 Then
       ' Ваш код реакции на событие
   End If
   Exit Sub

HandleErrors:
   Msgbox "Error " & Err & " in line " & Erl & ": " & Error _
    , MB_ICONSTOP, "macro:Sheet_OnChange"
End Sub


UPDATED:
Макрос Sheet_OnChange подключается вручную щелчком ПКМ по ярлычку листа >> Sheet Events...

Ваших ячеек может быть много. Определяйте через пересечение диапазонов (oCell ⋂ oTarget), что было изменено, и выполняйте соответствующий Case (Select Case).

UPDATED:
Ячейка не имеет метода queryIntersection, поэтому надо использовать диапазон из одной ячейки. См. исправленный пример в ответе #30.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

Kadet

Лучше поясню на примере.
Есть две ячейки: "Наименование" и "Размер". Обе ячейки со списками выбора. В зависимости от данных, которые установленны в ячейке "Наименование" в ячейке "Размер" список выбора должен меняться. При одном значении "Наименования" это один список, а при другом - это уже другой список.

Для изменения списка "Размер" в зависимости от значения в ячейке "Наименование" я вешаю на ячейки "Наименование" этот листенер.

Kadet

#17
Цитата: eeigor от 15 января 2022, 10:41Я использую событие листа "Content changed", и мне хватает...
Попробую

eeigor

#18
@Kadet, ответ #15 с примером содержит полный ответ на Ваш вопрос в этой теме.
Как подключить, я написал. А <Ваш код реакции на событие> - это Ваша логика программы.

UPDATED:
Цитата: Kadet от 15 января 2022, 10:51зависимости от данных, которые установленны в ячейке "Наименование" в ячейке "Размер" список выбора должен меняться.
Для этого не требуется программирование. Решается формулами.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

Kadet

Цитата: eeigor от 15 января 2022, 11:06@Kadet, ответ #15 с примером содержит полный ответ на Ваш вопрос в этой теме.
Да, да... Уже разбираюсь.

Цитата: eeigor от 15 января 2022, 10:41Макрос Sheet_OnChange подключается вручную щелчком ПКМ по ярлычку листа >> Sheet Events...
Вот этот момент совсем не годится.
Потому как не только листы, но и сам документ Calc у меня всегда создаётся автоматически и заново, из другой программы (Base). Теоретически, можно повесить макрос на событие и макросом, но...
В общем, спасибо. Поразбираюсь и попробую. Получится/не_получится.

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

economist

Цитата: Kadet от 15 января 2022, 10:51Есть две ячейки: "Наименование" и "Размер". Обе ячейки со списками выбора. В зависимости от данных, которые установлены в ячейке "Наименование" в ячейке "Размер" список выбора должен меняться. При одном значении "Наименования" это один список, а при другом - это уже другой список.

Такое поведение, в смысле "связанные списки" - можно реализовать и без макроса, формулами на служебном листе. Формулы сами порождают события и грамотно их выполняют, без "дребезга". Листнеры только для этого - избыточны. Есть, конечно, места где без них 100% не обойтись - например во Writer при смене значения  в полях типа Список. там штатных событий не возникает, и приходится создавать события для смены выделения, изменения текста итп.  

Еще один способ реализации связанных списков - обновление диапазонов базы данных в Calc (на SQL) - очень быстро работает. То есть выбрали эл-т в контроле списке А - макросом обновили диапазон B, на который ссылается контрол С для выбора эл-та.  
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

eeigor

#21
Цитата: Kadet от 15 января 2022, 11:13Цитата: eeigor от Сегодня в 10:41
Макрос Sheet_OnChange подключается вручную щелчком ПКМ по ярлычку листа >> Sheet Events...
Вот этот момент совсем не годится.
Можно и программно, уверен. У меня не было необходимости в этом...

Цитата: Kadet от 15 января 2022, 11:13А это событие будет срабатывать всегда-всегда, когда я даже точку где угодном в этот лист вставлю?
Да. Для этого и проверяем пересечение диапазонов.

Цитата: eeigor от 15 января 2022, 11:06Для этого не требуется программирование. Решается формулами.
Почитайте тему по MS Excel:
Create Dependent Drop Down Lists
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

Kadet

#22
Цитата: economist от 15 января 2022, 11:16формулами на служебном листе
Цитата: economist от 15 января 2022, 11:16обновление диапазонов базы данных в Calc (на SQL)
Не слишком ли это всё усложняет? Каждый раз создавать служебный лист, формировать и переформировывать его.
Мало того, уверен, что при переформировывании этого служебного листа он будет становиться активным, что зачастую бывает, и пользователь - простой обывательский юзер, будет все эти переброски и переформирование наблюдать... Оно ему нужно?

К тому же, для упрощения я не описал все процедуры, которые нужно выполнить после изменения данных в ячейке, допустим, "Наименование". Помимо формирования самого списка зависимой ячейки нужно ещё: получить ID этого нового значения, взятый из БД по значению как фильтру; записать этот ID в служебную область этого листа; очистить зависимую ячейку "Размер"; скорректировать некоторые другие зависимые ячейки; сформировать и заполнить список остатков отфильтрованных по этому новому значению.
А эту работу никакими формулами не осилить.

Kadet

#23
Цитата: eeigor от 15 января 2022, 11:28Цитата: Kadet от Сегодня в 11:13
А это событие будет срабатывать всегда-всегда, когда я даже точку где угодном в этот лист вставлю?
Да. Для этого и проверяем пересечение диапазонов.
Ну, тады "Ой". Мне этот вариант никак не подходит.
Выше описал, что должно происходить при изменении ячейки "Наименование".
Думаю понятно, что у меня лишь одно единственное маленькое изменение в этой ячейке провоцирует целую массу изменений к контенте листа. В примере внизу обширная таблица. Вот эта таблица всякий раз при изменении полей "Наименование" и "Размер" полностью переформировывается заново, использую данные из вышеперечисленных полей как фильтры. Представьте сколько времени будет занимать удаление, а затем формирование зановой этой таблицы если после изменения в каждой ячейке будет срабатывать макрос листенера. Уму не постижимо.

mikekaganski

Цитата: Kadet от 15 января 2022, 11:34Каждый раз создавать служебный лист, формировать и переформировывать его.
Мало того, уверен, что при переформировывании этого служебного листа он будет становиться активным ...

Цитата: Kadet от 15 января 2022, 11:34А эту работу никакими формулами не осилить

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

mikekaganski

Цитата: Kadet от 15 января 2022, 11:39Представьте сколько времени будет занимать удаление, а затем формирование зановой этой таблицы если после изменения в каждой ячейке будет срабатывать макрос листенера. Уму не постижимо

Ох. Вы перечитайте ответ 15.

Цитата: eeigor от 15 января 2022, 10:41Определяйте через пересечение диапазонов (oCell ⋂ oTarget), что было изменено
С уважением,
Михаил Каганский

Kadet

Цитата: mikekaganski от 15 января 2022, 11:44Ох. Вы перечитайте ответ 15.
Да понял уже весь смысл. Но, вы забываете, что даже просто обращение к листенеру, даже без каких-нибудь там проверок и т.п., при таких объёмах данных уже даёт весьма существенную задержку в работе.
А базы у меня работают не на 12-ти ядерных процессорах... а на уже порядком подустаревшем оборудовании. И тут каждая миллисекунда дорога.
Я подобные варианты уже проверял. Тормоза.

Kadet

Цитата: mikekaganski от 15 января 2022, 11:42Я, конечно, не знаю деталей, но у меня впечатление, что велосипедостроительство можно было бы значительно упростить введением постоянных (не создаваемых каждый раз) скрытых служебных листов, ведением всех работ (в т.ч. хранением идентификаторов) там, и использованием формул, ссылающихся туда.
Не стоит забывать, что у меня при запуске каждый раз создаётся новый документ Calc с нуля. И, если следовать вашему предложению, послекаждого создания, при загрузке формы, вначале я должен несколько таблиц БД, причём весьма объёмных, загнать в некий служебный лист, а потом использовать.
Не слишком ли это всё усложняет?

Kadet

Однако, главное я понял.
При создании нового листа все листенеры этого типа в документе будут срабатывать. И никуда от этого не деться.
Займусь созданием обходного пути.
И удаление листенеров поковыряю. Есть пара идей в этом нарправлении.

Спасибо!

mikekaganski

Вы проверяли, помогает ли addActionLock/removeActionLock вокруг кода, меняющего большие массивы данных?
С уважением,
Михаил Каганский