Array Indirekt ansprechen

tobl2002

Level-2
Beiträge
75
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo.

Ich habe ein "kleines" Problem:

In einem DB habe ich ein Array of UDT erstellt. z.b. [1..10]
In dem UDT steht eine Artikelnummer und verschiedene Daten die dem Artikel im laufenden Prozess zugeordnet werden.

Um mir viel programmierarbeit zu sparen, suche ich eine "einfache" lösung um erst mal in dem Array die richtige stelle zu finden.

Im moment habe ich es so gemacht das ich 10x das gleiche netzwerk habe mit jeweil einem anderen Index (1 bis 10) . Bei 10 ist das ja noch machbar... wird aber einiges mehr werden...

Ich würde das dann gerne so machen dass ich dies mit einer schleife durchlaufe und dann jeweils meinen index um eins erhöhe.

in dieser schleife rufe ich einen baustein auf der folgende funktion hat:
als eingangsparameter ein array und einen wert z.b. Int als Arrayindex. Als ausgang dann meine Artikelnummer als String, und dann die verschiedenen Daten (die meisten sind DINT)

Danke für eure Hilfe
ich hoffe das ist einigermaßer verständlich was ich geschrieben habe...

SCL ist auch möglich. habe ich nur so gut wie keine erfahrungen mit.

Gruß
Tobl
 
Na ... wenn SCL für dich auch ein Thema ist, dann würde ich diese Aufgabe auch damit lösen.
Wo genau hängt es denn ?
In SCL wäre dass dann besonders elegant zu lösen, wenn die Daten, die du durchsuchen / ausgeben möchtest sowieso schon in dem Instanz-DB stehen.
Wo kommen die Daten ursprünglich her ?

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
SCL ist schon möglich aber habe keine Ahnung wie ich damit anfangen soll.

Was ich gestern noch vergessen habe ist, dass ich ja eigentlich erst mal die daten einlesen muss, und dann später wieder zurückschreiben musss. also den gleichen baustein in die andere richtgung. aber ich denke mal wenn ich den einen habe dann ist die andere richtung auch kein problem mehr.

es hängt schon ganz am anfang.... ich habe keine ahnung wo ich anfangen soll...

Die Daten werden in der ersten Station erfassst. Also Artikelnummer wird eingelesen (1.Baustein) . dann bekomme ich von einem PC eine Rückmeldung was mit dem Artikel passieren soll. (2. Baustein) Dann wird der Artikel bearbeitet (3. Baustein), kontrolle ob barbeitung ok war (4. Baustein) und zum schluss löschen des Datensatzes (5.Baustein).
Der Ablauf ist soweit klar nur eben bei 10 möglichen Artikel (oder Datensätzen) wäre das 10x das gleiche netzwerk mit jeweils einem anderen Arrayindex.

deswegen eben die Idee einen Baustein zu erstellen mit folgenden eigenschaften:
In: Array (oder was sont benötigt wird, Pointer und größe völlig egal)
In: Arrayindex
Out: Artikelnummer (String[10]
Out: z.b. Höhe artikel DINT
Out: z.b. Länge artikel DINT
usw.

ein Array ist immer 50Byte groß , was aus einem UDT besteht und befindet sich in einem einzelnen DB, da die Artikelzahl die zwischengespeichert werden soll noch nicht feststeht (können auch 1000 oder mehr werden)

Also die Daten werden von mir alle erstellt.

Gruß
Tobl
 
So hier mal ein Ansatz, was mir bis jetzt so eingefallen ist.
Der generator sagt mir aber "baustein nicht korrekt" in Zeile 18 (letzte Zeile). Wie schon gesagt ich habe mir SCL noch nix gemacht... also bitte nicht gleich steinigen wegen blöden anfängerfehlern^^

ID = Artikelnummer

Code:
FUNCTION_BLOCK FB116
TITLE   = 'Array_Auswahl'
NAME    : ARRAY_A
VERSION : '0.1'
AUTHOR  : MSE
VAR_INPUT
    Artikel_Array : ARRAY [1..10] OF UDT10;      
    Arrayindex : INT;
END_VAR
VAR_OUTPUT
    ID : STRING;
    Laenge : DINT;
    Pos : DINT;
    vorhanden : BOOL;
END_VAR
BEGIN
ID = Artikel_Array[Arrayindex].ID
Laenge = Artikel_Array[Arrayindex].Laenge
Pos = Artikel_Array[Arrayindex].Pos
IF vorhanden = True THEN 
    Artikel_Array[Arrayindex].vorhanden = true 
    ELSE 
        Artikel_Array[Arrayindex].vorhanden = False
End_IF 
 
END_FUNCTION_BLOCK
 
Du musst jede Zeile mit einem ; abschließen.
Code:
BEGIN
ID = Artikel_Array[Arrayindex].ID[B];[/B]
Laenge = Artikel_Array[Arrayindex].Laenge[B];[/B]
Pos = Artikel_Array[Arrayindex].Pos[B];[/B]
IF vorhanden = True THEN 
    Artikel_Array[Arrayindex].vorhanden = true [B];[/B]
    ELSE 
        Artikel_Array[Arrayindex].vorhanden = False[B];[/B]
End_IF[B];[/B] 
 
END_FUNCTION_BLOCK

Den Rest hab ich jetzt nicht kontrolliert, aber das sollte schon mal ein Fortschritt sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ICh habe es mit ein FC gemacht:

Code:
TYPE Artikel_UDT 
    STRUCT
        Artikel_nummer : STRING[10] ;
        Artikel_hoehe : DINT ;
        Artikel_laenge : DINT ;
    END_STRUCT
END_TYPE
 
TYPE Artikel_Array_UDT 
    STRUCT
        Artikel : ARRAY[1..10] OF Artikel_UDT ;
    END_STRUCT
END_TYPE

FUNCTION Array_daten_holen_FC : VOID
VAR_INPUT
    array_in : Artikel_array_UDT ;
    iArrayindex : INT ;
END_VAR
VAR_OUTPUT
    out_Artikel_nummer : STRING[10] ;
    out_Artikel_hoehe : DINT ;
    out_Artikel_laenge : DINT ;
END_VAR
    out_Artikel_nummer :=  array_in.Artikel[iArrayIndex].Artikel_nummer ;
    out_Artikel_hoehe := array_in.Artikel[iArrayIndex].Artikel_hoehe ;
    out_Artikel_laenge := array_in.Artikel[iArrayIndex].Artikel_laenge ;
END_FUNCTION
 
Hallo Tobi,
ich interpretiere deine Anwendung als Rundschalttisch o.ä.
Etwas ähnliches mache ich auch.
Ich würde für alle Vorgänge den gleichen FB nehmen und ihn die Daten entsprechend seiner äußeren Beschaltung wegpacken lassen.
Also wenn die St.Nummer 1 ist (IN-Parameter) und du das Bit "Daten-Speichern" (IN-Parameter) setzt, dann schreibst du den IN-Parameter Artikelnummer in den richtigen ARRAY-Platz (ggf. 1). Entsprechend verfährst du mit den anderen Stationen.
Falls es wirklich ein Rundschalttisch ist, so könnte der Eingang "Tisch fährt" alle Datensätze vom Index her um 1 nach oben schieben.
Wenn du die Datensätze an irgendeiner Stelle entnimmst (und vielleicht nach irgend wohin weiterleitest), dann wäre das dann auch die Aufgabe der entsprechenden Beschaltung.

Falls dieser Ansatz für dich interessant ist, dann würdest du diesen Baustein in deinem Programm bei jeder Station mit unterschiedlicher Beschaltung (Parametrierung) aufrufen.

Nach Klärung dieser Sachen steht für mich dann erst die Programm-Umsetzung ...

Gruß
LL
 
Nein ist kein Rundschalttisch. eine Artikelverfolgung.
Artikel wird an einer stelle erfasst und zu einem bestimmten Ziel geleitet.
Datenerfassung ist an einer festen Stelle, der Rest wird über einen Drehgeber gemacht. beispiel: Drehgeber = 100 dann den Artikel x an Station 1 auschleusen... Drehgeber = 105 dann artikel y an Station 3 ausschleusen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ICh habe es mit ein FC gemacht:


das sieht schon mal gut aus. Wie ich sehe hast du aber 2 UDT´s erstellt. Ich brauche aber einen UDT und diesen rufe ich dann in einem DB auf mit (wie bei dir im 2. UDT)
Wie kann ich den UDT denn am einfachsten in einen DB ändern?

Gruß
Tobl
 
das sieht schon mal gut aus. Wie ich sehe hast du aber 2 UDT´s erstellt. Ich brauche aber einen UDT und diesen rufe ich dann in einem DB auf mit (wie bei dir im 2. UDT)
Wie kann ich den UDT denn am einfachsten in einen DB ändern?

Gruß
Tobl

Einen DB anlegen, in dem DB eine Variable, dieser Variablen als Typ deine UDT, speichern, fertig.
 
Einen DB anlegen, in dem DB eine Variable, dieser Variablen als Typ deine UDT, speichern, fertig.

Ähm ich glaube ich habe da wohl was nicht so ganz verstanden?!?!

Ich will doch die werte, Strings usw. aus meinem DB einlesen bzw. zurückschreiben.
Wenn ich den UDT abfrage dann ist dadrinnen doch alles leer bzw. die Standartwerte, oder nicht? ich schreibe meine werte doch in den DB und nicht in den UDT.

oder habe ich da jetzt einen denkfehler??
 
Zuviel Werbung?
-> Hier kostenlos registrieren
das sieht schon mal gut aus. Wie ich sehe hast du aber 2 UDT´s erstellt. Ich brauche aber einen UDT und diesen rufe ich dann in einem DB auf mit (wie bei dir im 2. UDT)
Wie kann ich den UDT denn am einfachsten in einen DB ändern?
Nur ein UDT ist klar möglich.
Aber es lohnt sich oft mit ein gewisse aufteilung in 'strukturen'.

Hier ist der SCL code ein bisschen geändert:
Code:
 TYPE Artikel_UDT 
    STRUCT
        nummer : STRING[10] ;
        hoehe : DINT ;
        laenge : DINT ;
    END_STRUCT
END_TYPE
 
TYPE Artikel_Array_UDT 
    STRUCT
        Artikel : ARRAY[1..10] OF Artikel_UDT ;
    END_STRUCT
END_TYPE
 
FUNCTION Array_daten_holen_FC : VOID
VAR_INPUT
    array_in : Artikel_array_UDT ;
    iArrayindex : INT ;
END_VAR
VAR_OUTPUT
    out_Artikel_nummer : STRING[10] ;
    out_Artikel_hoehe : DINT ;
    out_Artikel_laenge : DINT ;
END_VAR
    out_Artikel_nummer :=  array_in.Artikel[iArrayIndex].nummer ;
    out_Artikel_hoehe := array_in.Artikel[iArrayIndex].hoehe ;
    out_Artikel_laenge := array_in.Artikel[iArrayIndex].laenge ;
END_FUNCTION

Hier ein DB mit einzelelement 'active' und array 'stored':
Code:
  STRUCT  
   active : "Artikel_UDT"; 
   stored : "Artikel_Array_UDT"; 
  END_STRUCT ;

edit: Tipfehler

Hier ist ein aufruf von den FC.
Code:
CALL "Array_daten_holen_FC" (
     array_in                 := "MyDB".stored,
     iArrayindex              := MW    10,
     out_Artikel_nummer       := "MyDB".active.nummer,
     out_Artikel_hoehe        := "MyDB".active.hoehe,
     out_Artikel_laenge       := "MyDB".active.laenge);
NOP   0;

Wenn jetzt der 'ur'-UDT Artikel_UDT geändert wird, ändert sich der rest automatisch.
 
Zuletzt bearbeitet:
Die UDT ist praktisch nur ein definierter Datentyp, eine Struckturbeschreibung. Erst, wenn du sie in einen DB einfügst oder in einem FB als Stat-Var deklarierst bekommt sie wirklich "pysikalisch" im Speicher Daten. Wenn an deinem FB eine INOUT als UDT deklariert wird, kannst du außen an die Schnittstelle eine UDT-Variable antragen, die in deinem DB definiert sein muß. Im FB kannst du diese Variable lesen und schreiben und zwar mit der Struktur der UDT. Du kannst natürlich auch an eine IN eine UDT-Variable aus einem DB schreiben zum "nur lesen" und an eine OUT, zum "nur schreiben".
 
Ich will doch die werte, Strings usw. aus meinem DB einlesen bzw. zurückschreiben.
So weit haben wir es nur geschaft die daten aus den DB zu lesen.

Wenn ich den UDT abfrage dann ist dadrinnen doch alles leer bzw. die Standartwerte, oder nicht? ich schreibe meine werte doch in den DB und nicht in den UDT.
Zuerst gibt es nur die initalwerte. Und die sind null wenn nicht anders spezifiziert ist.
 
Zurück
Oben