Список форумов Форум Libreoffice

Форум Libreoffice

Добро пожаловать на Форум Libreoffice!
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

English French German Italian Portuguese Russian Spanish
Адрес активной ячейки при выделении нескольких диапазонов
На страницу 1, 2  След.
 
Начать новую тему   Ответить на тему    Список форумов Форум Libreoffice -> Basic
Предыдущая тема :: Следующая тема  
Автор Сообщение
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Чт Окт 06, 2011 10:39 am    Заголовок сообщения: Адрес активной ячейки при выделении нескольких диапазонов Ответить с цитатой

Адрес активной ячейки - это адрес последней ячейки, на которой была нажата клавиша мыши (или отпущена - это может зависеть от конкретной реализации), т.е. последней выделенной ячейки до начала (или после окончания) выделения непрерывной области (последней непрерывной области в случае нескольких областей (при нажатом Ctrl).

Где-то он запоминается, но где?

Но, в принципе, отслеживая нажатия/отпускания мыши и ее перемещения для выделения области, можно его определить.

Или проще, адрес последней единственной выделенной ячейки до начала выделения области ячеек.

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

PS. Сам не пробовал. Чисто теоретически. Rolling Eyes


Последний раз редактировалось: RFJ (Вс Фев 12, 2012 8:26 am), всего редактировалось 2 раз(а)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Чт Окт 06, 2011 10:44 am    Заголовок сообщения: Ответить с цитатой

RFJ писал(а):

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

PS. Сам не пробовал. Чисто теоретически.

Я пробовал - тоже плохо получается. Этот макрос у Питоньяка в листинге 6.12: Find the active cell. (автор Paolo Mantovani).
Адрес действительно получаем, но после восстановления выделения активная ячейка перепрыгивает - активной становится верхняя левая ячейка выделения...

RFJ писал(а):

Это адрес последней ячейки, на которой была нажата клавиша мыши (именно нажата, а не отпущена), т.е. последней выделенной ячейки до начала выделения непрерывной области (последней непрерывной области в случае нескольких областей (при нажатом Ctrl).

Увы! Тоже не совсем так. Словами это описать затрудняюсь, но на картинке должно быть видно.

RFJ писал(а):

Где-то он запоминается, но где?

Calc ведет себя как партизан на допросе - сам знает, а нам не говорит. Или мы не правильно спрашиваем? Может, в его терминах это не "активная ячейка", а какой-нибудь "базовый адрес"?
RFJ писал(а):

Но, в принципе, отслеживая нажатия мыши и ее перемещения для выделения области, можно его определить.

Да я над этой проблемой уже половину мозгов иссушил. Кучу форумов перерыл... Потому и говорю, что "никто не знает"...
RFJ писал(а):

Или проще, адрес последней единственной выделенной ячейки до начала выделения области ячеек.

Не всегда успеваю перехватить. Такое впечатление, что бэйсику не все извещения о событиях передаются... Если кликать часто и в разных местах, макрос начинает взглюкивать...
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Чт Окт 06, 2011 11:13 am    Заголовок сообщения: Ответить с цитатой

JohnSUN писал(а):
Да я над этой проблемой уже половину мозгов иссушил.

Ну так половина еще осталась. И, возможно, лучшая половина. Smile

JohnSUN писал(а):
Calc ведет себя как партизан на допросе - сам знает, а нам не говорит. Или мы не правильно спрашиваем? Может, в его терминах это не "активная ячейка", а какой-нибудь "базовый адрес"?


Скорее всего, это не "активная" ячейка, а он просто запомнил этот адрес для отображения на экране, как "активной".

JohnSUN писал(а):
Я пробовал - тоже плохо получается. Этот макрос у Питоньяка в листинге 6.12: Find the active cell. (автор Paolo Mantovani).
Адрес действительно получаем, но после восстановления выделения активная ячейка перепрыгивает - активной становится верхняя левая ячейка выделения...

Может, Paolo Mantovani чего-то недоделал, как надо.

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

А ваши "пробы" вы не могли бы выложить для ознакомления?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Чт Окт 06, 2011 11:58 am    Заголовок сообщения: Ответить с цитатой

RFJ писал(а):

Ну так половина еще осталась. И, возможно, лучшая половина. Smile

Само собой - лучшая! Для себя оставлял! Smile
RFJ писал(а):

Скорее всего, это не "активная" ячейка, а он просто запомнил этот адрес для отображения на экране, как "активной".

Причем запомнил для каждого из листов открытой книги. И не только открытой, а еще и для правильно сохраненной... О! А это, кажется, идея! Может, стоит перешерстить содержимое сохраненного файла?

RFJ писал(а):

Может, Paolo Mantovani чего-то недоделал, как надо.
Надо бы поковыряться, как будет побольше времени.
А ваши "пробы" вы не могли бы выложить для ознакомления?

(Не "ваши", а "твои"... Если не трудно...)
Так ведь уже и выложил. В той теме, где все это обсуждение начиналось. Один из макросов и есть код Paolo Mantovani. Только обрезанный в конце. Так и написано:
Код:
REM Чтобы отображать АЯ, нужно знать где она.
REM Author: Paolo Mantovani
REM  Modified: JohnSUN
Private Function getAdrOfActiveCell()
Dim oCurrentController As Object   ' Контроллер текущего документа
Dim oOldSelection As Object         ' Текущее выделение (чтобы не потерять его)
Dim oRanges As Object            ' Пустой диапазон, чтобы "сбить" текущее выделение
Dim oActiveCell As Object         ' Искомая АЯ
   oCurrentController = ThisComponent.getCurrentController()
REM Запоминаем текущее выделение
   oOldSelection = oCurrentController.getSelection()
REM Создаем пустой диапазон и "выделяем" его
   oRanges = ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges")
   oCurrentController.Select(oRanges)
REM Теперь выделена только АЯ
   oActiveCell = oCurrentController.getSelection()
REM Результат функции - структура с номерами листа, строки и столбца АЯ   
   getAdrOfActiveCell = oActiveCell.getCellAddress()
REM НЕ Восстанавливаем запомненое текущее выделение - иначе изменится активная ячейка
REM   ThisComponent.CurrentController.Select(oOldSelection)
REM Не хорошо, конечно, но тут уж или отслеживать активную ячейку, или отслеживать активное выделение, или не выделять
End Function

Три закомментированных строчки в конце - это и есть восстановление выделения с потерей старого адреса. Я эту функцию использую только один раз, при активации слушателя. В этот момент если и собъётся выделение - мы не виноваты, это пользователь макрос запустил... Улыбка
А потом, когда уже обрабатываются события смены выделения или отображаемой области, с активной ячейкой поступаю так:
Код:
REM Из oEvent получаем текущую видимую область aVisibleRange и текущее выделение
REM oSelection. Поскольку пока неизвестен способ вычленить из выделения одну активную
REM ячейку, то если выделено больше одной ячейки в качестве АЯ будем брать
REM сохраненное значение. То есть, если выделялся диапазон(ы) ячеек, то активной
REM будем считать ячейку, по которой кликнули первой...
Private Sub paintNewSelection(oEvent)
Dim oSelection As Object
...
REM Текущее выделение (реальное)
   oSelection = oEvent.source.getSelection()
REM Определим, что же выделено сейчас
     If IsNull(oSelection) Then Exit Sub       ' Ничего не выделено
     If oSelection.supportsService(SheetCellRanges) Then aCellAddress = aOldSelectedCell ' Слишком много диапазонов выделено
     If oSelection.supportsService(SheetCellRange) Then aCellAddress = aOldSelectedCell   ' Слишком много ячеек выделено
     If oSelection.supportsService(SheetCell) Then aCellAddress = oSelection.getCellAddress() ' Выделена одна ячейка или её часть
...
ну, и пересохраняю найденную активную ячейку в глобальной переменной aOldSelectedCell.
Полный текст лежит на ifolder
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Чт Окт 06, 2011 1:51 pm    Заголовок сообщения: Ответить с цитатой

JohnSUN писал(а):
Может, стоит перешерстить содержимое сохраненного файла?

Боюсь, что он хранит этот адрес в памяти, и пишет в файл только при сохранении.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Чт Окт 06, 2011 2:10 pm    Заголовок сообщения: Ответить с цитатой

Н-да... Найти-то их нашел... Это в settings.xml, чуть ли не открытым текстом
Код:
<config:config-item-map-entry config:name="Sheet1">
    <config:config-item config:name="CursorPositionX" config:type="int">
3
   </config:config-item>
   <config:config-item config:name="CursorPositionY" config:type="int">
14
   </config:config-item>

Теперь предстоит разобраться кто и во что преобразует эти CursorPosition при загрузке файла и как к ним дотянуться...
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
mathnew



Репутация: 0    

Зарегистрирован: 20.08.2011
Сообщения: 24

СообщениеДобавлено: Пт Окт 07, 2011 6:02 am    Заголовок сообщения: Ответить с цитатой

JohnSUN писал(а):
Теперь предстоит разобраться кто и во что преобразует эти CursorPosition при загрузке файла и как к ним дотянуться...

Придется потрошить source и восстанавливать реверсивно всю цепочку, приводящую к CursorPositionX(Y).
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
mathnew



Репутация: 0    

Зарегистрирован: 20.08.2011
Сообщения: 24

СообщениеДобавлено: Сб Окт 08, 2011 7:34 am    Заголовок сообщения: Ответить с цитатой

Потрошить source - это долго и муторно. И нет гарантии, что можно добраться до чего-то полезного.
Возможно, что "выделенная" (на экране черной границей) ячейка совпадает с "выбранной" (Selection) только если ячейка - единственная.

Если Selection содержит диапазон ячеек , или даже несколько диапазонов ячеек, то "выделенная" и "выбранные" ячейки никак не связаны.

А если из API пользователь имеет доступ только к выбранным" (Selection) ячейкам (а это, возможно, так и есть), то до "выделенной" (черной рамкой) ячейки никак не доберешься, адрес её - внутренняя переменная, адрес которой совпадает с адресом "выбранной" (Selection) ячейки, если ячейка одна единственная.

PS. "А если я не прав, то пусть старшие товарищи меня поправят." (цитата из известного фильма).
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Сб Окт 08, 2011 8:03 am    Заголовок сообщения: Ответить с цитатой

Ну да, похоже, что так и есть... Поскольку весь Selection не сохраняется и не восстанавливается, то, скорее всего, перед сохранением выполняется что-то вроде того, что предложил Paolo Mantovani - выделение сбрасывается до одной ячейки и уже её координаты записываются в CursorPositionX(Y).

Я уже подумываю, а не пора ли вспомнить навыки работы с ArtMoney Смеется
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
mathnew



Репутация: 0    

Зарегистрирован: 20.08.2011
Сообщения: 24

СообщениеДобавлено: Сб Окт 08, 2011 2:05 pm    Заголовок сообщения: Ответить с цитатой

JohnSUN писал(а):
Поскольку весь Selection не сохраняется и не восстанавливается, то, скорее всего, перед сохранением выполняется что-то вроде того, что предложил Paolo Mantovani - выделение сбрасывается до одной ячейки и уже её координаты записываются в CursorPositionX(Y

Да нет, не так. Selection (весь) и сохраняется и восстанавливается из API. Но вот адрес "выделенной" (рамкой) ячейки тоже хранится во какой-то внутренней недоступной для пользователя переменной и при сохранении файла просто записывается в settings.xml. Сбрасывать ничего не надо - они хранятся в разных переменных. Для единственной ячейки они просто совпадают.
При загрузке файла это значение прочитается из файла и будет присвоено этой переменной.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Вт Янв 17, 2012 6:37 pm    Заголовок сообщения: Ответить с цитатой

Нашлась ячейка... Нельзя сказать, что решение лежало совсем на поверхности, но было совсем рядом.
Итак, аналог ActiveCell можно получить с помощью getViewData
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Ср Янв 18, 2012 5:50 pm    Заголовок сообщения: Ответить с цитатой

JohnSUN писал(а):
Нашлась ячейка... Нельзя сказать, что решение лежало совсем на поверхности, но было совсем рядом.

Весьма интересно, и совсем-совсем не очевидно.
Надо будет внимательно с этим разобраться.

Имею большое желание прибить разработчиков за исключительно мерзкую документацию, точнее за её отсутствие.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
mathnew



Репутация: 0    

Зарегистрирован: 20.08.2011
Сообщения: 24

СообщениеДобавлено: Ср Янв 18, 2012 6:26 pm    Заголовок сообщения: Ответить с цитатой

Да, действительно, uros это использовал в свое время. Но тема называлась "How to get current focused cell?" и связать ее с ActiveCell оказалось непросто.
http://www.oooforum.org/forum/viewtopic.phtml?t=19348&start=0&postdays=0&postorder=asc&highlight=&sid=cf2d951b6a66c55a7d9c6768334fef5a
Его код:
Код:
Sub CallGetFocusedCell3
Dim aAdr
   oDocument = ThisComponent
   aAdr = GetFocusedCell3(oDocument)
   nSheet = aAdr(0) : nCol = aAdr(1) : nRow = aAdr(2) :
   MsgBox "Sheet: " & nSheet & "  Col: " & nCol & "  Row: " & nRow
End Sub

Function GetFocusedCell3(oDoc as Object)
Dim as1, cell(2) As Long, sDum as String
   as1  = Split(oDoc.currentController.ViewData, ";")
   cell(0) = CLng(as1(1))
   sDum = as1(cell(0)+3)
   as1  = Split(sDum, "/")
   cell(1) = CLng(as1(0))
   cell(2) = CLng(as1(1))
   GetFocusedCell3 = cell()
End Function

Иллюстрация к этому коду:
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Ср Янв 18, 2012 6:42 pm    Заголовок сообщения: Ответить с цитатой

JohnSUN
У тебя в функции, кажется, ошибка
Цитата:
If UBound(arrayOfString) 0 Then

И можно ли привести пример использования твоей функции?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Ср Янв 18, 2012 7:33 pm    Заголовок сообщения: Ответить с цитатой

Спасибо! Не в функции, а на сайте... Обычная история про семь нянек...
На самом деле в оригинале было
Код:
   arrayOfString() = Split(tmpString, ";")
   If UBound(arrayOfString) < (3 + iSheet) Then Exit Function
   tmpString = arrayOfString(3 + iSheet)
   If InStr(tmpString,"+") > 0 Then
      arrayOfString() = Split(tmpString, "+")
   Else
      arrayOfString() = Split(tmpString, "/")
   EndIf
Полторы строки кода - как корова языком...
А пример использования - что-то вроде такого:
Код:
Sub tstAC
Dim Res
   Res = ActiveCell()
   If IsNull(Res) Then
      print "Без параметров - нет результата"
   Else
      print "Без параметров " + Res.AbsoluteName
   EndIf
   Res = ActiveCell(7)
   If IsNull(Res) Then
      print "С 1 параметром - нет результата "
   Else
      print "С 1 параметром " + Res.AbsoluteName
   EndIf
End Sub

_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Форум Libreoffice -> Basic Часовой пояс: GMT
На страницу 1, 2  След.
Страница 1 из 2

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group
Вы можете бесплатно создать форум на MyBB2.ru, RSS