Zum Programmanfang zurückkehren...

  • Hallo Gemeinde,

    gibt es eine (einfache) Möglichkeit zum Anfangsstatus eines Programms zurückzukehren, ohne es sich selbst neu starten zu lassen?

    Hintergrund: Ich programmiere immer noch mein Hardwarebuchungssystem. Dieses soll auf einem "Kiosk-System" immer laufen.
    D.h. ein MA geht ins Labor, schnappt sich ein Testdevice, Scannt seinen Ausweis und das Gerät und bucht es als ausgeliehen und geht. Der nächste user kommt und bucht usw.
    Das bedingt aber, dass nach einem Buchungsvorgang oder nach einem Buchungsfehler(z.B. S/N existiert nicht in der DB) das Programm wieder in seinen Anfangszustand "zurückkehrt",
    damit ein neuer Buchungsvorgang vorgenommen werden kann...

  • hipfzwirgel 12. Januar 2022 um 10:51

    Hat den Titel des Themas von „Zum Programmsstart zurückkehren...“ zu „Zum Programmanfang zurückkehren...“ geändert.
  • Ich nehme an, dass der Buchungsvorgang durch Benutzeraktivitäten über ein GUI ausgelöst wird. Dann sollte es reichen, nach Abschluß der Buchung die (wesentlichen) beteiligten Variablen und/oder GUI-Controls wieder auf Ihre Anfangswerte zu setzen.

  • Beispiel:

    Code
    While 1
        $iReturn = Verarbeitung()
        If $iReturn = 1 Then Exit ; Programm beenden
    WEnd
    
    Func Verarbeitung()
        ; Hier kommt Dein bisheriger Code rein
        ; Return 0 lässt das Skript weiterlaufen
        ; Return 1 beendet das Skript
    EndFunc
  • Das kannst du doch (wie bereits hier von water veranschaulicht als Code) immer mit einer Funktion realisieren (der ggf. die gescannte Seriennummer mitgegeben wird).

    Aber die entsprechenden Variablen (die jedes mal am Anfang Gleich sein sollen) müssen natürlich Local definiert sein und nicht global.

    Dann funktioniert das auch ohne Probleme.

  • Hallo Alle,

    zunächst ein gutes und vor allem ein gesundes neues Jahr euch allen.

    @ VE: So einfach geht das leider nicht, da das Einlesen des "nächsten" Betriebsausweises so nicht erneut startet...

    @ Water und Moombas:

    zunächst Danke für die Idee. Ich bin mir nur nicht im Klaren was in die vorgeschlagene While rein muss, bzw. wie ich diese in die Programmstruktur integrieren soll?

    Der Aufbau ist zur Zeit folgender:

    1. AutoitWrapperangaben

    2. Includes

    3. Fileinstall und Definition Globaler Variablen

    4. Definition des GUI
    5. Aufruf der Funktion Kallback() i.V. mit Funktion _KeyProc und EvaluateKey (siehe Hilfe zu _WinAPI_SetWindowsHookEx) zum Auslesen des Betriebsausweises

    6. WhileSchleife zur Steuerung des GUI

    7. Die Func EvaluateKey ruft nach Feststellung der Ausweisnummer die Func AusweisNrCheck auf um festzustellen ob die Nummer valide ist, der User bereits in der Db drinsteht
    und ob das AD-Objekt des Users überhaupt aktiv ist (wenn nicht wird die Func AD-Login aufgerufen -> User authentifiziert sich und bei Erfolg werden die Userdaten mit der Func InDBSchreiben() in die DB geschrieben).
    8. Wenn die User-Authentifizierung erfolgreich war, kann der User dann nach Scannen des HW-QR-Codes per Buttonklick( in GUI-Whileschleife -> Aufruf der Func Buchung) die Buchung vornehmen.

    CodeStruktur zur Übersicht:

  • Hallo,

    der Ablauf, wie ich ihn sehe:

    1. Das Skript startet, zeigt das GUI an ...
    2. ... und aktiviert die Routine zum Einlesen der Ausweisnummer.
    3. Bei erfolgreicher User-Authentifizierung werden die Routine für die Ausweisnummer deaktiviert und die Routine zum Einlesen des HW-QR-COdes aktiviert.
    4. Nach erfolgreichem Einlesen der HW-ID werden die Routine für den QR-Code deaktiviert und der Button für die Buchung im GUI freigegeben.
    5. Bei Buttonklick erfolgt die Buchung. Die zugehörigen Skriptvariablen und evtl. GUI-Controls werden geleert/initialisiert, der Button für die Buchung wird deaktiviert und die Routine zum Einlesen der Ausweisdaten wird neu gestartet (-> weiter bei 2.)

    Zu einfach gedacht? Es sollte wohl auch einen Button zum Abbruch der Verarbeitung geben.

  • Hallo Gemeinde,

    gibt es eine (einfache) Möglichkeit zum Anfangsstatus eines Programms zurückzukehren, ohne es sich selbst neu starten zu lassen?


    ich verstehe nicht ganz was du meinst,

    'S/N existiert nicht in der DB' Wenn du diesen Fehler bekommst steht dieser dann in deiner gui ?

    1. Wenn ja schreibe dir eine Funktion die ein array zurück mit dem auslesen des Input Feldes oder Felder^^.

    2.diese packst du dann unter End switch in die while schleife

    3.erstell dir eine Global $var[0] die oben genannte Funktion mit dieser variable.

    nun kannst du die Var[0] VAR[1] usw, immer wieder aktualisierend abrufen und dann kannst du auch einfach auf Fehler/fehleingaben prüfen
    Oder erscheint der Fehler dann lösch halt den Inhalt auf "" und starte Funktion axy nochmal

    So kannst du auch bsp. direkt auf die Sting länge direkt im Input Feld prüfen wenn falsch dann mach das und das ohne das der Nutzer davor nochmal den Butten drücken muss.

  • Hallo Leute,

    ich bin jetzt mal soweit, dass ich den Hauptcode in eine Funktion Verarbeitung() ausgelagert habe.
    1. Erfolg: Der AbruchButton innerhalb des Switches (Case $Button2) für die Gui, funktioniert und "startet" das Proggi neu,
    indem die Func Verarbeitung() neu aufgerufen wird.



    Hat jemand eine Idee warum der Codeschnipsel vom Case $Button2 in anderen Funktionen nicht das gleiche Ergebnis liefert?

    Wenn ich z.B. in der AD-Login Func den Codeschnipsel als Abbruch-code für den Cancelbutton einer InputBox ausführe,
    wird zwar das Fenster neu geladen, dieses bleibt aber weiss (leer)

    Spoiler anzeigen

    $sUserId = InputBox("Login", "AD-Loginname" & @CRLF & @CRLF & "e.g. de\xy123z", " ", " M")

    If @error = 1 Then ; Wenn user den Abbrechen Button drueckt...

    GUISetState(@SW_DISABLE, $hGui)

    MsgBox(4112, "Canceled by User - Alert", "Programm is canceled by useraction")

    Verarbeitung()

    EndIf


    Nachtrag: in der Titelleiste des Fesnters erscheint "keine Rückmeldung" und der Cursor mutiert zur Sanduhr...

  • Ich verstehe nicht, warum Du mit einem rekursiven Aufruf das GUI neu erstellen und eine zweite Nachrichtenschleife starten willst.

    Es wäre hilfreich, wenn Du etwas mehr von Deinem Code zeigen würdest, damit man prüfen kann, wo und wie man in den Ablauf eingreifen kann.

  • ich hab mir mal deine gui angesehen kann es sein das du meinst das der abbrechen butten erkennen soll ob es ein user oder bsp admin war der diesen geklickt hat?

    Wenn ja, musst du nicht die gui neustarten sondern eine If abfrage einbauen du Brauchst die Info in der Datenbank das dich eindeutig identifiziert das du admin bist.

    bsp.

    if $ID-Card[(userwertinderdatenbank)] = 'admin' Then

    Msgbox(1, 'Beenden','Programm wird beednet!')

    Exit

    Elseif $ID-Card[(userwertinderdatenbank)] ='user' Then

    MsgBox(4112, "Canceled by User - Alert", "Programm is canceled by useraction")

    GUICtrlSetData($idCode, '')

    endif


    Oder versteckst du einfach sehr viel von deinem normalem Code?^^

    Wir können nur rätseln was du genau möchtest.


    Edit nochmal deinen oberen Beitrag gelesen ^^

    - > Buchungsfehler

    Wie kommt den der Buchungsfehler an also wie sieht er aus, gibt es einfach ein error als string zurück ?

    Global $errorstring = 'zeichenfolgedesbuchungsfehlers'

    Wenn du es in eine Funktion packst dann Local

    3 Mal editiert, zuletzt von MojoeB (19. Januar 2022 um 19:25)

  • Hallo Velted und MojoeB,

    ich bedanke mich bei euch für eure Ideen, befürchte aber ihr denkt viel zu kompliziert. Der Sachverhalt stellt sich so dar:

    Das Tool soll ein Buchungssystem werden um Hardwareausgaben und -Rückgaben zu buchen. Es soll auf einem Kiosk-PC laufen(immer an).

    Wenn nun ein User eine Buchung startet und es irgendeinen Fehler/Abbruch gibt oder die Buchung erfolgreich durchgelaufen ist, muss das Programm quasi neu gestartet werden, damit
    die Leseroutine wieder aktiv wird um eine neue Buchung machen zu können. Welcher Fehler oder welcher Abbruch ist dabei unrelevant.
    Ob nun das Event ein fehlender User in der Db ist, ein manueller Abbruch durch den User, ein deaktiviertes AD-Konto oder die erfolgreiche Buchung ist, spielt keine Rolle.

    Es geht hier nicht um das Abfangen von Fehlern sondern nur darum das Programm wieder auf Anfang zu setzen!

  • Ich würde folgendes Basiskonstrukt verwenden ...

  • Es geht hier nicht um das Abfangen von Fehlern sondern nur darum das Programm wieder auf Anfang zu setzen!

    Ich würde das für diesen Fall so managen:

    1. Deklaration aller erforderlichen Variablen

    2. Erstellen einer Funktion _InitVars(), die allen Variablen die Startwerte zuweist

    3. eine Arbeits-Funktionen erstellen, die in der (äußeren) Endlosschleife gestartet wird

    4. in der Arbeitsfunktion eine Schleife, die bei Nichtauftreten von Fehlern kontinuierlich abgearbeitet wird - aber im Fehlerfall verlassen wird und die Variablen neu initialisiert

    Hier ein Bsp.:

  • Hallo water,

    vielen lieben Dank für den Denkanstoß. Ich habe deinen Tipp umgesetzt. Mein Proggi entspricht ja dem von dir skizzierten Basiskonstrukt.
    Gemäß deiner Ausführungen habe ich nun eine Func Neutstart() geschrieben, die alle Globalen Variablen zurücksetzt.

    Spoiler anzeigen

    Func Neustart()

    Global $sAusweisNr = ""

    Global $sSerial = ""

    Global $sString = ""

    Global $sUserId = ""

    Global $sPwd1 = ""

    Global $sPwd2 = ""

    Global $sName = "" ; LoGonName, z.B. ae91fe

    Global $sDispName = "" ; Username, z.B. Mustermann, Horschd wird erst in Ausweischeck() oder AD-Login() befüllt

    Global $start_char = 0

    Global $end_char = 47

    Global $sStartAd = 1

    Global $iRetValue = 0

    Global $sDatabaseName = @ScriptDir & "\TestHW.accdb"

    Global $sKundenNr = ""

    Global $sRechnername = ""

    Global $iReturn = 0

    Global $g_sBuffer = Null

    Global $g_hStub_KeyProc = Null

    Global $hmod = Null

    Global $g_hHook = Null

    Global $iLength = Nul

    GUICtrlSetData($sDisplayname, "Please lay your Company-ID-Card on the Reader....")

    GUICtrlSetFont($sDisplayname, 16, 600, 0, "Bosch Office Sans")

    GUICtrlSetData($idCode, "")

    EndFunc ;==>Neustart


    Kommt es im Programm zum Abbruch oder Fehler so wird zunächst diese Func aufgerufen und dann kommt der Return.

    Spoiler anzeigen

    $sUserId = InputBox("Login", "AD-Loginname" & @CRLF & @CRLF & "e.g. de\xy123z", " ", " M")

    If @error = 1 Then ; Wenn user den Abbrechen Button drueckt...

    Neustart()

    Return

    EndIf


    Das würde glaube ich auch funktionieren aber da kommt dann wieder ein Problem zum Tragen, das ich schon einmal zum Thema gemacht hatte:

    Die Callback-Funktion "speichert oder puffert" irgendwie und -wo die eingelesenen Werte und ich bekomme diese Werte nicht gelöscht. Denn wenn der Return erfolgt,
    wird in der While-Schleife der GUI die Callback aufgerufen, damit ich wieder einlesen kann. Allerdings sind wie gesagt die vorher eingelesenen Werte noch existent und es wird damit sofort eine Verarbeitung initiiert...

    Hier mal das Callback-Konstrukt:

    Bei einem Neustart des Proggis ist der Puffer aber weg. Darum auch die Intention mit dem Neuanfang des Proggis....

  • Hallo Bugfix,

    wünsche ein gesundes und gutes neues Jahr und danke für deine Idee. Sie entspricht so ziemlich dem was water vorgeschlagen hatte ;)
    Nur wie eben schon geschrieben spuckt mir da die Callback in die Suppe...

  • Hier noch ein paar Anmerkungen:

    • Globale Variablen sollte man im Skript nicht mehrfach definieren. Das ist unnötig und schlechter Programmierstil
    • Definiere ALLE Variablen am Beginn des Skriptes. Setze einen Initialwert nur für jene Variablen, die nicht zurückgesetzt werden müssen
    • Alle anderen Variablen setzt Du in der Neustart Funktion. Somit musst Du diese Werte nur an einer Stelle im Skript pflegen
    • Die Funktion Neustart rufst Du zu Beginn des Skriptes 1x auf.

    Mehr Anmerkungen folgen.

  • While-Schleife der GUI die Callback aufgerufen, damit ich wieder einlesen kann

    Das ist sehr unglücklich gelöst.

    Deine Funktion "Kallback()" ist ja nicht die Callback-Funktion, sondern initialisiert den Hook.

    Die Initialisierung des Key-Hooks sollte einmalig am Skriptanfang erfolgen. Danach musst du dort nicht wieder ran.

    Die registriert Callbackfunktion (_KeyProc) wird dann bei jedem Key-Event aufgerufen. In der Funktion wird nichts gespeichert. Es wird die Keyboard-Struct befüllt, die du anschliessend auswertest. Es existieren keine statischen Variablen, die einen Wert nach Verlassen der Funktion halten könnten.

    EDIT:

    Wo kommt eigentlich plötzlich die Variable "$sAusweisNr" her (EvaluateKey) - sie ist nirgendwo deklariert.

    Auf die Deklaration Globaler Variablen hat water bereits hingewiesen - niemals! innerhalb von Funktionen!

  • Wenn die Probleme mit einem Restart des Skriptes schlagartig alle behoben sind, dann empfehle ich die Restart UDF.

    Somit brauchen wir uns nicht mit den "irgendwie und irgendwo" Problemen rumzuschlagen ;)

  • Ich würde das von water ein wenig abwandeln:

    Hier noch ein paar Anmerkungen:

    • Globale Variablen sollte man im Skript nicht mehrfach definieren. Das ist unnötig und schlechter Programmierstil
    • Definiere ALLE Globalen Variablen am Beginn des Skriptes. Setze einen Initialwert nur für jene Variablen, die nicht zurückgesetzt werden müssen
    • Definiere Globale "Variablen" als CONST, wenn sie ihren Wert nie ändern sollen
    • Alle anderen Globalen Variablen setzt Du in der Neustart Funktion bzw. die Lokalen in den jeweiligen Funktionen. (Somit musst Du diese Werte nur an einer Stelle im Skript pflegen)
      • Die Anzahl der globalen Variablen sollte man meiner Meinung nach se klein wie nötig halten.
    • Die Funktion Neustart rufst Du zu Beginn des Skriptes 1x auf.

    Mehr Anmerkungen folgen.

  • Noch ein gravierendes Problem:

    $g_hStub_KeyProc = 0 in der Funktion "EvaluateKey".

    Das darfst du unter keinen Umständen machen. Du sägst damit den Ast ab, auf dem du sitzt. denn du befindest dich zu diesem Zeitpunkt mitten in der Auswertung der Procedur. Danach hast du keinerlei definierten Programmzustand mehr. Somit verstehe ich auch deinen Wunsch nach Restart. - Das ist aber ausschließlich ein Rumdoktern am Symptom ohne die Ursache zu bekämpfen.

    M.M.n ist das Problem die unsachgemäße Verwendung des Key-Hooks.

    Das sind ja bisher alles nur Skript-Segmente. Wenn du magst, zeig mir mal dein gesamtes Skript und ich versuche das zu ordnen.