Step 7 Blkmov mit SCL

Limette

Level-2
Beiträge
282
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Abend zusammen,

Bild anbei.NW.jpg

Ich blockmove einen Bereich von 360 Byte von einem DB vom Typ UDT „Recipe“ in einen DB mit einem Array[0..9] vom Typ Recipe.
In KOP ists easy. siehe Bild. In SCL bekomme ich es nicht so richtig hin. Bitte um Hilfe.
Als Input hab ich den UDT Recipe und Output den DB mit einem Array vom Typ Recipe.


Code:
FUNCTION FC2000 : VOID

VAR_INPUT
  iRecipe: "Recipe";                   
END_VAR
 
 
VAR_OUTPUT  
qDB_RecipeStack: BLOCK_DB  
END_VAR
 
VAR_TEMP 
RET_VAL1: INT;   
END_VAR
 
RET_VAL1 := "BLKMOV"(SRCBLK:=??, DSTBLK :=?? );
 
Der Aufruf in deinem KOP-Bild ist auch etwas ganz anderes als deinem Stück SCL Code.

Wenn das mit dem Parameter vom Typ BLOCK_DB so bleiben soll (was dein Vorhaben etwas verkompliziert und auch ansonsten eher unschön ist), dann musst du dir daraus erst selber einen ANY-Pointer z.B. im Temp-Bereich zusammenbauen..

Den KOP-Aufruf kannst du genauso in SCL schreiben, also die gleichen Texte die du auch in KOP an den Parametern angegeben hast, schreibst du auch in SCL an die Parameter.
 
Wenn das alles ist was in der Funktion passieren soll, dann ist die Funktion meiner Meinung nach überflüssig.
Dann kannst du an der Stelle genauso gut oder auch besser weil nichts versteckt wird, direkt den Blockmove aufrufen.
 
Übrigens kannst du in SCL auch direkt schreiben:

"Dummy_DB_Recipe".Recipes[1] := "Dummy_DB_Recipe".Recipes;

Nur bei großen Strukturen ist das Kopieren mit Blockmove effizienter.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde beide Parameter vom Typ deiner UDT machen, wenn möglich.

Code:
FUNCTION FC2000 : VOID

VAR_INPUT
  src: "Recipe"; // Quelle         
END_VAR
 
 
VAR_OUTPUT  
  dst : "Recipe"; // Ziel
END_VAR
 
VAR_TEMP 
RET_VAL1: INT;   
END_VAR
 
RET_VAL1 := "BLKMOV"(SRCBLK:=src, DSTBLK := dst);
 
Ich würde beide Parameter vom Typ deiner UDT machen, wenn möglich.

Code:
FUNCTION FC2000 : VOID

VAR_INPUT
  src: "Recipe"; // Quelle         
END_VAR
 
 
VAR_OUTPUT  
  dst : "Recipe"; // Ziel
END_VAR
 
VAR_TEMP 
RET_VAL1: INT;   
END_VAR
 
RET_VAL1 := "BLKMOV"(SRCBLK:=src, DSTBLK := dst);

Am Ausgang sollte ich schon einen DB mit einem Array von dem UDT auflegen können.
 
Am Ausgang sollte ich schon einen DB mit einem Array von dem UDT auflegen können.

Dann eben so:
Code:
FUNCTION FC2000 : VOID

VAR_INPUT
  src: "Recipe"; // Quelle     
  dstidx : INT;    
END_VAR
 
 
VAR_OUTPUT  
  dst : array[0..99] of "Recipe"; // Ziel
END_VAR
 
VAR_TEMP 
RET_VAL1: INT;   
END_VAR

IF dstidx >= 0 AND dstidx <= 99 then
  RET_VAL1 := "BLKMOV"(SRCBLK:=src, DSTBLK := dst[dstidx]);
ELSE
  // Fehlerbehandlung
 
Morgen zusammen,

nächste Frage:

Code:
VAR_INPUT
  src: "Recipe"; // Quelle     
  dstidx : INT;    
END_VAR

Wie kann ich src auf null abgleichen, oder nur Teile davon. Wären bei mir ja insgesamt 360 Byte. Wie eine "if-schleife" aussieht weiß ich. danke im Voraus.
 
Ich habe immer einen Block, der nicht benutzt oder so belegt ist, wie ich es benötige. Den kopiere ich dann auf den zu "Nullenden" Block oder vergleiche mit diesem, je nach Bedarf.
Sollte bei der 1500-er sogar mit einer Temp gehen, da diese ja bei der 1500-er mit null vorbelegt sind und nicht, wie bei der 300-er zufällig.
Bei einem FB nutze ich i.d.R. eine Stat gleichen Typs dafür.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Meisten arrays die ich verwende, fangen bei 0 an.
Ich ändere das Array dann immer so, dass es bei -1 anfängt und verwende diese nicht zum speichern.
Damit ist mein Array Element -1 immer mein initialisierungs Element.
Das mit der Initialisierung der TEMP variablen auf der 1500er gilt aber nur für optimierte Bausteine.
 
Zurück
Oben