Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice Calc

Dyskusje dotyczące tworzenia makropoleceń, pisania skryptów oraz programowania przy użyciu UNO
lukasz393
Posty: 7
Rejestracja: śr paź 21, 2009 1:18 pm

Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice Calc

Post autor: lukasz393 »

Witam!
Tworzę dokument w OpenOffice Calc w którym po naciśnięciu przycisku tworzy mi się nowy arkusz, który jest kopią innego arkusza... Zrobiłem to poprzez nagranie makra...

Kod: Zaznacz cały

sub kopiuj_arkusz2
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Nr"
args1(0).Value = 2

dispatcher.executeDispatch(document, ".uno:JumpToTable", "", 0, args1())

rem ----------------------------------------------------------------------
dim args2(2) as new com.sun.star.beans.PropertyValue
args2(0).Name = "DocName"
args2(0).Value = "kopiowanie arkusza"
args2(1).Name = "Index"
args2(1).Value = 32767
args2(2).Name = "Copy"
args2(2).Value = true

dispatcher.executeDispatch(document, ".uno:Move", "", 0, args2())

rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "Nr"
args3(0).Value = 1

dispatcher.executeDispatch(document, ".uno:JumpToTable", "", 0, args3())

end sub
Niestety nie wiem jak zrobić aby nowe arkusze tworzyły się ze zmienioną nazwą kolejno: Nowy1, Nowy2, Nowy3... itd.
OpenOffice 3.1 na Windows XP
mg2
Posty: 170
Rejestracja: czw sty 28, 2010 9:20 pm

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: mg2 »

Nie wszystkie znaki można używać w nazwie arkusza. Gdy podamy niedozwolony znak np. "*" poniższe makro zawiesi działanie.

Kod: Zaznacz cały

sub nowy()
 dim oDok as object
 dim oArk as object
 dim podstawa, nazwa as string
 dim ilosc as integer
 dim i as integer
 
 oDok = thisComponent
 podstawa = inputbox("podaj nazwę nowego arkusza")
 ilosc = inputbox("podaj ilość arkuszy")
 
 for i=1 to ilosc
  nazwa = podstawa & i
  if oDok.sheets.hasByName(nazwa)=false then
   oArk = oDok.createInstance("com.sun.star.sheet.Spreadsheet")
   oDok.sheets.insertByName(nazwa,oArk)
   else
    msgbox("""" & nazwa & """" & " już istnieje")
  end if
 next i
end sub
Załączniki
nowy_arkusz.ods
(10.02 KiB) Pobrany 511 razy
OOo3.1.1 na Ubuntu 9.04
mg2
Posty: 170
Rejestracja: czw sty 28, 2010 9:20 pm

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: mg2 »

Odpowiadając na pytanie jednego z forumowiczów:
Potrzebuje generować arkusze na każdy dzień miesiąca z nazwami:
01-C
02-P
03-S
04-N (najlepiej pomijany, ale niekoniecznie)
05-Poniedziałek
06-W
07-Ś

i tak dalej do 31.
powyższy format to 01 - data miesiąca i C - czyli czwartek

Jak wiadomo, nie zawsze miesiąc się zaczyna od czwartku więc to musi być
coś takiego co robi datę czy tam od 1 do 31, ale jako końcówkę podawać
dzień, który zdefiniuję jako pierwszy, czyli . . .
powinienem mieć chyba wybór:
- że od 1
- i dzień rozpoczynający
reszta już generowałaby się ze wzoru o krok.

Kod: Zaznacz cały

sub nowy()
  dim oDok as object
  dim oArk as object
  dim dzien_nr_poczatek as integer
  dim dzien_nr_koniec as integer
  dim dzien_litera_poczatek as string
  dim dzien_litera_licz
  dim dni_litery(7) as string
  dim pomin_niedz as boolean
  dim pomin_niedz_tn as string
  dim dzien_licz as integer
  dim wstaw_zero as string

  dni_litery(1) = "Pn"
  dni_litery(2) = "Wt"
  dni_litery(3) = "Śr"
  dni_litery(4) = "Cz"
  dni_litery(5) = "Pt"
  dni_litery(6) = "So"
  dni_litery(7) = "N"
  pomin_niedz = true
  pomin_niedz_tn = "T"
  dzien_licz = 0
 
  oDok = thisComponent
  dzien_nr_poczatek = inputbox("Numer pierwszego dnia:", "Nowy arkusz", 1)
  dzien_nr_koniec = inputbox("Numer ostatniego dnia:", "Nowy arkusz", 31)
  dzien_litera_poczatek = inputbox("Nazwa pierwszego dnia (Pn, Wt, Śr, Cz, Pt, So, N):", "Nowy arkusz", "Pn")
  pomin_niedz_tn = inputbox("Pomin niedziele (T/N):", "Nowy arkusz", "T")

  if(pomin_niedz_tn = "T") then
    pomin_niedz = true
  elseif(pomin_niedz_tn = "N") then
    pomin_niedz = false
  end if

  for dzien_litera_licz = 1 to 7
    if(dni_litery(dzien_litera_licz) = dzien_litera_poczatek) then
      dzien_litera_licz = dzien_litera_licz - 1
      exit for
    end if
  next dzien_litera_licz

  for dzien_licz = dzien_nr_poczatek to dzien_nr_koniec
    dzien_litera_licz = dzien_litera_licz + 1
  	if(dzien_litera_licz > 7) then
  	  dzien_litera_licz = 1
    end if
    if(dzien_licz < 10) then
      wstaw_zero = "0"
    else
      wstaw_zero = ""
    end if
    nazwa = dni_litery(dzien_litera_licz) & "-" & wstaw_zero & dzien_licz
    if not(dzien_litera_licz = 7 and pomin_niedz = true) then
      if oDok.sheets.hasByName(nazwa) = false then
        oArk = oDok.createInstance("com.sun.star.sheet.Spreadsheet")
        oDok.sheets.insertByName(nazwa,oArk)
      else
        msgbox("""" & nazwa & """" & " już istnieje")
      end if
   end if
  next dzien_licz
end sub

Załączniki
nowy_arkusz_dni.ods
(10.89 KiB) Pobrany 330 razy
OOo3.1.1 na Ubuntu 9.04
bolej1
Posty: 4
Rejestracja: czw gru 27, 2012 12:58 pm

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: bolej1 »

Witam ja potrzebowalbym zeby tworzyl mi sie nowy arkusz z wprowadzonym np. numerem seryjnym i numer zostal automatycznie wpisany w kolejny rekord pierwszego glownego arkusza i zeby byl widoczny w nowo utworzonym arkuszu. Nie umiem sobie z tym poradzic moze ktos pomoze.
OpenOffice 2.2.0
Jan_J
Posty: 4579
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: Jan_J »

Szkic załączony niżej zakłada, że w pierwszym arkuszu a kolumnie A prowadzimy numerację. Uruchomienie makra powoduje przydzielenie następnego numeru, założenie nowego arkusza i wpisanie do niego tego samego numeru.
Na pewno nie jest to gotowy produkt, ale pokazuje jak działa maszyneria.

Kod: Zaznacz cały

const arkuszZNumeramiSeryjnymi = 0   rem pierwszy -- niemądre, bo wrażliwe na przeciąganie zakładek
const kolumnaZNumeramiSeryjnymi = 0  rem kolumna A, może być

rem poszukuje ostatniej zajętej komórki w kolumnie; powolna
function znajdzOstatni(arkusz, kolumna) as object
  wiersz = 0
  kom = arkusz.getCellByPosition(kolumna, wiersz)
  poprzednia = kom ' na wypadek gdyby pierwsza była pusta
  while kom.String <> ""
    poprzednia = kom
    wiersz = wiersz + 1
    kom = arkusz.getCellByPosition(kolumna, wiersz)
  wend
  znajdzOstatni = poprzednia
end function

Sub test()
  skoroszyt = thisComponent
  arkusz = skoroszyt.Sheets.getByIndex(arkuszZNumeramiSeryjnymi)
  kom = znajdzOstatni(arkusz, kolumnaZNumeramiSeryjnymi)
  wiersz = kom.RangeAddress.StartRow + 1
  nowynumer = kom.getValue() + 1
  arkusz.getCellByPosition(kolumna, wiersz).setValue(nowynumer)
  nark = skoroszyt.Sheets.count()  ' numer pozycyjny nowego arkusza
  skoroszyt.Sheets.insertNewByName("Nr_" & str(nowynumer), nark)
  nowyArkusz = skoroszyt.Sheets.getByIndex(nark)
  nowyArkusz.getCellByPosition(0,0).setValue(nowynumer)
End Sub
JJ
LO (24.2|7.6) ∙ Python (3.12|3.11|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
bolej1
Posty: 4
Rejestracja: czw gru 27, 2012 12:58 pm

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: bolej1 »

Witaj bardzo Ci dziekuje za test ladnie dziala jest bardzo blisko tego co potrzebuje. Chcialbym zeby nowynumer = kom.getValue() + 1 nie nadawal i zwiekszal o jeden ale z czytywal z pierwszej kolumny arkusza glownego. No i zeby hiperlaczem z automatu sie laczylo to by byla bajka. Pomozesz?
OpenOffice 2.2.0
Jan_J
Posty: 4579
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: Jan_J »

bolej1 pisze:Witaj bardzo Ci dziekuje za test ladnie dziala jest bardzo blisko tego co potrzebuje. Chcialbym zeby nowynumer = kom.getValue() + 1 nie nadawal i zwiekszal o jeden ale z czytywal z pierwszej kolumny arkusza glownego. No i zeby hiperlaczem z automatu sie laczylo to by byla bajka. Pomozesz?
Taaak...
To znaczy, Ty wpisujesz numer i wymuszasz wykonanie makra, które zakłada arkusz o odpowiedniej nazwie.

Numer jest pobierany z ostatniej wypełnionej komórki w arkuszu bazowym.
W nowym arkuszu, w komórce A1 umieszczany jest odsyłacz (to znaczy formuła) do oryginalnego numeru w arkuszu bazowym.
Zmiana numeru w arkuszu bazowym nie zmieni nazwy arkusza, ale umieszczona w nim komórka zaktualizuje się poprzez formułę.

Kod: Zaznacz cały

const arkuszZNumeramiSeryjnymi = "Arkusz1"   rem bazowy
const kolumnaZNumeramiSeryjnymi = 0  rem kolumna A

rem poszukuje ostatniej zajętej komórki w bloku kolumnowym; szybka
rem wynik = uchwyt komórki (może być pusta, jeżeli pierwsza komórka w kolumnie jest pusta)
function znajdzOstatni(arkusz, kolumna) as object
  ostatni = 0
  poprzedni = ostatni
  krok = 1
  rem polujemy na pustą komórkę z coraz większym krokiem
  while arkusz.getCellByPosition(kolumna, ostatni).String <> ""
    poprzedni = ostatni
    ostatni = ostatni + krok
    krok = 2*krok
  wend
  rem blok kończy się między wierszami pierwszy i ostatni
  dim wiersz as integer
  while ostatni <> poprzedni
      wiersz = (ostatni + poprzedni) / 2
      kom = arkusz.getCellByPosition(kolumna, wiersz)
      if kom.String <> "" then
        poprzedni = wiersz
      else
        ostatni = wiersz-1
      end if 
  wend
  znajdzOstatni = arkusz.getCellByPosition(kolumna, ostatni)
end function

rem wstawia arkusz o zadanej nazwie do skoroszytu
rem wynik = znacznik logiczny powodzenia operacji
function wstawArkusz(skoroszyt, nazwa) as boolean
  on error goto blad
    nowyArkusz = skoroszyt.Sheets.getByName(nazwa)
  on error goto
    msgbox("Arkusz '" & nazwa & "' nie może zostać utworzony")
    wstawArkusz = false
    goto dalej
  blad:
    nark = skoroszyt.Sheets.count()  ' numer pozycyjny nowego arkusza
    skoroszyt.Sheets.insertNewByName(nazwa, nark)
    wstawArkusz = true
  dalej:
end function

sub test()
  skoroszyt = thisComponent
  arkusz = skoroszyt.Sheets.getByName(arkuszZNumeramiSeryjnymi)
  kom = znajdzOstatni(arkusz, kolumnaZNumeramiSeryjnymi)
  
  nowyNumer = kom.getString()
  if nowyNumer <> "" then
    nowaNazwa = "Nr_" & nowyNumer
    if wstawArkusz(skoroszyt, nowaNazwa) then
        nowyArkusz = skoroszyt.Sheets.getByName(nowaNazwa)
        nowyArkusz.getCellByPosition(0,0).setFormula("=" & kom.AbsoluteName)
    end if
  end if
end sub
Edit: podmieniłem funkcję znajdzOstatni na inną, szybszą.
JJ
LO (24.2|7.6) ∙ Python (3.12|3.11|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
belstar
Posty: 654
Rejestracja: czw mar 17, 2011 9:08 am

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: belstar »

A czy bolej1 nie chce mieć linku z arkusza bazowego do tego nowo utworzonego.
bolej1 pisze:No i zeby hiperlaczem z automatu sie laczylo to by byla bajka.
Jeśli tak to dopisz po linii

Kod: Zaznacz cały

nowyArkusz.getCellByPosition(0,0).setFormula("=" & kom.AbsoluteName)

poniższą linijkę.

Kod: Zaznacz cały

kom.FormulaLocal = "=HIPERŁĄCZE(""" & "#" &  nowaNazwa &  """ ;""" & nowyNumer & """)"
Ostatnio zmieniony śr sty 02, 2013 1:06 pm przez belstar, łącznie zmieniany 1 raz.
LibreOffice 5.1.2.2 Ubuntu 16 LTS
bolej1
Posty: 4
Rejestracja: czw gru 27, 2012 12:58 pm

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: bolej1 »

Dziekuje wam bardzo za pomoc. Dziala to juz ladnie hiperlocza tez potrzebna ale nie wiem w ktore miejsce wpisac ten kod:/ Moze jeszcze male udoskonalenie zamiast twozenia nowego arkusza kopiuje arkusz "szablon" i wpisuje tam ten nr seryjny jest to mozliwe?
OpenOffice 2.2.0
belstar
Posty: 654
Rejestracja: czw mar 17, 2011 9:08 am

Re: Tworzenie nowego arkusza ze zmienioną nazwą OpenOffice C

Post autor: belstar »

Witam
Musisz sprecyzuj co chcesz uzyskać, bo twoje wypowiedzi są trochę chaotyczne.
bolej1 pisze:Dziala to juz ladnie hiperlocza tez potrzebna ale nie wiem w ktore miejsce wpisac ten kod:/
Krok po kroku wypunktuj, co, gdzie i jak to widzisz a najlepiej wstaw przykładowy plik z komentarzami.
Ps.
Używaj narzędzi sprawdzania pisowni.
LibreOffice 5.1.2.2 Ubuntu 16 LTS
ODPOWIEDZ