TIA Rezept Laden mit Rezeptname

Andre1977

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

ich habe eine neue Herausforderung, und suche eine elegante Lösung.
Beim durchstreife des Internets, verhasple ich mich wohl gerade.

Geben:
TIA V19
Habe ein Globalen DB angelegt mit Optimierten Bausteinzugriff.
In diesem DB sind Rezept Daten hinterlegt, mit dem Datentyp Array 0...x of Rezept.
Rezept ist ein Datentyp; hier habe ich ein Wert Rezeptname mit den Datentyp String.

Gesucht:
Ich möchte die Array's durchsuchen nach dem Rezeptnamen.
Wenn Rezeptname gefunden, dann brauche ich die Array Nummer.
Wenn Rezeptname nicht gefunden, dann eine Fehlermeldung.

Noch nie hatte ich eine Anwendung, wo ich den DB nach werten suchen musste.
Deshalb tue ich mich gerade etwas schwer damit eine Lösung zu finden.

Gibt es ein PDF, wie man im DB Daten bzw. Werte sucht?

Gruß André
 
Eine For-Schleife, die das Array mit der Int-Variable I durchitteriert und den String "Rezeptname" mit dem zu suchenden String vergleicht.
Wenn der String gefunden wird, die Itteriervariable I auf eine Variable "Rezept-Number" schreiben. "Rezept-Number" wird vor Start der For-Schleife einmal auf 0 initialisiert. Wird nichts gefunden, ist "Rezept-Number" hinter der For-Schleife 0, ansonsten steht die Nummer des Array-Element, das den String beinhaltet, darin.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ralle,

danke für deine schnelle Antwort, wenn ich dich richtig verstanden habe, ist die einefachste Lösung mit SCL in eine FOR Schleife die Arrays abzufragen.

Ich tüfftel gerade daran.
 
Wenn das Rezept gefunden wurde, kann man die for schleife auch mit exit vorzeitig verlassen.
Die Frage die ich mir stelle, wie verhindert du doppelte Einträge?
 
Hallo Mrtain,
die gleichen gedanken habe ich mir auch schon gemachrt.
Vor ab, ich behersche noch kein SCL, aber ich gebe mir Mühe.

Ich denke Ralle hat mir eine gute Marschrichtung gegeben.

Gestern habe ich getüfftelt.
Stand: ich kann mit der For Schleife die Einträge zählen.
Um doppelte Einträge zu vermeiden, werde ich zwei Forschleifen verwenden.
Die erste Schleife schaut ob der Eintrag 1 oder 0 mal vorhanden ist und wenn >1 dann Fehler.
Mit der zweiten Schleife werde ich den Eintrag (Produktname) suchen.
Ich hoffe, das ich ein weg finde, das ich aus der Schleife raus springen kann, um dann den Index vom Array abzufragen.
Da muss ich aber noch tüffteln.

Ich habe noch eine verständniss Frage:
Beim Start einer For-Schleife, immer mit einer Flanken?

Wie macht Ihr den Flanken Merker in SCL
Im Internet habe ich dies gefunden
1. Lösung funktioniert bei mir nicht:
SCL-CODE:
#"Starten 1 FP" := #Start AND #"Starten 2 FP";
#"Starten 2 FP" := #Start;

2. Lösung funktioniert:
#R_TRIG(CLK:=#Start,
Q=> #"Starten 1 FP");

Ich denke, das es der richitige Ansatz ist eine For-Schleife mit einer Flanke zu starten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Mrtain,
die gleichen gedanken habe ich mir auch schon gemachrt.
Vor ab, ich behersche noch kein SCL, aber ich gebe mir Mühe.

Ich denke Ralle hat mir eine gute Marschrichtung gegeben.

Gestern habe ich getüfftelt.
Stand: ich kann mit der For Schleife die Einträge zählen.
Um doppelte Einträge zu vermeiden, werde ich zwei Forschleifen verwenden.
Die erste Schleife schaut ob der Eintrag 1 oder 0 mal vorhanden ist und wenn >1 dann Fehler.
Mit der zweiten Schleife werde ich den Eintrag (Produktname) suchen.
Ich hoffe, das ich ein weg finde, das ich aus der Schleife raus springen kann, um dann den Index vom Array abzufragen.
Da muss ich aber noch tüffteln.

Ich habe noch eine verständniss Frage:
Beim Start einer For-Schleife, immer mit einer Flanken?

Wie macht Ihr den Flanken Merker in SCL
Im Internet habe ich dies gefunden
1. Lösung funktioniert bei mir nicht:
SCL-CODE:
#"Starten 1 FP" := #Start AND #"Starten 2 FP";
#"Starten 2 FP" := #Start;

2. Lösung funktioniert:
#R_TRIG(CLK:=#Start,
Q=> #"Starten 1 FP");

Ich denke, das es der richitige Ansatz ist eine For-Schleife mit einer Flanke zu starten.
#"Starten 1 FP" := #Start AND NOT #"Starten 2 FP";
#"Starten 2 FP" := #Start;
 
Ich hoffe, das ich ein weg finde, das ich aus der Schleife raus springen kann, um dann den Index vom Array abzufragen.
Code:
FOR #i := 0 TO 100 DO
   
    // Wenn du in der Schleife deinen String gefunden hast, speicherst du dir
    // einfach deinen aktuellen Index und kannst ihn dann hinterher verwenden
    IF stringFound THEN
        actualIndex := #i;
        EXIT;
    END_IF;
   
END_FOR;

Ich würde das Array allerdings einmal komplett durchlaufen.
Dann speicherst du dir immer den Index an der Stelle wo der passende String lag.
Zusätzlich zählst du, wie oft der String gefunden wurde.
Nach dem Durchlauf schaust du einfach den Wert des Zählers an und kannst entscheiden ob der Wert gültig ist.

2. Lösung funktioniert:
#R_TRIG(CLK:=#Start,
Q=> #"Starten 1 FP");
So kannst du das machen.
 
1. Lösung funktioniert bei mir nicht:
SCL-CODE:
#"Starten 1 FP" := #Start AND #"Starten 2 FP";
#"Starten 2 FP" := #Start;
Code:
#"Starten 1 FP" := #Start AND NOT #"Starten 2 FP";
#"Starten 2 FP" := #Start;
außerdem darf #"Starten 2 FP" nicht in TEMP liegen, weil da können sich Variablen nichts bis zum nächsten Baustein-Durchlauf merken.

Und ein Hinweis: gewöhne Dir gleich wieder ab, Leerzeichen in Variablennamen zu verwenden. Das geht so nur bei Siemens und da auch nicht überall. Bei "internationalen" Programmiersprachen gibt es sowas nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
FOR #i := 0 TO 100 DO
   
    // Wenn du in der Schleife deinen String gefunden hast, speicherst du dir
    // einfach deinen aktuellen Index und kannst ihn dann hinterher verwenden
    IF stringFound THEN
        actualIndex := #i;
        EXIT;
    END_IF;
   
END_FOR;

Ich würde das Array allerdings einmal komplett durchlaufen.
Dann speicherst du dir immer den Index an der Stelle wo der passende String lag.
Zusätzlich zählst du, wie oft der String gefunden wurde.
Nach dem Durchlauf schaust du einfach den Wert des Zählers an und kannst entscheiden ob der Wert gültig ist.


So kannst du das machen.

Ich persönlich würde es etwas anders handhaben: wenn ich über ein HMI das Rezept anlege oder ein bestehendes ändere, würde ich beim betätigen des Speicher Buttons kriegen Rezepte durchlaufen. Natürlich muss bei einer Änderung eines bestehenden Rezeptes der entsprechende Index ignoriert werden
 
Hallo
ich Zähle die Werte wie häufig die vor kommen.
Dann Speicher ich mir in einem "ARRAY_INDEX[1..10] of INT" wo die Werte vorkommen.
Das funktioniert auch soweit.
Beim Start der Suche setze ich die Werte auf "0" mit dieser SCL Anweisung:
IF #"Starten 1 FP" THEN
#Stückzahl := 0;
#"Array Index"[1] := 0;
#"Array Index"[2] := 0;
#"Array Index"[3] := 0;
#"Array Index"[4] := 0;
#"Array Index"[5] := 0;
#"Array Index"[6] := 0;
#"Array Index"[7] := 0;
#"Array Index"[8] := 0;
#"Array Index"[9] := 0;
#"Array Index"[10] := 0;
#Fehler_1 := 0;
Gibt es eine elegantere Lösung, so das man nur eine Programm Zeile hat?
Vieleicht #"Array Index"[x] := 0;?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Könnte man so lösen:

FOR tmpInt := 0 TO 10 DO
"Array Index"[tmpInt] := 0;
END_FOR
Habe ich tatsächlich auch schon Probiert, hat aber nicht funktioniert bei mir.
Probiere es noch mal, vieleicht hatte ich auch ein Tippfehler.

Mein SCL Program mache ich im FB zur Zeit und Arbeit mit "Static" Variablen.
Und einen Globalen DB Frage ich zur Zeit ab mit Array[1..10] of String.
 
Zur verhinderung doppelter Einträge müsste man vor dam Ablegen des Rezepts pürfen ob der Name schon vergeben wurde, falls schon vorhanden dann entsprechende Meldung mit Aufforderung den Namen zu ändern!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Schnell mit dem Handy getippt und ungetestet.
Das überprüfen beim Speichern des rezeptes wäre wesentlich einfacher....

Code:
xDounleEntryPresent := false:
for i := 0 to 10 by 1 do
  TmpID := RecipeArray[i].ID;
  CountArray[i] := 0;
  for a := 0 to 10 by 1 do
       If 
          (i <> a) 
          and (TmpID = RecipeArray[i].ID)
       then
           CountArray[i] += 1;
           xDounleEntryPresent := True;
       End_if;
   end_for;
end_for;
 
Zuletzt bearbeitet:
Hallo,

ich habe gute fortschritte gemacht, zur Zeit geht es mir um eine elgante Lösung, um die Einträger zu löschen in einem Arry 1-10 of INT, wo ich mir merke in welchem Rezept INDEX die Doppelten werte vor kommen.
MIt einer Positiven Flanke Starte ich das Löschen der Werte:
IF #"Starten_1_FP" THEN
#Stückzahl := 0;
#"Array_Index"[1] := 0;
#"Array_Index"[2] := 0;
#"Array_Index"[3] := 0;
#"Array_Index"[4] := 0;
#"Array_Index"[5] := 0;
#"Array_Index"[6] := 0;
#"Array_Index"[7] := 0;
#"Array_Index"[8] := 0;
#"Array_Index"[9] := 0;
#"Array_Index"[10] := 0;
#Fehler_1 := 0;
Dann kommt die Schleife mit der Abfrage, was bis jetzt Funktioniert so wie ich es will.
Ich dachte das es vieleicht eleganter geht.
z.B. #"Array_Index"[x] := 0;
Das ich für "x" was einsetzen kann, das die Index 1-10 auf einmal gelöscht wird.
Herr BastiM, hat mir ein Lösungsvorschlag gemacht. diesen gedanken hatte ich aber auch schon.
Hat bei mir nicht funktioniert in Zeile 36, wrum ist mir gerade beim schreiben klar geworden warum Zeile 36 nicht funktioniert.

1746602542692.png
 
Nochmal, diesen ganzen heck meck könntes du sehr elegant und nachvollziehbar lösen, indem du beim anlegen des Rezeptes das array durchsuchst, und erst dann speicherst, wenn die ID eindeutig ist.
Desweiteren solltest du überlegen, ob ein string wirklich die geeignete Möglichkeit ist, ein Tezept eindeutig u identifizieren.
 
Zurück
Oben