Nr wiersza aktywnej komórki

Dyskusje dotyczące tworzenia makropoleceń, pisania skryptów oraz programowania przy użyciu UNO
Krzysiek_P
Posty: 3
Rejestracja: pt lut 08, 2013 11:57 pm

Nr wiersza aktywnej komórki

Post autor: Krzysiek_P »

Witam wszystkich. Jak uzyskać nr wiersza aktywnej komórki, aby podstawić go pod zmienną. Chcę wydrukować sformatowany Arkusz2, wypełniając go uprzednio
kilkoma komórkami z arkusza1, z wiersza w którym znajduje się kursor(aktywna komórka) wykonując makro i nie mam pojęcia jak to zrobić. Napisałem kilka makr w Excelu ale w OpenOffice nie wiem jak zacząć. Z góry dziękuję za każdą podpowiedź i pozdrawiam wszystkich użytkowników.
OpenOffice 3.4.1 na Windows XP
Jan_J
Posty: 4560
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Nr wiersza aktywnej komórki

Post autor: Jan_J »

Napisz sobie makro które ustawia jakikolwiek obiekt komórki, wykonaj je w trybie krokowym i podejrzyj właściwości w debuggerze. Zobaczysz, że komórka ma pole CellAddress, które jest obiektem z polami Sheet, Column, Row.

Kod: Zaznacz cały

sub razdwatrzy()
	c = thisComponent.Sheets.getByIndex(0).getCellByPosition(1,2)
	a = c.CellAddress
	print a.Sheet
	print a.Row
	print a.Column
	print c.AbsoluteName
end sub
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Krzysiek_P
Posty: 3
Rejestracja: pt lut 08, 2013 11:57 pm

Re: Nr wiersza aktywnej komórki

Post autor: Krzysiek_P »

Przy próbie wykonania otrzymuję komunikat "Symbol a został już inaczej zdefiniowany" . Jeśli znamy adres komórki ( w przykladzie 1,2) to nr wiersza jest znany,
ale jak poznać nr wiersz komórki aktywnej w arkuszu w danej chwili ?
OpenOffice 3.4.1 na Windows XP
Jan_J
Posty: 4560
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Nr wiersza aktywnej komórki

Post autor: Jan_J »

Krzysiek_P pisze:Przy próbie wykonania otrzymuję komunikat "Symbol a został już inaczej zdefiniowany" .
Widocznie masz gdzieś wcześniej w module wpisaną deklarację Dim a as ...
Zamień w moim przykładzie symbol a czymś innym, np. TakaNazwaObiektuJakaMiSieAkuratPodoba.
Jeśli znamy adres komórki ( w przykladzie 1,2) to nr wiersza jest znany,
ale jak poznać nr wiersz komórki aktywnej w arkuszu w danej chwili ?
No jasne. Przykład miał pokazać, że każdy obiekt typu Cell posiada informację o własnym adresie. Znajduje się ona m.in. w polach AbsoluteName (string), CellAddress (object) oraz RangeAddress (też object).
Pytanie o aktywną komórkę dotyczy czego innego: skąd sesja arkusza wie, która komórka (albo zakres) jest wyróżniona? Do tego służy osobna struktura zwana kontrolerem dokumentu. Odpowiada ona, w pewnym uproszczeniu, za interfejs użytkownika. Do obiektu kontrolera zarządzającego bieżącym dokumentem dojdziesz poprzez thisComponent.currentController, a do danych o bieżącej komórce lub zaznaczeniu -- thisComponent.currentController.Selection albo thisComponent.currentController.getSelection(). Jest to obiekt typu Cell albo Range, zależnie od tego co jest zaznaczone. Czy tak, czy siak, zawiera on dane adresowe.

Poczytaj materiały Andrew Pitonyaka (http://pitonyak.org) -- AndrewMacro i OpenOffice Macros Explained. Znajdziesz w nich trochę objaśnień i dużo przykładów.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Krzysiek_P
Posty: 3
Rejestracja: pt lut 08, 2013 11:57 pm

Re: Nr wiersza aktywnej komórki

Post autor: Krzysiek_P »

Dzięki za podpowiedź.Faktycznie symbol a zastąpiłem innym i błąd zniknął.Poczytałem trochę i w sumie chyba udało mi się coś stworzyć.Poniżej załączam kod który pewnie nie jest doskonały ale działa. Mile widziane uwagi jeśli można go napisać bardziej elegancko albo zwięźlej. Jeszcze tylko muszę dopisać kawałek aby można było wydrukować arkusz2 (sformatowany test z wstawionymi już komórkami z arkusza 1 - jedna strona) i jeszcze nie wiem jak to zrobić . A oto kod:

Kod: Zaznacz cały

sub zlecenia
  oDoc = ThisComponent
  If oDoc.CurrentController.getActiveSheet.Name <> "Arkusz1" Then
    MsgBox "Ustaw się na Arkuszu nr 1"
    exit sub
  End If
    
  oActiveCell = oDoc.CurrentSelection
  oCellAddress=oActiveCell.getCellAddress
  oRow=oCellAddress.Row
    
  aSheet=oDoc.Sheets(0) 
  aCell_nrzl=aSheet.getCellByposition(0,oRow) 		'Nr zlecenia
  aCell_datazl=aSheet.getCellByposition(1,oRow)		'Data zlecenia
  aCell_nazwisko=aSheet.getCellByposition(2,oRow)       'Nazwisko i imię klienta
  aCell_nrtel=aSheet.getCellByposition(3,oRow)		'Nr telefonu
  
  rem Zapisywanie wartości komórek w Arkusz2----------------------------------------
  oSheet=oDoc.Sheets(1)
  
  oCell=oSheet.getCellByPosition(3,6) 
  oCell.setString(aCell_nrzl.getString())

  oCell=oSheet.getCellByPosition(6,1)
  oCell.setString(aCell_datazl.getString())  
  

  oCell=oSheet.getCellByPosition(5,9)
  oCell.setString(aCell_nazwisko.getString())  

  oCell=oSheet.getCellByPosition(5,10)
  oCell.setString(aCell_nrtel.getString())  

end sub  
Dziękuję za porady - bardzo pomogły i proszę o następne (wydruk)
Ostatnio zmieniony wt lut 19, 2013 12:50 am przez Minio, łącznie zmieniany 1 raz.
Powód: przeniesienie tagów [code], aby otaczały tylko kod makra, a nie całą treść wiadomości
OpenOffice 3.4.1 na Windows XP
Awatar użytkownika
antekg
Posty: 18
Rejestracja: śr sie 25, 2010 6:18 pm
Lokalizacja: Warszawa

Re: Nr wiersza aktywnej komórki

Post autor: antekg »

Ja miałem problem z numerem kolumny aktywnej komórki. Rozwiązałem to w następujący sposób:

Kod: Zaznacz cały

Dim StartCol%
StartCol = ThisComponent.CurrentSelection.CellAddress.Column
Działa poprawnie z wyjątkiem sytuacji, kiedy na arkuszu jest zaznaczonych wiele komórek. Wtedy pojawia się błąd mówiący, że nie ma czegoś takiego jak CellAddress.
Rozwiązałem to imitując przesunięcie się na arkuszu. Imitacja polega na zastosowaniu przesunięcia o zero pozycji. Użyłem dispatcher'a:

Kod: Zaznacz cały

Dim StartCol%, args(1) As New com.sun.star.beans.PropertyValue, document, dispatcher As Object
Rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

args(0).Name = "By"
args(0).Value = 0
args(1).Name = "Sel"
args(1).Value = false

Rem Remove a selection if any
dispatcher.executeDispatch(document, ".uno:GoLeft", "", 0, args())

StartCol = ThisComponent.CurrentSelection.CellAddress.Column

Działa dobrze, ale czy może jest bardziej naturalna i prosta metoda usuwania selekcji wielu komórek?
AOO 4.1.4 (Polish) na Windows 10 (64b) / AOO 4.1.0 na Windows Vista / LibreOffice na Mageia Linux
Jan_J
Posty: 4560
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Nr wiersza aktywnej komórki

Post autor: Jan_J »

Używanie dispatchera to de facto emulacja skutków działania interfejsu użytkownika, czyli ostateczność.
Bardziej naturalne byłoby rozstrzygnięcie, czy chodzi o komórkę (CellAddress), zakres (CellRange) czy zestaw zakresów (w tej chwili nie pamiętam, ale chyba tablica kolejnych CellRange).
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
antekg
Posty: 18
Rejestracja: śr sie 25, 2010 6:18 pm
Lokalizacja: Warszawa

Re: Nr wiersza aktywnej komórki

Post autor: antekg »

Dziękuję Janie za Twoją odpowiedź.
Zasadniczo mój cel się zmienił po dyskusji na forum angielsko-języcznym.
https://forum.openoffice.org/en/forum/v ... 00#p432080
Teraz szukam wszelkich możliwych zagrożeń przy stosowaniu odwołania:

Kod: Zaznacz cały

ThisComponent.CurrentSelection.CellAddress
Jedno zagrożenie wcześniej opisałem i zaproponowałem rozwiązanie. To sytuacja, gdy CurrentSelection wykracza poza aktywną komórkę.
Czy są znane inne sytuacje stwarzające ryzyko pojawienia się komunikatu błędu?

Zgadzam się, że stosowanie dispatcher'a nie wygląda elegancko i być może nie jest efektywne czasowo. Ale szybkość ma znaczenie dopiero przy bardzo dużej liczbie poleceń.
Z drugiej strony, skoro jest to emulacja interfejsu użytkownika to skutki są dobrze przewidywalne. Można sprawdzić jak te polecenia zadziałają poruszając się bezpośrednio po arkuszu. Są mniejsze zagrożenia różnymi wyjątkami.
AOO 4.1.4 (Polish) na Windows 10 (64b) / AOO 4.1.0 na Windows Vista / LibreOffice na Mageia Linux
Awatar użytkownika
antekg
Posty: 18
Rejestracja: śr sie 25, 2010 6:18 pm
Lokalizacja: Warszawa

Re: Nr wiersza aktywnej komórki

Post autor: antekg »

Znalazłem lepsze i naturalne rozwiązanie ograniczenia selekcji do aktywnej komórki

Kod: Zaznacz cały

dispatcher.executeDispatch(document, ".uno:Deselect", "", 0, Array())
I pełny kod jest następujący:

Kod: Zaznacz cały

Dim document, dispatcher As Object

Rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Rem Removing a selection if any
dispatcher.executeDispatch(document, ".uno:Deselect", "", 0, Array())

StartCol% = ThisComponent.CurrentSelection.CellAddress.Column
Gdy ktoś chce mieć numer wiersza to zrobi drobną modyfikację.

Ponawiam swoją prośbę o zgłaszanie sytuacji, gdzie powyższy sposób zawiedzie.
AOO 4.1.4 (Polish) na Windows 10 (64b) / AOO 4.1.0 na Windows Vista / LibreOffice na Mageia Linux
Awatar użytkownika
antekg
Posty: 18
Rejestracja: śr sie 25, 2010 6:18 pm
Lokalizacja: Warszawa

Re: Nr wiersza aktywnej komórki

Post autor: antekg »

I w końcu rozwiązanie likwidacji zaznaczonego obszaru bez dispatcher'a podał mi Lupp https://forum.openoffice.org/en/forum/v ... 09#p432109 powołując się na JohnSUN-Pensioner'a https://forum.openoffice.org/en/forum/v ... s+#p428025. Mój kod obecnie jest następujący:

Kod: Zaznacz cały

ThisComponent.CurrentController.Select(ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges"))
StartCol% = ThisComponent.CurrentSelection.CellAddress.Column
AOO 4.1.4 (Polish) na Windows 10 (64b) / AOO 4.1.0 na Windows Vista / LibreOffice na Mageia Linux
ODPOWIEDZ