Scripting error on button for table

I have a table in a vision window that is pulling its data from a dataset in a memory tag. The column headers are called A, InterlockedTag, B, StatusForGood, and ColourNum. Column A and B are only there to give the appearance of brackets on either side of some of the InterlockedTag rows. I just added column A and B to the table and it was working properly before but now I am getting an error that says “IndexError: Row 0 doesn’t have the same number of columns as header list.” for the last line. Does anyone know what might be causing this?

#datasetPath = system.tag.write(Root_Container/TagPath/Interlock)
datasetPath = '[default]' + event.source.parent.TagPath + '/Interlock'

# Read the dataset tag. Convert to PyDataSet for easier iteration.
dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath])[0].value)

#Get column names. Coerce it to a list to use the same names in the new dataset.
headers = list(dataIn.getColumnNames())

# Get tag paths as a list
tagList  = dataIn.getColumnAsList(headers.index('InterlockedTag'))

# Read the tags
tagValues = [tag.value for tag in system.tag.readBlocking(tagList)]

# Construct the new dataset.
data = []
for row, actualVal in zip(dataIn, tagValues): 
	data.append([row['InterlockedTag'], row['StatusForGood'], int(row['StatusForGood'] == actualVal)])

# Write back to the original tag	
system.tag.writeBlocking([datasetPath],[system.dataset.toDataSet(headers, data)])

Your data.append() line will have to include dummy entries in each row where the A and B columns are.

1 Like

I thought that might be the problem. Do you know what the syntax for that would look like?

If you don’t need anything in the cells of those columns, something like this:

data.append([None, row['InterlockedTag'], None, row['StatusForGood'], int(row['StatusForGood'] == actualVal)])

I am hoping to put things like just “(” and “)” in them. Only strings.

If it’s a standard Vision table, you can just set the Prefix and Suffix properties in the table customizer:

Sorry I should have added this earlier, I will be using it mainly for brackets but sometimes one cell will have a bracket and the other will not or they will say ‘AND’ or ‘OR’.

Then I’d move up to a ‘Power Table’ and use the configureCell - you can override the text in a particular cell (without changing the underlying dataset) based on whatever condition you want.

I need the colour mapping functionality of the table so I don’t know if a Power Table will work. By placing None or Row as pturmel said, the error goes away but unfortunately it also removes the cell contents or places the cell location in the cell instead. Is there another word that will allow me to define those cells but not override them?

Try:

data.append([row['A'], row['InterlockedTag'], row['B'], row['StatusForGood'], int(row['StatusForGood'] == actualVal)])

There’s no “override”. You are creating a new dataset. Any data you want to keep from the original, you must copy into your new rows.

Does row contain the brackets and other data that you want in columns A and B, but only where they are needed ?
If so, you could just use row.get('A', default) to get the value of A when it exists, and get default when it doesn't exist.

If that's not where A and B values comes from, where do you get them from ?

I tried this and it got rid of my error but now when I press the button, nothing happens and the table does not update. Any idea why this might be the case? I did not change the location of the script (It is under action performed on the button).

Hi Joelle,

Let’s see your entire script, and perhaps a screenshot of the dataset. This a a tad different than what we were discussing before. :wink:

Hi Jordan. This is the full script and empty dataset. I am filling it in in each instance of this datatype.

#datasetPath = system.tag.write(Root_Container/TagPath/Interlock)
datasetPath = '[default]' + event.source.parent.TagPath + '/Interlock'

# Read the dataset tag. Convert to PyDataSet for easier iteration.
dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath])[0].value)

#Get column names. Coerce it to a list to use the same names in the new dataset.
headers = list(dataIn.getColumnNames())

# Get tag paths as a list
tagList  = dataIn.getColumnAsList(headers.index('InterlockedTag'))

# Read the tags
tagValues = [tag.value for tag in system.tag.readBlocking(tagList)]

# Construct the new dataset.
data = []
for row, actualVal in zip(dataIn, tagValues): 
	data.append([row['A'], row['InterlockedTag'], row['B'], row['StatusForGood'], int(row['StatusForGood'] == actualVal)])

# Write back to the original tag	
system.tag.writeBlocking([datasetPath],[system.dataset.toDataSet(headers, data)])

Does your dataset tag update?

Sorry, I am not quite sure what you mean by this. The dataset tag is called Interlock and I am going into each tag to fill it out. For example, placing things like “(” in the first column, “tag1234” in the second, “)” in the third, and true in the fourth. The fifth column updates to 1 if the value of tag1234 matches the value in the fourth column and updates to 0 if it does not.

Here’s what my understanding is:

  • Read a dataset tag called Interlock
  • Get all the tag names from the InterlockedTag column and read their values.
  • Make a new dataset, with everything the came, except for the ColorNum column, where we compare it to the StatusForGood column
  • Write this dataset back to the original Interlock tag.

If all this is happening, then the timstamp property of the tag will update.

That is correct. The issue I am having how that I got the error sorted out is that the button which is meant to run this script is not doing that. If I put in a new tagPath, nothing happens when I press the button…

So, does the timestamp update?

Also, putting some print statements in your script can help you troubleshoot things.

#datasetPath = system.tag.write(Root_Container/TagPath/Interlock)
datasetPath = '[default]' + event.source.parent.TagPath + '/Interlock'
print 'datasetPath : ', datasetPath

# Read the dataset tag. Convert to PyDataSet for easier iteration.
dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath])[0].value)

#Get column names. Coerce it to a list to use the same names in the new dataset.
headers = list(dataIn.getColumnNames())
print 'headers : ', headers

# Get tag paths as a list
tagList  = dataIn.getColumnAsList(headers.index('InterlockedTag'))
print 'length of tagList : ', len(tagList)

# Read the tags
tagValues = [tag.value for tag in system.tag.readBlocking(tagList)]
print 'length of tagValues : ', len(tagValues)

# Construct the new dataset.
data = []
for row, actualVal in zip(dataIn, tagValues):
	newRow = [row['A'], row['InterlockedTag'], row['B'], row['StatusForGood'], int(row['StatusForGood'] == actualVal)]
	print newRow
	data.append(newRow)

# Write back to the original tag	
system.tag.writeBlocking([datasetPath],[system.dataset.toDataSet(headers, data)])

Hi Jordan. I tried this and it looked like my script was working fine. I replaced the table with a new one and that resolved the issue I was having. Thank you for your help! (I’m sure you’ll hear from me again lol)

1 Like