WinCC String von SPS mit Zeilenumbrüchen auf HMI Textfeld oder E/A feld ausgeben

Frozen19

Level-2
Beiträge
66
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ich verwende folgende Hardware:
Sinumerik 840D sl mit einer 317F PLC
und als HMI einen IPC4777 22“ mit Windows 10

Und habe folgendes Problem:
Ich bekomme vom Kunden Level2 über OPC UA eine String[200] Variable beschrieben. In diesen wird eine Kommentar eingetragen. Dieser String soll ich auf der HMI in ein Textfeld oder E/A-Feld (als Ausgabe) darstellen.

Jedoch habe ich Probleme mit Zeilen Umbrüchen ich möchte den Text in z.B.: 4 Zeilen aufteilen zu je 50 Zeichen.

Folgendes habe ich probiert mit ein VB script wozu ich Forum Einträge gefunden habe
Code:
Dim TagInternal
Dim Var1
Dim Var2
Dim Var3
Dim Var4

Dim TagTotal

Set TagInternal =SmartTags("eingabe_text200")

Var1 = Mid (TagInternal,1,10) 'Zeile 1-->TagInternal=Stringname (script intern), 1= beginn im String ab Zeichen 1 in dieser Zeile (Startposition in der Zeichenkette) , 10= 10 Zeichen in Zeile 1
Var2 = Mid (TagInternal,11,10) 'Zeile 2-->TagInternal=Stringname (script intern), 1= beginn im String ab Zeichen 11 in dieser Zeile (Startposition in der Zeichenkette) , 10= 10 Zeichen in Zeile 2
Var3 = Mid (TagInternal,21,10) 'TagInternal=Stringname (script intern), 1=Zeilenposition 3, 10= 10 Zeichen in Zeileposition 1
Var4 = Mid (TagInternal,31,10) 'TagInternal=Stringname (script intern), 1=Zeilenposition 4, 10= 10 Zeichen in Zeileposition 1



TagTotal = Var1 & vbCrLf & Var2 & vbCrLf & Var3 & vbCrLf & Var4 'Zusammensetzen des Strings mit Zeilenumbruch (CrLf=carriage return & Line feed)
SmartTags("ausgabe_text200")= TagTotal'Übergabe an HMI interne Variable welche über ein Textfeld ausgegeben werden kann


'-------Test----------

SmartTags("ausgabe_text_test")="test1"& vbCr & "test2"

Das Funktioniert zwar in ein Textfeld jedoch habe ich den unerwünschten Effekt das Wörter abgeschnitten werden.

Welche möglichkeiten gäbe es noch sowas umzusetzen ohne das Wörter abgeschnitten werden? Z.b.: Den String senden lassen mit Semikolons um in der PLC oder VB script den String sauber aufzuteilen?

Vielen Dank für hilfe im voraus!

BG
Frozen
 
:unsure:
Wenn Du Trennzeichen mitschicken lassen kannst, muss man sich ja automatisch schon bei der Erstellung der Strings Gedanken machen, an welcher Stelle man den String sinnvoll umbrechen kann.

Dann geht das normale Textfeld, dort den String in voller Länge als Parameterfeld einfügen, $L im String wird z.B. als Zeilenumbruch interpretiert und das Textfeld macht je nach Formatierung automatisch den kompletten Rest:

Z.B. zweizeilig:
1639664416740.png

1639664446695.png

oder nur einzeilig:
1639664754237.png

1639664829217.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...
Das Funktioniert zwar in ein Textfeld jedoch habe ich den unerwünschten Effekt das Wörter abgeschnitten werden.

Welche Möglichkeiten gäbe es noch sowas umzusetzen ohne das Wörter abgeschnitten werden? ...
Hab' mal interessehalber auch ein Script gebastelt, das einen String in Zeilen mit je max. x Buchstaben in ganzen Wörtern (außer ein Wort hat schon mehr als x Buchstaben, das bleibt hier dann trotzdem zusammen) aufteilt:
Code:
Function vbSplitStr(ByVal Str, ByVal Mx)
'
'Script:            vbSplitStr
'Version:           1.00
'Author:            hucki
'issue Date:        17.12.2021
'last modified:     17.12.2021
'State:             draft
'
'Function:          split a Str in lines with <= Mx letters of complete words
'                   Teilt einen Str in Zeilen mit <= Mx Buchstaben in ganzen Wörtern
'                
'changes:            .
'


    Const SEP = " "                                                                     ' seperator of words in Str
 
    Dim Word, Line                                                                      ' arrays
    Dim i, j, uB                                                                        ' counter

 
    vbSplitStr = vbNullString                                                           ' init ret val to nothing

    Word = Split(Str, SEP, -1, vbTextCompare)                                           ' split Str to array
 
    uB = UBound(Word)                                                                   ' count of words
    If uB < 0 Then Exit Function                                                        ' no words -> exit
 
    ReDim Line(0)                                                                       ' first line
    Line(0) = Word(0)                                                                   ' add first word to first line
 
    i = 1                                                                               ' init counter to second word
    j = 0                                                                               ' init counter to first line
 
 
    While i <= uB                                                                       ' all next words
        If Len(Trim(Line(j) & SEP & Word(i))) > Mx Then                                 '    line with next word to long?
            j = j + 1                                                                   '       next line
            ReDim Preserve Line(j)                                                      '       add next line to array
        End If
        Line(j) = Trim(Line(j) & SEP & Word(i))                                         '    add word to current line
        i = i + 1                                                                       '    next word
    Wend
 
 
    vbSplitStr = Join(Line, vbLf)                                                       ' join line array with line feeds to ret val


End Function

Verwendung:
1639727862017.png

Beispiel:
1639727887883.png

Ergebnis:
1639727910790.png



PS:
Wenn man zum Wörtertrennen was anderes als ein Leerzeichen verwendet, funktioniert natürlich TRIM nicht mehr wirklich.
Sollte ja aber nicht so oft vorkommen.
 
Zuletzt bearbeitet:
Hallo Hucki

danke für deine Hilfe und die info mit den $L im string. Ich habe das mal auf der Test SPS ausprobiert und es hat funktioniert.

Und danke das Du dir die Zeit nimmst und ein VB script machst, werde das mal am Wochenende ausprobieren.

Zurück auf SPS seite es gibt ja in der TIA Baustein Bibliothek Bausteine für String siehe Bild 1639744799457.png

Demnach könnte man doch (ich programmiere gerne in SCL) mit dem Baustein RIGHT in z.B.: ab Zeichen 30 nach ein Leerzeichen mit dem Baustein FIND suchen lassen und das mit dem Baustein REPLACE durch "$L" ersetzen und von den "$L" wieder nach 30 Zeichen nach ein Leerzeichen suchen...

Jedoch denke ich läuft man gefahr über die String größe mit max 200 Zeichen durch das ersetzen zu überschreiten?
Hier könnte dann den von Level2 empfangen String[200] umpuffern auf eine z.B.: String[254] variable für die anzeige auf der HMI die Lösung sein.
 
Demnach könnte man doch (ich programmiere gerne in SCL) mit dem Baustein RIGHT in z.B.: ab Zeichen 30 nach ein Leerzeichen mit dem Baustein FIND suchen lassen und das mit dem Baustein REPLACE durch "$L" ersetzen und von den "$L" wieder nach 30 Zeichen nach ein Leerzeichen suchen...
Man könnte sicherlich.

Ein Nachteil mit dem $L gegenüber dem HMI-Script ist halt wieder, dass der Zeilenumbruch dann fest im übertragenen String verankert ist.
Wenn man dann den String z.B. auch in verschieden großen Textfeldern (unterschiedliche Buchstabenanzahl) darstellen möchte, muss man den String auch mehrfach in der SPS wandeln.

Daher hatte ich mich nach meinem ersten Post auch für das vbScript als Funktion interessiert.
Neben der mehrfachen Verwendbarkeit der Funktion kann man damit dann auch ein und den selben String der SPS im HMI in verschiedene interne Strings unterschiedlicher Zeilenlänge übertragen.



Davon ab ist das Teilen des Strings in einzelne Worte mit SPLIT so schön einfach.
😁


Jedoch denke ich läuft man gefahr über die String größe mit max 200 Zeichen durch das ersetzen zu überschreiten?
Längenbegrenzung sollte weder in der SPS noch im HMI ein Problem sein, weil nur ein bereits vorhandenes Leerzeichen gegen ein Linefeed-Zeichen ausgetauscht wird (auch $L ist nur ein Zeichen nicht 2).



PS:
Ich denke, $L ist anscheinend auch nur für die Direkteingabe des Strings (z.B. bei Variable steuern) gedacht.
Im Script musste ich statt "$L" auch vbLf verwenden. Ersteres wird nicht in ein Linefeed umgewandelt sondern genau so angezeigt.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
... eine String[200] Variable ...
Jedoch habe ich Probleme mit Zeilen Umbrüchen ich möchte den Text in z.B.: 4 Zeilen aufteilen zu je 50 Zeichen.
... jedoch habe ich den unerwünschten Effekt das Wörter abgeschnitten werden.
Nach welchen Gesichtspunkten möchtest Du denn die 200 Zeichen auf 4 Zeilen zu je 50 Zeichen aufteilen?
Die Vorgaben Deines Beispiels erlauben doch keinen anderen Lösungsweg als den, den Du vorgesehen hast:
abschneiden bzw. besser druchschneiden nach dem 50. 100. und 150.
Sollten dabei zufällig Stellen getroffen werden, an denen man sinnvoll einen ZeilenUmbruch durchführen kann, so hast Du ein RiesenGlück.

Irgendwie müsste man schon Reserve einplanen, z.B. 4 Zeilen à maximal 60 Zeichen oder maximal 5 oder 6 Zeilen a 50 Zeichen.
Eine Garantie für die Machbarkeit ist diese Reserve aber noch nicht. Das hängt sehr von den zu zerhackenden Texten ab.
Also sollte man noch eine zusätzliche Strategie einplanen, wie man die "sperrigen" Begriffe ggfs noch weiter zerkleinern kann.
Vielleicht ist es möglich, ausser an LeerZeichen auch nach einem BindeStrich zu trennen?
Aber nicht alles, was wie ein BindeStrich aussieht, ist auch als BindeStrich gemeint. Z.B. ein "Minus" als Vorzeichen einer Zahl.
Vielleicht enthält der Text häufig Begriffe, in denen BindeStriche als TrennZeichen in (z.B. BestellBezeichnungen oder KommissionsNrn) verwendet werden, die jedoch keinesfalls (oder "möglichst" nicht) getrennt werden sollen.
Eine Möglichkeit wäre auch - sofern "CamelCasing" in den Texten vorkommt - zwischen einem KleinBuchstaben und dem direkt darauf folgenden GrossBuchstaben einen BindeStrich und einen ZeilenUmbruch einzufügen.
Aber auch hier gilt, nicht alles, was wie CamelCasing aussieht, muss auch so gemeint sein. Z.B. "GmbH" zwischen b und H zu trennen wäre keine so gute Idee.

Man kann sich also einiges einfallen lassen, um dem Ziel näher bzw. nahe zu kommen, aber das kann recht schnell in einen hohen Aufwand ausarten.
Einplanen von Reserven, in denen sich die TextSchnipsel tummeln dürfen, ist am einfachsten zu realisieren.
Vielleicht kann man auch den Lieferanten der Texte/Begriffe dazu überreden, bestimmte Regeln einzuhalten (z.B. Vermeidung allzu langer Begriffe).
Schnapp Dir einfach viele Beispiele von typischen, zu zerlegenden Texten/Begriffen und teste mal.
Z.B. wie viele Zeichen pro Zeile wären nötig, um mit 4 Zeilen auszukommen oder wie viele Zeilen wären nötig, um mit 50 Zeichen pro Zeile auszukommen? Mit welchen "HärteFällen" muss man rechnen?
 
Zurück
Oben