FUNCTION "FC_StorageLines" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      nInDest : Int;   // allgemeine Destination für diese Section
   END_VAR

   VAR_OUTPUT 
      nOutStorageLevel : Int;   // Gesamt-Füllstand
      stOutCarrStats : "CarrierStatisticsStore";
   END_VAR

   VAR_IN_OUT 
      arInOutStorage : Array[*] of "stStorageLine";
   END_VAR

   VAR_TEMP 
      nIdx1 : Int;
      nIdx2 : Int;
      nArrayMax : Int;
      nDestMin : Int;   // Ziele kleiner gehören raus
      nDestMax : Int;   // Ziele größer gehören raus
   END_VAR

   VAR CONSTANT 
      cDummy : USInt := 1;
   END_VAR


BEGIN
	//Durchsucht die Lagerlinien um den Status/Füllstand zu ermitteln und gibt dabei Statistikwerte aus
	
	#stOutCarrStats.nEmptyCarrier := 0;
	#stOutCarrStats.nDummy := 0;
	#stOutCarrStats.stRdyToLeave.nCount := 0;
	
	REGION Arraygrenze ermitteln
	    #nArrayMax := DINT_TO_USINT(UPPER_BOUND(ARR := #arInOutStorage, DIM := 1));            // get array size
	    #nDestMin := #nInDest;
	    #nDestMax := #nInDest + #nArrayMax;
	END_REGION
	
	REGION Lager durchsuchen
	    FOR #nIdx1 := 1 TO #nArrayMax DO
	        //Prüft Einstellwert
	        IF (#arInOutStorage[#nIdx1].stData.Config.nCapacitySet > #arInOutStorage[#nIdx1].stData.Config.nCapacityMax) OR (#arInOutStorage[#nIdx1].stData.Config.nCapacitySet < 0) THEN //"kleiner gleich" zu "kleiner" gemacht, Embi
	            #arInOutStorage[#nIdx1].stData.Config.nCapacitySet := #arInOutStorage[#nIdx1].stData.Config.nCapacityMax;
	        END_IF;
	        FOR #nIdx2 := 1 TO "cNoPositions" DO
	            IF #nIdx2 = "cNoPositions" THEN
	                REGION Linienende erreicht
	                    IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode <> 0 THEN //Zählt nicht die Teile sondern merkt sich die Positionen wo ein Teil vorhanden ist
	                        #arInOutStorage[#nIdx1].stData.Status.nCount := #nIdx2;
	                        #arInOutStorage[#nIdx1].stData.Status.bByte.%X0 := FALSE;
	                        REGION Werte für Statistik ermitteln
	                            IF NOT #arInOutStorage[#nIdx1].arCarrier[#nIdx2].bStatus.%X1 AND #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode <> #cDummy THEN
	                                #stOutCarrStats.nEmptyCarrier += 1;
	                            END_IF;
	                            IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode = #cDummy THEN
	                                #stOutCarrStats.nDummy += 1;
	                            END_IF;
	                            IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nDestination < #nDestMin OR #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nDestination > #nDestMax THEN
	                                #stOutCarrStats.stRdyToLeave.nCount += 1;
	                                #stOutCarrStats.stRdyToLeave.nLine := #nIdx1;
	                                #stOutCarrStats.stRdyToLeave.nPos := #nIdx2;
	                            END_IF;
	                        END_REGION
	                        EXIT;
	                    ELSIF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode = 0 THEN //Verlässt Schleife nach letztem gefundenen Teil um nicht die Schleife für leere Plätze auszuführen
	                        REGION Leer
	                            #arInOutStorage[#nIdx1].stData.Status.nCount := 0;
	                            #arInOutStorage[#nIdx1].stData.Status.bByte.%X0 := TRUE;
	                            EXIT;
	                        END_REGION
	
	                    END_IF;
	                END_REGION
	            ELSIF #nIdx2 < "cNoPositions" THEN
	                IF (#arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode <> 0 AND #arInOutStorage[#nIdx1].arCarrier[#nIdx2 + 1].nBarcode = 0) THEN //Zählt nicht die Teile sondern merkt sich die Positionen wo ein Teil vorhanden ist
	                    REGION Letzter Carrier erreicht
	                        #arInOutStorage[#nIdx1].stData.Status.nCount := #nIdx2;
	                        #arInOutStorage[#nIdx1].stData.Status.bByte.%X0 := FALSE;
	                        REGION Werte für Statistik ermitteln
	                            IF NOT #arInOutStorage[#nIdx1].arCarrier[#nIdx2].bStatus.%X1 AND #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode <> #cDummy THEN
	                                #stOutCarrStats.nEmptyCarrier += 1;
	                            END_IF;
	                            IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode = #cDummy THEN
	                                #stOutCarrStats.nDummy += 1;
	                            END_IF;
	                            IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nDestination < #nDestMin OR #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nDestination > #nDestMax THEN
	                                #stOutCarrStats.stRdyToLeave.nCount += 1;
	                                #stOutCarrStats.stRdyToLeave.nLine := #nIdx1;
	                                #stOutCarrStats.stRdyToLeave.nPos := #nIdx2;
	                            END_IF;
	                        END_REGION
	                        EXIT;
	                    END_REGION
	                ELSIF (#arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode = 0) THEN //Verlässt Schleife nach letztem gefundenen Teil um nicht die Schleife für leere Plätze auszuführen
	                    REGION Leer
	                        #arInOutStorage[#nIdx1].stData.Status.nCount := 0;
	                        #arInOutStorage[#nIdx1].stData.Status.bByte.%X0 := TRUE;
	                        EXIT;
	                    END_REGION
	                END_IF;
	            ELSE
	                REGION Suchlauf
	                    REGION Werte für Statistik ermitteln
	                        IF NOT #arInOutStorage[#nIdx1].arCarrier[#nIdx2].bStatus.%X1 AND #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode <> #cDummy THEN
	                            #stOutCarrStats.nEmptyCarrier += 1;
	                        END_IF;
	                        IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nBarcode = #cDummy THEN
	                            #stOutCarrStats.nDummy += 1;
	                        END_IF;
	                        IF #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nDestination < #nDestMin OR #arInOutStorage[#nIdx1].arCarrier[#nIdx2].nDestination > #nDestMax THEN
	                            #stOutCarrStats.stRdyToLeave.nCount += 1;
	                            #stOutCarrStats.stRdyToLeave.nLine := #nIdx1;
	                            #stOutCarrStats.stRdyToLeave.nPos := #nIdx2;
	                        END_IF;
	                    END_REGION
	                END_REGION
	            END_IF;
	        END_FOR;
	    END_FOR;
	END_REGION
	
	REGION Gesamtfüllstand
	    //Zählt die einzelnen Füllstände zusammen
	    #nIdx2 := 0;
	    FOR #nIdx1 := 1 TO #nArrayMax DO
	        #nIdx2 := #nIdx2 + #arInOutStorage[#nIdx1].stData.Status.nCount
	        ;
	    END_FOR;
	    #nOutStorageLevel := #nIdx2;
	END_REGION
	
END_FUNCTION

