Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Reminder - Ein Tool für Erinnerungen bei Kundenkommunikation


  • Please log in to reply
32 replies to this topic
fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Guten Morgen!

 

Ich hab ein Problem, wenn ein Vorgang der per PopUp gemeldet wird vom User geschlossen wurde dann passiert es, dass der Vorgang nicht geschlossen wird. Das PopUp geht zwar zu kommt aber dann nach einer Minute wieder.

 

Es passiert aber nicht immer. Die Meisten Vorgänge werden normal geschlossen und blieben auch zu.

 

Ich finde den Fehler nicht. Habe mir den Code schon einige male angeschaut aber ich komm nicht drauf. Ich weiß auch leider nicht wie ich da nun vorgehen soll.

 

Hilfe!

 

MfG
fump



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Guten Tag!

 

Der Code an sich sieht nicht wirklich fehlerhaft aus, der komplette Vorgang ist aber recht 'anstrengend'. Schau Dir noch mal an, was da abläuft:

 

Spoiler

 

SQL-Fehler würden ja eine Meldung erzeugen, sodass diese Fehler wohl ausgeschlossen werden können. Vielleicht gibt es aber Situationen, in denen die Werte während der Verarbeitung inkonsistent werden, wenn z.B. ein Timer oder ein Messagehandler dazwischen funken. Möglicherweise kommt es dann zu unterschiedlichen Inhalten in der DB und den ListViews?

 

Und noch etwas:

 

Dein Primärkey ist zusammengesetzt (" PRIMARY KEY(Reminder_ID ASC, KD_Nr ASC));"), Deine Update-Anweisung nutzt für die Selektion aber nur die Reminder_ID. Das mag schon mal Probleme mit sich bringen, wenn die ID nicht eindeutig ist.

 

 


Prefer ahkscript.org for the time being.


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Dann gehst du davon aus, dass es nicht am SQL selber liegt sondern hier durchaus der SQL Befehl sauber durchläuft. Durch irgendwelche Umstände aber wird der Vorgag in Variablen oder im Listview nicht korrekt entfernt wodurch er letztendlich im nächsten durchlauf wieder aufpoppt. Wenn man dann erneut speichert und es läuft ordentlich durch wird der vorherige Eintrag in der DB einfach überschrieben.

 

Also muss ich den Code an der Stelle ausmisten und die Abläufe an andere Stellen legen.

 

Ich kann leider nur die Reminder_ID nutzen da der User auch die Kundennummer verändern kann. Ich hab das so gewählt mit dem PRIMARY KEY aufgrund deiner Empfehlung. Nachdem du mir den Sinn erklärt hattest erschien mir dies so eben Sinnvoll :) Bisher hat das auch keine Probleme bereitet. Eine ID ist bisher nicht doppelt vorgekommen.



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Hab es nun so zusammengestrichen:

RM_NoneCallNote:
Toff:=1 ; Entfernt ein evtl. offenes ToolTip
If (CallNotePopUpFlag=0)
	{
		Gui, Submit, NoHide
		FullTime:=RM_DateTime
		FormatTime, RM_DateTime, %RM_DateTime%, dd.MM.yyyy HH:mm
	}
If (RM_ToDo_Erl_Text!="")
	{	; Die Übermittlung um den Fall zu schließen startet nur dann wenn auch ein ToDo Text hinterlegt wurde.
		Settimer, TimeCheck, Off
		DB.Exec("BEGIN TRANSACTION;")
		SQL := "UPDATE " . TableName . " SET KD_Nr='" . RM_KDNr . "', D_ID='" . RM_DID . "', ToDo='" . RM_ToDo_DropDown . "', RR_Nr='" . RM_RRNr . "', WVL_Zeitpunkt='" . RM_DateTime . "', Status='Geschlossen', ToDo_Text='" . RM_ToDo_Text . "', ToDo_Erl_Text='" . RM_ToDo_Erl_Text . "', Benutzer='" . UserName . "', FullTime='" . FullTime . "', ShowFlag='0', FirstUser='" . RM_FirstUser . "' WHERE Reminder_ID='" . RM_ID . "';" ; Zusammensetzen des SQL Befehls als UPDATE da bestehender Vorgang - Hier wird nur die Reihe upgedatet deren ID mit RM_ID übereinstimmt.
		If !DB.Exec(SQL) {
			MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode . "`n`nReminder wird nun beendet. Starte das Modul bitte neu!"
			ExitApp
		}
		DB.Exec("COMMIT TRANSACTION;")
		If (CallNotePopUpFlag=0)
			{
				GoSub RefreshLV ; Refresh für das obere ListView.
				GoSub RefreshLV2 ; Refresh für das untere ListView.
				LVOpen:=0
				GuiControl, Disabled, RM_CallNote
				GoSub CleanUp
				GoSub LVColor
			}
		If (CallNotePopUpFlag=1)
			{
				GoSub RefreshLVPopUp ; Hier wird nun das Label angesprungen welches die Daten für die Notiz sammelt. Hier wird dann auch der Refresh der Listviews durchgeführt. Dann das PopUp geschlossen und dann die Notiz erstellt. Erst danach wird der Timer wieder gestartet.
			}
		; Dies startet den Timer für die Notification PopUp's
		if (A_Sec+0)   
			sleep,% (60-A_Sec)*1000
		Settimer, TimeCheck, 30000
	}
else
	{	; Meldung dies erscheint wenn im ToDoErl Text nichts steht.
		ToolTipText:="Es wurde kein 'Was hast Du gemacht?' Text eingetragen.`nOhne ist das Abschließen nicht möglich."
		TTZeit:=5000
		Settimer, STT, -1
		Return
	}
Return

Ich werds nun so mal laufen lassen und gucken was passiert.



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Hab es nun mit mehreren Vorgängen getestet, es liegt anscheinend nicht nur an diesem Part des Codes. Es passiert auch beim setzen eines WVL Termins. Ein Kollege berichtete, dass er nachdem er den Termin um einen Tag verschob kurz drauf den gleichen Vorgang zu sehen bekam nur eben ohne seinen Kommentar.

 

Es liegt also vermutlich eher an dem Part der das PopUp erzeugt. Bzw. der Part der die Daten im Listview ausließt.

 

Es ist eigentlich immer so, dass die HauptGui nicht offen ist. Sie wird meist per Gui, Hide geschlossen. Die PopUps werden aber dennoch aus den Daten erzeugt die das Listview liefert. Nur das Label Refresh aktualisiert diese Daten. Ich verstehe nur nicht warum es passiert. Ich stoppe den Timer, schreibe den Vorgang geschlossen in die DB und aktualisiere die Daten per Refresh, erst dann starte ich den Timer wieder.

 

Ich komm nicht weiter :(



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Ich habe den Code nun soweit verändert, dass das obere LV gelöscht wird direkt nachdem der Timer gestoppt wurde. Leider hilft auch das nicht, der Fehler ist immer noch da.

 

Der Vorgang der erneut aufpoppt ist auch nicht unter den geschlossenen Vorgängen zu sehen. Er bleibt oben als "überfälliger" Vorgang stehen. Also hat das Schreiben in die DB anscheinend nicht geklappt...

Nur kommt kein Fehler...

 

just me, hast du eine Idee dazu?

 

Wie kann man den Schreibvorgang auf Erfolg prüfen bzw. verifizieren?



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Hallo,

 

ich habe beim Drüberschauen keinen Fehler gefunden. Um den Updatevorgang abzuchecken, kannst Du vor "BEGIN TRANSACTION" und nach "COMMIT TRANSACTION" per DB.TotalChanges(Vorher) bzw. DB.TotalChanges(Nachher) prüfen, ob SQLite der Meinung ist, dass ein Eintrag geändert wurde.


Prefer ahkscript.org for the time being.


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Hi!

 

Wenn ich also dann prüfe per:

if (Vorher=Nachher)

Kann ich zusätzlich erkennen ob der Vorgang erfolgreich war, denn wenn er erfolgreich war müsste die Prüfung unwahr sein. Ist sie also Wahr muss ich den Schreibvorgang nochmal wiederholen.



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Ja, wenn Vorher = Nachher ist, ist die DB der Meinung, dass zwischen den beiden Abfragen nichts geändert wurde, warum auch immer! confused.png

Mir sind die Fehler lieber, die "immer oder nie" auftreten. Bei "manchmal aber meistens nicht" macht die Fehlerklärung meist mehr Arbeit.


Prefer ahkscript.org for the time being.


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Da sagste was... Ich habe nun vor dem "COMMIT TRANSACTION" noch einen kleinen Sleep, 10 eingebaut, die DB liegt ja im Netzwerkpfad... keine Ahnung ob das was bringt... Zudem leere ich vor dem anspringen des Labels das die Daten für das PopUp zieht alle Variablen die damit zu tun haben.

 

Bisher scheint es zu funktionieren. Ich werde nun meine Version mit dem Vorher=Nacher bestücken und mir nach jedem Vorgang eine msgbox ausgeben lassen mit dem Ergebnis. Dann werde ich ja sehen ob der Fehler nochmal kommt.

 

Danke dir für deine Hilfe! Wiedereinmal :)



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Hallo just me!

 

Fehler anscheinend behoben :) Bisher kam er jedenfalls nicht mehr vor.

 

Nun muss ich noch einen Offline Modus einbauen der dafür sorgt das der Reminder auch OHNE Netzwerkverbindung funktioniert.

 

Dazu lege ich in dem moment wo ich feststelle, dass kein Netzwerk mehr verfügbar ist eine Lokale DB an mit dem Inhalt aus dem oberen Listview. Wenn dann Netzwerk wieder verfügbar ist, werden die Vorgänge in die vorhandene DB die im Netzwerk liegt migriert.

 

Dazu aber eine Frage, Vorhandene Einträge in der DB muss man ja per UPDATE "erneuern" bzw. "überschreiben" neue per INSERT. Würde bedeuten, ich muss ich prüfen ob der Vorgang den ich da grad habe schon in der DB Vorhanden ist oder nicht und muss dann entsprechend den passenden SQL String nutzen.

 

Hälst du das so für praktikabel?

 

MfG

fump



SAPlayer
  • Members
  • 403 posts
  • Last active: Apr 11 2014 04:45 PM
  • Joined: 06 Nov 2012

Auch möglich ist REPLACE INTO, zumindest in MySQL:

REPLACE funktioniert auf exakt gleiche Weise wie INSERT. Der Unterschied besteht darin, dass, wenn ein alter Datensatz denselben Wert wie ein neuer Datensatz für einen Primärschlüssel oder einen eindeutigen Index hat, der alte Datensatz gelöscht wird, bevor der neue eingefügt wird. Siehe auch Abschnitt 13.2.4, „INSERT“.

http://dev.mysql.com...de/replace.html



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Wäre es gleichwertig mit dem hier: http://www.sqlite.or...g_conflict.html ?

 

EDIT:

 

Eher dies hier... http://www.sqlite.org/lang_insert.html auch hier gibts INSERT OR ROLBACK. Damit komm ich zurecht denke ich :)

 

Danke für den Tipp



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Hallo!

 

Leider ist der Fehler mit dem nicht funktionierenden Speichern weiterhin vorhanden. Ich habe den Part wie folgt umgeschrieben (hier am Beispiel des Wiedervorlagebuttons):

WVL:
GUIID:=A_Gui
GuiControl, %GUIID%:Disable, Snooze
GuiControl, %GUIID%:Disable, WVL
GuiControl, %GUIID%:Disable, NoCallNote
GuiControl, %GUIID%:Disable, CallNote
GuiControl, %GUIID%:Disable, KillFlag
Gosub GetVarPopUp
GoSub TimeCheckPopUp
If (Treffer=1)
	{
		Treffer:=0
		Return
	}
LVName := "ResultsLV" ; Name des LV
KillLV(LVName,1) ; Killt das obere LV
DB.Close
sleep, 100
DB := New SQLiteDB
If !DB.OpenDB(DBFilePath) {
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode . "`n`nReminder wird nun beendet. Starte das Modul bitte neu!"
   ExitApp
}
DB.TotalChanges(Vorher)
DB.Exec("BEGIN TRANSACTION;") ; Beginn der Übertragung
SQL := "UPDATE OR REPLACE " . TableName . " SET KD_Nr='" . RM_KDNr . "', D_ID='" . RM_DID . "', ToDo='" . RM_ToDo_DropDown . "', RR_Nr='" . RM_RRNr . "', WVL_Zeitpunkt='" . RM_DateTime . "', Status='Offen', ToDo_Text='" . RM_ToDo_Text . "', ToDo_Erl_Text='" . RM_ToDo_Erl_Text . "', Benutzer='" . UserName . "', FullTime='" . FullTime . "', ShowFlag='1', FirstUser='" . RM_FirstUser . "' WHERE Reminder_ID='" . RMIDPopUp . "';" ; Zusammensetzen des SQL Befehls als UPDATE da bestehender Vorgang - Hier wird nur die Reihe upgedatet deren ID mit RM_ID übereinstimmt.
If !DB.Exec(SQL) ; durchführen des SQL Befehls.
	MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode
sleep, 10
DB.Exec("COMMIT TRANSACTION;") ; Schließen der Übertragung.
sleep, 10
DB.TotalChanges(Nachher)
if (Vorher=Nachher) ; Sollte es dazu kommen das es keine Änderung in der DB gab wird der Schreibvorgang nochmal wiederholt. Sollte auch dies schief laufen wird eine Meldng ausgegeben und der Vorgang nochmal wiederholt. Klappt es wieder nicht, wird der Reminder beendet.
	{
		DB.Close
		sleep, 100
		DB := New SQLiteDB
		If !DB.OpenDB(DBFilePath) {
		   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode . "`n`nReminder wird nun beendet. Starte das Modul bitte neu!"
		   ExitApp
		}
		DB.TotalChanges(Vorher)
		DB.Exec("BEGIN TRANSACTION;")
		sleep, 250
		If !DB.Exec(SQL) {
			MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode . "`n`nReminder wird nun beendet. Starte das Modul bitte neu!"
			ExitApp
		}
		sleep, 1000
		DB.Exec("COMMIT TRANSACTION;")
		sleep, 500
		DB.TotalChanges(Nachher)
		if (Vorher=Nachher)
			{
				if (ErrorMeldung=0)
					{
						ErrorMeldung:=1
						msgbox, 4112, Fehler beim Speichern, Leider kam es zu mehreren Fehlern beim Speichern deines Vorgangs.`n`nVorgang wird nun wiederholt!
						GoTo WVL
						Return
					}
				if (ErrorMeldung=1)
					{
						Clipboard:=RM_ToDo_Erl_Text
						msgbox, 4112, Fehler beim Speichern, Leider kam es erneut zu mehreren Fehlern beim Speichern deines Vorgangs.`n`nDer Reminder wird nun neugestartet.`n`nDein "Was hast du gemacht?" Text wurde in die Zwischenablage kopiert.
						Reload()
					}
			}
	}
GoSub RefreshLVPopUp
ErrorMeldung:=0
Return

Wie zu sehen ist, schließe ich die DB und öffne sie neu, das habe ich nur eingebaut damit die Verbindung zur DB neu geöffnet wird. Dabei kommt es auch nie zu einem Fehler.

Anschließend setz ich den SQL Befehl zusammen und lasse ihn ausführen. Auch dabei kommt es anscheinend nie zu seinem Fehler.

Erst beim COMMIT scheint der Fehler zu entstehen. Denn Vorher und Nacher sind hin und wieder gleich. Es wurde also durch den COMMIT die Änderung nicht abgeschlossen.

 

Ich fange hier den Vorgang ab und lasse das ganze nochmal mit mehr Zeit durch längere Sleepings erneut durchlaufen. Das Hilft aber nicht. Es kommt die Meldung das was nicht geklappt hat und springe erneut nach oben und lasse den Vorgang komplett wiederholen. Leider klappt es dann auch nicht. Es kommt die zweite Meldung und darauf folgt ein Reload.

 

Hängt er einmal im Fehler fest, bringt ihn nichts mehr dazu es doch zu speichern, ich versteh nur nicht warum. Kann sich das hier jemand erklären?

 

Ich verzweifel noch an diesem Problem.

 

MfG
fump

 

//EDIT:

Ich vermute, es liegt am Netzwerk. Aber wenn ich den Fehler habe und die erste msgbox kommt und ich im Explorer auf das Netzlaufwerk klicke dann ist es verfügbar... Klicke ich dann auf OK kommt der Fehler dennoch wieder. Hängt er da einmal drin klappts einfach nicht. Nach dem Reload funktionierts aber sofort und einwandfrei.

 

Ich hab überlegt lokal eine TempDB zu nehmen und wie beim Archivieren den Vorgang in die HauptDB zu übertragen. Aber das ändert ja nichts am Problem, es würde nur verlagert werden.

 

Ich frag mich warum es bei den Wiederholungen nicht klappt.



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Guten Tag,
 
meine Vorschläge:

  • DB.Close gibt es nicht. Wenn Du die DB unbedingt schließen willst, musst Du schon DB.CloseDB() aufrufen. Für den Aufbau einer neuen Verbindung reicht danach ein DB.OpenDB(...). Ein neues DB-Objekt brauchst Du nicht.
     
  • Die Transaktionsanweisungen laufen z.Zt. ohne Fehlerprüfung. Ändere das mal wie bei der Update-Anweisung in
    If !DB.Exec("...")
       MsgBox, ...
    
  • Wenn das auch keine neuen Erkenntnisse bringt, probier mal If !DB.Exec("BEGIN IMMEDIATE TRANSACTION")
     
  • ???

 

Viel Erfolg!

 

just me


Prefer ahkscript.org for the time being.