Split 16 digit number into 4 parts and store them in 4 different Tags

Hello everyone,

I have an input composed of 16 digits numbers from a barcode scanner, which will be entered into a Numeric Text Field as one large number. For example, “1234567009000005”.

I need to

  • divide this number into four groups, such as 1234567, 009, 00, 0005.
  • store the groups into four variables

I was wondering if I can do this in Ignition? If yes, is it better to split that large number in Ignition or instead send it to a PLC, split it there, and send 4 tags to Ignition?

Appreciate your kind help.

I think your thinking something like:

v1 = n[:7]
v2 = n[7:10]
v3 = n[10:12]
v4 = n[12:16]

image

1 Like

What do you mean when you say “store the groups into four variables?” Are you trying to save these values to tags? Are you trying to use these values in a script and want to attach them to variable names to use later in your script? Are you trying to push the four number groups into different displays on the same screen?

Depending on which of these you’re wanting you can use expressions or scripting to accomplish this goal.

Expression:
toInt(substring(toStr({source}),0,2)) //Adjust 0,2 to the appropriate values.

Script:

source = 1234567009000005
strSource = str(source)
indes = [
	[0,7],
	[7,10],
	[10,12],
	[12,16]
]
values = []
for i in indes:
	print strSource[i[0]:i[1]]
1 Like

You may not want to use a numeric text field for this purpose - even if the input is all digits, splitting it into 4 pieces implies it’s not actually a number - but treating it as a number in Ignition may bite you down the line. For instance, if your leading set of 7 digits starts with a 0, Ignition will discard it (as not numerically significant) which will either cause an error, or worse, lead to incorrect values for one or more of these substrings.

4 Likes

Since Paul just nerd sniped me. :smirk:

numIn = 4567009000005
textIn = '{:016d}'.format(numIn)

slices = [0,7,10,12,len(textIn)]

for i, j in zip(slices, slices[1:]):
	print textIn[i:j]

Output:

0004567
009
00
0005

EDIT: Agreed, though, that a numeric input may not be your best bet.

3 Likes

Thank you! Appreciate your information.

Thank you very much for your response @zacht and @bpreston and @JordanCClark. I really appreciate it.
The application I am trying to do is getting a 16 digits number from a barcode scanner, split it into 4 values, and query an SQLserver 2017 database base on those 4 digits.
So basically I have to selected a row/rows from that SQL table based on those 4 values (ord no|qty|position|model).

image

Append your values into a list

values = []
for i, j in zip(slices, slices[1:]):
	values.append(int(textin[i,j]))

Then use that list in a system.db.runPrepQuery() to get your rows.

1 Like

Thank you very much @JordanCClark.

I tried to understand your code, but I could not understand the 2nd line of your code.
image

If you put a print textIn after that line, you can see the result.

This takes the number (if you notice, I removed the first three digits) and formats it to a string with leading zeroes to pad it to 16 characters.

1 Like

Perfect! Thank you very much, Jordan. Appreciate it.

Is there any way to select the fourth list highlighted in the picture below [1222753,1,3,1] and select its elements?
For example:
val1=1222753
val2=1
val3=3
val4=1
I am new to Jython but I tried so many things and non of them worked.

You can just index it to get the individual items out.

val1 = values[0]
val2 = values[1]
val3 = values[2]
val4 = values[3]

you can also loop to get each value

for value in values:
    print value
1 Like

Thank you for your response!
I tried this myself but it did not work. I do not understand why this command is not getting the first element of values, even if I change the format to str I still get the error.

I can only get the val1 for values(0):
Other than that if I add 1,2,3 I get the out off range error.

You would need to do it after you have built the list, so outside of the scope of the for loop.

numIn = 1222753001030001
textIn = '{}'.format(numIn)
slices = [0,7,10,12,len(textIn)]
value = []

for i, j in zip(slices,slices[1:]):
    val = int(textIn[i:j])
    values.append(val)

print values[0],values[1],values[2],values[3]
1 Like

It WORKED!!!
Thank you very much! I do REALLY appreciate it :slight_smile:

Just in case someone using Ignition 7.9 that uses an older version of Jython, the .format() method will not work. Below is an alternative that will work on both 7.9 and >v8

numIn = 1222753001030001
# wrong -> textIn = str(numIn)
textIn = '%016d' % numIn 
slices = [0,7,10,12,len(textIn)]
values = []

for i, j in zip(slices,slices[1:]):
	print i,j
	val = int(textIn[i:j])
	values.append(val)

print values[0],values[1],values[2],values[3]
1 Like

Thanks for sharing that! Appreciate it. @dkhayes117

1 Like

Right up until the value form the numeric input is less than 16 digits. Refer to @PGriffith’s post above. :wink:

Using old-style formatting:

numIn = 4567009000005
textIn = '%016d' % numIn
2 Likes