Событие изменения данных в ячейке Calc

Автор Alex16, 11 ноября 2016, 16:49

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

Alex16

Доброе время суток!
Как отловить событие подтверждения данных в ячейке? Например ввели что-то в ячейку и либо нажали ентер или стрелку или мышкой кликнули по другой ячейке. Или нажали Del в ячейке.
Как отловить этот момент и выполнить макрос в котором получить данные измененной ячейки?

rami

Цитата: Alex16 от 11 ноября 2016, 14:49Как отловить этот момент и выполнить макрос в котором получить данные измененной ячейки?
А что, Данные —> Проверка... не подходит?

Alex16

#2
Цитата: rami от 11 ноября 2016, 14:54А что, Данные —> Проверка... не подходит?
Незнаю. Есть много таких ячеек где нужно это делать. Но это не главное. А вот в макросе можно в этой проверке получить данные ячейки и ее координаты. т.е. Cell.Col и Cell.Row?

И это только при ошибке? Мне нужно всегда...

rami

Цитата: Alex16 от 11 ноября 2016, 17:02
Цитата: rami от 11 ноября 2016, 14:54А что, Данные —> Проверка... не подходит?
Незнаю. Есть много таких ячеек где нужно это делать. Но это не главное. А вот в макросе можно в этой проверке получить данные ячейки и ее координаты. т.е. Cell.Col и Cell.Row?

И это только при ошибке? Мне нужно всегда...
Во-первых "ошибку" можно сделать "всегда" ;D — любой ввод будет "ошибкой" запускающей макрос.

Но можно назначить событие листа — нужно щёлкнуть по ярлычку листа и вызвать контекстное меню, см. снимок:

Alex16

Цитата: rami от 11 ноября 2016, 15:12Но можно назначить событие листа — нужно щёлкнуть по ярлычку листа и вызвать контекстное меню
Ок. Попробую этот вариант. Но пока вопрос остается: как в макросе получить изменившуюся ячейку? ...ее адрес и содержимое

Alex16

Вроде вот так ChangedItem = ThisComponent.CurrentSelection
Верно?

rami

Цитата: Alex16 от 11 ноября 2016, 15:18Но пока вопрос остается: как в макросе получить изменившуюся ячейку? ...ее адрес и содержимое
Создайте макрос и назначьте  на нужное событие:
Sub Main(oEvent)

End Sub

Событие запускает макрос и передаёт ему параметр oEvent, который содержит информацию (переменную объекта вызвавшего макрос) иногда и другие параметры.

Alex16


rami

Только учтите, что события листа относятся ко всему листу (к каждой его ячейке), иногда нужно проверять источник события (например, если ячейка не из нужного диапазона) и "принимать соответствующие меры".

Alex16

#9
Цитата: rami от 11 ноября 2016, 15:29Sub Main(oEvent)

End Sub
А как в макросе определить на ячейку ссылается oEvent или на диапазон?
Макрос:
Sub Main(oEvent)
xray oEvent
End Sub

при изменении ячейки показывает ScCellObj а если выделить группу то - ScCellRangesObj

Или можно всегда обращаться к ячейке как к диапазону.

   print oEvent.RangeAddress.StartRow
   print oEvent.RangeAddress.EndRow
   print oEvent.RangeAddress.StartColumn
   print oEvent.RangeAddress.EndColumn

Но в таком варианте, если выделить несколько ячеек с ctrl'ом то вот такая ошибка "Свойство или метод не найдены: RangeAddress."
Как узнать что выделение "множественное"?

rami

Нужно проверить свойство ImplementationName
If oEvent.ImplementationName="ScCellRangeObj" Then Exit Sub   'если не нужно обрабатывать диапазоны

Для "попадания" в нужную ячейку, столбец, строку или диапазон нужно проверять CellAddress (если CellAddress <> или = тому, что нужно)

Alex16

#11
Цитата: rami от 14 ноября 2016, 08:29'если не нужно обрабатывать диапазоны
"Нормальный" диапазон я могу обработать
Sub MainChangeList(oEvent)
For R = oEvent.RangeAddress.StartRow to oEvent.RangeAddress.EndRow
  For C = oEvent.RangeAddress.StartColumn to oEvent.RangeAddress.EndColumn
    Print "Addr: (" & R & "," & C & ")"
  Next C
Next R 
End Sub

, а вот если с контролом ячейки выделять - пока не соображу как.
В любом случае спасибо за
Цитата: rami от 14 ноября 2016, 08:29If oEvent.ImplementationName="ScCellRangeObj" Then Exit Sub
Но в данном случае что с контролом, что обычный диапазон он - ScCellRangesObj или я не прав?

rami

#12
Цитата: Alex16 от 14 ноября 2016, 08:39а вот если с контролом ячейки выделять - пока не соображу как.
Пишите подробней, что за "контрол" и с чем его едят ???

Цитата: Alex16 от 14 ноября 2016, 08:39Но в данном случае что с контролом, что обычный диапазон он - ScCellRangesObj или я не прав?
Для диапазона ячеек всегда ImplementationName="ScCellRangeObj"

JohnSUN

#13
Цитата: rami от 14 ноября 2016, 12:45
Пишите подробней, что за "контрол" и с чем его едят ???
Брось, его не едят, его зажимают пока мышкой по ячейкам елозят - множественное выделение, не связанные диапазоны ячеек - тот самый третий случай, который муторнее всего обрабатывать: перебрать все диапазоны, попавшие в выделение, в каждом перебрать все ячейки, каждую ячейку обработать... Обычно мы с этой бедой старались не связываться - выделено больше одной ячейки и сразу Exit Sub

Цитата: rami от 14 ноября 2016, 12:45Для диапазона ячеек всегда ImplementationName="ScCellRangeObj"
И еще раз, для не очень внимательных читателей - есть ScCellObj  (одна ячейка), есть ScCellRangeObj (один диапазон) и есть ScCellRangesObj (несколько диапазонов). Разница между двумя последними - буква s

PS. Alex16, ещё раз перечитал с первого сообщения - похоже, ты не то событие для макроса выбрал. Тебе не выделение нужно обрабатывать, а изменение содержимого. Во втором случае довольно сложно получить ScCellRangesObj - нужно очень исхитриться, чтобы за один раз изменить содержимое несвязных диапазонов
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Alex16

#14
Цитата: JohnSUN от 14 ноября 2016, 11:49Тебе не выделение нужно обрабатывать, а изменение содержимого.
Так я его и обрабатываю.
Цитата: JohnSUN от 14 ноября 2016, 11:49довольно сложно получить ScCellRangesObj - нужно очень исхитриться, чтобы за один раз изменить содержимое несвязных диапазонов
Очень НЕ сложно :) Достаточно выбрать несколько ячеек с Контролом и затем нажать Del
Цитата: JohnSUN от 14 ноября 2016, 11:49есть ScCellRangeObj (один диапазон) и есть ScCellRangesObj (несколько диапазонов). Разница между двумя последними - буква s
Если это так просто - то мне этого будет достаточно :) Если без "s" - то обрабатываем, если "множественное выделение" то выдать предупреждение и выход из процедуры.
Спасибо за помощь. Сейчас проверю на предмет "ScCellRangeObj (один диапазон) и есть ScCellRangesObj (несколько диапазонов)"

ЗЫЖ Получился тестовый макрос примерно такой:
Sub MainChangeList(oEvent)
If oEvent.ImplementationName="ScCellRangesObj" Then
 msgbox "Множественное выделение не поддерживается, будет сделана обработка для всего отчета"
 Exit Sub
endif
For R = oEvent.RangeAddress.StartRow to oEvent.RangeAddress.EndRow
 For C = oEvent.RangeAddress.StartColumn to oEvent.RangeAddress.EndColumn
   Print "Addr: (" & R & "," & C & ")"
 Next C
Next R  
End Sub


Только есть еще один неприятный момент. Если мышкой перетащить(переместить) содержимое ячейки в другое место событие вообще не возникает.