Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT

Eine VAR_IN_OUT-Variable ist eine Ein- und Ausgabevariable, die Teil einer Bausteinschnittstelle ist und als formaler Durchgangsparameter dient.

Die VAR_IN_OUT-Variablen eines Bausteins müssen bei dem Aufruf des Bausteins zugewiesen werden.

Syntax:

<keyword> <POU name>
VAR_IN_OUT
    <variable name> : <data type>;
END_VAR
<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG

Sie können eine Ein- und Ausgabevariable in den Programmierbausteinen PRG, FUNCTION_BLOCK, METHOD oder FUNCTION im Deklarationsabschnitt VAR_IN_OUT deklarieren. Die VAR_IN_OUT-Variable kann gelesen und beschrieben werden.

Verwendung:

Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT 1:

Übergabe von Zeichenketten an VAR_IN_OUT CONSTANT

Wenn eine Zeichenkette als Variable oder auch als Konstante an eine formale VAR_IN_OUT CONSTANT-Variable übergeben wird, kann die String-Länge variabel sein. Weitere Informationen hierzu finden Sie unter „Übergabevariable VAR_IN_OUT CONSTANT“.

Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT 2:

Übergabe von Eigenschaften nicht möglich

An eine VAR_IN_OUT- oder eine VAR_IN_OUT CONSTANT-Variable kann keine Eigenschaft (Property) übergeben werden.

Ausnahme: Eine Zuweisung auf VAR_IN_OUT (CONSTANT) ist möglich, falls die Eigenschaft den Rückgabetyp REFERENCE besitzt. Sie müssen hierbei allerdings beachten, dass die Eigenschaft per REFERENCE nur eine Adresse zurückliefern darf, die über den Eigenschaftenaufruf hinaus gültig ist. Dies wäre z. B. nicht der Fall, wenn die Eigenschaft die Referenz auf eine temporäre Variable zurückliefern würde.

Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT 3:

Ähnlichkeit von VAR_IN_OUT zu REFERENCE TO

VAR_IN_OUT-Variablen besitzen eine große Ähnlichkeit zu Referenzen, wenn sie in Schnittstellen von Funktionen, Methoden und Funktionsbausteinen verwendet werden. Es wird empfohlen möglichst VAR_IN_OUT-Variablen zu bevorzugen.

Vorteile von VAR_IN_OUT gegenüber REFERENCE TO :
- VAR_IN_OUT-Variablen müssen bei Funktions-, Methoden- und Funktionsbausteinaufrufen zugewiesen werden. So sind diese immer gültig. Eine Referenz kann ungültig (0) sein.
- Einer VAR_IN_OUT-Variablen können auch Stack-Variablen zugewiesen werden.
- VAR_IN_OUT CONSTANT bietet zudem die Möglichkeit der Zuweisung mit nur lesendem Zugriff.

Beispiel:

Funktionsbaustein FB_Sample

FUNCTION_BLOCK FB_Sample
VAR_IN_OUT
    bInOut    : BOOL;
END_VAR

Programm MAIN:

VAR
    bTest     : BOOL;
    fbSample  : FB_Sample;
END_VAR
fbSample(bInOut := bTest);  // OK
fbSample();                 // NOK: not possible as the VAR_IN_OUT variable is not assigned in this FB call
fbSample.bInOut := bTest;   // NOK: direct access to VAR_IN_OUT variable from the outside not possible

Beispiel für einen Workaround für das Zuweisen einer Bitvariablen auf einen VAR_IN_OUT-Eingang:

Deklaration der Bitvariablen (bBit0):

VAR_GLOBAL
    bBit0 AT %MX0.1 : BOOL;
    bTemp           : BOOL;
END_VAR

Funktionsbaustein mit VAR_IN_OUT Eingang bInOut:

FUNCTION_BLOCK FB_Test
VAR_INPUT
    bIn    : BOOL;
END_VAR
VAR_IN_OUT      
    bInOut : BOOL;
END_VAR
IF bIn THEN
    bInOut := TRUE;
END_IF

Programm, das den Funktionsbaustein aufruft. Direktes Zuweisen der Bitvariablen auf den VAR_IN_OUT-Eingang (Fehler) und Zuweisen mithilfe einer Zwischenvariablen (Workaround):

PROGRAM MAIN
VAR
    bIn      : BOOL;
    fbTest1  : FB_Test;
    fbTest2  : FB_Test;
END_VAR
// Error C0201: Type 'BIT' doesn't correspond to the type 'BOOL' of VAR_IN_OUT 'bInOut'
fbTest1(bIn := bIn, bInOut := bBit0);

// Workaround
//bTemp := bBit0;
//fbTest2(bIn := bIn, bInOut := bTemp);
//bBit0 := bTemp;

 

Übergabevariable VAR_IN_OUT CONSTANT

Eine VAR_IN_OUT CONSTANT-Variable dient als konstanter Durchgangsparameter, der gelesen, aber nicht beschrieben werden kann.

Syntax:

<keyword> <POU name>
VAR_IN_OUT CONSTANT
    <variable name> : <data type>; // formal parameter
END_VAR
<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG

VAR_IN_OUT CONSTANT-Variablen werden deklariert, ohne einen Initialisierungswert zuzuweisen.

Verwendung:

Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT 4:

Wenn die Compileroption Konstanten ersetzen in der Kategorie Übersetzen in den SPS-Projekteigenschaften aktiviert ist, dann erzeugt die Parameterübergabe einer Konstanten mit Basisdatentyp ungleich STRING oder einer konstanten Variablen mit Basisdatentyp ungleich STRING einen Compilerfehler.

Beispiel:

Im Code werden Strings über verschiedene VAR_IN_OUT-Variablen an die Funktion F_Manipulate übergeben. Bei Übergabe eines Literals an eine VAR_IN_OUT-Variable wird ein Compilerfehler ausgegeben. Bei Übergabe eines Literals an eine VAR_IN_OUT CONSTANT-Variable wird korrekter Code erzeugt, ebenso bei der Übergabe von Stringvariablen.

Des Weiteren ist zu erkennen, dass die Übergabe einer zu kurzen Stringvariablen an eine VAR_IN_OUT-Variable nicht möglich ist (Compiler-Fehler), bei der Übergabe an eine VAR_IN_OUT CONSTANT-Variable ist dies hingegen möglich.

Funktion F_Manipulate:

FUNCTION F_Manipulate : BOOL
VAR_IN_OUT
    sReadWrite   : STRING(16);  (* Can be read or written here in POU *)
    nReadWrite   : DWORD;       (* Can be read or written here in POU *)
END_VAR
VAR_IN_OUT CONSTANT
    cReadOnly    : STRING(16);  (* Constant string variable can only be read here in POU *)
END_VAR
sReadWrite := 'String_from_POU';
nReadWrite := STRING_TO_DWORD(cReadOnly);

Programm MAIN:

PROGRAM MAIN
VAR
    sVar10 : STRING(10) := '1234567890';
    sVar16 : STRING(16) := '1234567890123456';
    sVar20 : STRING(20) := '12345678901234567890';
    nVar   : DWORD;
END_VAR
// The following line of code causes the compiler error:
// VAR_IN_OUT parameter 'sReadWrite' of 'F_Manipulate' needs variable with write access as input.
F_Manipulate(sReadWrite := '1234567890123456', cReadOnly := '1234567890123456', nReadWrite := nVar);
 
// The following line of code causes the compiler error:
// String variable 'sVar10' too short for VAR_IN_OUT parameter 'sReadWrite' of 'F_Manipulate'
F_Manipulate(sReadWrite := sVar10, cReadOnly := sVar10, nReadWrite := nVar);
 
// Correct code
F_Manipulate(sReadWrite := sVar16, cReadOnly := '1234567890', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := '1234567890123456', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := '12345678901234567890', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := sVar10, nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := sVar16, nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar20, cReadOnly := sVar20, nReadWrite := nVar);