# IF Abfrage in SCL



## fbeine (8 Februar 2006)

Hallo zusammen,

ich habe eine Problem mit eine If-Abfrage:


```
FUNCTION FC113 : VOID

VAR_TEMP
    // temporäre Variablen
    I:INT;                              // Schmiervariable in For-Schleifen
    J:INT;                              // Schmiervariable in For-Schleifen
END_VAR 
VAR_INPUT
    // INPUT Variablen deklarieren
    bPositionierung_starten:BOOL;       // Startbefehl um die Posiitonierung zu starten
    iRollendurchmesser:INT;             // Rollendurchmesser des Jumbos im Abwickler
    iDW_Soll:INT;                       // Datenwort, wo die Positionsollwerte in den DBs stehen
    iDB_Zaehlerkarte:BLOCK_DB;          // Datenbaustein Zählerkarte
    iDW_Zaehlerkarte:INT;               // Datenwort Zählerkarte, wo die Position in den DBs stehen
    
END_VAR
VAR_OUTPUT
    // OUTPUT Variablen deklarieren
    bRausfahren:BOOL;                   // Motor muss rausfahren
    bReinfahren:BOOL;                   // Motor muss reinfahren
END_VAR
VAR_IN_OUT
    // IN_OUTPUT Variablen deklarieren
    bPosition_OK:BOOL;                  // Positionierung abgeschlossen, POS_OK
    bPositionierung_REIN:BOOL;          // Motor ist aktuell am Positionieren / REINfahren, POS_ON
    bPositionierung_RAUS:BOOL;          // Motor ist aktuell am Positionieren / RAUSfahren, POS_ON
END_VAR

// Anweisungsteil

    CASE iRollendurchmesser OF
    100..150:          
        IF bPositionierung_starten = true THEN
            
            // Richtstab reinfahren starten
            IF bPositionierung_REIN = false AND DB41.DW[iDW_Soll] > iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] THEN
                bReinfahren := true;
                bPositionierung_REIN := true;
            END_IF;
            // Richtstab reinfahren Position erreicht
            IF bPositionierung_REIN = true AND DB41.DW[iDW_Soll] <= iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] THEN  
                bReinfahren := false;
                bPositionierung_REIN := false;
                bPosition_OK := true;
            END_IF;
            
            // Richtstab rausfahren starten
            IF DB41.DW[iDW_Soll] < iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] AND bPositionierung_RAUS = false THEN
                bRausfahren := true;
                bPositionierung_RAUS := true;
            END_IF;
            // Richtstab rausfahren Position erreicht
            IF bPositionierung_RAUS = true AND DB41.DW[iDW_Soll] >= iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] THEN
                bRausfahren := false;
                bPositionierung_RAUS := false;
                bPosition_OK := true;
            END_IF;
   
            
            
        END_IF;

        
    80..99:
        ;
        
    60..79:
        
        ;
    40..59:
        
        ;
    1..39:
        
        ;

  ELSE:
    // Anweisungen_ELSE
    ;
  END_CASE;
  
END_FUNCTION
```

Bei diesen Code bekomme ich in allen IF-Anweisungen der inneren IF-Schleifen im CASE folgende Fehlermeldungen:
==> Unzulässige Operandentypen
==> Ausdruck muss von Datentyp BOOL sein

Die Datenwörter in den DBs sind alle in INT deklariert.

vielen Dank im voraus
Frank


----------



## argv_user (8 Februar 2006)

Hallo, probier es mal mit Klammern:



           // Richtstab reinfahren starten 
            IF (bPositionierung_REIN = false) AND (DB41.DW[iDW_Soll] > iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte]) THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;


----------



## Anonymous (8 Februar 2006)

Klappt mit Klammern leider auch nicht.

Habe aber folgendes experementel ermittelt:

IF bPositionierung_REIN = false AND iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] <> DB41.DW[iDW_Soll] THEN
                bReinfahren := true;
                bPositionierung_REIN := true;
            END_IF;

mit "<>" klappt es mit "<" nicht ....  :?:


----------



## fbeine (8 Februar 2006)

ups, hatte mich nicht angemeldet ..., der Gast war meine Wenigkeit   

gruss Frank


----------



## Anonymous (8 Februar 2006)

Du musst um einen DB per Variable aufzurufen die Funktion WORD_TO_BLOCK_DB nutzen und für die DB brauchst du eine Word Variable.

Des weiteren beginne generell eine IF Variable mit 
IF NOT bPositionierung_REIN AND ( 

und nicht

IF bPositionierung_REIN = true

Ich hoffe ich konnte helfen !!!

Gruss
Thomas


----------



## fbeine (8 Februar 2006)

Hallo Thomas,

wo muss ich denn die BLOCK_DB deklarieren ?
wie müsste denn der Code aussehen ?

ich habe folgendes getestet, ohne erfolg ...

VAR_INPUT
    // INPUT Variablen deklarieren
    bPositionierung_starten:BOOL;       // Startbefehl um die Posiitonierung zu starten
    iRollendurchmesser:INT;             // Rollendurchmesser des Jumbos im Abwickler
    iDW_Soll:INT;                       // Datenwort, wo die Positionsollwerte in den DBs stehen
    iDB_Zaehlerkarte:BLOCK_DB;          // Datenbaustein Zählerkarte INT
*wDB_Zaehlerkarte:WORD;*              // Datenbaustein Zählerkarte WORD
    iDW_Zaehlerkarte:INT;               // Datenwort Zählerkarte, wo die Position in den DBs stehen
END_VAR

VAR_IN_OUT
    // IN_OUTPUT Variablen deklarieren
    bPosition_OK:BOOL;                  // Positionierung abgeschlossen, POS_OK
    bPositionierung_REIN:BOOL;          // Motor ist aktuell am Positionieren / REINfahren, POS_ON
    bPositionierung_RAUS:BOOL;          // Motor ist aktuell am Positionieren / RAUSfahren, POS_ON
*BLOCK_DB_Zaehlerkarte:BLOCK_DB;*
END_VAR



// Anweisungsteil
*BLOCK_DB_Zaehlerkarte := WORD_TO_BLOCK_DB(wDB_Zaehlerkarte);* 
    CASE iRollendurchmesser OF
    100..150:          
        IF bPositionierung_starten = true THEN

            // Richtstab reinfahren starten
          //  IF bPositionierung_REIN = false AND iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte] < DB41.DW[iDW_Soll] THEN
            IF bPositionierung_REIN = false AND *BLOCK_DB_Zaehlerkarte.DW[iDW_Zaehlerkarte]* < DB41.DW[iDW_Soll] THEN
                bReinfahren := true;
                bPositionierung_REIN := true;


gruss Frank


----------



## Ralle (8 Februar 2006)

Block_DB geht nur so zu verwenden:

Beispiel für Datentypen für Parameter

```
FUNCTION ABSTAND : REAL
VAR_INPUT
    MeinDB : BLOCK_DB;
    ZEIT : TIMER ;
END_VAR
VAR_TEMP
    INDEX : INT ;
END_VAR
BEGIN

ABSTAND := DWORD_TO_REAL(MeinDB.DD4) ;

END_FUNCTION
```
Du mußt die DB-Nummer übergeben und WORD_TO_BLOCK_DB benutzen:


```
VAR_INPUT
  // Eingangsparameter
  DB_Nr: INT;
  StartP: INT;
  Anzahl: INT;
 
END_VAR

VAR_IN_OUT
  // Durchgangsparameter
END_VAR

VAR_OUTPUT
 // Ausgangsparameter
  MAXIMUM: DINT;
END_VAR

VAR_TEMP
  // temporäre Variablen
  Wert: DINT;
  I: INT;
END_VAR

BEGIN
  // Anweisungsteil
  MAXIMUM := 0;
 
   FOR I := 1 TO Anzahl DO
       Wert := DWORD_TO_DINT(WORD_TO_BLOCK_DB(INT_TO_WORD(DB_Nr)).DD[StartP+((I-1)*4)]); 
      
       IF MAXIMUM < Wert THEN MAXIMUM := Wert; END_IF;          
END_FOR;
```


----------



## Onkel Dagobert (8 Februar 2006)

Mit Franks Bsp. könnte es dann so aussehen:


```
// Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND WORD_TO_INT(DB41.DW[iDW_Soll]) > WORD_TO_INT(iDB_Zaehlerkarte.DW[iDW_Zaehlerkarte]) THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;
```

SCL weiß  leider nicht dass es sich um Intergerwerte handelt. Daher ist ohne Konvertierung *"WORD_TO_INT"* der Befehl "<>" zulässig, andere Vergleichsbefehle hingegen nicht.


Gruß, Onkel


----------



## fbeine (9 Februar 2006)

Guten Morgen alle zusammen,

kann sein, dass ich mich zu dumm anstelle, aber ich bekomme es nicht zum laufen.
Ich habe es folgendermassen versucht:


```
VAR_INPUT
    // INPUT Variablen deklarieren
    bPositionierung_starten:BOOL;       // Startbefehl um die Posiitonierung zu starten
    iRollendurchmesser:INT;             // Rollendurchmesser des Jumbos im Abwickler
    iDW_Soll:INT;                       // Datenwort, wo die Positionsollwerte in den DBs stehen
    iDB_Zaehlerkarte:INT;               // Datenbaustein Zählerkarte INT
    iDW_Zaehlerkarte:INT;               // Datenwort Zählerkarte, wo die Position in den DBs stehen
END_VAR


// Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND DB41.DW[iDW_Soll] > WORD_TO_BLOCK_DB(INT_TO_WORD(iDB_Zaehlerkarte)).DW[iDW_Zaehlerkarte] THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;
```

aber es kommen 2 Fehlermeldungen:
==> Unzulässige Operandentypen
==> Der Ausdruck muss von Typ BOOL sein

vieleicht habt ihr ja noch eine zündende Idee ....

Gruss Frank


----------



## argv_user (9 Februar 2006)

Also nochmal: probier es mal mit Klammern.

// Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND ( DB41.DW[iDW_Soll] > WORD_TO_BLOCK_DB(INT_TO_WORD(iDB_Zaehlerkarte)).DW[iDW_Zaehlerkarte] ) THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;

SCL ist PASCAL für S7  !!!


----------



## Ralle (9 Februar 2006)

So geht es:


```
// Richtstab reinfahren starten 
            IF NOT bPositionierung_REIN AND WORD_TO_INT(DB41.DW[iDW_Soll]) > WORD_TO_INT(WORD_TO_BLOCK_DB(INT_TO_WORD(iDB_Zaehlerkarte)).DW[iDW_Zaehlerkarte]) THEN 
                bReinfahren := true; 
                bPositionierung_REIN := true; 
            END_IF;
```

Such mal in der SCL-Hilfe unter "Vergleichsausdrücke". Man kann Word-Variablen nicht mit > oder < vergleichen, also muß man Variablen, bei denen das Format nicht bekannt ist wohl erst explizit in Int-Variablen umwandeln, damit der Compiler das schluckt.


----------



## fbeine (9 Februar 2006)

Es klappt, vielen Dank für eure Hilfe   

bis denne
Frank


----------



## Django2012 (31 August 2012)

Ralle schrieb:


> Block_DB geht nur so zu verwenden:
> 
> Beispiel für Datentypen für Parameter
> 
> ...



Wofür stehen die ganzen  &# ?   #Variable?  & ist aber kein "And" , oder?


----------



## Ralle (31 August 2012)

@Django2012

Der Code ist aus 2006, inzwischen hat die Forensoftware einige Versionsänderungen inkl. komplettem Systemwechsel erfahren. Da ist wohl was beim Umformatieren der Texte schiefgelaufen.

: ist ein Doppelpunkt ( : )
( ist Klammer auf ( ( )
) ist Klammer zu ( ) )

usw.


----------



## Django2012 (31 August 2012)

Ah. OK.  Habe nämlich gestern in nem Siemens Beispiel  schon  %M10.0  entdeckt.  Da war mir % schon nicht klar, das weiß ich mittlerweile.  Aber die &# waren jetzt ein bisschen viel des guten ;-=


----------

