Structured Text String Alterations

painterman

Member
Join Date
Sep 2023
Location
Sulligent, AL
Posts
5
Hello,

I am using studio 5000 pro and am trying to figure out the structured text. Here's my scenario:

An operator scans a barcode, the barcode is processed then the PLC searches an array for that part number. If it finds the number then it will report back the elements in the subtag associated with the number, if it doesn't find the part number it will create a new subtag with the required elements. Well some part nubmers are the exact same the only difference being that some start with a "P" which is no bueno. For example the tag array will have the number 11223344 but the operator scans a barcode that's listed as "P11223344" so it will create a new tag. So far I have over 90 duplicate tags all due to this one letter.

I was hoping there was a way to remove that first letter of the string only if it starts with a "P" I just assumed the best way to do this was structured text, but if there's another way then I would love to know. I have been scratching my head on this for a while now.
 
You can probably do this with about 2 instructions in Ladder. EQU on the first element of the .DATA member of the string tag to see if it's "P" and then a MID (I think) instruction to extract the rest of the value into another location. Or back into itself.
 
Sorry, it took 3 instructions:
RemoveLeadingLetter.PNG
Note that 80 is the ASCII value for the letter "P". You can change the EQU to a LIM if you want it to be able to remove any non-numeric character.
 
In the Scan_PNUM.DATA[0] it shows the letter "P" I have the barcode scanner go ahead and convert the ascii to allen bradley. A question, if i remove 1 from the Scan_PNUM.len would that remove it from the front end or the backend? I don't want an empty space at the start of the string

PS thank you for the advice I didn't even think about setting it up to look at the .DATA[] part of the tag
 
A question, if i remove 1 from the Scan_PNUM.len would that remove it from the front end or the backend? I don't want an empty space at the start of the string
Decreasing .LEN will cut characters off the back end of the string. Increasing it will add characters (blank spaces unless you've been messing with the .DATA[] values).

Use the built-in commands (either DELETE or MID should work fine) and the length will automatically adjust to account for the removed characters.
 
In the Scan_PNUM.DATA[0] it shows the letter "P" I have the barcode scanner go ahead and convert the ascii to allen bradley. A question, if i remove 1 from the Scan_PNUM.len would that remove it from the front end or the backend? I don't want an empty space at the start of the string

PS thank you for the advice I didn't even think about setting it up to look at the .DATA[] part of the tag

The MID instruction suggested by @joseph_e2 has a Start parameter value of 2, so will extract the string data starting at the second character of the string i.e. starting at ScanString.DATA[1] since ScanString.DATA[0] is the first character of the string. The DELETE instruction simply removes the data as specified by the Qty and Start input parameters, and adjusts the string length accordingly.

I suppose this could also be done with the COP instruction:
Code:
EQU ScanString.DATA[0] 80 COP ScanString.Data[1] ScanString[0] 80 SUB ScanString.LEN 1 ScanString.LEN
but using the built-in string handlers is better.

Btw, you might want to add a test for a zero-length string.
 
The MID instruction suggested by @joseph_e2 has a Start parameter value of 2, so will extract the string data starting at the second character of the string i.e. starting at ScanString.DATA[1] since ScanString.DATA[0] is the first character of the string. The DELETE instruction simply removes the data as specified by the Qty and Start input parameters, and adjusts the string length accordingly.

I suppose this could also be done with the COP instruction:
Code:
EQU ScanString.DATA[0] 80 COP ScanString.Data[1] ScanString[0] 80 SUB ScanString.LEN 1 ScanString.LEN
but using the built-in string handlers is better.

Btw, you might want to add a test for a zero-length string.
So if I used the DELETE would it remove .DATA[0] as a whole and shift all the subsequent .DATA[#] value up? making DATA[1] into DATA[0]? I plan on just placing the string back into itself. which also makes me question if the last character of the string would be repeated since the new string is one character shorter than before.

The trigger for the whole event is checking if the string.len is neq to 0.
 
Good call on the DELETE instruction. It is faster and cleaner. I tested the DELETE instruction with a copy of the string, with itself as the destination. The trailing character does remain in the .DATA array but the .LEN is shortened so it only appears if you look at the SINT array directly:
RemoveLeadingLetter2.PNG

Here's the result:
RemoveLeadingLetter3.PNG
Note that .DATA[9] is past the end of the new 9-character string but retains its value of '9' instead of '$00'
 
Good call on the DELETE instruction. It is faster and cleaner. I tested the DELETE instruction with a copy of the string, with itself as the destination. The trailing character does remain in the .DATA array but the .LEN is shortened so it only appears if you look at the SINT array directly:
View attachment 69643

Here's the result:
View attachment 69644
Note that .DATA[9] is past the end of the new 9-character string but retains its value of '9' instead of '$00'
Thats what i thought, but i can just use another delete function to remove the last character based on the original length of the string.
 
Thats what i thought, but i can just use another delete function to remove the last character based on the original length of the string.
You don't have to and in fact that is wrong: once the.LEN is changed to e.g. from 9 to 8, the character "at" the "ninth" position in the string (i.e. at .DATA[8], at offset 8 characters from the first character in the string) is irrelevant, because it is no longer considered part of the string.
 
Last edited:
You don't have to and in fact that is wrong: once the.LEN is changed to e.g. from 9 to 8, the character "at" the "ninth" position in the string (i.e. at .DATA[8], at offset 8 characters from the first character in the string) is irrelevant, because it is no longer considered pay off the strong.
The way the string is used later in the PLC though is called for the Scan_Pnum directly as a string though, so wouldn't it include the last value? Also when the code is searching for the part number it will look for an exact match, would it still match with the extra digit at the end?
 
Hmmm....I just went down the rabbit hole a little. It looks like all of these string manipulation instructions leave a relic behind, including COP. If you start with a longer string and then edit it so it's shorter (using a DELETE or MID instruction), the LEN parameter adjusts but the SINT array retains the original characters past the end of the new string. When viewing online, you only see the "legit" portion of the string unless you expand the .DATA member of the tag. Then you'll see the "extra" characters.

The built in compare instructions (like EQU, etc.) only look at the "legit" characters, but if you're dealing with the SINT array directly somewhere, you may need to clean it up. For instance, we have a Maple systems HMI that doesn't look at the .LEN member at all. It just reads the .DATA member and considers the first '$00' to be the string terminator (like other programming languages do).
 
As long as the compare, whether the simplest built-in EQU comparing two string data types, or some custom compare that loops over the .DATA[] SINT array, uses the .LEN attribute of the SYRING data type, whatever data are in element .DATA[.LEN] and beyond are irrelevant.

Changing the .LEN parameter after it is decremented by 1 via the DELETE instruction is definitely a mistake.

Even if you overwrite the palimpsest last "duplicate" character's value, which is hanging around like a stale f@rt, why would the value you replace it with be any better than the duplicate value it starts with?

No, @joseph_e2 was right at the first: two instructions and any leading 'P' is gone, and the string that remains is the same as if the barcode came in on the serial line without the prefix in the first place.
 

Similar Topics

Hi all, I have a customer that is asking for a recipe of 200 recipes to be sorted. I'm trying to do this by way of a bubble sort. Basically my...
Replies
18
Views
3,544
Hi, For strictly development purposes I would like to save the memory address of a variable as a string (e.g. "16#FFFFFFFF"). Now, specifically...
Replies
5
Views
3,862
Hi, i am trying to compare a string value in an IF statement My string value is user defined string called Barcode_String max characters 26...
Replies
6
Views
7,386
How do I Concatenate an XML String in Structured Text? I am using codesys 2.3 with a Wago 750-852. I would expect the answer to be the same...
Replies
5
Views
4,864
Firs of all I'm working with Structured Text on B&R Automation Studio 4.0: I have a binary message on a string (collected from serial port). The...
Replies
4
Views
8,226
Back
Top Bottom