Seite 1 von 1
GELÖST Datenbank läuft nicht mehr
Verfasst: Mo, 12.05.2014 19:13
von WSO
Wegen einem fehlenden End If in einem Makro bekam ich eine Fehlermeldung (an deren Text ich mich nicht mehr erinnere) sinngemäß overflow, ???
Habe im Forum einen Hinweis auf einen loop-Fehler gefunden, fehlte tatsächlich ein End IF.
Das habe ich eingebaut, aber seit den funktioniert fast nichts mehr.
Habe dann gemerkt, dass meine Datenbank nicht mehr angemeldet war!
OK, zur Sicherheit den Rechner neu gebootet, dann die Datenbank wieder angemeldet, aber
jedes Makro, das auf die Datenkank zugreifen will bringt diesen Fehler:

- img1.png (26.13 KiB) 26407 mal betrachtet
Hier das makro mit dem die ganze story begann, das stuerzt, wie alle anderen bei : "Datasource = thisComponent.Parent.CurrentController" ab.
Code: Alles auswählen
Function getMessage(ID as integer)
DIM oDatasource AS OBJECT
DIM oConnection AS OBJECT
DIM oSql AS OBJECT
DIM oResultSet AS OBJECT
DIM stSql AS STRING
DIM stSql1 as string
DIM stSql2 as string
Dim iTyp as integer
DIM iJN as integer
dim iHeader as string
stID = ID
[b]oDatasource = thisComponent.Parent.CurrentController[/b] <--------- Fehler
IF NOT (oDatasource.isConnected()) THEN oDatasource.connect()
oConnection = oDatasource.ActiveConnection()
stSql1 = "SELECT ""err_id"", ""err_text"", ""err_typ"" FROM ""tError"""
stSql2 = "WHERE err_id = " & ID
stSql = stSql1 + stSql2
oSql = oConnection.createStatement()
oResultSet = oSql_AUF.executeQuery(stSql)
If not isNull (oResultSet) then
WHILE oResultSet.Next
REM: Meldung aufbereiten und ausgeben
iF1 = ResultSet.getString(2)
iTyp = Resultset.getint(3)
iF2 = iTyp
iTyp = Resultset.getint(3)
getMessage = True
SELECT case iTyp ' es koennen nur 0,16 oder 36 vorkommen
case 0:
iF3 = "Hinweis" + "Nr. " + stID
msgbox(iF1,iF2,iF3)
case 16:
iF3 = "Fehler" + "Nr. " + stID
iJN = msgbox(iF1,iF2,iF3)
if iJN = 0 then
getMessage = False
end if
case 36:
iF3 = "Bestätigungsabfrage" + "Nr. " + stID
msgbox(iF1,iF2,iF3)
END SELECT
WEND
ELSE
iF1 = "Die Meldung mit Nummer " + stID + "wurde nicht gefunden, Chr$(13) die Verarbeitung wird abgebrochen"
iF2 = 16
iF3 = "Systemfehler"
msgbox iF1,iF2,iF3
getMessage = False
END IF
End Function
Habe mir "ThisComponent" mit xray angeschaut, und tatsächlich die Methode "Parent" ist nicht da.
Bin voellig ratlos und muss die Entwicklung erst mal einstellen.
Die Anwemdung hat nichts vertrauliches und auch nur ein Prototyp fuer ein größeres Projekt.
Hier kann man sie runterladen:
https://www.dropbox.com/s/c4fncyx0mptet ... Arbeit.odb
Zum Nachstellen des Fehlers:
das Maro"Testmsg" unter "HM - in Arbeit" --> Standart --> Allgemein aufrufen
Wäre super toll, wenn ich nochmal Hilfe bekomme.
Gruss von einem etwas frustriertem
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Mo, 12.05.2014 21:03
von RobertG
Hallo Wolfram,
kann es sein, dass Du das Makro außerhalb eines Formulars direkt auf der Datenbankoberfläche ausgeführt hast? Da bekomme ich die Fehlermeldung auch - ist aber nicht verwunderlich, da dort tatsächlich auch kein .parent zur Verfügung steht. Sobald Du das aus einem geöffneten Formular heraus aufrufst werden an anderen Stellen Fehler produziert - die aber Stück für Stück beseitigt werden können.
Gruß
Robert
Re: Datenbank läuft nicht mehr
Verfasst: Mo, 12.05.2014 23:10
von WSO
Hallo Robert,
stimmt genau, zum Test des Error-Message-Handlers habe ich das Testmodul (welches den Handler testweise aufruft) direkt aufgerufen.
Du machst mir Hoffnung die Arbeiten der letzten 24 Stunden nichtrekonstruieren zu müssen.
Wie bekomme ich den Fehler denn wieder raus?
Vielleicht ist es doch besser (zumindest in einer Entwicklungsumgbung die Datensicherung automatisiert laufen zu lassen.
Dann wäre diese Geschichte schon Vergangenheit ...
Gruss,
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Di, 13.05.2014 11:06
von RobertG
Hallo Wolfram,
der Fehler tritt doch nur auf, wenn Du das Makro nicht aus dem Formular heraus startest. Sonst funktioniert zumindest der erste Zugriff auf das Makro. Nur in der Folge gibt es Fehlermeldungen - die haben aber andere Ursachen.
Wenn Du das Makro tatsächlich direkt von der Oberfläche heraus auslösen willst (wie machst Du das?), dann musst Du natürlich aufpassen, was es denn auslesen soll. Vermutlich aber doch Formularinhalte. Und der Start unabhängig vom Formular macht dann doch keinen Sinn.
Gruß
Robert
Re: Datenbank läuft nicht mehr
Verfasst: Di, 13.05.2014 11:45
von WSO
Hallo Robert,
die function wird der zentrale Handler für Fehlermeldungen.
Sie wird immer nur von einem andreren Makro oder Funktion aufgerufen werden, dabei wird die Fehlernummer übergeben.
Der Text der Meldung wird aus der Tabelle tError ausgelesen, etwas aufbereitet (msgbox_typ) und ausgegeben.
Der Aufruf ist in den Makros, die jetzt noch msgbox verwenden nicht implementiert.
Um das modul zu testen habe das kleine Makro "Testmsg" mit aufruf den Message-Handlers (getMessage) erstellt und ueber EXTRAS-MAKRO-AUSFUEREN gestartet.
Das aber wie gesagt nur zu Testzwecken.
Gruss,
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Di, 13.05.2014 12:48
von WSO
H Robert,
habe eine Sicherungskopie nacheditiert und kann wieder arbeiten.
Würde nur zu gerne wissen, wie ich derart unerfreuliche Aktionen vermeiden kann.
Ist es denn so, das ein loop-Fehler die odb zerschießt?
Das wäre für mich ein ko-Kriterium für diese Systemkonstellation, aber die Ursache für das Problem ist ja noch nicht wirklich identifiziert...
Wird mit MySql das System stabiler?
Mache jetzt erst mal vor jeder wesentlichen Änderung eine Sicherung, um weitere Datenverluste vermeiden.
Gruss,
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Di, 13.05.2014 14:56
von acco
Hallo Wolfram,
das ein loop-Fehler, bzw. ein fehlendes "end if" eine DB zerschießt, hatte ich bisher noch nicht. Hast Du mehr Daten verloren, als Du seit dem öffnen der DB eingegeben hattest? Wurden Teile der DB wirklich zerschossen, also unbrauchbar? Oder hatte es mit der Ausführung der Makros außerhalb eines Formulars zu tun?
Bei neuen Funktionen und vor jeder Veränderung an der DB-Struktur (wenn umfangreich auch zwischendurch) mache ich gleich eine Sicherung, da es vielfältige Möglichkeiten gibt, das sich die DB aufhängt und nicht mehr zu bearbeiten ist, oder gleich ganz abstürzt. Nach der Wiederherstellung ist dann die Arbeit seit der letzten Speicherung verloren. Ist eigene unerfreuliche Erfahrung.
Bei Deiner DB entdecke ich keinen grundsätzlichen Fehler, wenn ich in einem Formular eine Schaltfläche einbaue und mit dem Makro "Testmsg" belege, läuft es durch bis
Da heißt es Objektvariable nicht belegt. Und das stimmt,
oSQL_Auf ist nicht belegt, das müßte
oSQL heißen. Es sind also "ganz normale" Fehler vorhanden, die halt nach und nach bereinigt werden müssen, wie Robert schon schrieb.
Gruß
acco
Re: Datenbank läuft nicht mehr
Verfasst: Di, 13.05.2014 17:07
von WSO
Hallo acco,
vielen Dank fuer deine Muehe.
Ja, das Makro ist noch nicht getestet.
Ich bin mir sicher, dass der Loop-Fehler das Problem verursacht hat.
Das war der allererste Aufruf nach der Codierung des Error-Handlers.
Der hat die Anmeldung der Datenbank geloescht, danach ging dann erst mal nichts mehr.
Offenbar hat die Wiederanmeldung das Problem beseiting, ich habe danach aber nur nochmal das neue marko aufgerufen, bin auf den von dir
zitierten Fehler gelaufen ujnd habe dann spaet nachts das "Handtuch geschmissen".
Das ich auf einen Stand vom Vortag zurueckgegangen bin, war somit nicht notwendig.
In einer Entwicklñungsumgebung alles noch ok, in Produktion waere das wirklich kritisch.
Sorry fuer die Umlaute, arbeite mit spanischer Tastatur.
Liebe Gruesse Wolfram
by the way,
das backup-makro laeuft jetzt beim Start von Base und schaut so aus:
Code: Alles auswählen
SUB Datenbankbackup
DIM oPath AS OBJECT
DIM oDoc AS OBJECT
DIM sTitel AS STRING
DIM sUrl_Ziel AS STRING
DIM sUrl_Start AS STRING
DIM i AS INTEGER
DIM k AS INTEGER
DIM iMax as integer ' Anahl der Sicherungsgenerationen
DIM iMax_1 as Integer
Dim iMax_2 as Integer
iMax = 30
iMax_1 = iMax - 1
iMax_2 = iMax - 2
DIM oDaten AS OBJECT
DIM oDataSource AS OBJECT
oDaten = ThisDatabaseDocument.CurrentController
IF NOT ( oDaten.isConnected() ) THEN oDaten.connect()
' DB-Cache schreiben um aktuelle Aenderungen in die Sicherung zu uebernehmen
oDataSource = oDaten.DataSource
oDataSource.flush
sTitel = ThisDatabaseDocument.Title
sUrl_Start = ThisDatabaseDocument.URL
oPath = createUnoService("com.sun.star.util.PathSettings")
FOR i = 1 TO iMax
IF NOT FileExists(oPath.Backup & "/" & i & "_" & sTitel) THEN
IF i > iMax_1 THEN
FOR k = iMax_2 TO 1 STEP -1
IF FileDateTime(oPath.Backup & "/" & k & "_" & sTitel) <= FileDateTime(oPath.Backup & "/" & k+1 & "_" & sTitel) THEN
IF k = 1 THEN
i = k
EXIT FOR
END IF
ELSE
i = k + 1
EXIT FOR
END IF
NEXT
END IF
EXIT FOR
END IF
NEXT
sUrl_Ziel = oPath.Backup & "/" & i &"_" & sTitel
FileCopy(sUrl_Start,sUrl_Ziel)
End Sub
Re: Datenbank läuft nicht mehr
Verfasst: Mi, 14.05.2014 10:37
von WSO
Guten Morgen acco und Robert,
zunächst nochmal ein herzliches Dankeschön für eure Geduld mit mir.
Nach intensiver Suche habe ich die ursache für das nicht gefundene ".Parent" gefunden:
Makro-a (Aufruf über Formularereignis) macht Datenbankoperationen (Fehlerfrei)
schliesst das aufrufende Formular,
ruft Makro-b auf (.Parent wird nicht mehr gefunden)
Wenn ich
erst Makro-b aufrufe und
danach das Formular schliesse läuft Makro-b einwandfrei.
Ob diese System,verhalten so sein muss, kann ich nicht beurteilen.
Also viel Wind um Nichts und viele Stunden der Fehlersuche.
Für alle, die es brauchen können, hier die function zur Aufbereitung und Augabe der msgbox:
Code: Alles auswählen
Function getMessage(ID as integer, Replacement_1 As String, Replacement_2 as String)
REM ID=Felernummer, Replacetext-1, Replacetext-2
DIM oDatasource AS OBJECT
DIM oConnection AS OBJECT
DIM oSql AS OBJECT
DIM oResultSet AS OBJECT
DIM stSql AS STRING
DIM stSql1 as string
DIM stSql2 as string
Dim iTyp as integer
DIM iJN as integer
DIM stID as String
DIM iF1 as String
DIM iF2 As String
DIM iF3 As String
stID = ID
oDatasource = thisComponent.Parent.CurrentController
IF NOT (oDatasource.isConnected()) THEN oDatasource.connect()
oConnection = oDatasource.ActiveConnection()
stSql1 = "SELECT ""err_id"", ""err_txt"", ""err_typ"" FROM ""tError"""
stSql2 = "WHERE err_id = " & ID
stSql = stSql1 + stSql2
oSql = oConnection.createStatement()
oResultSet = oSql.executeQuery(stSql)
If not isNull (oResultSet) then
WHILE oResultSet.Next
REM: Meldung aufbereiten und ausgeben igel_betrag = Replace(igel_betrag, ",", ".")
If not isEmpty(Replacement_1) then
iF1 = oResultSet.getString(2)
iF1 = Replace(iF1, "@1", Replacement_1)
else
iF1 = oResultSet.getString(2)
end if
If not isEmpty(Replacement_2) then
iF1 = Replace(iF1, "@2", Replacement_2)
end if
iTyp = oResultset.getint(3)
iF2 = iTyp
iTyp = oResultset.getint(3)
getMessage = True
SELECT case iTyp ' es koennen nur 16, 36 oder 64 vorkommen
case 16:
iF3 = "Fehlermeldung" + " Nr.: " + stID
iJN = msgbox(iF1,iF2,iF3)
if iJN = 0 then
getMessage = False
end if
case 36:
iF3 = "Bestätigungsabfrage" + " Nr.: " + stID
msgbox(iF1,iF2,iF3)
case 64:
iF3 = "Hinweis" + " Nr.: " + stID
msgbox(iF1,iF2,iF3)
END SELECT
WEND
ELSE
iF1 = "Die Meldung mit Nummer " + stID + "wurde nicht gefunden, die Verarbeitung wird abgebrochen"
iF2 = 16
iF3 = "Systemfehler im Modul getMessage"
msgbox iF1,iF2,iF3
getMessage = False
END IF
End Function
Hier ist noch ein offener Punkt, den ich nicht lösen konnte.
Der Text der Meldungen kommt aus einer Tablle (tError).
Wie kann ich dort ein CHR(13) wirksam werden machen, oder (nur so kann ich es mir vorstellen) das entsprechede ASCII als Zeichen in den Text bringen?
Gruss,
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Mi, 14.05.2014 10:54
von acco
Hallo Wolfram,
prima das kein großer Schaden entstand.
Bei Deinem Makro würde ich überlegen 2 Kleinigkeiten zu ändern:
Durch den Variableneinsatz iMax.. machst Du es Dir einfacher die Anzahl der Sicherungen mal zu ändern. Gute Idee. Wenn Du aber 30 Sicherungen haben willst, muß iMax 31 sein.
Falls Dein Makro auch beim Start der DB ausgeführt wird: Ich würde das Schreiben aus dem Cache in einer separaten SUB lassen und dann über eine weitere SUB die beiden Makros ausführen, wenn wirklich beide gebraucht werden. So wie es Robert hier weiter oben gepostet hat.
In Deinem Makro wird der Cache auch bei jedem Start der DB ausgelesen und das ist überflüssig, weil ja nichts drin sein kann. Hier ist das sicherlich vernachlässigbar, aber wenn eine überflüssige umfangreiche Routine abgearbeitet werden muß, kostet das Zeit (auch bei der eventl. Fehlersuche). Das ist ebenfalls eigene unerfreuliche Erfahrung.
Gruß
acco
Re: Datenbank läuft nicht mehr
Verfasst: Mi, 14.05.2014 12:45
von WSO
Moin acco,
danke dafür, ist mir bei der nächtlichen Fehlersuche auch schon aufgefallen und bereits umgesetzt.
Gruss,
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Mi, 14.05.2014 14:05
von acco
Hallo Wolfram,
Deinen Post von 10:37 sehe ich gerade erst
Schau hier:
viewtopic.php?f=8&t=23847#p231055
Funktionierende Eingabe eines Zeilenumbruchs direkt in der Tabelle ist demnach nicht möglich. Du kannst aber eine Abfrage zwischenschalten.
Gruß
acco
Re: Datenbank läuft nicht mehr
Verfasst: Mi, 14.05.2014 14:23
von WSO
ist schon gelöst:
PLatzhalterzeichen im Fehlertext eingefügt,
Bei der Aufbereitung des Fehlertextes den Platzhalter durch eine Variable (String) ersetzt, der zuvor CHR(13) zugewiesen wurde.
Ich habe in der Backup-Routine noch einen Schönheitzsfehler verbessert:
Da jetzt mehr als 9 Generationen angelegt werden können bekommen Generationen < 10 noch eine führende Null in den Dateinamen verpasst.
Ist jetzt richtig rund und läuft stabil:
Code: Alles auswählen
SUB Systemstart ' Datenbank sichern und Hauptformular der Anwendung aufrufen
call Datenbankbackup
call Hauptformular_oeffnen
end sub
SUB BackupDurchUser
call Daten_aus_Cache_schreiben
call Datenbankbackup
msgbox "Eine neue Generation der Datenbanksicherung wurde erstellt",64 ,"Hinweis"
end sub
SUB Datenbankbackup ' Legt eine neue Backup-Generation an
DIM oPath AS OBJECT
DIM oDoc AS OBJECT
DIM oDaten AS OBJECT
DIM oDataSource AS OBJECT
DIM sTitel AS STRING
DIM sUrl_Ziel AS STRING
DIM sUrl_Start AS STRING
DIM i AS INTEGER
Dim sti AS STRING
DIM k AS INTEGER
DIM stK AS STRING
DIM stNull AS STRING
DIM iAnzGenerationen as INTEGER
DIM iMax as INTEGER
DIM iMax_1 as INTEGER
DIM iMax_2 as INTEGER
iAnzGenerationen = 30 ' Anzahl der Backup-Generationen
iMax = iAnzGenerationen +1
iMax_1 = iMax - 1
iMax_2 = iMax - 2
stNull = "0"
oDaten = ThisDatabaseDocument.CurrentController
IF NOT ( oDaten.isConnected() ) THEN oDaten.connect()
sTitel = ThisDatabaseDocument.Title
sUrl_Start = ThisDatabaseDocument.URL
oPath = createUnoService("com.sun.star.util.PathSettings")
FOR i = 1 TO iMax
IF i < 10 THEN
sti = stNull + i
ELSE
sti = i
END IF
IF NOT FileExists(oPath.Backup & "/" & sti & "_" & sTitel) THEN
IF i > iMax_1 THEN
FOR k = iMax_2 TO 1 STEP -1
IF k < 9 THEN
stK = stNull + (k + 1)
ELSE
stk = (k + 1)
END IF
IF FileDateTime(oPath.Backup & "/" & stK & "_" & sTitel) <= FileDateTime(oPath.Backup & "/" & stK & "_" & sTitel) THEN
IF k = 1 THEN
i = k
EXIT FOR
END IF
ELSE
i = k + 1
IF i < 10 THEN
sti = stNull + i
ELSE
sti = i
END IF
EXIT FOR
END IF
NEXT
END IF
EXIT FOR
END IF
NEXT
sUrl_Ziel = oPath.Backup & "/" & sti &"_" & sTitel
FileCopy(sUrl_Start,sUrl_Ziel)
End Sub
SUB Daten_aus_Cache_schreiben ' erforderlich vor einen Backup der nicht unmittelbar
' nach dem Systemstart anläuft
DIM oDaten AS OBJECT
DIM oDataSource AS OBJECT
oDaten = ThisDatabaseDocument.CurrentController
IF NOT ( oDaten.isConnected() ) THEN oDaten.connect()
oDataSource = oDaten.DataSource
oDataSource.flush
END SUB
Und hier Handler für msgbox:
Code: Alles auswählen
Function getMessage(ID as integer, Replacement_1 As String, Replacement_2 as String)
REM ID=Felernummer, Replacetext-1, Replacetext-2
DIM oDatasource AS OBJECT
DIM oConnection AS OBJECT
DIM oSql AS OBJECT
DIM oResultSet AS OBJECT
DIM stSql AS STRING
DIM stSql1 as string
DIM stSql2 as string
Dim iTyp as integer
DIM iJN as integer
DIM stID as String
DIM iCHR13 as string
DIM iF1 as String
DIM iF2 As String
DIM iF3 As String
stID = ID
iCHR13 = CHR(13)
oDatasource = thisComponent.Parent.CurrentController
IF NOT (oDatasource.isConnected()) THEN oDatasource.connect()
oConnection = oDatasource.ActiveConnection()
stSql1 = "SELECT ""err_id"", ""err_txt"", ""err_typ"" FROM ""tError"""
stSql2 = "WHERE err_id = " & ID
stSql = stSql1 + stSql2
oSql = oConnection.createStatement()
oResultSet = oSql.executeQuery(stSql)
If not isNull (oResultSet) then
WHILE oResultSet.Next
REM: Meldung aufbereiten und ausgeben
If not isEmpty(Replacement_1) then
iF1 = oResultSet.getString(2)
iF1 = Replace(iF1, "@1", Replacement_1)
else
iF1 = oResultSet.getString(2)
end if
If not isEmpty(Replacement_2) then
iF1 = Replace(iF1, "@2", Replacement_2)
end if
iF1 = Replace(iF1, "CHR13", iCHR13)
iTyp = oResultset.getint(3)
iF2 = iTyp
iTyp = oResultset.getint(3)
getMessage = True
SELECT case iTyp ' es koennen nur 16, 36 oder 64 vorkommen
case 16:
iF3 = "Fehlermeldung" + " Nr.: " + stID
iJN = msgbox(iF1,iF2,iF3)
if iJN = 0 then
getMessage = False
end if
case 36:
iF3 = "Bestätigungsabfrage" + " Nr.: " + stID
msgbox(iF1,iF2,iF3)
case 64:
iF3 = "Hinweis" + " Nr.: " + stID
msgbox(iF1,iF2,iF3)
END SELECT
WEND
ELSE
iF1 = "Die Meldung mit Nummer " + stID + "wurde nicht gefunden, die Verarbeitung wird abgebrochen"
iF2 = 16
iF3 = "Systemfehler im Modul getMessage"
msgbox iF1,iF2,iF3
getMessage = False
END IF
End Function
Dazu gehört die Tabelle "tError":

- shot.png (58.58 KiB) 26309 mal betrachtet
Für alle die es brauchen können.
Vielen Dank an acco und Robert,
die mir sehr proffesionell und rühriger Geduld zur Seite gestanden haben.
Gruss,
Wolfram
Re: Datenbank läuft nicht mehr
Verfasst: Mi, 14.05.2014 14:48
von acco
Hallo Wolfram,
das mit den Platzhaltern ist elegant, hatte ich gar nicht mehr auf dem Schirm. Und eine Tabelle Terror (tError) zu nennen, hat auch was.
Weiterhin viel Erfolg und Sonne.
Gruß
acco