SCL - nur eine Zeile beschreiben

testuser

Level-2
Beiträge
139
Reaktionspunkte
11
Zuviel Werbung?
-> Hier kostenlos registrieren
habe mal eine frage zu einem problem mit dem ich mich rumschlage: und zwar möchte ich daten die von 8 verschieden panels eingegeben werden können in ein array schreiben. die eingegebenen daten haben immer die gleiche struktur. dafür habe ich mir ein UDT angelegt. davon habe ich wiederrum ein array[1..50] im DB_Wartespeicher angelegt. die daten sollen nach einer überprüfung in weitere speicher geschrieben werden. falls dies möglich ist, wird die ID auf null gesetzt (bedeutet: Zeile = leer bzw. kann neu beschrieben werden).

Code:
 IF "DB_Wartespeicher".Abschicken THEN
    "DB_Wartespeicher".index_1 := "DB_Wartespeicher".index_1 + 1;
    
    FOR "DB_Wartespeicher".index_2 := 1 TO 50 BY 1 DO
       IF ("DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_2].ID <> 0) THEN       
        IF (DB106.DBX212.1 OR DB108.DBX212.1) THEN
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ID := "DB_Wartespeicher".index_1;
    
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_EG := TRUE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_OG1 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_OG2 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_OG3 := FALSE;
       //hier kommt noch ein bisschen was, ich denke zur veranschaulichung reicht dies hier
       END_IF
     END_IF;
   END_IF;
END_FOR;
jetzt möchte ich aber einen eingegebenen datensatz auch nur einmal (in eine "zeile") in das feld schreiben. leider fehlt mir hierzu die idee. ich hoffe mir kann jemand weiterhelfen.
 
Hallo,
ich weiß nicht, ob ich deine Anfrage so ganz richtig verstanden habe ...

Mein Ansatz:
Du hast für jedes deiner Panel eine eigene Input-Variable. Schreibst du nun in die Input-Variable vom TP_1 einen Wert hinein, so muß dieser in deinen Wartespeicher. hierfür kontrollierst du, ob deine Input-Variable beschrieben wurde und wenn ja, dann suchst du dir einen freien Platz in deinem Speicher. Auf diese Weise können auch bei mehreren TP's gleichzeitig Eingaben gemacht werden. Du scannst dann jede Eingabe für sich. Du kannst hier ggf. auch ein ARRAY_of_Eingabewerte machen ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
mal noch kurz was zu erläuterung, ich arbeite hier jetzt an einem projekt was ein kollege angefangen hat und leider krank geworden ist bzw. er generell unterstützung benötigt.

er hat es sich so vorgestellt: jedes TP schreibt in einen DB (E1: DB_Daten_EG bis zu E4: DB_Daten_OG2). aus diesen DBs lese ich immer wenn "Abschicken" gedrückt wurde die Daten in das Feld ein. "Abschicken" soll auch die ID um eins erhöhen, unabhängig welches TP "Abschicken" bringt.

hier mal noch ein stück code. hier werden
Code:
  IF "DB_Wartespeicher".Abschicken THEN
    "DB_Wartespeicher".index_1 := "DB_Wartespeicher".index_1 + 1;
    
    FOR "DB_Wartespeicher".index_2 := 1 TO 50 BY 1 DO
      //ggf bit "geschrieben" einbauen, damit auftrag nur einmal in wartespeicher geschrieben wird
      IF ("DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_2].ID <> 0) THEN       
        //abfrage von abschicken und standort der eingabe
        //Ebene 1 - Panel 1 (Aussen) DB106.DBX212.1 -> Auftrag abschicken
        //Ebene 1 - Panel 2 (Innen)  DB108.DBX212.1 -> Auftrag abschicken
        IF (DB106.DBX212.1 OR DB108.DBX212.1) THEN
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ID := "DB_Wartespeicher".index_1;
    
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_EG := TRUE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_OG1 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_OG2 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SE_OG3 := FALSE;        

          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E1_21 := "DB_Daten_EG".Eingabe.Daten_0.Start_Band_Gebucht_21A;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E1_25 := "DB_Daten_EG".Eingabe.Daten_0.Start_Band_Gebucht_25A;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E1_30 := "DB_Daten_EG".Eingabe.Daten_0.Start_Band_Gebucht_30A;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E1_31 := "DB_Daten_EG".Eingabe.Daten_0.Start_Band_Gebucht_31A;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E1_32 := "DB_Daten_EG".Eingabe.Daten_0.Start_Band_Gebucht_32A;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E2_131 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E2_192 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E2_193 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E3_230 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E4_331 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E4_392 := FALSE;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].SB_E4_393 := FALSE;
    
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].STAPEL_SCHMAL := "DB_Daten_EG".Ausgabe.Daten_1010.Stapel_Schmal;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].STAPEL_BREIT := "DB_Daten_EG".Ausgabe.Daten_1010.Stapel_Breit;
        
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZE_EG := "DB_Daten_EG".Ausgabe.Daten_1010.Ziel_EG;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZE_OG1 := "DB_Daten_EG".Ausgabe.Daten_1010.Ziel_OG1;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZE_OG2 := "DB_Daten_EG".Ausgabe.Daten_1010.Ziel_OG2;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZE_OG3 := "DB_Daten_EG".Ausgabe.Daten_1010.Ziel_OG3;

          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZIEL_ALTBAU := "DB_Daten_EG".Ausgabe.Daten_1010.Neubau_Ziel;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZIEL_NEUBAU := "DB_Daten_EG".Ausgabe.Daten_1010.Altbau_Ziel;

          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].VS_NORMAL := DB106.DBX200.1;//"DB_Panel EG-1".Panel_S_A.Anzeige.BA_Auto_Normal;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].VS_VORRANG := DB106.DBX200.2;//"DB_Panel EG-1".Panel_S_A.Anzeige.BA_Auto_Vorrang;
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].VS_EXPRESS := DB106.DBX200.3;//"DB_Panel EG-1".Panel_S_A.Anzeige.BA_Auto_Express;
          
          "DB_Wartespeicher".WARTE_SPEICHER["DB_Abarbeitungsspeicher".index_1].ZIEL_FREI := FALSE;
          
          //generieren der Fahrstuhlanforderung FS_ANF
          IF "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].ZE_EG = TRUE THEN
            "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].FS_ANF := FALSE;
          ELSE
            "DB_Wartespeicher".WARTE_SPEICHER["DB_Wartespeicher".index_1].FS_ANF := TRUE;                        
          END_IF;
        END_IF;
       END_IF;
   .....
   END_FOR;
END_IF;
dies habe ich noch dreimal (für jede etage) in meiner scl-quelle.

@LL: verstehe deinen ansatz noch nicht richtig. ggf kannst du ihn nochmal etwas präzisieren.
 
Zuletzt bearbeitet:
OK ... dann reiche ich noch etwas nach ...

Vorher aber noch so am Rande :
In deinem´ersten SCL-Codeschnipsel habe ich einige absolute Adressen entdeckt ... So etwas würde ich beim SCL-programmieren ganz generell vermeiden ...

Mein Ansatz:
Wenn an deinem TP (welches ist egal) eine Eingabe gemacht wurde, die dann in deinen Speicher soll, dann ist das schon mal nicht schlecht, wenn du ein Signal-Bit dafür hast.
Dein FB-Wartespeicher sollte die Eingabe als INPUT-Variablen zur Verfügung gestellt bekommen (saubere Kapselung). Nun kontrollierst du bei der Input-Variablen einfach, ob das Signal-Bit = TRUE ist und wenn ja schreibst du deren Wert in deinen Speicher (und löscht ggf. die Variable und das Signal-Bit - dies ginge dann allerdings nur mit Variablen, die bei IN_OUT deklariert sind).
So in etwa hattest du das sicherlich auch schon vor ...

Zur Ablauf-Optimierung könntest du die Eingangs-Variablen auch als UDT übergeben (in dem das Ganze als ARRAY deklariert ist). Dadurch könntest du das Abarbeiten der Eingaben auch per Schleife machen ...

Gruß
LL
 
weiterer Nachsatz:
Der Wartespeicher könnte auch in Bestandteil der FB-Instanz sein. Das macht den Zugang zu den Einzelwerten erheblich einfacher ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
okay die absoluten adressen werden dort noch verschwinden.

ich nehme jetzt mal dein posting etwas auseinander und schreibe meine gedankengänge dazu.

Wenn an deinem TP (welches ist egal) eine Eingabe gemacht wurde, die dann in deinen Speicher soll, dann ist das schon mal nicht schlecht, wenn du ein Signal-Bit dafür hast.
ja habe ich. das signal zum schreiben ist immer das "Abschicken"-bit.

Dein FB-Wartespeicher sollte die Eingabe als INPUT-Variablen zur Verfügung gestellt bekommen (saubere Kapselung). Nun kontrollierst du bei der Input-Variablen einfach, ob das Signal-Bit = TRUE ist und wenn ja schreibst du deren Wert in deinen Speicher (und löscht ggf. die Variable und das Signal-Bit - dies ginge dann allerdings nur mit Variablen, die bei IN_OUT deklariert sind).
also zur zeit arbeite ich ja mit einem FC. warum jetzt die verwendung eines FBs?

So in etwa hattest du das sicherlich auch schon vor ...
die idee mit dem bit, welches nach dem schreiben gesetzt wird, hatte ich schon nur weiß ich nicht wo ich es hinschreiben soll? ins UDT? und wie und wann ich es zurücksetzten soll? oder soll es durch das "abschicken"-bit gesetzt werden und ich setze es nach dem schreiben zurück. gleichzeitig wird es nich in einer if-anweisung abgefragt. müsste ja eigtl gehen?!?

Zur Ablauf-Optimierung könntest du die Eingangs-Variablen auch als UDT übergeben (in dem das Ganze als ARRAY deklariert ist). Dadurch könntest du das Abarbeiten der Eingaben auch per Schleife machen ...
hatte mir nach deinem vorhergehenden post schon mal gedanken gemacht:
Code:
FUNCTION FC54 : INT

VAR_INPUT
  IP43_abschicken : BOOL;    
  IP43_normal : BOOL;
  IP43_express : BOOL;
  IP43_vorrang : BOOL;
  IP43_ze_eg : BOOL;
  IP43_ze_og1 : BOOL;
  IP43_ze_og2 : BOOL;        
  IP43_ze_og3 : BOOL;
  IP43_stapel_schmal : BOOL; 
  IP43_stapel_breit : BOOL;  
  IP43_ziel_altbau : BOOL; 
  IP43_ziel_neubau : BOOL;  
  //müsste hier für die restlichen tp ergänzt werden
END_VAR
VAR_TEMP
  // temporäre Variablen
END_VAR

  // Anweisungsteil
  // entspricht dem code von oben
  ;
  FC54 := 100;
END_FUNCTION
weiterer Nachsatz:
Der Wartespeicher könnte auch in Bestandteil der FB-Instanz sein. Das macht den Zugang zu den Einzelwerten erheblich einfacher ...
versteh ich nicht. bin aber für jeden tipp dankbar. es soll so einfach wie möglich, da meine kollegen keine scl-"freunde" sind.
 
... das mit dem FC hatte ich überlesen ...

Ich hätte das Ganze als FB aufgezogen und den Wartespeicher als ARRAY in dem FB deklariert. Auf diese Weise könntest du auf dessen Inhalte sehr viel leichter zugreifen (nicht erst umständlich durchadressieren).

Wenn deine Kollegen keine SCL-Freunde sind, dann ist dann keine gute Einstiegsbedingung - für diese Aufgabe aber m.E. einfach der bessere Weg. Ich bin übrigens ein großer SCL-Fan ... ;)

Zu der Übergabe UDT. Das könnte so aussehen :
Code:
UDT100 : array [1..10] of struct 
  abschicken : BOOL;    
  normal : BOOL;
  express : BOOL;
  vorrang : BOOL;
  ze_eg : BOOL;
  ze_og1 : BOOL;
  ze_og2 : BOOL;        
  ze_og3 : BOOL;
  stapel_schmal : BOOL; 
  stapel_breit : BOOL;  
  ziel_altbau : BOOL; 
  ziel_neubau : BOOL;  
end_struct ;
Diesen UDT kannst du als IN_OUT-Parameter nehmen - das setzt aber voraus, dass du ihn irgendwo anders (z.B. in einem DB) deklariert hast und ihn vor Aufruf des FB () zuweisst. Auf diese Weise hast du dann nur einen Parameter, den du im SCL-Script dann sogar noch sinnvoll indexieren kannst ...

Hilft dir das weiter ?
 
Wenn deine Kollegen keine SCL-Freunde sind, dann ist dann keine gute Einstiegsbedingung - für diese Aufgabe aber m.E. einfach der bessere Weg. Ich bin übrigens ein großer SCL-Fan ... ;)
der kollege wollte es mit awl machen oder alle möglichen daten in den, ich habe mich dann für scl ausgesprochen und schwupps hatte ich es am bein. ich persönlich finde es nicht schlecht, man sollte es schon verwenden wenn es angebracht ist.

Zu der Übergabe UDT. Das könnte so aussehen :
Code:
UDT100 : array [1..10] of struct 
  abschicken : BOOL;    
  normal : BOOL;
  express : BOOL;
  vorrang : BOOL;
  ze_eg : BOOL;
  ze_og1 : BOOL;
  ze_og2 : BOOL;        
  ze_og3 : BOOL;
  stapel_schmal : BOOL; 
  stapel_breit : BOOL;  
  ziel_altbau : BOOL; 
  ziel_neubau : BOOL;  
end_struct ;
Diesen UDT kannst du als IN_OUT-Parameter nehmen - das setzt aber voraus, dass du ihn irgendwo anders (z.B. in einem DB) deklariert hast und ihn vor Aufruf des FB () zuweisst. Auf diese Weise hast du dann nur einen Parameter, den du im SCL-Script dann sogar noch sinnvoll indexieren kannst ...

Hilft dir das weiter ?
nicht wirklich. es muss dann noch ein eindeutige ID rein und die fahrstuhlanforderung in den "datnesatz".
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... nicht wirklich. es muss dann noch ein eindeutige ID rein und die fahrstuhlanforderung in den "datnesatz".

Den Datensatz habe ich aus deinem Beispiel übernommen.
Die "ID" ergibt sich über den ARRAY-Index. Probier das einfach mal aus ... ;)
 
Zurück
Oben