Step 7 flexibler Zugriff auf Datenbaustein

DasRallum

Level-1
Beiträge
20
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

Ich habe einen Datenbaustein in welchem 80 Produktnummern gespeichert sind. Eine Produktnummer könnte nach einem Raster mit Über- und Unterkategorien gefunden werden, wie in einem Lager
z.B. HalleW.RegalX.ReiheY.SpalteZ
Nun bekomme ich als Eingang die 4 Zahlen W,X,Y,Z und muss anhand dieser aus dem DB die Produktnummer auslesen.
Meine Idee wäre eine eine Reihe von Strukturen und Unterstrukturen, welche einen flexiblen Pfad bilden. Anhand der 4 Zahlen würde ich mir dann meinen Pfad zusammenbauen und so die passende Produktnummer finden.

Ich hab keine Ahnung, ob sowas geht. Ich finde leider nichts passendes dazu. Mir fällt auch außer einer großen Schleife, welche jedes Mal alle 80 Produktnummer durchsucht auch keine Alternative ein.

Vielleicht hat einer von euch eine Idee.
Danke schonmal
 
Hallo,
erstmal grundsätzlich : du hast somit eine Art Array mit 4 Dimensionen aus dem du etwas herausbekommen willst ? Produkte[1..Anzahl_Hallen , 1..Anzahl_Regale , 1..Anzahl_Reihen , 1..Anzahl_Spalten] - das könntest du mit SCL schon mal recht simpel auflösen (ohne großen Programmier-Aufwand).
Wie viele Hallen, Regale, Reihen und Spalten gibt es denn bei dir ? Beziffer das doch mal im Einzelnen ...
Was ist denn die Produktnummer ? Eine Zahl ... oder eher eine Zeichenkette (String) ?

Aus dem Bauch heraus würde ich sagen, dass diese Aufgabenstellung in einer SPS nicht unbedingt richtig aufgehoben ist.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Produktnummer liegt atm noch als String[13] vor. Ich überlege aber schon, ob es eine "einfache" Möglichkeit gibt sie in DInt umzuwandeln. Das würde auf jedenfalls den Speicherbedarf massiv verringern.

Um Mal genaue Zahlen zu nennen. Es gibt:
4 Hallen
7 Regale je Halle
2 Ebenen je Regal
11 Höhen je Ebene
2 Reihen je Höhe

SCL bin ich noch Anfänger. Ich kann Beispiele verstehen und auch anpassen. Aber ich bin noch nicht gut genug um selbst was brauchbares zu entwickeln. Aber ich verschäftige mich Mal mit den Arrays im SCL.

Hm... dabei gibt es, wie man sieht noch ein Problem.
die von mir genannten Zahlen führen zu rund 1200 Möglichkeiten. Aber nur 80 davon werden genutzt. Ein Array würde viel ungenutzten Speicherplatz erzeugen, denke ich mir.
 
Zuletzt bearbeitet:
Naja ... diese rund 1200 Möglichkeiten sind aber doch als Fächer vorhanden ... und du willst doch wissen, welcher Artikel in einem bestimmten Fach liegt (oder auch wenn keiner drin ist).
Davon abgesehen kann doch ein Artikel auch in mehr als einem Fach sein ... oder ?

Ich sehe nur diese Möglichkeit, das zu realisieren ...
In SCL ist das dann übrigens wirklich sehr simpel umzusetzen - vor Allem, wenn du das als FB erstellst und der dann den Array-Produktspeicher in seiner Instanz selbst verwaltet (er also zu dem Instanz gehört) ...

Gruß
Larry
 
Es gibt:
4 Hallen
7 Regale je Halle
2 Ebenen je Regal
11 Höhen je Ebene
2 Reihen je Höhe

passt irgendwie nicht mit HalleW.RegalX.ReiheY.SpalteZ zusammen.

Wie sind denn deine 80 Produktnummern auf die 1200 Plätze verteilt?

Vielleicht wäre es besser, 80 Datensätze für die 80 Produktnummern anzulegen.
Und in jedem Datensatz die Koordinaten X,Y,Z,... ablegen.
Benötigt wesentlich weniger Speicherplatz.

Funktioniert halt nur, wenn die Produktnummern nicht öfters vorhanden sind.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Rallum,

wenn ich es richtig verstanden habe, hast du 80 Produkte mit Produkt-IDs vom Typ STRING[23] die in den genannten 1232 Lagerfächern gelagert sein können. Wie du schon richtig erkannt hast, wird die Datenmenge recht umfangreich, wenn du für jedes Datenfach einen STRING[23] definierst. Daher würde ich zunächst erst einmal einen UDT vom Typ ARRAY[1..80] of STRING[23] für die Produkt-IDs anlegen, um diese STRINGS damit zu ersetzen. Als zweites einen UDT für die Datenfächer. Dieser besteht aus verschachtelten Strukturen vom Typ ARRAY[1..?]. Nur die unterste Ebene ist vom Typ INT. In dieser steht dann die Substitution deiner Produkte als Integer (1..80). Diese beiden UDT verwendest du zunächst jeweils in einen DB, den du natürlich mit Daten füttern musst.

Dann brauchst du nur noch eine Funktion, der du deine genannten Parameter (Halle, Regal, usw.als INT) für das Datenfach übergibst. Als weitere Parameter übergibst du die beiden Strukturen der DBs als Eingangs-Parameter vom Typ deiner beiden UDT. In SCL ist es damit sehr einfach, die entsprechenden Daten aus den Array-Strukturen zu lesen.

Um dir nicht die Freude am Programmieren zu nehmen, presentiere ich keine komplette Lösung. Aber ich denke, ein wenig Starthilfe ist schon angebracht. Es ist auch ein sehr schönes Beispiel zu Übungszwecken.

Als Beispiel den UDT für das Lagerfach in AWL:
Code:
TYPE "UDT_LAGER"
VERSION : 0.1

  STRUCT     
   HALLE : ARRAY  [1 .. 4 ] OF STRUCT     
    REGAL : ARRAY  [1 .. 7 ] OF STRUCT     
     EBENE : ARRAY  [1 .. 2 ] OF STRUCT     
      HOEHE : ARRAY  [1 .. 11 ] OF STRUCT     
       REIHE : ARRAY  [1 .. 2 ] OF INT ;    
      END_STRUCT ;    
     END_STRUCT ;    
    END_STRUCT ;    
   END_STRUCT ;    
  END_STRUCT ;    
END_TYPE

Dazu der DB
Code:
DATA_BLOCK "DB_LAGER"
TITLE =
VERSION : 0.1

  STRUCT     
   FACH : "UDT_LAGER";    
  END_STRUCT ;    
BEGIN
END_DATA_BLOCK

Und noch ein wenig SCL (nur der Bausteinkopf)
Code:
FUNCTION "FC_LAGERFACH_PRODUKT" : INT

VAR_INPUT
  LAGERFACH                         : UDT_LAGER;
  PRODUKT                           : UDT_PRODUKT;
  HALLE, REGAL, EBENE, HOEHE, REIHE : INT;
END_VAR

VAR_OUTPUT
  PRODUKTSTRING                     : STRING[23];
END_VAR

VAR_TEMP
  n                                 : INT;
END_VAR

Die beiden DBs belegen übrigens nur 2500 und 2116 Bytes im Arbeitsspeicher. Also kein großes Ding.
Habe dabei sogar versehentlich mit STRING[23] gearbeitet.


Gruß, Onkel
 
Zuletzt bearbeitet:
Hallo nochmal.

Ich habe mittlerweile eine Projektbezogene Lösung gefunden. Ich habe festgestellt, dass ich Hallen und Ebenen auch anders auswerten kann und diese deshalb nicht in die Struktur einfließen müssen. Also bleiben nur noch 7 Regale, 11 Höhen und 2 Reihen übrig, was die Anzahl der Fächer drastisch reduziert. Also habe ich nun nur noch 154 mögliche Fächer. (In meinem Beispiel habe ich die Höhe "Ebene" genannt. Bitte nicht verwirren lassen.

Code:
TYPE "UDT_Daten"

  STRUCT     
    PrgNr: BYTE;
    PNR: STRING[14];
    Belegt: BOOL;
    Magnete: INT;     
  END_STRUCT ;    
END_TYPE

Code:
DATA_BLOCK "DB_LAGER"

  STRUCT     
   Fach : ARRAY  [1 .. 7 ],[1 .. 11 ],[1 .. 2 ] OF "UDT_Daten"    
  END_STRUCT ;   
BEGIN
END_DATA_BLOCK

Code:
FUNCTION_BLOCK FB82

Title = 'Lagerfach'

VAR_INPUT
  // Eingangsparameter
  IN_Regal: INT;
  IN_Ebene: INT;
  IN_Reihe: INT;
END_VAR

VAR_OUTPUT 
  // Ausgangsparameter
  OUT_PrgNr: BYTE;
  OUT_PNR: STRING[14];
  OUT_Belegt: BOOL;
  OUT_Magnete: INT;
END_VAR

VAR_TEMP
  // Temporäre Variabeln
  
END_VAR

//Auslesen der Daten
OUT_PrgNr :=              DB_LAGER.Fach[IN_Regal,IN_Ebene,IN_Reihe].PrgNr;
OUT_PNR :=              DB_LAGER.Fach[IN_Regal,IN_Ebene,IN_Reihe].PNR;
OUT_Belegt :=              DB_LAGER.Fach[IN_Regal,IN_Ebene,IN_Reihe].Belegt;
OUT_Magnete :=              DB_LAGER.Fach[IN_Regal,IN_Ebene,IN_Reihe].Magnete;
END_FUNCTION_BLOCK

Die Idee mit den ausgelagerten Produktnummern ist super. Ich überlege ob ich das trotzdem noch einbaue, da es mMn die Flexibilität erhöht.
Ich verstehe nur nicht ganz, warum ich die Array-Struktur erstmal in einem UDT erstellen muss. Das macht doch nur Sinn, wenn ich plane sie mehrmals zu verwenden. Da ich aber nur ein Lager hab, kann ich sie doch auch direkt im DB erstellen, oder irre ich mich da?
 
Zuletzt bearbeitet:
Nein ... du irrst dich nicht und du brauchst den UDT auch nicht, wenn du ihn nicht willst.
Deine DB-Deklaration sähe da so aus :
Code:
DATA_BLOCK "DB_LAGER"

   STRUCT     
      Fach : ARRAY  [1 .. 7 ],[1 .. 11 ],[1 .. 2 ] OF STRUCT     
         PrgNr: BYTE;
         PNR: STRING[14];
         Belegt: BOOL;
         Magnete: INT;     
      END_STRUCT ;    
   END_STRUCT ;   
 
END_DATA_BLOCK
(aus deinem Code entnommen)

Vielleicht noch einige Anmerkungen dazu :
- wenn PNr für Produktnummer steht - warum nennst du die Variable dann nicht auch so ? Variablennamen selber "fressen" erstmal keinen Speicher
- wie kommen die Daten in den DB ? Vielleicht modifizierst du den Baustein so, dass es auch Daten einlagern kann ...
- vielleicht ist es irgendwann sinnvoll Unter-Informationen zu bekommen, wie :
- wo befindet sich Produkt XYZ ?
- welches ist das nächste freie Fach ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
..Ich verstehe nur nicht ganz, warum ich die Array-Struktur erstmal in einem UDT erstellen muss. Das macht doch nur Sinn, wenn ich plane sie mehrmals zu verwenden...
Bei einer Lagerverwaltung würde ich davon ausgehen, einen solchen UDT möglicherweise mehrmals zu verwenden. Und wenn nicht, dann schadet es auch nicht. Aber so etwas ist bei Bedarf auch schnell mal geändert. In meinem Beispiel hatte ich die beiden UDTs z.Bsp. als Eingangsparameter verwendet, da es mMn die Flexibilität erhöht ;) .
 
Zuletzt bearbeitet:
...
Vielleicht noch einige Anmerkungen dazu :
- wenn PNr für Produktnummer steht - warum nennst du die Variable dann nicht auch so ? Variablennamen selber "fressen" erstmal keinen Speicher
- wie kommen die Daten in den DB ? Vielleicht modifizierst du den Baustein so, dass es auch Daten einlagern kann ...
- vielleicht ist es irgendwann sinnvoll Unter-Informationen zu bekommen, wie :
- wo befindet sich Produkt XYZ ?
- welches ist das nächste freie Fach ?

Gruß
Larry

Ich hab die Produktnummer PNR genannt, weil es auch in der Doku, die ich bekommen habe so steht. Hab ich also nur aus Gründen der Einheitlichkeit gemacht.

Das mit den Daten im DB ist noch so ne Sache... Tatsache ist, dass die Daten möglichst fest hinterlegt werden müssen. Das heißt das selbe Produkt wird vorraussichtlich für lange Zeit (evtl Jahre) immer an der gleichen Stelle zu finden sein. Deshalb muss ich auch nicht nach Leerfächern suchen. Die werden ebenfalls für sehr lange Zeit leer sein. Es handelt sich nicht um ein Lager im eigentlichen Sinn. Vielmehr um eine Art Standart-Einzelteil Speicher für die Montage. Für ein Endprodukt müssen immer wieder die gleichen Einzelteile aus den gleichen Fächern geholt werden. Mittels eines Barcodereaders wird die Produktnummer zur Sicherheit nochmal eingelesen und mit der im DB hinterlegten PNR verglichen, um auszuschließen, dass jemand etwas ins falsche Fach gelegt hat. Die PrgNr ist die Programmnummer für den Montage-Roboter, die ebenfalls hinterlegt ist.

Dementsprechend überlege ich noch, wie ich die Daten möglichst fest im DB hinterlege. Ich könnte alles als manuell Ausgangswert in den DB schreiben, aber das wäre ganz schön viel aufwand, denke ich mir.
 
..Dementsprechend überlege ich noch, wie ich die Daten möglichst fest im DB hinterlege. Ich könnte alles als manuell Ausgangswert in den DB schreiben, aber das wäre ganz schön viel aufwand, denke ich mir.
Wenn die Daten in elektronischer Form als Excel-Tabelle, ASCII-File o.ä. vorliegen, würde ich versuchen diese mit der Macro-Funktionalität z.Bsp. von TextPad ins richtige Quellen-Format zu bringen.
 
Zurück
Oben