Claude Session mit Empfehlungen zur Standardisierung der Library hinzugefügt. Manuelle Prüfung jedes Bausteins noch nötig

This commit is contained in:
2026-06-29 10:24:45 +02:00
parent d4ce88715e
commit 3bf291fdf8
13 changed files with 1442 additions and 0 deletions
@@ -0,0 +1,200 @@
FUNCTION_BLOCK "FB_Visu_Jam"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_IN_OUT
arInOutJam : Array[*] of "stCarrier"; // Jam Daten
stInOutHMIJam : "UDT_Visu_Jam_List";
stInOutHMIData : "UDT_HMI_JamData"; // Jam Daten HMI Schnittstelle
END_VAR
VAR
xReInit : Bool;
nUpperBound : Int;
END_VAR
VAR_TEMP
nIdx : Int;
nIdxMerker : Int;
END_VAR
BEGIN
// Hier werden die Carrierlisten für die Visu erstellt
// Auf Knopfdruck am HMI werden Aktionen durchgeführt, um die Liste zu scrollen
// Aktuell werden immer 10 Carrier gleichzeitig angezeigt
#stInOutHMIJam.#upperBound := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
#nUpperBound := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
REGION Jam Daten Liste
// Beim ersten Aufruf nach reinit ausführen, damit Daten drinstehen
IF NOT #xReInit THEN
#stInOutHMIJam.nIndex := 1;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#xReInit := TRUE;
END_IF;
// Wenn nichts an der Liste gemacht wird, Daten nur aktualisieren
IF NOT #stInOutHMIJam.#DecOne AND NOT #stInOutHMIJam.#DecFive AND NOT #stInOutHMIJam.#IncOne AND NOT #stInOutHMIJam.#IncFive AND NOT #stInOutHMIJam.#ScrollEnd AND NOT #stInOutHMIJam.#ScrollStart THEN
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
END_IF;
// Liste um eins nach oben bewegen
IF #stInOutHMIJam.#DecOne THEN
#stInOutHMIJam.#nIndex -= 1;
IF #stInOutHMIJam.#nIndex < 1 THEN
#stInOutHMIJam.#nIndex := 1;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#DecOne := FALSE;
END_IF;
// Liste um fünf nach oben bewegen
IF #stInOutHMIJam.#DecFive THEN
#stInOutHMIJam.#nIndex -= 5;
IF #stInOutHMIJam.#nIndex < 1 THEN
#stInOutHMIJam.#nIndex := 1;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#DecFive := FALSE;
END_IF;
// Liste um eins nach unten bewegen
IF #stInOutHMIJam.#IncOne THEN
#stInOutHMIJam.#nIndex += 1;
IF #stInOutHMIJam.#nIndex > #stInOutHMIJam.#upperBound - 9 THEN
#stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
IF #stInOutHMIJam.nIndex <= 0 THEN
#stInOutHMIJam.nIndex := 1;
END_IF;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#IncOne := FALSE;
END_IF;
// Liste um fünf nach unten bewegen
IF #stInOutHMIJam.#IncFive THEN
#stInOutHMIJam.#nIndex += 5;
IF #stInOutHMIJam.#nIndex > #stInOutHMIJam.#upperBound - 9 THEN
#stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
IF #stInOutHMIJam.nIndex < 0 THEN
#stInOutHMIJam.nIndex := 1;
END_IF;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#IncFive := FALSE;
END_IF;
// Zum Listenanfang springen
IF #stInOutHMIJam.#ScrollStart THEN
#stInOutHMIJam.#nIndex := 1;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#ScrollStart := FALSE;
END_IF;
// Zum Listenende springen
IF #stInOutHMIJam.#ScrollEnd THEN
#stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
IF #stInOutHMIJam.nIndex < 0 THEN
#stInOutHMIJam.nIndex := 1;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#ScrollEnd := FALSE;
END_IF;
END_REGION
REGION FC_CAR_MOVE
// "FC_CARR_MOVE"(nInCommand := #stHMIJam.stCarMove.nCommand,
// nInJamNr := #nInJamNr,//braucht nicht von HMI zu kommen - #stHMIJam.stCarMove.nJamNr,
// nInTarget := #stHMIJam.stCarMove.nTarget,
// xInStart := #stHMIJam.stCarMove.xStart,
// xOutError => #stHMIJam.stCarMove.xError);
// #stInOutHMIJam.stCarMove.xStart := FALSE;
"FC_CarrierManipulator"(stInOutHMIJamData := #stInOutHMIData,
stInOutHMIJamList := #stInOutHMIJam,
arInOutJam := #arInOutJam,
arInOutHyperJam := "DB_HyperJam".stHyperJam.arCarrier);
#stInOutHMIJam.stCarMove.xStart := FALSE;
END_REGION
REGION Manuelle Zielvergabe für Jam
IF #stInOutHMIData.stStatus.bByte.%X7 THEN //%X7: Manuelle Zielvergabe aktiviert
#arInOutJam[1].nDestination := #stInOutHMIData.stJamConfig.nManualDest; //Sorgt dafür, dass Carrier ein festes Ziel bekommen
END_IF;
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,197 @@
FUNCTION_BLOCK "FB_Visu_JamStorage"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
nInJamCount : UInt;
END_VAR
VAR_IN_OUT
arInOutJam : Array[*] of "stCarrier"; // Jam Daten
stInOutHMIJam : "UDT_Visu_Jam_List";
stInOutHMIData : "UDT_HMI_StorageData"; // Jam Daten HMI Schnittstelle
END_VAR
VAR
xReInit : Bool;
nUpperBound : Int;
END_VAR
VAR_TEMP
nIdx : Int;
nIdxMerker : Int;
END_VAR
BEGIN
// Hier werden die Carrierlisten für die Visu erstellt
// Auf Knopfdruck am HMI werden Aktionen durchgeführt, um die Liste zu scrollen
// Aktuell werden immer 10 Carrier gleichzeitig angezeigt
#stInOutHMIJam.#upperBound := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
#nUpperBound := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
REGION Jam Daten Liste
// Beim ersten Aufruf nach reinit ausführen, damit Daten drinstehen
IF NOT #xReInit THEN
#stInOutHMIJam.nIndex := 1;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#xReInit := TRUE;
END_IF;
// Wenn nichts an der Liste gemacht wird, Daten nur aktualisieren
IF NOT #stInOutHMIJam.#DecOne AND NOT #stInOutHMIJam.#DecFive AND NOT #stInOutHMIJam.#IncOne AND NOT #stInOutHMIJam.#IncFive AND NOT #stInOutHMIJam.#ScrollEnd AND NOT #stInOutHMIJam.#ScrollStart THEN
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
END_IF;
// Liste um eins nach oben bewegen
IF #stInOutHMIJam.#DecOne THEN
#stInOutHMIJam.#nIndex -= 1;
IF #stInOutHMIJam.#nIndex < 1 THEN
#stInOutHMIJam.#nIndex := 1;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#DecOne := FALSE;
END_IF;
// Liste um fünf nach oben bewegen
IF #stInOutHMIJam.#DecFive THEN
#stInOutHMIJam.#nIndex -= 5;
IF #stInOutHMIJam.#nIndex < 1 THEN
#stInOutHMIJam.#nIndex := 1;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#DecFive := FALSE;
END_IF;
// Liste um eins nach unten bewegen
IF #stInOutHMIJam.#IncOne THEN
#stInOutHMIJam.#nIndex += 1;
IF #stInOutHMIJam.#nIndex > #stInOutHMIJam.#upperBound - 9 THEN
#stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
IF #stInOutHMIJam.nIndex <= 0 THEN
#stInOutHMIJam.nIndex := 1;
END_IF;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#IncOne := FALSE;
END_IF;
// Liste um fünf nach unten bewegen
IF #stInOutHMIJam.#IncFive THEN
#stInOutHMIJam.#nIndex += 5;
IF #stInOutHMIJam.#nIndex > #stInOutHMIJam.#upperBound - 9 THEN
#stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
IF #stInOutHMIJam.nIndex < 0 THEN
#stInOutHMIJam.nIndex := 1;
END_IF;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#IncFive := FALSE;
END_IF;
// Zum Listenanfang springen
IF #stInOutHMIJam.#ScrollStart THEN
#stInOutHMIJam.#nIndex := 1;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#ScrollStart := FALSE;
END_IF;
// Zum Listenende springen
IF #stInOutHMIJam.#ScrollEnd THEN
#stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
IF #stInOutHMIJam.nIndex < 0 THEN
#stInOutHMIJam.nIndex := 1;
END_IF;
#nIdxMerker := #stInOutHMIJam.nIndex;
FOR #nIdx := 1 TO 10 DO
#stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
#nIdxMerker += 1;
IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
EXIT;
END_IF;
END_FOR;
#stInOutHMIJam.#ScrollEnd := FALSE;
END_IF;
END_REGION
REGION FC_CAR_MOVE
// "FC_CARR_MOVE"(nInCommand := #stHMIJam.stCarMove.nCommand,
// nInJamNr := #nInJamNr,//braucht nicht von HMI zu kommen - #stHMIJam.stCarMove.nJamNr,
// nInTarget := #stHMIJam.stCarMove.nTarget,
// xInStart := #stHMIJam.stCarMove.xStart,
// xOutError => #stHMIJam.stCarMove.xError);
#stInOutHMIJam.stCarMove.xStart := FALSE;
END_REGION
REGION HMI
IF #stInOutHMIData.stStatus.bByte.%X7 THEN //%X7: Manuelle Zielvergabe aktiviert
#arInOutJam[1].nDestination := #stInOutHMIData.stConfig.nCapacitySetHMI; //Sorgt dafür, dass Carrier ein festes Ziel bekommen
END_IF;
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,159 @@
FUNCTION "FC_CarrierManipulator" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_IN_OUT
stInOutHMIJamData : "UDT_HMI_JamData"; // Jam Daten HMI
stInOutHMIJamList : "UDT_Visu_Jam_List"; // Jam Liste HMI
arInOutJam : Array[*] of "stCarrier"; // Jam SPS
arInOutHyperJam : Array[*] of "stCarrier";
END_VAR
VAR_TEMP
tmpEmptyCarr : "stCarrier";
nCounter : DInt;
nArrayMax : Int;
nIdx : Int;
nStatus : Int;
xResult : Bool;
END_VAR
VAR CONSTANT
cFirstAhead : Int := 1; // Carrier weiterbuchen
cLastBack : Int := 2; // Carrier zurückbuchen
cSwapFirstLast : Int := 3; // Ersten und letzten Carrier im Jam tauschen
cDeleteAll : Int := 4; // Alle Jam Daten löschen (macht Sinn, wenn Jam unklar und man einfach bereinigen will)
cDeletePos : Int := 5; // Position, falls bestimmter Carrier gelöscht werden soll (macht Sinn, wenn man Carrier entnimmt)
cPutToHyperJam : Int := 6; // Position, falls bestimmter Carrier zum HyperJam soll (macht Sinn, wenn Carrier nicht auffindbar)
END_VAR
BEGIN
REGION Info
(*
Funktionen
- Alle carrier daten in einem jam leeren - check
- bestimmten carrier löschen - check
MUBEA bereits gemacht:
- Carrier in Hyper-Jam - check
- Weiterbuchen
- Zurückbuchen
- Tauschen (erster und letzter)
*)
END_REGION
REGION Array-Grenzen
#nArrayMax := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
END_REGION
REGION Befehl ausführen
CASE #stInOutHMIJamList.stCarMove.nCommand OF
#cDeleteAll:
REGION Jam bereinigen
IF #stInOutHMIJamList.stCarMove.xStart THEN
IF NOT #arInOutJam[1].bStatus.%X0 OR NOT #stInOutHMIJamData.stStatus.bByte.%X2 OR NOT #stInOutHMIJamData.stStatus.bByte.%X3 THEN
#stInOutHMIJamList.stCarMove.xStart := FALSE;
RETURN;
END_IF;
FOR #nIdx := 1 TO #nArrayMax DO
IF #arInOutJam[#nIdx].bStatus.%X0 THEN
#arInOutJam[#nIdx] := #tmpEmptyCarr; // Carrierdaten löschen/überschreiben
ELSE
EXIT; //fertig, nichts mehr zu tun
END_IF;
END_FOR;
#stInOutHMIJamList.stCarMove.xStart := FALSE;
END_IF;
END_REGION
#cDeletePos:
REGION Bestimmten Carrier löschen
IF #stInOutHMIJamList.stCarMove.xStart THEN
IF #stInOutHMIJamList.stCarMove.nPosDeleteCarrier < 1 OR #stInOutHMIJamList.stCarMove.nPosDeleteCarrier > #nArrayMax OR NOT #arInOutJam[1].bStatus.%X0 OR NOT #stInOutHMIJamData.stStatus.bByte.%X2 OR NOT #stInOutHMIJamData.stStatus.bByte.%X3 THEN
//Wenn Positionsangabe zu klein oder zu groß ist, oder in Jam ist gar kein Carrier online, dann beende
#stInOutHMIJamList.stCarMove.nPosDeleteCarrier := 1;
#stInOutHMIJamList.stCarMove.xStart := FALSE;
RETURN;
END_IF;
//lösche den ausgewählten
#arInOutJam[#stInOutHMIJamList.stCarMove.nPosDeleteCarrier] := #tmpEmptyCarr;
IF #stInOutHMIJamList.stCarMove.nPosDeleteCarrier < #nArrayMax THEN
//Rücke danach auf um Lücke zu beseitigen aber nur wenn es nicht die letzte Stelle war
#nStatus := MOVE_BLK_VARIANT(SRC := #arInOutJam,
COUNT := INT_TO_UDINT(#nArrayMax - #stInOutHMIJamList.stCarMove.nPosDeleteCarrier),
SRC_INDEX := #stInOutHMIJamList.stCarMove.nPosDeleteCarrier,
DEST_INDEX := #stInOutHMIJamList.stCarMove.nPosDeleteCarrier - 1,
DEST => #arInOutJam);
//letztes löschen damit dort nichts doppeltes drinsteht
#arInOutJam[#nArrayMax] := #tmpEmptyCarr;
END_IF;
//fertig, setze Startbefehl zurück und Position auf Default
#stInOutHMIJamList.stCarMove.nPosDeleteCarrier := 1;
#stInOutHMIJamList.stCarMove.xStart := FALSE;
END_IF;
END_REGION
#cPutToHyperJam:
REGION Carrier zum Hyper-Jam
IF #stInOutHMIJamList.stCarMove.xStart THEN
IF #stInOutHMIJamList.stCarMove.nPosTransferHj < 1 OR #stInOutHMIJamList.stCarMove.nPosTransferHj > #nArrayMax OR NOT #arInOutJam[1].bStatus.%X0 OR NOT #stInOutHMIJamData.stStatus.bByte.%X2 OR NOT #stInOutHMIJamData.stStatus.bByte.%X3 THEN
//Wenn Positionsangabe zu klein oder zu groß ist, oder in Jam ist gar kein Carrier online, dann beende
#stInOutHMIJamList.stCarMove.nPosTransferHj := 1;
#stInOutHMIJamList.stCarMove.xStart := FALSE;
RETURN;
END_IF;
IF #arInOutJam[#stInOutHMIJamList.stCarMove.nPosTransferHj].nBarcode > 2 THEN
REGION normale Barcodes
//Füge Carrier am Ende des Hyperjams ein nur wenn nicht Dummy oder BadRead, also nur bei normalem Code
"FC_TSHR_AddAtEnd"(stInTrolley := #arInOutJam[#stInOutHMIJamList.stCarMove.nPosTransferHj],
nOutCounter => #nCounter,
xOutResult => #xResult,
arTSHR := #arInOutHyperJam);
//lösche den ausgewählten
#arInOutJam[#stInOutHMIJamList.stCarMove.nPosTransferHj] := #tmpEmptyCarr;
IF #stInOutHMIJamList.stCarMove.nPosTransferHj < #nArrayMax THEN
//Rücke danach auf um Lücke zu beseitigen aber nur wenn es nicht die letzte Stelle war
#nStatus := MOVE_BLK_VARIANT(SRC := #arInOutJam,
COUNT := INT_TO_UDINT(#nArrayMax - #stInOutHMIJamList.stCarMove.nPosTransferHj),
SRC_INDEX := #stInOutHMIJamList.stCarMove.nPosTransferHj,
DEST_INDEX := #stInOutHMIJamList.stCarMove.nPosTransferHj - 1,
DEST => #arInOutJam);
//letztes löschen damit dort nichts doppeltes drinsteht
#arInOutJam[#nArrayMax] := #tmpEmptyCarr;
END_IF;
//fertig, setze Startbefehl zurück und Position auf Default
#stInOutHMIJamList.stCarMove.nPosTransferHj := 1;
#stInOutHMIJamList.stCarMove.xStart := FALSE;
END_REGION
ELSE
REGION Dummy oder unbekannt
//Falls doch Dummy oder unbekannter Barcode, lösche nur
#arInOutJam[#stInOutHMIJamList.stCarMove.nPosTransferHj] := #tmpEmptyCarr;
IF #stInOutHMIJamList.stCarMove.nPosTransferHj < #nArrayMax THEN
//Rücke danach auf um Lücke zu beseitigen aber nur wenn es nicht die letzte Stelle war
#nStatus := MOVE_BLK_VARIANT(SRC := #arInOutJam,
COUNT := INT_TO_UDINT(#nArrayMax - #stInOutHMIJamList.stCarMove.nPosTransferHj),
SRC_INDEX := #stInOutHMIJamList.stCarMove.nPosTransferHj,
DEST_INDEX := #stInOutHMIJamList.stCarMove.nPosTransferHj - 1,
DEST => #arInOutJam);
//letztes letztes löschen damit dort nichts doppeltes drinsteht
#arInOutJam[#nArrayMax] := #tmpEmptyCarr;
END_IF;
//fertig, setze Startbefehl zurück und Position auf Default
#stInOutHMIJamList.stCarMove.nPosTransferHj := 1;
#stInOutHMIJamList.stCarMove.xStart := FALSE;
END_REGION
END_IF;
END_IF;
END_REGION
END_CASE;
END_REGION
END_FUNCTION