Finding size of table and current row index script

Hello!

I have a table called “Interlock” with three columns. The data is coming from a tag called “Interlock”. I have it set up so that I can pass in a tag path and the table will show the information in the interlock section of that tag. The first column is called “InterlockedTag” and it is a string value which contains the exact tag path of the value I will be comparing the second column with. The second column is called “DesiredStatus” and is a boolean value. Overall, I am trying to take the string value in column “InterlockedTag” and use it to check the value of that tag. I am then trying to get it to check and see if the value is the same as the value in column “DesiredStatus”. I am trying to set the third column “ColourNum” to 1 if they are the same and 0 if they are not.

I need to do this for every row indiviually so I am trying to use a for loop to loop through all the rows. Unfortunatley, the size of the table will be different depending on the initial tag path that has been passed in. I am using a range of (0 - numOfRows) for the for loop to operate and I do not know how to get the current row that the script is on and the maxiumum number of rows in that instance of the table.

Does anyone know how I can get the current row number (as in the position) and the number of rows that appear? I have posted the code I have written so far.

Thank you!

rowNum = 0 #Index of row that the for loop is on. Need to get this value. 0 is placeholder value.
numOfRow = 4 #Number of total rows (this will vary depending on the tagpath). Need to get this value. 4 is placeholder value.

table = event.source.parent.getComponent('Table')
for rowNum in range (0, numOfRow, 1):
	data = event.source.parent.getComponent('Interlock').data
	pathToRead = system.tag.read("InterlockedTags").value.geValueAt(rowNum, 0) #String containing the tag path
	trueStatusCheck = data.getValueAt(rowNum, 1) #Boolean which shows the desired status
	if pathToRead == trueStatusCheck:
		colourNum = 1 #ColourNum is the third column and I would like to make it control the colour of the row in the future.
	else:
		colourNum = 0

I will answer the basic question first, to get the number of rows in a dataset you would call dataset.rowCount().

Now on to the more involved question. What version is this? I will assume 8+.

Overall, the way you’re attempting to do this is probably not the most performant, I’ll get to that later though, because I don’t believe the code as you have supplied it will do the task which you described in your post.

For instance this section:

if pathToRead == trueStatusCheck:
    colourNum = 1
else:
    colourNum = 0

This code will always set colourNum to 0. My understanding is that pathToRead is a string value representing a tag path, and trueStatusCheck is a boolean value, those two will never be equivalent.

The reason this will have, fairly awful performance is because you will be calling a blocking function system.tag.read* multiple times.

Don’t do that. Especially in a component script, you will lock up your client. Instead, build a list of tag paths and read them all at once, the benefits of this become much more obvious as you need to read more tags.

Once you’ve done that you can then loop through the values and verify if they match your expectation or not. Something like this:

def testItlk(dsItlk):
    itlkPaths = []
    itlkExpectedVals = []
    for itlk in range(dsItlk.rowCount()):
        itlkPaths.append(dsItlk.getValueAt(itlk,0))
        itlkExpectedVals.append(dsItlk.getValueAt(itlk,1))

    itlkActualVals = system.tag.readBlocking(itlkPaths)
    
    return [ itlkActualVals[v].value == itlkExpectedVals[v] for v in range(dsItlk.rowCount())]

This function will return a list of boolean values representing the result of the comparison. If you go down this type of route I strongly suggest that you look into running this on a separate thread. It will not be friendly running on the GUI thread.

All of that being said, if I understood more about what you were trying to accomplish there might be a better way to go about it.

Another approach that I have taken when referencing tag values and performing comparisons to be displayed in a tabular format is to crate a template that looks like a single row. You can then configure the template to use indirect referencing and a basic expression for the comparisons. Put this row template into a template repeater and you now have a “table”.

It is dynamic, and passing the tagPath string as a parameter to the row template eliminates the need for scripting.

@lrose
I recently found from @JordanCClark’s post that you can use getColumnAsList to get column data from a table as a list :slight_smile:

From him:

# 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('InterlockedTags'))

(thanks Jordan - post added to my ignition goodies collection :grin:)

1 Like

@nminchin, from the other post on the same topic? :smirk:

LOL oops! I think there are a few of the ‘same’ topic actually. I didn’t realise your reply was for one of them haha, i just snatched it from my collection :sweat_smile:

1 Like