Otwarcie zestawu rekordów pod linuxem

Makropolecenia i funkcje w języku Basic
massaada
Posty: 5
Rejestracja: sob sty 21, 2012 5:31 pm

Otwarcie zestawu rekordów pod linuxem

Post autor: massaada »

Witam

Chciałbym w module Calc'a otworzyć zestaw rekordów i wypełnić nimi komórki. W windowsie robie tak:

Kod: Zaznacz cały

dim cnn as new adodb.connection
dim rs as new adodb.recordset
dim strsql as string

with cnn
.connectionstring="ścieżka do pliku bazy"
.provider="microsoft.jet.oledb.4.0"
.open
end with
' mam otwarte połączenie

' teraz pobieram dane dla recordset
strsql="select * from JakaśTabela"
rs.open strsql,cnn
W tym momencie mam jakieś rekordy w obiekcie z którymi mogę coś robić

Sedno problemu: Jak to zrobić pod linuxem gdzie nie ma ADODB ani DAO?. Super gdyby ktoś podał przykład VB z połączeniem do postgresql
LibreOffice 3.4.4 Lubuntu
Jan_J
Posty: 4557
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Otwarcie zestawu rekordów pod linuxem

Post autor: Jan_J »

Ten przykład to chyba z Excela?
W OpenOffice jeżeli korzystasz ze źródła danych zdefiniowanego jako plik odb, to jego obsługa przebiega niezależnie od systemu. W skrócie

Kod: Zaznacz cały

Sub sqltest()
dbContext = createUnoService("com.sun.star.sdb.DatabaseContext")
baza = dbContext.getByName(<tu nazwa zarejestrowanego źródłą danych>)
conn = baza.GetConnection(<tu nazwa użytkownika>, <tu jego hasło>)
rem tak pobieram treść zapytania z gotowej kwerendy w pliku odb
dbq = baza.QueryDefinitions.GetByName(<tu nazwa kwerendy w pliku odb>)
q = dbq.Command
rem albo zadaję pytanie bezpośrednio
q = "select * from dual"
rem wysyłamy zapytanie
stm = conn.createStatement()
res = stm.executeQuery(q)
conn.close()
End Sub
rem tak dobieram się do wyników
sub wynikiNaArkusz(wyniki, arkusz, kolumna, wiersz)
	if not isnull(wyniki) then
		szer = wyniki.columns.count
		for i = 0 to szer-1
		   arkusz.getCellByPosition(kolumna+i, wiersz).String = wyniki.Columns.ElementNames(i)
		next i
		while wyniki.next
		   wiersz = wiersz+1
		   for i = 0 to szer-1
		      arkusz.getCellByPosition(kolumna+i, wiersz).String = wyniki.GetString(i+1)
		   next i   
		wend 
	endif
end sub
Ja tego używam do komunikacji z postgres-em. Nigdy nie definiowałem połączenia bezpośrednio w kodzie, co nie znaczy że się nie da.
JJ
LO (7.6) ∙ AOO (4.1) ∙ Python (3.11|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
massaada
Posty: 5
Rejestracja: sob sty 21, 2012 5:31 pm

Re: Otwarcie zestawu rekordów pod linuxem

Post autor: massaada »

Bardzo Ci dziękuję. Spróbuję tak się połączyć.
Jeszcze mnie nurtuje ten sposób zdefiniowania połączenia bezpośrednio do postgre bez pliku odt.
Jeżeli masz jakiś przykład albo linka gdzie tego szukać było by extra, ale i tak Ci jestem bardzo wdzięczny
LibreOffice 3.4.4 Lubuntu
Jan_J
Posty: 4557
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Otwarcie zestawu rekordów pod linuxem

Post autor: Jan_J »

Nigdy tego nie robiłem, ale postanowiłem poszukać.
Za pośrednictwem znanego serwisu Google.com dotarłem do dokumentu http://www.packtpub.com/sites/default/f ... hapter.pdf recenzowanego przez samego A. Pitonyaka, w którym autor, M. A. Bain, objaśnia szczegóły dostępu do baz danych z poziomu Basica w OOo. Zaczyna od skonfigurowania interfejsu odb, którym się dalej posługuje. Czyli tak jak podałem wyżej.

Po przewertowaniu dokumentacji połączenie z bazą bez użycia interfejsu odb udało się:

Kod: Zaznacz cały

  dbc = createUnoService("com.sun.star.sdb.DatabaseContext")

  dbs = dbc.createInstance() rem obiekt klasy DatabaseSource
  dbs.URL = "jdbc:postgresql://<adres serwerowy Twojej bazy>"
  dbs.user = "<nazwa użytkownika>"
  dbs.password = "<hasło użytkownika>"
  dbs.IsPasswordRequired = True
  
  Dim args(0) As New com.sun.star.beans.PropertyValue
  args(0).Name = "JavaDriverClass"
  args(0).Value = "org.postgresql.Driver"
  dbs.setPropertyValue("Info", args())
  
  handler = createUnoService("com.sun.star.sdb.InteractionHandler")
  conn = dbs.ConnectWithCompletion(handler)

  stm = conn.createStatement()
  q = "<treść Twojego zapytania>"
  res = stm.executeQuery(q)
  
  rem trzeba przejrzeć res

  conn.Close()
Wybór źródeł:
http://www.oooforum.org/forum/viewtopic.phtml?t=19146
http://www.openoffice.org/api/docs/comm ... ource.html
http://www.openoffice.org/api/docs/comm ... river.html

// edit. Po kilku próbach mamy to samo w Pythonie:

Kod: Zaznacz cały

# coding: utf-8
import uno

def pobierzDaneZBazy():
# łączy się z bazą za pośrednictwem sterownika JDBC, bez pośrednictwa pliku ODB
    ctx = uno.getComponentContext()
    smgr = ctx.ServiceManager
    dbc = smgr.createInstance("com.sun.star.sdb.DatabaseContext")

    dbs = dbc.createInstance()
    dbs.URL = "jdbc:postgresql://<tu adres Twojej bazy>"
    dbs.User = "<tu nazwa Twojego użytkownika>"
    dbs.IsPasswordRequired = True
    
    arg = uno.createUnoStruct("com.sun.star.beans.PropertyValue") 
    arg.Name = "JavaDriverClass"
    arg.Value = "org.postgresql.Driver"  # lub inna dla innej bazy (klasa musi być zarejestrowana w konfiguracji  OOo/LO)

    dbs.Info = (arg,)

    handler = smgr.createInstance("com.sun.star.sdb.InteractionHandler")
    conn = dbs.connectWithCompletion(handler)
    stm = conn.createStatement()
    q = "<tu treść Twojego zapytania SQL>"
    res = stm.executeQuery(q)
    
    ark = XSCRIPTCONTEXT.getDocument().getCurrentController().getActiveSheet()
    wstawNaArkusz(res, ark, 0, 0)
    
    conn.close()

def drukuj(wyniki):
    if not wyniki is None:
        n = wyniki.Columns.Count
        wzorzec = '\t'.join(n * ('%s',)) + '\n'
        print (wzorzec % wyniki.Columns.ElementNames).encode('utf8'),
        while wyniki.next():
            print wzorzec % tuple([ wyniki.getString(i) for i in range(1,n+1) ]),

def wstawNaArkusz(wyniki, arkusz, kolumna, wiersz):
    if not wyniki is None:
        n = wyniki.Columns.Count
        for i in range(n):
            arkusz.getCellByPosition(kolumna+i, wiersz).setString(wyniki.Columns.ElementNames[i])
        while wyniki.next():
            wiersz += 1
            for i in range(n):
                arkusz.getCellByPosition(kolumna+i, wiersz).setString(wyniki.getString(i+1))

JJ
LO (7.6) ∙ AOO (4.1) ∙ Python (3.11|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
massaada
Posty: 5
Rejestracja: sob sty 21, 2012 5:31 pm

Re: Otwarcie zestawu rekordów pod linuxem

Post autor: massaada »

Dzieki za pomoc. Wszystko udało mi się doprowadzić do oczekiwanego rezultatu poza jednym:

Kiedy wstawiam rekordy do pól poprzez

Kod: Zaznacz cały

arkusz.getCellByPosition(kolumna+i, wiersz).String = res.GetString(i+1)
komórka zawiera wartość '5 a nie 5 czyli przed liczbą jest apostrof i pole jest traktowane jako tekst a nie liczba.

Może jakiś pomysł?
LibreOffice 3.4.4 Lubuntu
Jan_J
Posty: 4557
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Otwarcie zestawu rekordów pod linuxem

Post autor: Jan_J »

Pamiętaj, że komórka.String = xxx oraz funkcja komórka.setString() wstawiają do komórki wartość typu string, podczas gdy komórka.Value = xxx oraz funkcja komórka.setValue() wstawiają do niej wartość liczbową.
Powinno pomóc. Jeśli nie, to zmień także sposób pobierania wartości z bazy: zamiast wynik.getString(i) użyj wynik.getInt(i) w tych kolumnach, gdzie spodziewasz się liczb.
JJ
LO (7.6) ∙ AOO (4.1) ∙ Python (3.11|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
massaada
Posty: 5
Rejestracja: sob sty 21, 2012 5:31 pm

Re: Otwarcie zestawu rekordów pod linuxem

Post autor: massaada »

Jesteś wielki, bardzo mi pomogłeś.

To już moje ostatnie pytanie.

W zestawie rekordów mam pole typu interval czyli przedzial czasowy np 49:32. Format komórki w oo odpowiadający temu polu to [HH]:MM.
Jak to pole zapisać do komorki prawidłowo. Value się nie nadaje, string wiadomo zamienia na łańcuch. Próbowałem coś wykombinować z dokumentacji
ale jakoś mi nie wychodzi.(Nie znam javy). Próbowałem zrobić tak:

Kod: Zaznacz cały

arkusz.getCellByPosition(4, wiersz).Data = res.GetDate(3)
' nie działa, coś mu z właściwością nie pasuje
Niw wiem o co chodzi, jeśli jeszcze możesz coś podpowiedzieć ... ;)

-----------------------------------------------------------------------------------------------------------
Udało mi się znaleźć rozwiązanie:

Kod: Zaznacz cały

arkusz.getCellByPosition(4, wiersz).Value = TimeValue(res.GetString(3))
Być może na około, ale działa. Mimo wszystko jeśli ktoś znajdzie bezpośredni sposób, będę wdzięczny.
LibreOffice 3.4.4 Lubuntu
ODPOWIEDZ