Formular schließen?

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

Moderator: Moderatoren

geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Formular schließen?

Beitrag von geimist »

Hallo,

ein Base-Formular möchte ich per Makro schließen.
So habe ich es versucht:

Code: Alles auswählen

	   oDoc = ThisComponent
       oDoc.close(true) 'Fenster schliessen   
Allerdings erscheint jetzt die Fehlermeldung:
BASIC-Laufzeitfehler.
Es ist eine Exception aufgetreten
Type: com.sun.star.util.CloseVetoException
Message: .


Könnt ihr mir helfen (ist wahrscheinlich auch nicht so schwer - aber für mich ;-)
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

Ich bin mir nicht ganz sicher, aber hast Du es schon mal mit Close(false) versucht?
Ich mache es ganz anders...., aber ich habe seit dem keine Probleme mehr mit dem Close.
Ist eine allgemeine Close-Routine, die zudem noch schnell dafür sorgt, daß alle anhängigen Daten zwangsweise gespeichert werden, weil ich mit einem externen Startmodul arbeite....

Per Ende-Button rufe ich aus jedem Formular ein kleines Sub auf, welches dann die echte Close-Routine aufruft:

Sub FormularClose
DocumentSchliessen(ThisComponent)
End Sub

Sub DocumentSchliessen(oThisComponent)
Dim oDoc As Object
Dim oDispatch As Object
oThisComponent.Parent.store() ' Daten speichern.... zur Sicherheit
oDoc = oThisComponent.CurrentController.Frame
oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
oDispatch.executeDispatch(oDoc, ".uno:CloseDoc", "", 0, Array())
End Sub

Gruß eBayer
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Hallo eBayer,

vielen Dank auch diesmal für deine Hilfe.

Da möchte ich gleich noch ganz unbescheiden eine anschließende Frage aufwerfen:

Aus einem Formular (in Base) heraus möchte ich die gesamte Datenbank (die verwendete .odb - Datei sowie die daraus geöffneten Formulare) schließen. Mit StarDesktop.terminate() kann man zwar das gesamte OpenOffice.org beenden, aber das ist mir eben zu grob.

Idee?
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

Das sollte klappen: (aber vorher zur sicherheit mit store() die bearbeiteten daten speichern!!!)

Sub Ende
oDoc = ThisComponent.CurrentController.Frame
oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
oDispatch.executeDispatch(oDoc, ".uno:CloseDoc", "", 0, Array()) ' erst das aktive Formular schließen

' ***************************************************************************
' * Bei der folgenden Methode bleibt OO im Speicher *
' ***************************************************************************
oDoc = ThisComponent.Parent.CurrentController.Frame ' und nun das Hauptfenster (Parent) holen
oDoc.close(true) ' und schließen
' ***************************************************************************
' * Hier kommt die harte Methode, die OO komplett beendet (incl. Schnellstart)*
' ***************************************************************************
' oDoc = ThisComponent.Parent.CurrentController.Frame
' oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
' oDispatch.executeDispatch(oDoc, ".uno:CloseDoc", "", 0, Array())
' oDispatch.executeDispatch(oDoc, ".uno:CloseWin", "", 0, Array())
End Sub

Gruß eBayer
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Vielen Dank.
Kannst du mir noch sagen, wo und wie ich das Store() unterbringen muss?
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

schau in meine erste Antwort.... da ist es drin.
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Sorry - war nicht aufmerksam. Aber da eröffnet sich bei mir gleich die nächste Lücke:
Ist oThisComponent nicht nur eine Variable - wo wird die definiert? Hat es etwas damit zu tun, dass sie schon hinter dem Namen des Makros steht (was ich auch noch nicht verstehe)?

Tut mir leid, aber ich habe es leider noch nicht so mit Basic :?
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

schau, was ich dir beim erstenmal geantwortet habe....
Ich wollte es Dir etwas allgemeingültiger erklären, ist aber offensichtlich etwas zuviel für Dich.
Mußt halt noch etwas trainieren..... wirklich!
Damit Du meinen Lösungsvorschlag einfach in Dein Formular übernehmen kannst, habe ich ihn nun etwas simpler gestaltet.
Also einfach das unten stehende Sub in Dein Formular kopieren, ok?

Mit dem Ende-PushButton willst Du ja vermutlich das Formular beenden..... Also verbindest Du bei dem Pushbutton das Ereignis "beimAuslösen" mit dem unten stehenden Makro.
Leider wird das Makro nicht angesprungen, wenn das Formular mit dem X geschlossen wird.
Wie das geht, werde ich Dir ggf. in einem weiteren Schritt zeigen.
Wenn Du das Makro ohne Veränderung so reinkopiert und mit dem PushButton verbunden hast, sollte es auf Anhieb laufen!
Gruß und viel Erfolg mit der Bitte um Erfolgsmeldung
eBayer

Sub DocumentSchliessen
Dim oDoc As Object
Dim oDispatch As Object
ThisComponent.Parent.store() ' Daten speichern.... zur Sicherheit
oDoc = ThisComponent.CurrentController.Frame
oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
oDispatch.executeDispatch(oDoc, ".uno:CloseDoc", "", 0, Array()) ' jetzt das aktive Formular schließen

' ***************************************************************************
' * Bei der folgenden Methode bleibt OO im Speicher *
' ***************************************************************************
oDoc = ThisComponent.Parent.CurrentController.Frame ' und nun das Hauptfenster (Parent) holen
oDoc.close(true) ' und schließen
' ***************************************************************************
' * Hier kommt als Alternative die harte Methode -anstatt close(true)-, die OO komplett beendet (incl. Schnellstart)*
' ***************************************************************************
' oDoc = ThisComponent.Parent.CurrentController.Frame
' oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
' oDispatch.executeDispatch(oDoc, ".uno:CloseDoc", "", 0, Array())
' oDispatch.executeDispatch(oDoc, ".uno:CloseWin", "", 0, Array())
End Sub
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Es funktioniert - DANKE.

Allerdings: Wenn noch etwas zu speichern ist, so stürzt OOo ab.
Fehlermeldung: com.sun.star.uno.RuntimeExceptionComponent is already disposed. (Diese Meldung erscheint allerdings nicht immer - der Absturz ist jedoch reproduzierbar so bald noch etwas zu speichern ist. Versuchsweise habe ich einmal ein wait(1000) nach dem store() eingefügt - ohne Verbesserung.) Trotz des abstürzens wird noch erfolgreich gespeichert.

Dem Sinn nach würde ich vermuten, dass der Speicherbefehl zu spät im Code aufgerufen wird, aber das ist ja nicht der Fall :?
Wenn nichts zu speichern ist, so funktioniert der Code prima.
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

Hallo Stephan,
kann es sein, daß Du in Deiner Anwendung irgendwelche Verbindungen aufbaust, um per SQL Updates oder Abfragen zu machen?
Du solltest eine geöffnete Verbindung immer schließen, sonst bleibt sie im Speicher.
also in den entsprechenden Makros zum Schluss:
1. oStatement.close()
2. oVerbindung.close()

Weitere Frage: was passiert, wenn Dein Formular mit dem x geschlossen wird?
Hast Du da möglicherweise eine Ende-Routine eingebaut, die beim Ende-Event aufgerufen wird?
Dann könnte das Problem deherrühren.

Ich habe mal eine kleine Testanwendung geschrieben.... schon vorher für andere Zwecke - und dort Deine Ssachen eingebaut.
Die könnte ich Dir bei Bedarf schicken, denn bei mir läuft das reibungslos..... auch mit dem x.
Gruß eBayer
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Also zum einen habe ich eine Filtermakro für Listenfelder:

Code: Alles auswählen

sub FORM_BEARBEITUNG_NUMMERNFILTER

           Dim oFeld as variant
           Dim oDoc2 as variant
           Dim oForm2 as variant

           oDoc2 = ThisComponent
           oForm2 = oDoc2.DrawPage.Forms.getByIndex(0)
        REM das Feld des Formulars wird ausgelesen:
           oFeld = oForm2.getByName("WertTextBox")
           sSuchwort = oFeld.text
           
           oForm2.filter = "`Nr` = "+ cInt(sSuchwort) 'dann Filter setzen
           oForm2.ApplyFilter=true 'setzen des Filters für das neue Formulardokument
           
           if oForm2.isModified = true then 'Überprüfung ob Datensatz modifiziert wurde - wenn ja, dann:
           oForm2.upDateRow() 'geänderten Datensatz speichern
           end if
           
           oForm2.reload()
end sub
und dann noch ein Makro zum Defragmentieren der DB:

Code: Alles auswählen

Sub DATENBANK_DEFRAGMENTIEREN

	Dim DatabaseContext as Object
	Dim oDatenquelle as Object
	Dim oHandler as Object
	Dim oDatVerb as Object
	Dim oStatement as Object
	Dim oErgSet as Object
	
	
	DatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
	
	oDatenquelle = DatabaseContext.getByName("Datenbankname")
	
	If not oDatenquelle.IsPasswordRequired Then
	oDatVerb = oDatenquelle.getConnection("","")
	else
	oHandler = oDatenquelle.createUnoService("com.sun.star.sdb.InteractionHandler")
	oDatVerb = oDatenquelle.ConnectWithCompletion(oHandler)
	end if
	
	oStatement = oDatVerb.createStatement()
	oErgSet = oStatement.executeQuery("Checkpoint Defrag")
	
end sub
Das ganze bediene ich aus einem "Startformular" heraus (in der .odb Datei eingebunden). Die DB stürzt aber selbst dann ab, wenn ich sie lediglich öffne und über das Startformular über das entsprechende Makro wieder schließe. Dabei wurden die anderen Makros ja noch nicht ausgeführt und können so ja auch noch nicht im Speicher sein, oder?
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

Das ist richtig......
kannst Du mir die Anwendung mal schicken?
Muß mir selbst mal ein Bild davon machen. Es MUSS gehen!!!
Gruß eBayer
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Leider kann ich dir die DB nicht schicken. (Es klingt evtl. blöd aber sie ist selbst von der Struktur vertraulich.)

Ich habe analog eine DB erstellt, die lediglich im Formular die Schliessenfunktion zur Verfügung stellt - auch hier das selbe Problem. Auch auf einem anderen Rechner.

Hier die DB:
Dateianhänge
SCHLIESSEN.odb
DB muss mit Namen SCHLIESSEN registriert werden.
(11.5 KiB) 86-mal heruntergeladen
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
eBayer
******
Beiträge: 556
Registriert: Do, 04.12.2008 14:33
Wohnort: Augsburg

Re: Formular schließen?

Beitrag von eBayer »

So, jetzt funktioniert die Anwendung sowohl mit dem Schliessen-Button wie auch über das "x".
Wegen der Schließroutine mit dem "x" brauchst Du ein Stück der Logik in einer eigenen Library (Library4), sonst zieht sich die Anwendung selbst den Boden unter den Füssen weg. Schau es Dir einfach mal an. Ich habe die Anwendung und die Library4 in ein Zip-File verpackt. Einfach entpacken und Doppelklick auf Library4, damit die Lib in Dein OO eingebunden wird. Ich hoffe, bei Dir existiert noch keine Library4!!!!!
Wichtig ist zu beachten: Auf Formularebene unter Extras - Anpassen - Ereignisse ist definiert, was beim öffnen und beim schliessen des Formulars passieren muß.
Im Main-Modul des Formulars wir dann die Library geladen. Die Store-Funktion habe ich stillgelegt - sieht so aus, als wenn sie unter 3.1 Probleme macht, aber es kann auch damit zusammenhängen, daß in der Anwendung noch keine Tabelle existiert.
Du solltest einfach mal aufmerksam den Code lesen (auch die Kommentare).
Übrigens.... wenn Du das Formular editierst wird beim Verlassen des Formulars OO komplett geschlossen - evtl. für Testzwecke die Schließroutine in der Library4 mit "exit Sub" stilllegen.
So, nun viel Spaß und Erfolg.
Gruß eBayer
Dateianhänge
Schliessen.zip
(11.32 KiB) 123-mal heruntergeladen
Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz mit 4 GB Memory (3,2 GB aktiv)
Vista Home Premium 32 Bit
openOffice 3.1.1 mit Sun Report Builder 1.1.0 und MySql 5.1
Hauptinteresse ooBase seit 12.2008
geimist
****
Beiträge: 191
Registriert: Fr, 15.02.2008 16:10

Re: Formular schließen?

Beitrag von geimist »

Hallo eBayer,

sorry, dass ich mich erst so spät melde, aber du hast mich ja auch zum trainieren gezwungen :) Vielen Dank für deine Mühe. Ich bin jetzt nun schon ein großen Stückchen weiter.

Einen Schönheitsfehler hätte ich dann noch:
Du hast mir ja schon einmal den Code und eine entsprechende Extension geschickt, wodurch man die Datenbank wie eine eigenständige Anwendung verwenden kann. Wenn ich so mein Startformular öffne sowie mit diesem noch weitere Formulare, so kann ich leider mit der Schliessenroutine lediglich das Startformular beenden, da man ja kein "Parent-Frame" in diesem Sinne hat. Also bleiben die anderen Formulare geöffnet.
Um das zu umgehen, habe ich in meiner DB beim Ereignis Dokument öffnen dieses Makro eingebunden:

Code: Alles auswählen

Sub FENSTER_MINIMIEREN_UND_STARTFORMULAR_OEFFNEN

Dim oFrame As Object
Dim handle

oFrame = ThisComponent.CurrentController.Frame
oMenuWin = oFrame.ContainerWindow()
handle = oMenuWin.getWindowHandle(dimarray(), 1) ' 1 = WIN32
ShowWindow( handle, 2 ) ' ' 1 = SW_NORMALIZE / 2 = SW_ICONIZE / 3 = SW_MAXIMIZE

Dim Context AS Object
Dim Conn As Object
Dim DB As Object
Dim FormDoc As Object
Dim Args(1) As New com.sun.star.beans.PropertyValue
Dim FormName As String
       
FormName = "STARTFORMULAR"
Context=CreateUnoService("com.sun.star.sdb.DatabaseContext")
DB=Context.getByName("DB-Name")
Conn=DB.getconnection("","")
Args(0).Name="ActiveConnection" : Args(0).Value=Conn
Args(1).Name="OpenMode" : Args(1).Value="open"
FormDoc=DB.DatabaseDocument.FormDocuments.loadComponentFromURL(FormName,"_self",2,Args) REM << BASIC-Laufzeitfehler.
FormDoc.CurrentController.Frame.ContainerWindow.setFocus()
ThisDatabaseDocument.FormDocuments.getByName("STARTFORMULAR").open

End Sub
Öffne ich nun über das automatisch geöffnete Startformular weitere Fomulare und editiere Daten, so sind diese teilweise nicht konsistent, d.h. dass meine Änderungen einen Neustart der Datenbank nicht überstehen. Das kann ich mir aber nicht so richtig erklären. Das gleiche ist es, wenn ich mein Startformular extern speichere, und von da aus meine Formulare eigenständig öffne. Während der Sitzung sind alle Änderungen vorhanden, aber nicht mehr nach einem Neustart der DB?
(generell würde ich gern den zweiten Ansatz favorisieren, um auch die Möglichkeit für manuelle Eingriffe haben zu können)
Gruß
Stephan

LibreOffice 5.3 - MAC OS/X 10.11
Antworten