Otwarcie zestawu rekordów pod linuxem

Makropolecenia i funkcje w języku Basic

Otwarcie zestawu rekordów pod linuxem

Postprzez massaada » So sty 21, 2012 5:48 pm

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   Rozszerz widokZwiń widok
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
massaada
 
Posty: 5
Dołączył(a): So sty 21, 2012 5:31 pm

Re: Otwarcie zestawu rekordów pod linuxem

Postprzez Jan_J » N sty 22, 2012 8:04 pm

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   Rozszerz widokZwiń widok
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 Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3989
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Otwarcie zestawu rekordów pod linuxem

Postprzez massaada » N sty 22, 2012 9:55 pm

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
massaada
 
Posty: 5
Dołączył(a): So sty 21, 2012 5:31 pm

Re: Otwarcie zestawu rekordów pod linuxem

Postprzez Jan_J » N sty 22, 2012 10:28 pm

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   Rozszerz widokZwiń widok
  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   Rozszerz widokZwiń widok
# 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 Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3989
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Otwarcie zestawu rekordów pod linuxem

Postprzez massaada » N sty 29, 2012 2:44 pm

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   Rozszerz widokZwiń widok
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
massaada
 
Posty: 5
Dołączył(a): So sty 21, 2012 5:31 pm

Re: Otwarcie zestawu rekordów pod linuxem

Postprzez Jan_J » N sty 29, 2012 7:11 pm

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 Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3989
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Otwarcie zestawu rekordów pod linuxem

Postprzez massaada » N sty 29, 2012 9:57 pm

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   Rozszerz widokZwiń widok
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   Rozszerz widokZwiń widok
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
massaada
 
Posty: 5
Dołączył(a): So sty 21, 2012 5:31 pm


Powrót do Basic

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość