TIA dynamischer String

BaumimGarten

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

Ich hab mal wieder ne Frage. Ich hab eventuell gerade ein Brett vorm Kopf aber ich sitz jetzt hier schon ein bisschen länger an der Sache.
Der String soll aus mehreren Array "Zellen" bestehen die hintereinander gefügt werden.
Dabei soll der String dynamisch verlängert werden, wenn eine weitere Zelle in das Array eingetragen wird.
Ich habe ein DB Array erstellt wo alle meine Werte die in den String kommen sollen vermerkt werden mit Name und einem zugehörigen Value. Das hab ich schon soweit verkleinert, dass ich auf die das einzelne Teil "Datenbaustein_1"."THIS"[] gekommen bin.
Anstatt das ich mein String Manuel per Hand immer verlängern muss, indem ich dort eine weitere Zeilen mit seinem index, will ich quasi nur eine Zeile im String haben die anhand der länge der beschriebenen Zellen im Array alle Zellen in den String hinzufügt .
Wenn man es so will quasi ein
"IN4 := "Datenbaustein_1"."THIS"[n],"
"IN5:= "Datenbaustein_1"."THIS"[n]"
...
...
und immer so weiter bis die Stelle n erreicht ist, in der kein Name mehr in der Zelle steht.

Ich hoffe man konnte mir einigermaßen folgen und bedanke mich schon mal für eure Beiträge.
 

Anhänge

  • string.PNG
    string.PNG
    16,2 KB · Aufrufe: 26
Das mit die 'Zellen' verstehe ich nicht, aber irgendwie willst du mehrere STRINGs in ein STRING zusammenfügen.
Verwende dafür aus die erweiterte Befehle den CONCAT Befehl.
Ein STRING ist halt einfach eine Reihe von Zeichen. Wenn du dir innerhalb von 255 Zeichen hältst, dann ist es kein Problem.
Wenn es insgesammt mehr als 255 Zeichen wird, dann musst du mit WSTRING arbeiten.

N.B. Wähle doch bessere symbolische Namen anstatt "Datenbaustein_1", und "THIS" !
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich versteh erstmal nur Bahnhof.
Vermutung:
1200- oder 1500-er Siemens-SPS
Du hast eine Variable MeineArrVar vom Typ Array[0...20] of String in einem DB
Dazu eine Variable MeinStr von Typ String.
Wenn in in einer Zelle von MeineArrVar etwas <>'' sehr, soll dann diese Zelle an den Gesamtstring MeinStr angehängt werden.

Hier mal aus dem Kopf ein Anfangsvorschlag:
Du programmierst eine Schleife.
In der Schleife siehst du nach, ob in der Zelle ein Leerstring ('') steht, wenn ja ist die Sache für dich beendet.
Wenn nein, dann String aus Zelle zum Gesamtstring addieren. (Geht auch mit Concat, ist in SCL nicht nötig)

Code:
MeinStr := '';
For i := 0 to 20 do
    IF MeineArrVar[i] = '' then
        Exit;
    else
        MeinStr := MeinStr + MeineArrVar[i];
    end_if;
End_for;

Die Schleife endet, wenn ein Leerstring '' gfunden wird.

Wichtig: In jeder deiner Array Zellen muß der Leerstring '' enthalten sein, wenn du eine Zelle löscht, dann indem du dort einen Leerstring einträgst.
Alle Zellen müssen als Startwert so vorbelegt sein.

MeineArrVar[5] := '';
 
Zuletzt bearbeitet:
Das mit die 'Zellen' verstehe ich nicht, aber irgendwie willst du mehrere STRINGs in ein STRING zusammenfügen.
Verwende dafür aus die erweiterte Befehle den CONCAT Befehl.
Ein STRING ist halt einfach eine Reihe von Zeichen. Wenn du dir innerhalb von 255 Zeichen hältst, dann ist es kein Problem.
Wenn es insgesammt mehr als 255 Zeichen wird, dann musst du mit WSTRING arbeiten.

N.B. Wähle doch bessere symbolische Namen anstatt "Datenbaustein_1", und "THIS" !
ja das weiß ich alles leider schon. Das hab ich ja auch schon im Anhang verwendet.

1500-er Siemens-SPS
stimmt

Ich hab quasi das array (siehe anhang), in dem befinden sich Namen und Werte, die in ein String geschrieben werden sollen.
Ich weiß dass ich jeden dieser Strings mit einem Concat String zusammenfassen kann, müsste aber ja dann jeden einzelnen selber in den Concat String eintragen. Das Ziel ist es ein Concat String dynamisch zumachen, so dass jede Stelle im Array die einen Eintrag hat (also alle AUßER den Defaultwert von ',"":+0.0000000000E+0') automatisch an den Concat String hinten angefügt wird.
Im Endeffekt soll der zusammengesetzte String bei einem neuen Eintrag in das Array erweitert werden.

Mit einer Indexzahl, kann ich zwar jede "Zelle" (für mich eine einzelne Zeile im Array z.b. Datenbaustein_1[0]) einfügen und durch das Hochzählen des Index diese eingefügte Arrayzeile ändern, allerdings hab ich, wenn ich nur einen Datenbaustein_1[#index] einfüge, auch nur eine Zeile aus dem Array.
 

Anhänge

  • array.PNG
    array.PNG
    50,7 KB · Aufrufe: 26
Code:
MeinStr := '';
For i := 0 to 25 do
    IF MeineArrVar[i] <> ',"":+0.0000000000E+0' then
        MeinStr := MeinStr + MeineArrVar[i];
    end_if;
End_for;

In etwa so vieleicht.
Aussagekräftige Variablennamen wären noch gut.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dein "leeres" Array enthält vermutlich folgende "Formatierung" als Vorbesetzung (statt der Hochkommata ' habe ich mal > und < verwendet - diese Zeichen sind in den Strings NICHT enthalten, sondern begrenzen die Strings nur "optisch", um sie hier darstellen zu können):

x[0] := >"":+0.0000000000000E+0<
x[1] := >,"":+0.0000000000000E+0<
...
x[25]:= >,"":+0.0000000000000E+0<

Ab Index 1 beginnen die Strings mit einem Komma, bei Index 0 fehlt dieses Komma.
Als Trennzeichen zwischen Name und Wert wird grundsätzlich ein : verwendet.

Sooo, nun werden Daten angeliefert, Namen und (zugehörige!?) Werte.
Deine EinsortierRoutine soll sich nun selbst den ersten freien Platz im Array suchen, das noch keinen Namen enthält bzw. noch keinen Wert (ungleich +0.0000000000000E+0) und diesen Platz automatisch mit der neuen Information belegen.

Woher weiss die Routine, welcher Wert zu welchem Namen gehört?
Der erste Wert, der angeliefert wird, gehört zum ersten angelieferten Namen, der zweite Wert zum zweiten Namen u.s.w.?

Woher weiss die Routine, ob noch kein Name eingetragen ist?
Sie guckt, an welcher Position der DoppelPunkt steht. Ist die Position bei Index 0 > 3 oder sonst > 4, dann ist bereits ein Name eingetragen und sie muss weitersuchen.
Ansonsten fügt sie zwischen der DoppelpunktPosition - 2 und DoppelpunktPosition - 1 den angelieferten Namen ein.

Woher weiss die Routine, ob noch kein Wert eingetragen ist?
Sie guckt, an welcher Position der DoppelPunkt steht und vergleicht, ob auf den Doppelpunkt die Zeichenfolge +0.0000000000000E+0 folgt.
Ist dies nicht der Fall, muss sie weitersuchen.
Ist dies der Fall, so übernimmt sie die ersten n Zeichen aus dem Array (n ist die DoppelpunktPosition) und hängt den angelieferten Wert an.
Allerdings muss sich die Routine darauf verlassen können, dass garantiert nie +0.0000000000000E+0 als einzutragender Werte angeliefert wird.

Position eines gesuchten Zeichens in einem String ermitteln: FIND.
Zeichen ab Position n übernehmen: MID bzw. LEN und RIGHT
Linke n Zeichen (ab StringAnfang) liefern: LEFT.

Ob dieser Beitrag off topic ist oder nicht? Keine Ahnung. Habe die Aufgabenstellung nicht verstanden.

PS:
In VBA würde ich das Suchen mit INSTR und ggfs das Austauschen mit REPLACE machen:
IF instr( x, """""" ) then x = Replace( x, """""", name )
bzw.
IF instr( x, "+0.0000000000000E+0" ) then x = Replace( x, "+0.0000000000000E+0", wert )
 
Zuletzt bearbeitet:
Code:
MeinStr := '';
For i := 0 to 25 do
    IF MeineArrVar[i] <> ',"":+0.0000000000E+0' then
        MeinStr := MeinStr + MeineArrVar[i];
    end_if;
End_for;

In etwa so vieleicht.
Aussagekräftige Variablennamen wären noch gut.

Auf die Variante bin ich schon gekommen, aber korrigier mich wenn ich da falsch liege, aber würde dann nicht in dem letzten vollendeten String nicht nur ein Wert stehen, der sich bei jedem Zyklus ändert ?
Bzw. hätte jeder Wert dann nicht einen anderen Zeitstemepel?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Woher weiss die Routine, welcher Wert zu welchem Namen gehört?
Der erste Wert, der angeliefert wird, gehört zum ersten angelieferten Namen, der zweite Wert zum zweiten Namen u.s.w.?

Quasi. Ich hab schon vorab ein Array aus einem vorgefertigten UDT, indem er seinen Messdatenwert (bzw. den Eingang an der SPS angibt) und dazu diesen mit einem Namen beschriftet etc. Diese werden dann vom Programm in ein Concat String vorab zusammengefügt und dann nochmal in ein Array gepackt um eine übersichtliche Darstellung für den String bestehend aus allen Messdaten zubewerkstelligen. Dadurch komme ich auch auf String aus dem "Datenbaustein1_[0]". Das Kommata die ab [1] vor dem "eigentlichen" String stehen werden benötigt, um den String als JSON zuschicken.

Position eines gesuchten Zeichens in einem String ermitteln: FIND.
Zeichen ab Position n übernehmen: MID bzw. LEN und RIGHT
Linke n Zeichen (ab StringAnfang) liefern: LEFT

Das genauso wie das PS hab ich noch nicht genau verstanden. magst du mir das eventuell nochmal erläutern?
 
Wo hast Du denn in Deinem dynamischen string den Platz für einen (oder mehrere) ZeitStempel vorgesehen?
Die Aufgabenstellung wird für meine Glaskugel immer undurchsichtiger statt klarer. :confused:

Ich hab in meinem ersten Beitrag ein Beispiel angegeben
Ich will ja ein zusammenhängenden Datensatz aus
-Zeitstempel
-Values:
-Messwertname + Messwert
-Messwertname2 + Messwert2

So das ich quasi am Ende eine String habe der als JSON so aus sehen sollte

"{"ts":1451649600512, "values":{"Sinuswert":"-8.1919115781E-1, "Seagezahnwert":"+3.0000000000E+0"}}

(Das Beispiel ist jetzt direkt auch schon auf meine Beispielmesswerte bezogen die ich simuliert habe)
"Sinuswert":"-8.1919115781E-1 wäre in dem Fall mein erster Datensatzwert und "Seagezahnwert":"+3.0000000000E+0" mein zweiter.
 
Auf die Variante bin ich schon gekommen, aber korrigier mich wenn ich da falsch liege, aber würde dann nicht in dem letzten vollendeten String nicht nur ein Wert stehen, der sich bei jedem Zyklus ändert ?
Bzw. hätte jeder Wert dann nicht einen anderen Zeitstemepel?
Der Gesamt-String wird immer wieder neu erzeugt und enthält Alle Werte ungleich ',"":+0.0000000000E+0', die in deinem Array stehen.
Du kannst auch 'Oma' als Wert eintragen, das steht dann auch im String.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Gesamt-String wird immer wieder neu erzeugt und enthält Alle Werte ungleich ',"":+0.0000000000E+0', die in deinem Array stehen.
Du kannst auch 'Oma' als Wert eintragen, das steht dann auch im String.
Okay ich werde den mal schnell austesten danke dir

Ich habs gerade ausprobiert und ja er hängt alle Datensätze die ich will hinten mit an, aber hängt dann noch ein weiteren >,"":+0.0000000000E+0< hinten an, da ja der Index zum prüfen einen zu weit springt.
Und wenn ich den index in der anweisung -1 nehme komme ich in ein Fehler soweit ich weiß

Hab das jetzt mit einem Exit gelöst
also

[MeinStrg:= '';
FOR #i := 0 TO 25 DO
IF MeinArray[#i] <> ' ' THEN
MeinStrg := CONCAT_STRING(IN1 := MeinStrg, IN2 := "Datenbaustein_1"."THIS"[#i]);
ELSE EXIT;

END_IF;
END_FOR;]
 
Zuletzt bearbeitet:
Das genauso wie das PS hab ich noch nicht genau verstanden. magst du mir das eventuell nochmal erläutern?
Zu "PS": Das darfst Du getrost ignorieren, wenn Du die Sprache VBA nicht kennst.

Zu "FIND, LEFT, MID, RIGHT und LEN":
Das sind die S7-SCL-Standard-Funktionen die Du benötigst, um
- in einem String ein Zeichen oder eine Zeichenkette zu finden
- Teile eines Strings zu übernehmen
- die Länge eines Strings zu ermitteln
Also die Funktionen, mit denen Du eine Zeile Deines Arrays darauf prüfen kannst, ob bereits eine Name bzw. ein Wert eingetragen ist und mit denen Du dann die "fehlende" Information anstelle der Vorbesetzung in die ArrayZeile eintragen kannst.
 
Zurück
Oben