[gelöst] LiO Calc - stürzt nach längerer Makro-Laufzeit ab

Antwort erstellen


BBCode ist eingeschaltet
[img] ist ausgeschaltet
[url] ist eingeschaltet
Smileys sind ausgeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: [gelöst] LiO Calc - stürzt nach längerer Makro-Laufzeit ab

Re: AW: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mo, 28.01.2013 18:00

komma4 hat geschrieben:...Tausche bitte mal den Treiber gegen einen JDBC aus.
JDBC - da musste ich erst mal nachschauen was das überhaupt ist und wie das angewendet wird... 8)

Aber es hat sich gelohnt: Der Speicherverbrauch wächst nur noch in ganz unerheblichem Maß und das Makro läuft problemlos durch.
Ich bilde mir sogar ein, dass es schneller läuft...

Vielen Dank für diesen entscheidenden Hinweis - auf die Idee an dieser Schraube zu drehen wäre ich nie gekommen...

Re: AW: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von komma4 » Mo, 28.01.2013 14:49

Kenne diese Probleme - bei so einfachen Abfragen - nicht.
Und ich mache sowas seit Jahren...

Tausche bitte mal den Treiber gegen einen JDBC aus.

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mo, 28.01.2013 14:03

Ich finde keine Lösung für dieses Problem... :cry:

Beholfen habe ich mir jetzt so, dass ich das Dokument immer nach 5 Zeilen abspeichern lasse, dann muss das Makro nicht von vorne anfangen, wenn es nach 50-80 Zeilen abstürzt...
Keine schöne Lösung, aber besser als nichts.

Danke noch mal an alle, die versucht haben, mir hier zu helfen 8)

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Do, 24.01.2013 14:35

Das mit dem Dispose() habe ich jetzt in den Griff bekommen:
Das Dim als Deklaration nur an den Anfang und die RowSets nach Benutzung mit Dispose() freigeben.

Vor der Verwendung der RowSets erstelle ich sie mit

Code: Alles auswählen

createUnoService("com.sun.star.sdb.RowSet")
jeweils neu.
Das Programm läuft durch, am Speicherverbrauch ändert sich nichts...



Dann noch ein Versuch ohne das globale Datenbank-Objekt

Code: Alles auswählen

db = connect_to_database("Adimens")
...
Sql = "SELECT artikel, name, vbme FROM artikel where artikel = '" & Artikel & "'"
oArtikelRowSet = createUnoService("com.sun.star.sdb.RowSet")
oArtikelRowSet.activeConnection = db
oArtikelRowSet.Command = Sql
oArtikelRowSet.execute
stattdessen wird bei jedem Neuerstellen eines Rowsets das zugrundeliegende Datenbankobjekt neu erstellt, soweit ich dies verstanden habe (wegen der Angabe des DataSourceName statt der activeConnection:

Code: Alles auswählen

Sql = "SELECT artikel, name, vbme FROM artikel where artikel = '" & Artikel & "'"
oArtikelRowSet = createUnoService("com.sun.star.sdb.RowSet")
oArtikelRowSet.DataSourceName = "Adimens"
oArtikelRowSet.Command = Sql
oArtikelRowSet.execute
Auch hier: Das Programm läuft durch (zu meiner Überraschung ohne Geschwindigkeitseinbußen), aber der Speicherverbrauch und damit der Absturz beim Speichern bleiben..



Ich werde jetzt noch ein paar Tests mit einem Minimalprogramm und verschiedenen Datenbanken (SQL-Server über ODBC soie Base-Datenbank) anstellen, ob hier auch jedesmal der Speicher volläuft...

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Do, 24.01.2013 09:33

Hallo Winfried,

ich habe schon statt LibreOffice die aktuelle Version von OpenOffice (portabel) ausprobiert - selbes Ergebnis...

Dispose ist für das Rowset möglich, aber danach kann ich es nicht mehr mit geändertem SQL-Command "wiederverwenden" (was eigentlich logisch ist, das RowSet-Objekt existiert ja nicht mehr).
Muss ich es vor dem erneueten Verwenden mit Redim neu erzeugen und ihm den DB-Kontext neu zuweisen?
In C++ würde ich es mit delete und new machen - bei Basic stehe ich hier etwas auf dem Schlauch... Erzeugt Dim (oder Redim) ein neues Objekt oder dient es nur der Deklaration?

Grüße,
Andreas

Re: AW: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von komma4 » Do, 24.01.2013 08:56

Bin unterwegs, deshalb nur einen Tipp aus dem Handgelenk:

Schau mal in der Dokumentation ob es in der Nähe von .close auch eine .dispose Anweisung gibt.
Die erste schließt "nur" die zweite verwirft das Objekt (und gibt damit auch belegten Speicher frei).

Vllt auch ein Problem der von Dir genutzten Version - arbeite schon seit Jahren problemlos mit OOo und MySQL bzw Postgresql über JDBC... und immer noch mit OOo 3 2.1

Teste mal mit einer anderen Version, ggfs vom Stick.

Viel Erfolg!

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Do, 24.01.2013 08:23

Zu früh gefreut:
Das Makro läuft durch, der Speicher wird vollgeschaufelt (am Ende benötigt soffice.bin etwa 1GB Speicher :shock: ) und beim Versuch zu speichern schmiert Calc kommentarlos ab...

Schade, ich hatte gehofft meine Firma etwas aus den Klauen von Microsoft befreien zu können :cry:

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mi, 23.01.2013 21:09

Auf das Format, in dem die Daten in der Datenbank abgelegt werden, habe ich leider keinen Einfluss:
Die liegen auf einem SQL-Server, die Date-Felder sind dort vom Typ DateTime. Das ist durch unser PPS-System so vorgegeben...
Das Ganze ist über ODBC an eine LiO-Datenbank gebunden über die ich von Calc aus darauf zugreife.
Wie ich direkt aus Basic heraus eine ODBC-Verbindung erstelle habe ich noch nicht herausgefunden.

Ich habe aber jetzt mal mit CDate(...) alle Datenbank-Werte konvertiert.

Mit dem Absturz bin ich (hoffentlich) auch weitergekommen:
Kurz bevor ich wegfahren musste habe ich noch eine Änderung gestartet:
Ich habe alle RowSets mit .Close() geschlossen, nachden ich mit ihnen fertig war und bevor ich sie mit einer neuen SQL-Abfrage neu ausgeführt habe.
Ein erster Versuch hat gezeigt, dass zwar der Speicher immer noch vollläuft, aber bei dem einen Versuch den ich noch machen konnte ließ es sich zumindest abspeichern.
Morgen mal schauen...

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Karolus » Mi, 23.01.2013 17:23

Hallo
Ich hatte "gehofft" dass OO, wenn eine Variable als Date deklariert ist, zugewiesene Strings ins Date-Format castet und Vergleiche auch automatisch im Date-Format vornimmt...
Deine "Hoffnung" wird tatsächlich (wider meine Erwartung) erfüllt. Durch das vorherige 'dim .. as date' wird richtig verglichen.
Trotzdem würde ich die Datumswerte zumindest als Text im Iso-Format 'yyyy-mm-dd' in die Datenbank schreiben.

Mich würde mal interessieren wieviel Zeit die gleichen sql-Abfragen aus Base heraus benötigen?

Karolus

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mi, 23.01.2013 16:07

Hallo Karolus,

danke dass du dir meinen Code mal angeschaut hast...

Die Laufzeitfunktion "rtrim(...)" (rstrip ist Python, glaube ich) habe ich inzwischen auch gefunden und mein StripString (das war noch ein Erbe aus der Excel-Zeit) damit ersetzt. Das bringt durchaus einiges an Geschwindigkeit...

Codeblöcke auslagern in eine Funktion wäre bestimmt möglich, zunächst ist es mir aber so wie es ist übersichtlicher was den Ablauf angeht.
Am prinzipiellen Problem des Absturzes würde das wohl auch nichts ändern.

Und die meiste Zeit wird wohl nicht für das Füllen der Zellen benötigt, sondern für die vielen Summenabfragen mit Fallunterscheidung auf die Datenbank:
Der aufwändigste Programmteil ermittelt für drei Jahre nacheindender für jedes Bauteil in welchen Stücklisten es hinterlegt ist und berechnet dann den Verbrauch dieses Bauteils indem ermittelt wird, wie oft das Produkt in dem das Bauteil verbaut ist im jeweiligen Jahr verkauft wurde (über die Rechnungen bzw. Rechnungpositionen).
Mir fällt im Augenblick keine bessere Lösung hierfür ein als zunächst für jedes Bauteil über die Stücklisten zu iterieren und dann für jedes Vorkommen die Rechnungen zu "durchwühlen" (mit der Summenabfrage).
Ich bin aber auch kein SQL-Profi und leider auch noch blutiger OO-Basic-Anfänger...

Das mit dem Datum muss ich mir noch mal anschauen...
Ich hatte "gehofft" dass OO, wenn eine Variable als Date deklariert ist, zugewiesene Strings ins Date-Format castet und Vergleiche auch automatisch im Date-Format vornimmt...
Das ist wohl etwas blauäugig.

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Karolus » Mi, 23.01.2013 15:40

Hallo
Ich hab den Eindruck das dein gesamter Code sehr ineffizient ist.
( Ein paar Datenbankabfragen mit einer Laufzeit ~1Stunde :? - Dieses Forum hat auch eine Datenbank im Hintergrund mit ca. 35000 Datensätzen, eine einfache Suche läuft in unter 2 sec ab )

Die Punkte die mir besonders auffallen
- du hast eine extra Function 'stripString( arg )' die nichts tut als ihrerseits rstrip( arg ) zurückzugeben, die kannst du weglassen und direkt die Laufzeitfunction 'rstrip' verwenden
- andererseits hast du mehrere Codeblöcke die völlig identisch ablaufen mit Ausnahme des sql-Statements, diese wiederholten Blöcke könntest du wunderbar in eine Funktion auslagern.
- Datumwerte als Text im Format 'dd.mm.yyyy' die als solche verglichen werden, was glaubst du ergibt:

Code: Alles auswählen

msgbox ( "25.12.1970" > "24.01.2013") 
?
- Die meiste Laufzeit dürfte dabei draufgehen die Zellen einzeln mit 'handgedrechselten' Inhalten zu füllen.

Karolus

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mi, 23.01.2013 14:08

Ich habe noch etwas weiter geforscht - es scheint mit dem Ressourcenverbrauch zu tun zu haben:

Im Taskmanager verbraucht der Prozess soffice.bin bei frisch geöffnetem Dokument etwa 63.000 Byte.
Bei jeder Datenzeile, die das Programm bearbeitet, erhöht sich dieser Verbrauch um 4.000 bis 12.000 Byte.

Ich lasse das Programm immer 15 Datenzeilen bearbeiten und speichere danach von Hand.
Sobald der Speicherverbrauch von soffice.bin eine Höhe von etwa 700.000 Byte erreicht hat, lässt sich das Dokument nicht mehr speichern und Calc stürzt ab.

Habe ich in meinem Programmcode irgendetwas stehen, was diesen Speicherverbrauch verursacht?
Oder ist dies eher ein "internes" LibreOffice-Problem?

Nachstehend noch das Bild des Taskmanagers mit dem Speicherverbrauch - die Sprünge "nach unten" sind jeweils beim Neustart mit Dokumentenwiederherstellung entstanden...

.
Dateianhänge
Taskmanager.png
Taskmanager.png (110.32 KiB) 2402 mal betrachtet

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mi, 23.01.2013 12:43

Leider war das nicht das eigentliche Problem - der Absturz beim Speichern nach dem Programmdurchlauf tritt weiterhin auf... :cry:

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von Kappler » Mi, 23.01.2013 12:35

Hallo Balu,

danke für den Hinweis - das probiere ich gleich mal aus...
Da ist bei mir C zu stark im Hirn verankert - das würde mir hier eine Fehlermeldung an den Kopf schmeißen.
Aber auf die Farben bei der Deklaration werde ich (hoffentlich 8) ) in Zukunft achten - guter Tipp...

Gruß
Andreas

Re: LiO Calc - stürzt nach längerer Makro-Laufzeit ab

von balu » Mi, 23.01.2013 12:29

Hallo Andreas,

Code: Alles auswählen

	Dim Name as String
Ist das Korrekt, dass Du die Anweisung Name als String deklarieren musst? Ich kann mir nicht vorstellen das das was Du da machst erlaubt ist. Denn die Anweisung Name ist doch fest vorgegeben als:
Online Hilfe (F1) hat geschrieben: Name-Anweisung [Laufzeit]
Gibt einer bereits vorhandenen Datei oder einem bereits vorhandenen Verzeichnis einen neuen Namen.
Aber in deinem Code ist nix davon zu sehen das Du Name wie erlaubt verwendest, sondern im Gegenteil ehern missbrauchst.

Code: Alles auswählen

			Name = StripString(oArtikelRowSet.Columns.GetByName("name").getString())
			If(oSheet.getCellByPosition(1,Zeile).getType =  com.sun.star.table.CellContentType.EMPTY) Then
				oSheet.getCellByPosition(1,Zeile).setFormula(Name)
Garantieren will ich es wohl nicht, aber ich befürchte das dies Office (OOo/AOO/LO) sehr sauer aufstößt. Deshalb würde ich dir dringend raten das zu ändern. Ich stelle mir das ganze dann so vor.

Code: Alles auswählen

	Dim sName as String

Code: Alles auswählen

			sName = StripString(oArtikelRowSet.Columns.GetByName("name").getString())
			If(oSheet.getCellByPosition(1,Zeile).getType =  com.sun.star.table.CellContentType.EMPTY) Then
				oSheet.getCellByPosition(1,Zeile).setFormula(sName)
Als Faustformel solltest Du dir am besten folgendes merken.
Wenn bei der deklaration von Variablen der Variablenname Blau zu sehen ist, dann sollten die Alarmglocken läuten! Denn das bedeutet, dass die Variable schon fest als Anweisung oder als Funktion vom System vergeben ist. In diesem Falle nicht den Variablennamen so nehmen, sondern entweder einen total anderen überlegen oder ihn leicht abändern.

Noch was.

Code: Alles auswählen

    Dim Dummy$ as String
Weißt Du eigentlich was Du da gemacht hast? Ich will dir das mal übersetzen.
Du hast die Kurzform einer Variablendeklaration mit einer Langform davon kombiniert. Richtig ausgeschrieben steht dann nämlich folgendes dort.

Code: Alles auswählen

    Dim Dummy as String as String
Denn das Dollarzeichen direkt am Variablennamen sagt ja schon das es sich um einen String handelt. Folglich ist auch folgende schreibweise zulässug und erlaubt.

Code: Alles auswählen

    Dim Dummy$
Ich hoffe das hilft dir weiter, und ferner hoffe ich das ich nicht daneben lag.



Gruß
balu

Nach oben