TIA VB-Skript für Rezept-Datenbank

Zuviel Werbung?
-> Hier kostenlos registrieren
Soooooo....jetzt kann mich das Ding dann mal langsam. Das ist ja wie Lotto-Spielen :mad:
Aufgrund eures Feedback habe ich (obwohl IMHO nicht Auslöser) alle Skripts gelöscht und alle Button's.
Es gibt nur noch den E/A-Button "Aufwärts blättern" und "Abwärts blättern" um die Einträge in der Rezepturdatenbank durchzugehen.
Hinter jedem E/A-Button steckt ein eigenes Skript. "Aufwärts blättern" ist nun wie im bereits vorgestellten Code ausgeführt:
Code:
Sub VB_DatabaseNextEntry()
'Ermittelt den naechst hoeheren vorhandenen Datensatz um diesen anzuwaehlen (um Luecken im Datenspeicher zu ueberspringen)
' -> Funktion wird mittels des Statuswertes der Abfrage gesteuert
'
'
Const TRANSFER_CLEAR = 0, TRANSFER_RUN = 2, TRANSFER_FINISHED = 4, TRANSFER_ERROR = 12            'Statusvariablen: Uebertragung; "Bereit" / "Laeuft" / "Beendet" / "Fehlerhaft"

Dim startNumber, loopNumber

startNumber = SmartTags("DB820_RezeptHMI_strRecept.Rezeptinfo.iDatanumber") + 1                    'Wertuebergabe an die Variable

For loopNumber = startNumber To 500
    Database_ScriptStatus = TRANSFER_CLEAR
    GetDataRecordName _
        1, _
        loopNumber, _
        "DB600_HMI_StateWord_ReceptName", _
        "DB600_HMI_StateWord_DataName", _
        "Database_ScriptStatus"                                                                    'Ausfuehrungsbefehl "LeseDatensatzname"
       
    ' wait for execution
    Do
    Loop Until Database_ScriptStatus > TRANSFER_RUN
   
    ' evaluation
    If Database_ScriptStatus = TRANSFER_FINISHED Then
        SmartTags("DB820_RezeptHMI_strRecept.Rezeptinfo.iDatanumber") = loopNumber
        Exit For
    End If
    SmartTags("DB600_HMI_StateWord_wHMILoopFail") = loopNumber
Next

End Sub
Wenn ich die Simulation ganz neu starte, überlebt das Skript tatsächlich volle 500 Durchläufe. Wenn ich den Button ein Zweites Mal drücke ,dann stirbt es irgendwo im 150. Durchlauf mit der Fehlermeldung
- $190010 : "DB600_HMI_StateWord_DataName": Überlast, Werte gehen verloren
- $190010 : ""DB600_HMI_StateWord_wHMILoopFail": Überlast, Werte gehen verloren
- $20010 : Fehler 'Überlauf' in Skript <VB_DatabaseNextEntry()> in Zeile 31

Das klingt ja langsam ganz nach einem Problem während der Speicherauslesung oder beim Beschreiben der Variablen.....????
 
Versuche mal folgendes:
ersetze alle Database_ScriptStatus durch SmartTags("Database_ScriptStatus")
und ändere Loop Until Database_ScriptStatus > TRANSFER_RUN zu Loop Until SmartTags("Database_ScriptStatus") <> TRANSFER_RUN

PS: welchen Datentyp hat die HMI-Variable Database_ScriptStatus ?

PPS: oder lass die Do..Loop-Schleife was tun, damit sie etwas langsamer wird
Code:
Dim scriptStatus

Do
    scriptStatus = SmartTags("Database_ScriptStatus")
Loop While (scriptStatus And 4) = 0 ' 4=fertig OK / 12=abgebrochen mit Fehler
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@PN/DP
Hab ich alles gemacht SmartTags("Database_ScriptStatus"). Bei der Systemfunktion "GetDataRecordName" muss ich die Variable aber als "Database_ScriptStatus" angeben. An dieser Stelle akzeptiert mir die Syntaxprüfung keine SmartTags-Variable. Das Verhalten hat sich nun leicht geändert, bzw. die Fehlermeldung. Wobei man sagen kann, dass das Skript nun im Durchschnitt bereits eine Überlebenschance von 40% erreicht hat :cool:
Die Variable "Database_ScriptStatus" ist eine UINT
bekannte Fehlermeldungen:
- $190010 : "DB600_HMI_StateWord_DataName": Überlast, Werte gehen verloren
- $190010 : ""DB600_HMI_StateWord_wHMILoopFail": Überlast, Werte gehen verloren
- $20010 : Fehler 'Überlauf' in Skript <VB_DatabaseNextEntry()> in Zeile 30
Zusätzlich mit gleichen Zeitstempel, aber nur sporadisch auftretende Fehlermeldung:
- $290042: Datensatzbearbeitung nicht möglich, da bereits eine Rezepturaktion läuft

Fazit:
- Egal ob "Database_ScriptStatus" oder SmartTags("Database_ScriptStatus") -> keine reproduzierbare Veränderung
- Do Loop While Schlaufe verlangsamen mit Variablenzugriff -> keine reproduzierbare Veränderung
- Je nach Neustart der Simulation mal 10% Überlebenchance / mal 40% Überlebenschance -> nicht reproduzierbar
 
usätzlich mit gleichen Zeitstempel, aber nur sporadisch auftretende Fehlermeldung:
- $290042: Datensatzbearbeitung nicht möglich, da bereits eine Rezepturaktion läuft
Das deutet für mich darauf hin, dass deine Datensatzabfrage asynchron läuft und du dadurch (wie schon von mir vermutet) deine Überlast bekommst ...
Deine prozentuale Überlebenschance ist für mich keine belastbare Größe - sorry ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde jetzt erst mal noch auf Nummer sicher gehen, dass dieses Script nur 1x läuft (und auch nicht das für die Gegenrichtung).
Nicht, dass der Button prellt o.ä..
Dafür eine boolsche Variable im HMI anlegen, diese am Anfang des Scripts abfragen und ggf. das Script abbrechen.

Z.B.:
Code:
Sub vbDatabaseCountUp()
'Ermittelt den naechst vorhandenen Datensatz um diesen anzuwaehlen (um Luecken im Datenspeicher zu ueberspringen)
' -> Funktion wird mittels des Statuswertes der Abfrage gesteuert
'
'

     SmartTags("ScriptRunning") = True

    ' das eigentliche Script:
    ...
 
    SmartTags("ScriptRunning") = False

End Sub

PS:
Ach, ist auch wieder Quatsch! :eek:
Wird ja eh nur ein Script ausgeführt und die anderen Aufrufe "nur" in den Queue eingetragen.

Also besser die Button mit dieser Variable aktivieren/deaktivieren.
 
Zuletzt bearbeitet:
Ich würde jetzt erst mal noch auf Nummer sicher gehen, dass dieses Script nur 1x läuft (und auch nicht das für die Gegenrichtung).
Nicht, dass der Button prellt o.ä..
Dafür eine boolsche Variable im HMI anlegen, diese am Anfang des Scripts abfragen und ggf. das Script abbrechen.

Z.B.:
Code:
Sub vbDatabaseCountUp()
'Ermittelt den naechst vorhandenen Datensatz um diesen anzuwaehlen (um Luecken im Datenspeicher zu ueberspringen)
' -> Funktion wird mittels des Statuswertes der Abfrage gesteuert
'
'

     SmartTags("ScriptRunning") = True

    ' das eigentliche Script:
    ...
 
    SmartTags("ScriptRunning") = False

End Sub

PS:
Ach, ist auch wieder Quatsch! :eek:
Wird ja eh nur ein Script ausgeführt und die anderen Aufrufe "nur" in den Queue eingetragen.

Also besser die Button mit dieser Variable aktivieren/deaktivieren.
Danke für den Nachtrag....Bin jetzt allerdings ein wenig verunsichert......
Soll ich nun das Script mit dieser Funktion erweitern und den E/A-Button damit belegen? Oder hast du es anders gemeint?
Sorry....steh langsam auf dem Schlauch :)
Ist es denn nicht so das wenn ich im E/A-Button das Erreignis mit "Drücken" auslöse, das Skript nur ein einziges Mal angetriggert wird?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Möchte mich zwischenzeitlich noch bedanken für euren tollen und enthusiastischen Einsatz mit meiner Problemstellung.
Herzliches Danke an:
@hucki
@Larry Laffer
@PN/DP
@faust
Werde das Problem morgen erneut angehen....Obschon ich befürchte, dass Lösungsansätze langsam dünn werden.
Bin ich eigentlich der einzige, der sich mit solch Rezept-DB-Problemen rumschlagen muss, wennn man sich gegen die Original-Siemens-Rezepturanzeige entscheidet ???
 
Nach etwas mehr darüber nachdenken, würde ich es jetzt so machen:
- in der Funktionsliste des Button die Variable setzen (dann erst das Script starten)
- mit der Variable die Animation Anzeige->Bedienbarkeit steuern
- am Ende des Scripts die Variable wieder zurücksetzen
 
Bin ich eigentlich der einzige, der sich mit solch Rezept-DB-Problemen rumschlagen muss, wennn man sich gegen die Original-Siemens-Rezepturanzeige entscheidet ???
Wahrscheinlich Ja - es gehen tatsächlich nur sehr wenige den Weg sich etwas speziell anzupassen ...

Auch wenn die Ansätze langsam dünn werden - du hast ja wenigstens ein sicheres Problem : die Script-Überlast (heißt zuviele Aktionen im Puffer).
Wenn es korrekt ist, dass die GetDataRecordName-Abfrage asynchron ist (was ich als ziemlich sicher annehme) und die die Überlast bewirkt : was wäre denn wenn du hier einen doppelten Loop machst : einmal, dass der Start angenommen worden ist und dann, dass sie so oder so beendet worden ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wahrscheinlich Ja - es gehen tatsächlich nur sehr wenige den Weg sich etwas speziell anzupassen ...

Auch wenn die Ansätze langsam dünn werden - du hast ja wenigstens ein sicheres Problem : die Script-Überlast (heißt zuviele Aktionen im Puffer).
Wenn es korrekt ist, dass die GetDataRecordName-Abfrage asynchron ist (was ich als ziemlich sicher annehme) und die die Überlast bewirkt : was wäre denn wenn du hier einen doppelten Loop machst : einmal, dass der Start angenommen worden ist und dann, dass sie so oder so beendet worden ist.
Steig ich nicht ganz durch.....kannst du mir das bitte ein wenig aufschlüsseln, wie du das genau meinst?
Also 2 Skripts schreiben und nacheinander ablaufen lassen, oder ein Subscript im Script aufrufen, in dem dann das eigentlich GetDataRecordName ausgeführt wird?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Steig ich nicht ganz durch.....kannst du mir das bitte ein wenig aufschlüsseln, wie du das genau meinst?
Also 2 Skripts schreiben und nacheinander ablaufen lassen, oder ein Subscript im Script aufrufen, in dem dann das eigentlich GetDataRecordName ausgeführt wird?
Nein ... so meinte ich das nicht ...
Ich meinte, dass du erst warten sollst, dass die Abfrage gestartet worden ist und dann (anschließend) dass sie (so oder so) beendet worden ist.
Meine Vermutung ist, dass du die zweite Abfrage bereits startest bevor die erste Abfrage zuende bearbeitet worden ist (naja usw.).
Irgendwann bist du dann vielleicht im Flow drin - bis dahin hast du aber möglicherweise schon x Abfragen gestartet (wegen asynchron).

auch @PN/DP : ich denke nicht, dass der Siemens-Support bbei DEM THEMA sinnvoll weiterhelfen wird (ich lasse mich aber gerne überraschen) - ich glaube eher, dass da eine Antwort kommt wie "so hatten wir uns die Benutzung des Befehls auch nicht gedacht" (oder sinngemäß ähnlich ...)
 
Nabend.

Lese zwar schon den ganzen Tag mit, komme aber jetzt erst dazu, "meinen Senf dazuzugeben" :)


Zuerst eine Frage, die nicht zum eigentlichen Problem gehört (aber vielleicht dennoch interessant ist):
Du sagst
Wenn ich einen neuen Datensatz im Panel erzeuge, kriegt dieser im Rezeptur-Speicher einfach die nächst freie "Datensatznummer".
Wo kommt diese Datensatznummer her? Erzeugst bzw. ermittelst du diese selbst? Die Systemfunktion "SpeichereDatensatz" tut dies nämlich nicht von sich aus (siehe TIA-Hilfe:
1707503830894.png

Weitere Fragen:
Die Variablen "DB600_HMI_..." und "DB820_..." sind Variablen mit Steuerungsanbindung, richtig?
Frage 1: Warum? Benötigst du JEDES Ergebnis der Abfrage "GetDataRecordName" in der Steuerung?
Frage 2: Wie sind denn Erfassungsart und Erfassungszyklus für diese Variablen eingestellt?


Gruß, Fred


PS:
@markus.dietschi: Wie ich es in der Vergangenheit auch schon anderen angeboten habe: Gerne können wir uns direkt per Telefon/Teamviewer o.ä. austauschen. Solange wir dann die Lösung des Problems hier veröffentlichen, hat auch bestimmt keiner was dagegen ;)
 
Zuletzt bearbeitet:
@faust : das könnt ihr natürlich machen - ich denke aber mal, dass dieses Thema schon zum allemeinen Interesse geworden ist zumal sich ja schon einige hier engagieren ... Ich würde es hier halten ... aber das ist natürlich eure Entscheidung ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Weitere Fragen:
Die Variablen "DB600_HMI_..." und "DB820_..." sind Variablen mit Steuerungsanbindung, richtig?
Frage 1: Warum? Benötigst du JEDES Ergebnis der Abfrage "GetDataRecordName" in der Steuerung?
Frage 2: Wie sind denn Erfassungsart und Erfassungszyklus für diese Variablen eingestellt?
Das sind sehr wahrscheinlich die Problembringer.

Ich hab' das Ganze heute (wo ich wieder daheim bin) mal in meinem HMI (Sim eines TP1200 Comfort Pro) nachgebaut.
Zunächst mit HMI internen Variablen -> Keinerlei Fehlermeldungen.
Dann die HMI-Variablen auf einen PLC-DB verbunden -> Überlast
PLC-Verbindung wieder entfernt -> wie (jetzt) zu erwarten, keinerlei Fehlermeldungen mehr.
 
Zuletzt bearbeitet:
@markus.dietschi,
für Dich (aber auch andere Suchende) zur Info, wie ich das Ganze im Test aufgebaut habe, womit es bei mir in der Sim (allerdings ohne den Rest einer Rezepturverwaltung) läuft:


die benötigten HMI-Variablen:
1707519736130.png

das zugehörige Script, wobei ich eine Funktion (kein Sub) gleich für beide Suchrichtungen genutzt habe, um den ermittelteten Wert zurück zu geben:
Code:
Function vbRecordNext(ByVal RecipeNr, ByVal StartNr, ByVal Dir)
'
'Script:            vbRecordNext
'Version:           1.00
'Author:            hucki
'issue Date:        09.02.2024
'last modified:     09.02.2024
'State:             draft
'
'Function:          determines the next existing data record in order to select it (to skip gaps in the data storage)
'                   -> function is controlled using the status value of the query
'                   Ermittelt den naechst vorhandenen Datensatz, um diesen anzuwaehlen (um Luecken im Datenspeicher zu ueberspringen)
'                   -> Funktion wird mittels des Statuswertes der Abfrage gesteuert
'                    
'changes:            .
'

    Const RECORD_MN = 1, RECORD_MX = 500            ' 
    Const QUERY_RUN = 2, QUERY_FINISHED = 4, QUERY_ERROR = 12    
    
    Dim DataRecordNr
    

    SetBit "QueryRunning"

    
    vbRecordNext = StartNr
    DataRecordNr = StartNr
    
    Do
        
        ' next record number
        DataRecordNr = DataRecordNr + Dir
        If DataRecordNr < RECORD_MN Or DataRecordNr > RECORD_MX Then Exit Do
        
        ' query
        GetDataRecordName RecipeNr, DataRecordNr, "RecipeName", "DataRecordName", "QueryStatus"
    
        ' wait for execution
        Do
        Loop Until QueryStatus > QUERY_RUN
        
        ' evaluation
        If QueryStatus = QUERY_FINISHED Then vbRecordNext = DataRecordNr    

    Loop While QueryStatus = QUERY_ERROR
    
    
    ResetBit "QueryRunning"

End Function

Meine Testseite mit der Rückwärts-Suche:
1707519803665.png

bzw. der Vorwärtssuche:
1707519865611.png

und dann noch die Animation, damit das Script nicht mehrfach zur gleichen Zeit angestossen werden kann:
1707519971485.png

mit der gleichen Animationsvariablen habe ich dann auch noch die Button während der Scriptlaufzeit umgefärbt:
1707520067045.png


Wie im Post vorher bereits gesagt, wird das gewählte Rezept bei mir so ohne Überlast innerhalb der 500 zulässigen Datensätze (nur 4 existieren) abgefragt.
Der höchste vorhandene bei mir ist die Nr. 6. Wenn mit Next dann noch weiter gesucht wird, sieht man anhand der Färbung sehr gut die Laufzeit des Scripts.
 
Zwischen "Loop While..." und "ResetBit..." würde ich als Nächstes noch eine Abfrage einfügen, ob "vbRecordNext = StartNr" und ggf. für den Benutzer eine Meldung ausgeben, dass kein weiterer Datensatz vorhanden ist.
 
Zuletzt bearbeitet:
Zurück
Oben