TIA DB in Array kopieren und sortieren

Deep Blue

Level-2
Beiträge
443
Reaktionspunkte
17
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich möchte aus einem DB, welcher strukturiert ist, Daten entnehmen und in ein Array kopieren, dort sortieren und wieder zurück in einen anderen DB kopieren.

Z.B. habe ich im DB Rezept 1 - 4. In jedem Rezept gibt es eine Artikelnummer, eine Sollmenge und noch eine Temperatur. Die Datentypen der Daten sind unterschiedlich. Die Art.Nr. ist ein DINT, die Sollmenge ein Int und die Temperatur ein Byte.

Jetzt sollen aber die Rezepte alle nach der Art.Nr. in Reihenfolge aufsteigend sortiert werden um dann in einen anderen DB so wieder abgelegt zu werden.

Meine Idee wäre, die Daten aus dem DB in ein Array zu kopieren, dort zu sortieren und dann wieder in einen anderen DB abzulegen. Nur fehlt mir dazu die Syntax. Vielleicht gibt es ja auch einen anderen Weg?

Für Hilfe wäre ich hier sehr dankbar.
 
Falls Du mit TIA und einer S7-1200/1500 arbeitest: in der Lib LGF gibt es LGF_ShellSort..., vielleicht gefällt Dir der Baustein. Zumindest kannst Du Dir da die SCL-Syntax für Array-Anweisungen anschauen.

Harald
Danke für den Tipp. Schau ich mir ma an. Hatte das vorhin in engl. schon überflogen. Leider müssen wohl die Variablen alle vom gleichen Typ sein.
 
Gibt es in dem Bereich, den Du sortieren willst auch nicht belegte Sätze?
Wenn ja, ...
- woran erkennt man sie (z.B. ArtikelNr=0)?
- wohin sollen sie sortiert werden (z.B. nach hinten, abweichend von "aufwärts nach Grösse sortiert" der ArtikelNr)?
 
Z.B. habe ich im DB Rezept 1 - 4.
Wieviele Datensätze sind es maximal, die da sortiert werden sollen?

Leider müssen wohl die Variablen alle vom gleichen Typ sein.
Willst Du quer über alle Rezepte bzw. Rezept-Typen sortieren? Und die Rezepte sind verschieden aufgebaut, womöglich sogar unterschiedlich groß?
Die "Sortierspalte" z.B. Artikelnummer ist aber in allen Rezepten vom gleichen Typ?! Und für das Umspeichern danach wäre es vermutlich hilfreich, wenn am Anfang der Rezeptur ein Kennungsfeld wäre, wo die Länge oder eine Kennung der Rezeptur drin steht.

Achja: Verrätst Du uns auch, welche SPS und welche TIA-Version Du hast?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Rezept.png


Sorry für die halben Infos. Also es ist TIA 15.1 auf einer 1511-PN.

Ich möchte nun Anhand des Eintrages "Ist_Zeit..." aus Rezept 1 - 5 diese so aufsteigend sortieren, das z.B. Rezept 3 vor 2, vor 5 vor 1 ... angeordnet ist. Das möchte ich dann in einem neuen DB genau so umsortiert ablegen. Die Einträge könnte ich alle auf DINT bringen um Bubblesort zu nutzen bzw. die LFG-Lib zu benutzen. Bei weiterer Verwendung könnte ich ja wieder ein Byte aus dem DINT machen.


Sort.png
 
Leider müssen wohl die Variablen alle vom gleichen Typ sein.
Vermutlich sprichst Du davon, dass in einem Array alle Elemente vom gleichen DatenTyp sein müssen. Daran lässt sich auch nichts ändern.
Dieser einheitliche DatenTyp kann aber ein selbstdefinierter Typ sein, der verschiedene DatenTypen enthält. Das nennt man dann ein Array of Struct.

Deine Tabelle aus dem DB kannst Du in ein solches Array of Struct einlesen/kopieren.
Dieses Array kannst Du sortieren ... musst Du für Deine Anwendung aber gar nicht.
Dir würde es genügen, die einzelnen Sätze der Tabelle in einer wunschgemäss "sortierten Reihenfolge" nacheinander auszulesen und in dieser Reihenfolge in einem anderen DB abzulegen.

Dazu ein weiteres Array anlegen mit DatenTyp des Array-Indexes und identische LowerBound und UpperBound (kleinster verwendedeter Index bis bis grösster verwendeter Index) des Array of Struct. Bei diesem zusätzlichen Array in jedes Element seinen Index schreiben.
Dann die SortierRoutine so schreiben, dass alle Zugriffe auf das Array of Struct indirekt über das zusätzliche Array adressiert werden, also ArrayOfStruct(ArrayHilfsIndex(Index)).
Aus dem Array of Struct wird ausschliesslich gelesen - SchreibZugriffe erfolgen ausschliesslich beim ArrayHilfsIndex, denn nur dieses Array wird sortiert, allerdings abhängig vom Inhalt der Spalte der ArrayOfStruct-Tabelle, die das SortierKriterium (z.B. ArtikelNr) enthält.

Die Einträge könnte ich alle auf DINT bringen um Bubblesort zu nutzen bzw. die LFG-Lib zu benutzen.
Ich glaube, hier liegt ein fürchterliches Missverständnis vor.
Du hast eine Tabelle mit 3 Spalten (ArtikelNr, SollMenge und Temperatur).
Diese Tabelle könntest Du dann zwar in einem zweidimensionalen Array vom Typ DINT abbilden (erste Dimension = Zeile und zweite Dimension = Spalte), aber ich weiss nicht, ob Du Deiner vorgefertigten SortierRoutine diesen Umstand, dass nämlich nur die erste Dimension sortiert werden soll, klar machen kannst. Das Sortieren der zweiten Dimension macht in Deinem Fall sicherlich gar keinen Sinn, denn die ArtikelNr soll ArtikelNr bleiben, die SollMenge soll SollMenge bleiben, u.s.w. ... .
Durch das Packen aller Informationen der Tabelle in ein eindimensionales Array wird das ganze Verfahren viel zu unübersichtlich. Vergiss das bitte ganz schnell wieder!
 
Ich möchte nun Anhand des Eintrages "Ist_Zeit..." aus Rezept 1 - 5 diese so aufsteigend sortieren, das z.B. Rezept 3 vor 2, vor 5 vor 1 ... angeordnet ist. Das möchte ich dann in einem neuen DB genau so umsortiert ablegen.
:unsure: Was ist das jetzt? Eine 4. Spalte in Deiner Tabelle?
Und Du willst jetzt anhand der Einträge in der Spalte IstZeit die Sätze den verschiedenen Rezepten zuordnen? Mutig, mutig. ;)
Wahrscheinlich fehlen mir die Kenntnisse im Umgang mit den Rezepten ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Weil Deine Rezept-Datensätze nicht als Array vorliegen, könnte ein Sortierprogramm nach "Artikelnummer" etwa so aussehen:

Die Rezeptur als Datentyp (UDT) anlegen
Code:
Rezept_t Struct
  Kesselnummer : Byte;
  ...
  Artikelnummer : DInt;

Der Ausgabe-DB sollte die Rezepte als Array of Rezept_t beeinhalten:
Code:
"AusgabeDB"
Static
  Rezept : Array[1..5] OF Rezept_t;

Das Sortierprogramm etwa so:
Code:
VAR_TEMP
  MySortierArray : Array[1..5] OF Dint;
  tempAN : DInt;
  i : Int;

// Artikelnummern in Sortier-Array kopieren
MySortierArray[1] := "MyDB"."Rezept 1".Artikelnummer;
MySortierArray[2] := "MyDB"."Rezept 2".Artikelnummer;
MySortierArray[3] := "MyDB"."Rezept 3".Artikelnummer;
MySortierArray[4] := "MyDB"."Rezept 4".Artikelnummer;
MySortierArray[5] := "MyDB"."Rezept 5".Artikelnummer;

// MySortierArray[] nach aufsteigender Artikelnummer sortieren
LGF_ShellSort_DInt(array:=MySortierArray);

// Rezepte in der sortierten Reihenfolge umkopieren zu "AusgabeDB"
FOR i := 1 TO 5 DO
  tempAN := MySortierArray[i];
  IF tempAN = "MyDB"."Rezept 1".Artikelnummer THEN
    "AusgabeDB".Rezept[i] := "MyDB"."Rezept 1";

  ELSIF tempAN = "MyDB"."Rezept 2".Artikelnummer THEN
    "AusgabeDB".Rezept[i] := "MyDB"."Rezept 2";

  ELSIF tempAN = "MyDB"."Rezept 3".Artikelnummer THEN
    "AusgabeDB".Rezept[i] := "MyDB"."Rezept 3";

  ELSIF tempAN = "MyDB"."Rezept 4".Artikelnummer THEN
    "AusgabeDB".Rezept[i] := "MyDB"."Rezept 4";

  ELSE
    "AusgabeDB".Rezept[i] := "MyDB"."Rezept 5";
  END_IF;
END_FOR;

Falls gleiche Artikelnummern mehrfach vorkommen können, dann mußt Du Dir beim umkopieren merken, welches Rezept kopiert wurde und dieses Rezept nicht nochmal kopieren. Oder ein weiteres Unter-Sortierkriterium verwenden?

Besser als die fertige LGF Sortierfunktion wäre vermutlich eine (selbstgeschriebene) Sortierfunktion, die zwar Artikelnummer vergleicht aber die zugehörigen Rezept/Datensatznummern sortiert speichert.

Tipp: Verwende keine Leerzeichen in Variablennamen, auch wenn TIA sowas zulässt.

Harald
 
Zurück
Oben