TIA CASE ersatz für Dynamische abzweiger?

vollmi

Level-3
Beiträge
5.749
Reaktionspunkte
1.690
Zuviel Werbung?
-> Hier kostenlos registrieren
Normalerweise baut man ja CASE so auf:
Code:
CASE #Sollwert OF
    111:
        ;// tudiesunddas
    21:
        ;   // nun jenes
    113:
        ;
    ELSE
        ;   // aber sonst dieseswelches
END_CASE;

Wobei die Werte vor dem Doppelpunkt Konstanten sein müssen, entweder in der Deklaration oder halt gleich im Code

Wie würdet ihr einen CASE verteiler aufbauen wo ihr die Verzweigung variabel angeben könnt?

Klar man kann auch einfach ein IF THEN machen aber sieht als Case einfach netter aus wenn man eh immer mit der gleichen Variable vergleicht.

geht das irgendwie?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich denke er möchte statt den konstanten „Sprungmarken“ eine Variable verwenden. Also statt wie im Beispiel „111:“ etwas wie „DB_Param.Label1“.

Soweit ich weiß geht das nicht... da geht nur werzweigtes IF-ELSE Konstrukt.
 
Da bin ich mir fast ziemlich sicher das dies nur mit Festwerten geht. Du fragst im Prinzip einen Status ab. Einen DB zu nutzen würde da nicht viel bis keinen Sinn machen.

Gesendet von meinem SM-A505FN mit Tapatalk
 
Klar man kann auch einfach ein IF THEN machen aber sieht als Case einfach netter aus wenn man eh immer mit der gleichen Variable vergleicht.

Normaleweise lege ich mir die abzufragende "variable" Variable als Steuerbefehl für CASE und die Kriterien nach denen diese ausgewertet wird, als CASE-Bedingungen. Welchen Anwendungsfall gibt es um ein variables CASE zu machen ? Indem du deine Sprungmarken aus einer Rezeptur vergibst oder wie ?

Im CASE geht generell folgendes:

- Konstanten;
- Hexadezimale Sprungmarken, wie z.B. INT#16#24FF
- Umwandlung der Steuervariable aus anderem Datentyp wie z.B.

Code:
CASE DWORD_TO_INT(SHL(IN := DINT_TO_DWORD(#Steuervariable), N := 16 )) OF 

INT#16#20 :
;
INT#16#80 :
;

Es geht auch CASE in CASE, Anwendung von Masken usw.

Letzen Endes ist von der Syntax her die Anweisung

Code:
IF Bestellung = Chickenburger THEN
;
ELSIF Bestellung = Cheesburger THEN
;
ELSIF Bestellung = LongChiliCheese THEN
;
ELSE
END_IF;

Nicht irgendwie wesentlich länger oder komplizierter als eine gewöhnliche Case Anweisung. Möchtest du mal sehen, wie die Inder bei Siemens neuerdings programmieren ? In der neuesten APL V9.0 ? Das ist der der Horror. Aber so richtig heavy Metall. Guck mal, wie man ohne Case programmiert:

Code:
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#9 THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 82;
                                                    T_CH2[2*X + 1] := 82;
                                                    
                                                ELSE
                                                    T_CH2[X] := 82;
                                                END_IF; 
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#A THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 83;
                                                    T_CH2[2*X + 1] := 83;
                                                    
                                                ELSE
                                                    T_CH2[X] := 83;
                                                END_IF;  
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#B THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 83;
                                                    T_CH2[2*X + 1] := 83;
                                                    
                                                ELSE
                                                    T_CH2[X] := 83;
                                                END_IF; 
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#C THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 83;
                                                    T_CH2[2*X + 1] := 83;
                                                    
                                                ELSE
                                                    T_CH2[X] := 83;
                                                END_IF;
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#D THEN

Das Ganze dann über Paar Kilometer so, und wieder holt sich auch noch Paar Mal. Dazu noch ist dieses "TEST" ein AT-Zugriff auf eine extern refernzierte Variable. Was es im Compilat macht, kannst du dir glaube ich vorstellen.

Die das geschrieben haben, das sind offensichtlich Leute, die keine Ahnung davon haben, wie man Case Anweisungen umsetzt, und wie man generell auf Steuerungen programmiert. Und dazu wahrscheinlich auch noch Leute, die keinerlei innere Motivation haben, irgendetwas richtig zu machen, oder überhaupt zu lernen wie man es richtig macht. Formelle Bachelor-Idioten, die für Appel und Ei irgendwelche "blöde bits und bytes" durch die Gegend schieben. Wahrscheinlich hergeholt aus irgend einem bengalischen Dorf, um unsere PCS7 Bibliotheken zu programmieren. Wir schauen großartigen Zeiten entgegen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ein Bisschen variabel könnte man so ...
Code:
IF AlleKonstantenSindVariabel THEN 
    #Sollwert := #SollwertAnders ;
ELSE 
    #Sollwert := #SollwertSo ;
END_IF ;
CASE #Sollwert OF
    111:
        ; // er tut
    21:
        ; // nix er
    113:
        ; // will nur
    ELSE
        ; // spielen
END_CASE;
Nicht ganz ohne IF, aber dennoch mit CASE.

Braucht man bei CASE VergleichsWerte in Variablen? Manche meinen ja, denn z.B. in VBA sind sie möglich.
Manche meinen nein, denn in vielen Sprachen ist es nicht möglich.
Ich sehe die CASE-Selection als verknappte SchreibWeise mit verknappten Möglichkeiten - jedoch mit angenehmen Schreibweisen für "von ... bis" oder Aufzählungen - für SonderFälle von
IF ... THEN
ELSIF ... THEN
...
ELSIF ... THEN
ELSE
END_IF ;
und kann deshalb fehlende Möglichkeiten einer CASE-Selektion ganz gut verknusen.
 
Zuletzt bearbeitet:
Ein IF-THEN-ELSIF-ELSIF-ELSIF-Konstrukt ist nicht nur etwas schwerer zu lesen als ein CASE, es ist auch anfälliger für Programmierfehler/Tippfehler beim Variablenname im VergleichsAusdruck gegenüber der CASE-Anweisung, wo die Variable nur ein einziges mal steht.

Harald
 
Nachdem TIA ja SCL-Netzwerke in KOP/FUP ermöglicht, nutze ich bei sowas auch gerne mal FUP.
Ist meist übersichtlicher als ellenlange If-Then-ElseIf-Else-Konstrukte.
Vor allem beim Beobachten im Status.
Reine SCL-Bausteine sind bei mir eigentlich selten geworden.

Gruß
Blockmove
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Normaleweise lege ich mir die abzufragende "variable" Variable als Steuerbefehl für CASE und die Kriterien nach denen diese ausgewertet wird, als CASE-Bedingungen. Welchen Anwendungsfall gibt es um ein variables CASE zu machen ? Indem du deine Sprungmarken aus einer Rezeptur vergibst oder wie ?

Mein Anwendungsfall wäre wesentlich trivialer. Denn die Sprungmarken würden bei mir eigentlich Konstanten bleiben. Nur sind sie bei verschiedenen Aufrufen den Bausteins welcher den CASE beinhaltet unterschiedlich. Es wäre also schon dienlich wenn man von aussen (über die Schnittstelle) spezifische Konstanten dem Baustein übergeben könnte.

Nicht irgendwie wesentlich länger oder komplizierter als eine gewöhnliche Case Anweisung. Möchtest du mal sehen, wie die Inder bei Siemens neuerdings programmieren ? In der neuesten APL V9.0 ? Das ist der der Horror. Aber so richtig heavy Metall. Guck mal, wie man ohne Case programmiert:

Code:
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#9 THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 82;
                                                    T_CH2[2*X + 1] := 82;
                                                    
                                                ELSE
                                                    T_CH2[X] := 82;
                                                END_IF; 
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#A THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 83;
                                                    T_CH2[2*X + 1] := 83;
                                                    
                                                ELSE
                                                    T_CH2[X] := 83;
                                                END_IF;  
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#B THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 83;
                                                    T_CH2[2*X + 1] := 83;
                                                    
                                                ELSE
                                                    T_CH2[X] := 83;
                                                END_IF; 
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#C THEN
                                                
                                                IF FEATURE_01 = W#16#2 THEN
                                                
                                                    T_CH2[2*X] := 83;
                                                    T_CH2[2*X + 1] := 83;
                                                    
                                                ELSE
                                                    T_CH2[X] := 83;
                                                END_IF;
                                                
                                            ELSIF TEST[RETURN_CODE*3 + 12] = 16#D THEN

Das Ganze dann über Paar Kilometer so, und wieder holt sich auch noch Paar Mal. Dazu noch ist dieses "TEST" ein AT-Zugriff auf eine extern refernzierte Variable. Was es im Compilat macht, kannst du dir glaube ich vorstellen.

Genau sowas will ich eigentlich vermeiden. Wobei bei deinem Beispiel die Sprungmarken sogar Konstanten sind. und die Case Variable ja eigentlich lesbarer über eine Temporäre Variable gelegt werden könnte was vermutlich auch Rechenzeit spart, denn jetzt wird das "TEST[RETURN_CODE*3 + 12]" ja für jeden nicht erfüllten Zweig neu berechnet. Und in TEST kann natürlich so richtig krasser Code drin stehen.

Die das geschrieben haben, das sind offensichtlich Leute, die keine Ahnung davon haben, wie man Case Anweisungen umsetzt, und wie man generell auf Steuerungen programmiert. Und dazu wahrscheinlich auch noch Leute, die keinerlei innere Motivation haben, irgendetwas richtig zu machen, oder überhaupt zu lernen wie man es richtig macht. Formelle Bachelor-Idioten, die für Appel und Ei irgendwelche "blöde bits und bytes" durch die Gegend schieben. Wahrscheinlich hergeholt aus irgend einem bengalischen Dorf, um unsere PCS7 Bibliotheken zu programmieren. Wir schauen großartigen Zeiten entgegen.

Für mich sieht das eher nach einem Kompilat aus einem anderen Programm aus. Irgend ein Excel das einfach Zeile für Zeile seine Tabelle in Code wandelt. Ich kann mir nicht vorstellen wie das irgendjemand wirklich so Codet.
 
Mein Anwendungsfall wäre wesentlich trivialer. Denn die Sprungmarken würden bei mir eigentlich Konstanten bleiben. Nur sind sie bei verschiedenen Aufrufen den Bausteins welcher den CASE beinhaltet unterschiedlich. Es wäre also schon dienlich wenn man von aussen (über die Schnittstelle) spezifische Konstanten dem Baustein übergeben könnte.

Für so einen Anwendungsfall habe ich das Case durch eine Schleife und ein Array of UDT ersetzt.
In der UDT steht die "Konstante" und verschiedene "ActionsCodes".
Das Ganze war ein Grundgerüst für flexible, per HMI einstallbare Abläufe.
Lässt sich schachteln und auch z.B. gut in Graph verwenden.

Gruß
Blockmove
 
.....
- Konstanten;
- Hexadezimale Sprungmarken, wie z.B. INT#16#24FF
- Umwandlung der Steuervariable aus anderem Datentyp wie z.B.

Code:
CASE DWORD_TO_INT(SHL(IN := DINT_TO_DWORD(#Steuervariable), N := 16 )) OF 

INT#16#20 :
;
INT#16#80 :
;
.....

Als kleine Ergänzung zu deinem Beitrag, ab TIA V16 kann man CASE auch direkt mit WORD Variablen beschalten

Case.jpg

Quelle:
https://www.google.com/url?sa=t&rct...lides_de.pdf&usg=AOvVaw3bXMPeoZKH3zUtJ_ugiL5z
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Für so einen Anwendungsfall habe ich das Case durch eine Schleife und ein Array of UDT ersetzt.
In der UDT steht die "Konstante" und verschiedene "ActionsCodes".

Genau so habe ich es jetzt auch gemacht, funktioniert zwar wunderbar. Ist dann zwar immernoch ein IF THEN, aber ich glaube so ist es gut verständlich was sie macht.
 
Mein Anwendungsfall wäre wesentlich trivialer. Denn die Sprungmarken würden bei mir eigentlich Konstanten bleiben. Nur sind sie bei verschiedenen Aufrufen den Bausteins welcher den CASE beinhaltet unterschiedlich.
Mehrere Konstanten je Case anzugeben reicht in diesem Fall nicht aus?
Bzw. dann den #Sollwert in entsprechende Bereiche zu verschieben?
Code:
CASE #Sollwert OF
    111, 1021:
        ;// tudiesunddas
    21, 1111:
        ;   // nun jenes
    113, 1013:
        ;
    ELSE
        ;   // aber sonst dieseswelches
END_CASE;
 
Genau sowas will ich eigentlich vermeiden. Wobei bei deinem Beispiel die Sprungmarken sogar Konstanten sind. und die Case Variable ja eigentlich lesbarer über eine Temporäre Variable gelegt werden könnte was vermutlich auch Rechenzeit spart, denn jetzt wird das "TEST[RETURN_CODE*3 + 12]" ja für jeden nicht erfüllten Zweig neu berechnet. Und in TEST kann natürlich so richtig krasser Code drin stehen.


Für mich sieht das eher nach einem Kompilat aus einem anderen Programm aus. Irgend ein Excel das einfach Zeile für Zeile seine Tabelle in Code wandelt. Ich kann mir nicht vorstellen wie das irgendjemand wirklich so Codet.

Es ist ja nicht nur das. Diese kilometerlange IF...ELSIF... Abfrage läuft auch noch in einer FOR-Schleife. Und von diesen FOR-Schleifen gibt es zwei, die jeweils nur leicht unterschiedlich aussehen (andere Zugriffsbereiche). Noch irriger kann man diesen Irrsinn glaube ich nicht mehr machen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Genau so habe ich es jetzt auch gemacht, funktioniert zwar wunderbar. Ist dann zwar immernoch ein IF THEN, aber ich glaube so ist es gut verständlich was sie macht.

Ich pack sowas auch gerne mal in Graph. Ist eigentlich eine recht übersichtliche Lösung und lässt sich auch nocht gut beobachten.
 
Ich pack sowas auch gerne mal in Graph. Ist eigentlich eine recht übersichtliche Lösung und lässt sich auch nocht gut beobachten.

Na, na. Bloß jetzt die armen Schäflein nicht durcheinander bringen. Was ist das ? Ein Kommunikationsbaustein ? Dann gehört er nicht ins Graph. Ist es ein Maschinenablauf ? Dann gehört er nicht in SCL.
 
Mehrere Konstanten je Case anzugeben reicht in diesem Fall nicht aus?
Bzw. dann den #Sollwert in entsprechende Bereiche zu verschieben?
Code:
CASE #Sollwert OF
    111, 1021:
        ;// tudiesunddas
    21, 1111:
        ;   // nun jenes
    113, 1013:
        ;
    ELSE
        ;   // aber sonst dieseswelches
END_CASE;

Das ist dann halt wieder Fixiert. Ausserdem will ich vermeiden das an einem Baustein ein Falscher Case akzeptiert wird, der beim anderen Aufruf legal wäre.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Na, na. Bloß jetzt die armen Schäflein nicht durcheinander bringen. Was ist das ? Ein Kommunikationsbaustein ? Dann gehört er nicht ins Graph. Ist es ein Maschinenablauf ? Dann gehört er nicht in SCL.

Ich seh das deutlich pragmatischer. Ich such mir die Programmiersprache aus, die meiner Meinung nach einfach zur Aufgabe passt.
Für komplexe Kommunikationsbausteine braucht man sehr oft Zustandsautomaten. Und so was kann ich nun mal in einer Graphkette übersichtlicher umsetzen als in SCL.

Gruß
Blockmove
 
Ich seh das deutlich pragmatischer. Ich such mir die Programmiersprache aus, die meiner Meinung nach einfach zur Aufgabe passt.
Für komplexe Kommunikationsbausteine braucht man sehr oft Zustandsautomaten. Und so was kann ich nun mal in einer Graphkette übersichtlicher umsetzen als in SCL.

Gruß
Blockmove

Es geht nicht um Pragmatismus, oder Dogmatismus, sondern um Rationalität.

GRAPH-Ketten verbrauchen eine Menge Ressourcen, haben auf der anderen Seite aber nicht die Programmierflexibilität von SCL. Graphketten sind dort gefragt, wo die Abläufe maximal transparent und analytisch sein müssen. Deswegen auch ProAgent. Hingegen sind Kommunikationsbausteine zwar auch Zustandsmaschinen, aber keine, die sich alle 2-3 Tage mal ändern. In der Regel wird ein fertig ausprogrammierter Kommunikationsbaustein nimmer mehr angepackt. Einen Zustandsautomaten für eine Gerätekommunikation kann ich auch in einer CASE-Kette abbilden. Hat dann zwar keine Verriegelung und Überwachungskriterien, aber die brauche ich dort auch nicht, wenn ich bloß mit einem Gerät kommuniziere ?
 
Rational ist meine Arbeitszeit die teuerste Ressource.

Ich weiß nicht woher die Meinung kommt, dass Graph so verschwenderisch sei.
Wenn du Graph mit den Minimalparametern übersetzt, dann erzeugt es nur eine recht normale Kette mit Sprungverteilern.

Gruß
Blockmove
 
Zurück
Oben