CALC: BASE-Abfrage in Tabelle bekommen

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Moin, ich habe mir mit OpenOffice eine Datenbank mit Base angelegt. Auf diese kann ich nun in Calc zugreifen über "Datenquellen". Da kann man ja einfach eine gespeicherte Abfrage per drag&drop in eine Tabelle ziehen. Ich würde das gern mit einem Makro erreichen, aber mit "Makro aufzeichnen" scheint das nicht zu funktionieren. Wie müsste der Code aussehen, um eine Abfrage um die Tabelle zu bekommen?

Danke für eure Anregungen
crush




Moderation,4: verschoben in BASIC-Unterbereich, wo alle Makro-Fragen hin gehören; Betreff angepasst
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von komma4 »

Willkommen im Forum.

Benutze die SUCHE (ggfs. über Google mit site:http://de.openoffice.info/) und finde viele Hinweise auf Deine Frage, wenn Du nach Resultset suchst.


Viel Erfolg!
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Hallo, ich habe nun schon etwas zustande gebracht.

Code: Alles auswählen

REM  *****  BASIC  *****


sub Main
rem ----------------------------------------------------------------------
rem define variables
Dim DatabaseContext As Object
Dim DataSource As Object
Dim Connection As Object
Dim InteractionHandler as Object
Dim Statement As Object
Dim ResultSet As Object
dim document   as object
dim dispatcher as object
dim args2(0) as new com.sun.star.beans.PropertyValue
dim args3(0) as new com.sun.star.beans.PropertyValue

rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
 
DatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
DataSource = DatabaseContext.getByName("Neue Datenbank3")
 
rem If Not DataSource.IsPasswordRequired Then
  Connection = DataSource.GetConnection("user","pw")
rem Else
rem  InteractionHandler = createUnoService("com.sun.star.sdb.InteractionHandler")
rem  Connection = DataSource.ConnectWithCompletion(InteractionHandler)
rem End If
 
Statement = Connection.createStatement()
ResultSet = Statement.executeQuery("SELECT ""ksttr"", ""bezeichnung_0_"" FROM ""heinebekost"" WHERE ""ksttr"" BETWEEN 1301 AND 1370") rem ""ksttr"", ""bezeichnung_0_""

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

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

rem ----------------------------------------------------------------------
args2(0).Name = "StringName"
args3(0).Name = "StringName"

If Not IsNull(ResultSet) Then
  While ResultSet.next
    args2(0).Value = ResultSet.getString(1)
    args3(0).Value = ResultSet.getString(2)
    dispatcher.executeDispatch(document, ".uno:EnterString", "", 0, args2())
    rem HIER MÜSSTE EIN CODE STEHEN, DER DEN CURSER NACH RECHTS STELLT
    dispatcher.executeDispatch(document, ".uno:EnterString", "", 0, args3())
    dispatcher.executeDispatch(document, ".uno:JumpToNextCell", "", 0, Array())
  Wend
End If



end sub
Meine Frage: Das Resultset ist zweispaltig. Diese beiden Spalten werden dann über die Schleife ganz unten ausgegeben. Ich finde aber keinen Code wie erst eine Zelle nach rechts gesprungen wird bevor args3 ausgegeben wird und dann "JumpToNextCell" ausgefüht wird. Also habe ich bis jetzt immer nur eine Spalte, und die zweite fehlt. Wie komme ich nach dem schreiben von args2 in die Zelle rechts daneben? Wenn ich von Hand eine Tabelle fülle, springt der Cursor nach mehrmaligem betätigen von "tab" und anschließendem "Return" wieder in die erste Spalte der nächsten Zeile. Klappt das mit BASIC auch?

Gruß crush
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Niemand eine Ahnung, oder muss ich das Resultset zweimal durchlaufen, und beide Spalten getrennt voneinander ausgeben lassen?

Gruß crush
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von komma4 »

Wenn Du Dich mal ein wenig umgesehen hättest, dann wäre Dir aufgefallen, dass fast niemand (der Makros schreibt!) dispatcher Code verwendet.

Zum Setzen kannst Du einfachst .getCellByPosition nehmen.

Für grössere Datenmengen empfiehlt sich das Setzen aller Daten auf einmal: .setDataArray( aDaten )


Ein Beispiel in einer Anwendung, siehe meine Extension OOoDIL - DokumentInfoListe
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Ich würde mich ja gern mehr selbst belesen und einarbeiten, aber ich habe bis jetzt keine geeignete Dokumentation gefunden, in der nicht nur beschrieben ist, wie ein Array initialisiert wird, sondern auch wieder es in einer Tabelle ausgegeben wird. Gibt es ein Nachschlagewerk, wo Funktionen wie ".getCellByPosition" und ähnliche beschrieben und dokumentiert sind? Ich habe bis jetzt C++, MATLAB, Java, SQL... programmiert und bin mit Visual- und StarBasic noch ein wenig ungeübt.

Gruß crush
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von komma4 »

crush hat geschrieben:Ich würde mich ja gern mehr selbst belesen und einarbeiten
SDK
Andrews Makro-Dokument

Siehe auch das Coding von OOoDIL - zwar nicht viel dokumentiert, aber -so hoffe ich- selbsterklärend
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Ok hier mein Versuch ohne dispatcher...

Code: Alles auswählen

dim MyArray(2,1000)
dim i as Integer
i = 1
rem ----------------------------------------------------------------------

If Not IsNull(ResultSet) Then
  While ResultSet.next
    MyArray(1,i) = ResultSet.getString(1)
    MyArray(2,i) = ResultSet.getString(2)
    i = i+1
  Wend
End If
osheet = thiscomponent.sheets(0)
osheet.getCellRangeByName("C2:D1000").setDataArray(MyArray())
Ich hänge im Moment noch daran, die Größe des Resultsets herauszubekommen, um das Array nicht überzudimensionieren. Aber selbst wenn, funktioniert es noch nicht, es kommt:
"BASIC Laufzeitfehler Type: com.sun.star.unoRuntimeException Message: ." mit verweis auf die letzte Zeile. Kann ich die Methoden nicht hintereinander hängen, sondern muss die Range noch extra definieren und dann erst .setDataArray hinten dranhängen oder was mache ich noch falsch?

Gruß crush
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von Karolus »

Hallo
Etwa so:

Code: Alles auswählen

dim MyArray(1000)
    i = -1

    If Not IsNull(ResultSet) Then
      While ResultSet.next
        i = i+1
        MyArray(i) = array( ResultSet.getString(1),ResultSet.getString(2))
      Wend
        redim Preserve MyArray( i )
    End If
    osheet = thiscomponent.sheets(0)
    osheet.getCellRangeByPosition(2,1,3,1+i).setDataArray(MyArray())
Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Super, das hat geklappt. Aber warum bekomme ich bei getCellRangeByName eine Fehlermeldung?

Zwei kleine Fragen hätte ich noch: Mit "ResultSet = Statement.executeQuery(....." führe ich ja die Abfrage aus. Kann ich da nicht auch den Namen der Abfrage eintragen, die in der Datenbank abgespeichert ist, statt die query als String einzugeben?
Und gibt es die Möglichkeit "osheet = ThisComponent.sheets(7)" auch mit dem Tabellenblatt-Namen anzusprechen, statt die Nummer des Blattes einzutragen?

Gruß crush
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von Karolus »

Hallo
crush hat geschrieben:Super, das hat geklappt. Aber warum bekomme ich bei getCellRangeByName eine Fehlermeldung?

Gruß crush
Woher sollen wir das wissen, wenn du zu bequem bist, den Quellcode zur Fehlermeldung hier zu posten und nichtmal die Fehlermeldung selbst postest.

Ich rate mal: dein ' .getCellRangeByName("bereichsadresse") hat nicht die passende Dimensionierung für ' .setDataArray( MyArray )

Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von komma4 »

crush hat geschrieben:Abfrage eintragen, die in der Datenbank abgespeichert ist

Code: Alles auswählen

' Kontext holen
oDatenbankKontext = CreateUnoService ( "com.sun.star.sdb.DatabaseContext" )

' Datenquelle auswählen
' registrierte Datenquelle
oDatenquelle = oDatenbankKontext.getByName( "hsqldb_test1" )


sQuery = "qry_order_positionen_Parameter"

' Abfragen
oAbfragen = oDatenquelle.QueryDefinitions 
' gewünschte Abfrage vorhanden?
if ( oAbfragen.hasByName( sQuery) ) Then
' Abfrage holen
oAbfrage = oAbfragen.getByName( sQuery )


' SQL-Ausdruck von Abfrage entnehmen
 sQuery = oAbfrage.Command
 ' Verbindung zur DB herstellen
 oVerbindung = oDatenquelle.getConnection( , )
 ' Statement erzeugen
 oStatement = oVerbindung.createStatement()
 ' Abfrage absetzen
 oResultSet = oStatement.executeQuery( oAbfrage.Command )
crush hat geschrieben:mit dem Tabellenblatt-Namen anzusprechen

Code: Alles auswählen

ThisComponent.Sheets().getByName( "meineTabelle" )


Besorge Dir Andrews Makro-Dokument für die Grundlagen, und vom gleichen Author Andrews Base-Dokument
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Klappt alles wunderbar, nur bekomme ich eine Fehlermeldung: "Unzulässiger Wert oder Datentyp: Überlauf" wenn ich sehr viele Spalten an das Array übergebe:

Code: Alles auswählen

If Not IsNull(Kraftstoff) Then
  While Kraftstoff.next
    j = j+1
    MyArray2(j) = array( CInt(Kraftstoff.getString(1)),  CInt(Kraftstoff.getString(2)),  CInt(Kraftstoff.getString(3)), CInt(Kraftstoff.getString(4)),  CInt(Kraftstoff.getstring(5)),  CInt(Kraftstoff.getstring(6)),  CInt(Kraftstoff.getstring(7)),  CInt(Kraftstoff.getstring(8)),  CInt(Kraftstoff.getstring(9)),  CInt(Kraftstoff.getstring(10)),  CInt(Kraftstoff.getstring(11)),  CInt(Kraftstoff.getstring(12)),  CInt(Kraftstoff.getstring(13)),  CInt(Kraftstoff.getstring(14)),  CInt(Kraftstoff.getstring(15)))
  Wend	
  	redim Preserve MyArray2(j)
End If
Ist dem Compiler die Zeile zu lang, denn bei mir stehen alle hintereinander. Habe in dem Handbuch keinen Hinweis gefunden, wie ich den Code auf mehrere Zeilen verteilen kann. Gibt es neben .getString auch sowas wie getValue oder getInteger, habe schon einige probiert, aber diese Methoden scheint es für das Resultset nicht zu geben.


EDIT: Die Fehlermeldung hat sich erledigt: Eine der Spalten aus der DB-Tabelle war kein Integer. CDbl statt CInt sollte die Lösung, da habe ich aber das Problem, dass das Komma als Dezimaltrennzeichen nicht erkannt wird, und aus 52,50 wird 5250...

EDIT: Ich glaube ich weiß auch warum, denn wenn ich nur getString für diese Spalte ausgeben lasse, ohne das CDbl, dann steht da "52.50" mit "Punkt" statt "Komma", obwohl in Base die Abfrage in der Tabelle ein "52,20" mit "Komma" ausgibt. Das liegt dann wahrscheinlich an der Ländereinstellung. Kann man das bei einer Konvertierung des Strings berücksichtigen?

EDIT: OK selbst gefunden, Val(...getString) statt der ganzen anderen bringt den Erfolg.
crush
**
Beiträge: 36
Registriert: Mo, 26.03.2012 08:19

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von crush »

Hallo, wie kann man Calc dazu bringen, eine Datenbankdatei wiederzufinden, die man nur von einem Ordner in den nächsten verschoben hat. Bei mir findet CALC die Datenbank deswegen nicht mehr. Zu dem habe ich noch durch diverses rumprobieren und falsches abspeichern meine Abfragen gelöscht :(. Um das noch einmal zu vermeide meine Frage: Wie kann ich nach dem Verschieben der .odb-Datei diese wieder dem System bekannt machen?

EDIT: Hab die Datei wieder hergestellt bekommen, und unter "Datenquellen" und "registrierte Datenquellen" kann man die Datei unter dem neuen Speicherort einfach nochmal in die Liste eintragen. Schönes Wochenende

Grüße crush
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: CALC: BASE-Abfrage in Tabelle bekommen

Beitrag von komma4 »

Extras>Optionen...>OpenOffice.org Base>Datenbanken
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Antworten