Kopierfehler SFC20 (BLKMOV) ??

Zuviel Werbung?
-> Hier kostenlos registrieren
Ich mache das eigentlich nicht gerne, aber in diesem Fall :
Warum machst du das mit dem ANY-Pointer in einem anderen Baustein ? Das könnte doch dein SCL-FB genauso schön erledigen und du hättest eine potentielle Fehlerquelle weniger ... Vielleicht resultiert dein Problem auch genau aus dieser Situation ...

...

Weil ich anhand der "Datensatznummer" mir einen Pointer zusammen "stricken" muss. Das erschien mir in AWL einfacher.
 
Weil ich anhand der "Datensatznummer" mit einen Pointer zusammen "stricken" muss. Das erschien mir in AWL einfacher.

Musst du denn Überhaupt mit Pointern arbeiten ?
Wenn ich es richtig in Erinnerung habe, dann sind doch die OUTPUT-Daten aus deinen INPUT-Daten abgeleitet ?
Falls ich da aber jetzt etwas "verknotet" habe ... Es ist m.E. in SCL wesentlich einfacher sich einen ANY-Pointer zu basteln als in AWL ...

...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Musst du denn Überhaupt mit Pointern arbeiten ?

Wie soll ich denn sonst eine String-Variable angeben, welche mir erst zu Laufzeit bekannt wird?

Wenn ich es richtig in Erinnerung habe, dann sind doch die OUTPUT-Daten aus deinen INPUT-Daten abgeleitet ?

Ja, aber nicht "String_01" = String_OUT_01"
Das ist völlig variabel.

Falls ich da aber jetzt etwas "verknotet" habe ... Es ist m.E. in SCL wesentlich einfacher sich einen ANY-Pointer zu basteln als in AWL ...

...

In SCL habe ich dies nicht so richtig hinbekommen, deshalb mein Weg über den AWL-FB. Aber wenn Du evtl. ein kleines Bespiel für so etwas in SCL hättest, wäre das echt super.

Gruß Wastel
 
Zu dem Thema ANY-Pointer in SCL kann ich dir natürlich ein Beispiel geben, ist aber (glaube ich) gar nicht mehr nötig. Das kannst du dir nämlich komplett sparen, wenn du die Bedingungen, nach denen du den Pointer bauen läßt im Script abhandelst. Das müßte doch dann ungefähr so laufen :
Code:
if (Index = 2) then
   if Uebernahme then
      String_Temp := String_Input[02] ;
   end_if ;
   if bearbeitet then
      for i := 1 to 35
         if String_Output[i] <> "" then
            String_Output[02] := String_Temp ;
            String_Temp := "" ;
            exit_for ;
         end_if ;
      end_for ;
   end_if ;
end if ;
... oder liege ich da jetzt völlig falsch ...?

...
 
@Larry

Hat der Input und Output als Array definiert?, dann ok.

Aber:

Code:
String_Output[[COLOR="Red"]i[/COLOR]] := String_Temp ;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Larry

Hat der Input und Output als Array definiert?, dann ok.

Aber:
Code:
String_Output[[COLOR=red]i[/COLOR]] := String_Temp ;

Hat er sicher nicht ... aber es geht mir jetzt darum, Alternativen aufzuzeigen. Sehr wahrscheinlich ist dann auch der "Fehler" vom Tisch.
Mit dem Index hattest du natürlich recht, Ralle.
 
Ich denke, eine wichtige Sache habe ich nicht ausführlich genug erklärt:

Der Anlagenfahrer wählt nicht direkt einen String-Wert aus, sondern gibt einen String-Wert in ein Eingabefeld und startet eine Such-Funktion.

Diese Such-Funktion (FOR-Schleife) überprüft alle 34 Eingangsstrings auf Gleichheit. Wird eine gleicher String gefunden, habe ich jetzt über die Laufvariable der Schleife, eine Datensatznummer ermittelt, die ich zum Basteln des Pointers verwende.

Warum ich jetzt Datensätze verwende:
Zu jeder String-Variable gehört eine REAL-Variable (LOT-Nr & Ist-Gewicht).

Diese REAL-Variable wird genauso mitkopiert wie die String-Variable, allerdings in einem anderen SFC-Kopiervorgang. Wichtig ist zudem die Reihenfolge der verwendeten String-Variablen, deshalb kann ich nicht STRING_01 = STRING_OUT_01 machen.

Gruß Wastel
 
Der Anlagenfahrer wählt nicht direkt einen String-Wert aus, sondern gibt einen String-Wert in ein Eingabefeld und startet eine Such-Funktion.

Diese Such-Funktion (FOR-Schleife) überprüft alle 34 Eingangsstrings auf Gleichheit. Wird eine gleicher String gefunden, habe ich jetzt über die Laufvariable der Schleife, eine Datensatznummer ermittelt, die ich zum Basteln des Pointers verwende.

Das habe ich (so in etwa) dann schon richtig verstanden. Wie der Index in meinem Beispiel zu Stande kommt ist völlig unerheblich. Aber ... auf die gleiche Weise, wie du die Position der Auswahl ermittelst kannst du auch die Zuweisung der OUTPUT-Strings machen (jeden Falls in etwa). In meinem Beispiel kannst du dann auch sehen, dass ich nicht willkürlich "1 in 1" schreibe, sondern den über Index erkannten String in die erste freie Stelle. Entsprach das nicht deiner Vorgabe ?

Wenn du so arbeitest (was ich für grundsätzlich machbar halte - auch ohne deinen FB zu kennen), dann entfällt der ANY-Pointer und der SFC20 komplett. Außerdem wird in jedem Fall das Konstrukt durchsichtiger ...

...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das habe ich (so in etwa) dann schon richtig verstanden. Wie der Index in meinem Beispiel zu Stande kommt ist völlig unerheblich. Aber ... auf die gleiche Weise, wie du die Position der Auswahl ermittelst kannst du auch die Zuweisung der OUTPUT-Strings machen (jeden Falls in etwa). In meinem Beispiel kannst du dann auch sehen, dass ich nicht willkürlich "1 in 1" schreibe, sondern den über Index erkannten String in die erste freie Stelle. Entsprach das nicht deiner Vorgabe ?

Wenn du so arbeitest (was ich für grundsätzlich machbar halte - auch ohne deinen FB zu kennen), dann entfällt der ANY-Pointer und der SFC20 komplett. Außerdem wird in jedem Fall das Konstrukt durchsichtiger ...

...

Das gebe ich dir vollkommen Recht! Das sehe ich genauso!

Ich habe das eben mal mit dem Index probiert:

Code:
VAR_INPUT
  // Eingangsparameter
i                :INT;                   //
IN1            :STRING[32];        //
IN2            :STRING[32];        //
IN3            :STRING[32];        //
IN4            :STRING[32];        //
   
END_VAR
 
VAR
//  Interne Hilfs Variablen

END_VAR
 
VAR_OUTPUT
    //Ausgangsparameter
OUT            :STRING[32];          //WRITE wurde ausgeführt
 
END_VAR
 
BEGIN
 
OUT := IN[COLOR=red][i][/COLOR];
 
END_FUNCTION_BLOCK

Sollte ja so funktionieren, oder?
Jedenfalls mekert der SCL-Compiler:"Der Bezeicherner existiert nicht"
(rote Markierung im Code) Da dies so nicht fuktioniert habe ich damals die AWL-Variante vorgezogen.
 
Das kann auch so nicht funktionieren. Den Grund dafür hatte Ralle vorhin schon genannt. Du müßtest ein ARRAY of String haben - dann geht das. Eine Alternative dafür wäre :
Code:
VAR_INPUT
  // Eingangsparameter
i                :INT;                   //
IN1            :STRING[32];        //
IN2            :STRING[32];        //
IN3            :STRING[32];        //
IN4            :STRING[32];        //
   
END_VAR

Var
In_Daten : ARRAY [1..4] of String[32] ;
End_Var ;
 
Begin
In_Daten[1] := In1 ;
In_Daten[2] := In2 ;
In_Daten[3] := In3 ;
In_Daten[4] := In4 ;
ist aber in diesem Fall m.E. nicht so schön.

Müssen deine Vorgabe-Strings unbedingt INPUT's sein, oder sind es quasi Konstanten ? In dem Fall ginge auch :
Code:
Var
Vergleichs_Daten : ARRAY [1..4] of String[32] :=  'Eintrag 1' , 'Text 2' , 'Daten 3' , 'dies und das' ;
End_Var ;
 
Müssen deine Vorgabe-Strings unbedingt INPUT's sein, oder sind es quasi Konstanten ? In dem Fall ginge auch :
Code:
Var
Vergleichs_Daten : ARRAY [1..4] of String[32] :=  'Eintrag 1' , 'Text 2' , 'Daten 3' , 'dies und das' ;
End_Var ;

Man könnte die 32 Strings auch in einem Global-DB ablegen (Array) und das gesamte Array dann als Input an den FB legen. In desem Falle paltzsparender wäre dann allerdings ein FC und das Array als IN_OUT angelegt, bei der FB-Variante hat man die 32 Strings leider in 2 DB, dem globalen und dem IDB.

FB:

Code:
FUNCTION_BLOCK FB10

VAR_INPUT
  strArray: ARRAY[1..32] OF STRING[32];
END_VAR

VAR_TEMP
    // temporäre Variablen

END_VAR
VAR
    // statische Variablen

END_VAR

    strArray[2] := '';
    
END_FUNCTION_BLOCK
FC:

Code:
FUNCTION FC10 : INT

VAR_IN_OUT
  strArray: ARRAY[1..32] OF STRING[32];
END_VAR

VAR_TEMP
    // temporäre Variablen

END_VAR

    strArray[2] := '';
    ;
    FC10 := 100;
END_FUNCTION
Aufruf:

Code:
CALL  "strArray_FB" , DB100
       strArray:="strArray".StrArray

 CALL  FC    10
       RET_VAL :=MW2
       strArray:="strArray".StrArray
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@ Larry & Ralle,

habt erstmal vielen Dank für eure Hilfe.
Heute Vormittag habe ich erstmal als "Schnellhilfe", den SFC20 gegen den SFC81 ausgetauscht. Leider sind mal wieder andere Sachen dazwischen gekommen, die wichtiger sind.

Zu den Eingangsstrings:

Diese müssen unbedingt INPUT`S sein, da diese Werte aus der Rezeptsteuerung (Simatic Batch) kommen.

Die Lösung mit dem ARRAY werde ich auf jeden Fall verfolgen.
Auch ich bin davon überzeugt, dass eine Lösung ohne SFC20(81) schon besser wäre.

Gruß Wastel
 
Wastel;143263Zu den Eingangsstrings: Diese müssen unbedingt INPUT`s sein schrieb:
Hallo Wastel,
in dem Fall drängt sich aus meiner Sicht der Vorschlag von Ralle (alternativ Global-DB oder UDT als In-Parameter) geradezu auf. Wenn du also über eine Veränderungs des Gesamt-Konstrukt nachdenkst, dann solltest du das auf alle Fälle erwägen ...

Viel Erfolg und Gruß
LL
 
Zurück
Oben