Hallo Notes-Gemeinde,
seit vielen Jahren läuft bei uns ein Code ohne Probleme. Seit dem ich mit V12 entwickele, gibt es an einer Stelle ein Problem.
Als medizinischer Servicedienstleister existieren in einer unserer DB Patieten-Dokumente (docPat), zu denen Gesprächs-Dokumente (docGes) als Antworten erstellt werden.
Wird ein solches Gespräch als "beendet" gekennzeichnet, so müssen Daten, wie Anamnese, Diagnose oder ein ICD10-Schlüssel in die Stammakte übernommen werden, um bei einem Folgegespräch zur Verfügung zu stehen.
Für Dokumente, die zum Lesen geöffnet werden, werden Sperrsätze erzeugt bzw. geprüft, ob ein Sperrsatz exitiert. Wird das Dokument wieder geschlossen, wird der Sperrsatz gelöscht.
Situation: Das Gesprächs-Dokument ist im Edit-Modus geöffnet und soll mit dem Status "beendet" gespeichert und geschlossen werden. Dabei kann die Situation bestehen, dass
- das Patienten-Dokument durch einen anderen MA im Zugriff ist; Sperrsatz da, Rückgabe: "gesperrt"
- man selber das Patienten-Dokument im Read-Modus geöffnet hat; Sperrsatz da, Rückgabe "selbst"
- man selber das Patienten-Dokument im Edit-Modus geöffnet hat; Sperrsatz da, Rückgabe "selbst"
- kein Sprrsatz da, Rückgabe: "frei"; Sperrsatz für docPat wird dann angelegt
Im ersten Fall wird eine Meldung ausgegeben und ggf. die Verarbeitung beendet (siehe Schleife "Versuch").
Bei Fall zwei und drei wird auf das Vordergrund-Dokument des Patienten-Dokuments umgeschaltet, um den EditMode festzustellen:
Ist das Vordergrund-Patienten-Dokument im Read-Modus (zweiter Fall), wird es geschlossen und nur im Hintergrund erneut geöffnet.
Ist das Vordergrund-Patienten-Dokument im Edit-Modus (dritter Fall), wird wieder auf das Vordergrund-Gesprächs-Dokument umgeschaltet.
Der Code dazu ist folgender:
Set uiDocGes = ws.CurrentDocument
Set docGes = uiDoc.Document
...
'Lesen und Prüfen, ob docPat gesperrt ist;
Set docPat = db.GetDocumentByUNID(docGes.PatDocUID(0))
Versuch:
Call CreateLck(docPat.PatDocUID(0), EditStatus, docPat.PatID(0)) 'EditStatus = "frei", wenn nicht im Zugriff
If EditStatus = "gesperrt" Then
antwort = Messagebox("Zur weiteren Bearbeitung muss die Stammakte bearbeitbar sein." + Chr(13) _
+ "Sie haben die Stammakte freigeben lassen und wiederholen den Versuch -> Ja?" + Chr(13) _
+ "Das Gespräch wird nur gespeichert, es erfolgt KEINE Datenübernahme in die Stammakte! -> Nein", _
+ mb_yesno + mb_iconquestion, "TEO - Stammakte gesperrt - Freigeben lassen?")
If antwort = 6 Then 'Yes
Goto Versuch
Else
NoLck = False
End If
Else
If EditStatus = "selbst" Then
'Umschalten auf das Register mit docPat, um EditMode zu prüfen
+++ Fehler Set uiDocPat = ws.EditDocument(False, docPat,,,, False)
'>>> neu eingefügt, als der Debugger zeigte, dass zwar zum Register mit docPat umgeschaltet wird, aber uiDocPat leer blieb
Set uiDocPat = ws.CurrentDocument
If uiDocPat.EditMode = False Then 'geladenes Dokument im Read-Modus; es muss zur Aktualisierung geschlossen werden
uiDocPat.Close(True) 'Sperrsatz wird im QueryClose gelöscht
PatDocEditStatus = False
EditStatus = ""
Set docPat = db.GetDocumentByUNID(doc.PatDocUID(0)) 'durch uiDoc.Close wird das Objekt docPat zerstört, darum Nachlesen
Call CreateLck(docPat.PatDocUID(0), EditStatus, docPat.PatID(0))
Else
PatDocEditStatus = True 'geladenes Dokument im Edit-Modus; Aktualisierung geschieht automatisch in der Anzeige
End If
'wieder zurück umschalten auf das Register mit docGes
Set uiDocGes = ws.EditDocument (False, docGes,,,,False)
'>>> neu eingefügt, als der Debugger zeigte, dass zwar zum Register mit docGes umgeschaltet wird, aber uiDocGes leer blieb
Set uiDocGes = ws.CurrentDocument
Else
PatDocEditStatus = False 'EditStaus = "frei", docPat nirgends geladen
End If
NoLck = True
End If
...
Der Fehler tritt an der Stelle auf, an dem auf das uiDocPat umgeschaltet werden soll. Der OnError gibt eine Meldung ins Agents Log "Unable to find Document Window" Eine Suche hier im Forum ergab den Fehlercode 4405. Aber ob es wirklich der Fehler 4405 ist, kann ich nicht sagen, da leider keine Fehlernummer ausgegeben wird, obwohl dies im LogError-Befehl codiert ist.
Ich hatte nach 4405 im Forum geguckt, und hatte die Erkenntnis gewonnen, dass der Fehler auftreten kann, aber nicht unbedingt die Verarbeitung abbrechen muss. Nachdem der Debugger zeigte, dass das Umschalten zu uiDocPat trotz Auftreten des Fehlers gelang, uiDocPat aber "nothing" war, habe ich einen ws.CurrentDocument hinterhergeschoben. Dann war auch das uiDocPat da.
Inzwischen vermute ich, dass es leider doch nicht der Fehler 4405 ist, nachdem ich für ihn eine eigene Fehlerroutine programmiert habe, die aber nie angesprungen wurde. Und auch die Verarbeitung bricht ab. Aber welcher Fehler ist es? Der Fehler tritt auch nicht immer auf. In meinen Tests trat er nie auf! Und warum funktioniert der Code seit vielen Jahren fehlerfrei und mit einem Mal öfter nicht mehr?
Für Tipps wäre ich dankbar.
Liebe Grüße
Frank
Hallo Carsten!
Danke für Deinen Hinweis. Ich kann es auch mal mit der Abfrage des Fehlercodes 12272 probieren, frage mich aber, warum der Fehlercode nicht im LogError ausgegeben wird. Der Befehl ist ja nun nicht so kompliziert:
Call logfile.LogError(Err, "Beendet " + Error$ + " in line " + Erl)
Ich habe mal hinter fast jeden Befehl in meinem gesendeten Code-Ausschnitt einen LogAction-Befehl gesetzt, um sicher zu sein, dass die Zeilenangabe im LogError-Befehl stimmt. Und siehe da: Das Programm tut, was es soll, findet seine Fenster, liefert keine Fehler und schaltet zwischen den Registern richtig hin und her. Nur wird jetzt das Agents Log zugemüllt, was ich auch nicht so toll finde.
Was mache ich jetzt? ??? Die LogAction-Befehle drinlassen? Oder hat der Interpreter ein Problem, bzw. ist die Ausführungsebene zu langsam? Wurde der Code durch die vielen Änderungen erst jetzt "richtig" übersetzt? Soll ich Sprünge zu Speudo-Functions machen, um Zeit zu schinden? ;)
Was könnte das Verhalten denn noch verursachen? Die Grafikkarte?
Schönen Dienstag
Frank
Hallo Harald!
Im ersten Moment habe ich mich freudig überrascht gefragt: Warum erfahre ich nach zig Jahren des Programmierens erst jetzt von diesem Befehl? :o
Das wäre eine Lösung für einige Probleme, z.B. bei der PDF-Erstellung oder beim Aufrufen eines zip-Programms, wenn die Ergebnis-Datei weiter verarbeitet werden soll durch das Script.
Allerdings ist der Code in allen Beispielen falsch. Statt Shell muss ShellID aufgerufen werden, um eine TaskID zu erhalten. Das funktioniert auch heute noch.
Nach ein paar Tests hat sich allerdings herausgestellt, dass der erforderliche Handle von Windows nicht (mehr) abzufragen ist. GetModuleUsage gab's nur in 16-Bit-Windows systemen. Für 32-Bit Systeme gibt es keine Entsprechung. Und ein Abfragen von GetModuleHandle habe ich nicht hinbekommen.
Mein Versuch, dem Sript Zeit zu verschaffen, indem ich die LogAction-Befehle durch Print-Befehle ersetzt habe, damit mir die Log-DB nicht zugemüllt wird, war leider nicht erfolgreich. Fehler -28363 tritt nach wie vor auf. Ich fange ihn jetzt durch einen If-Befehl in der allgemeinen OnError-Routine ab und hoffe, dann mit einem Resume Next fehlerfrei durch das Script zu kommen.
Übrigens: Um ein externes Programm aufzurufen und das Script solange anzuhalten, bis das Programm wieder geschlossen ist, darf man es nicht über einen Shell-Befehl starten, sondern mit
Set vShell = CreateObject("WScript.Shell")
retval = vShell.Run(sCommand, 2, True)
Schönes Wochenende!
Frank