New to Ignition. Some help to fix this please. I have this Table Script in which line 13: table_data[i]["qtyKitted"] = current_qty_kitted + 1 , gives the error DatasetUtilities$PyDataSet$PyRow indices must be integers.
Here is the script:
def transform(self, value, quality, timestamp):
table_data = system.dataset.toPyDataSet(value) # Convert dataset
# Current number of parts to pick
cur_val = self.getSibling("NumericQtyPicked").props.value
# Iterate through each row in the table to distribute parts picked to each truck
for i in range(table_data.getRowCount()):
if table_data.getValueAt(i, "itemNo") == self.getSibling("LabPartNumber").props.text:
# Distribute currentValue to qtyKitted not exceeding PEG_QTY
while cur_val > 0 and table_data.getValueAt(i, "qtyKitted") < table_data.getValueAt(i, "PEG_QTY"):
current_qty_kitted = table_data.getValueAt(i, "qtyKitted")
if current_qty_kitted < table_data.getValueAt(i, "PEG_QTY"):
# Update value one at at time
table_data[i]["qtyKitted"] = current_qty_kitted + 1
cur_val -= 1
# Convert back to dataset
value = system.dataset.toDataSet(table_data)
self.view.params.SelectedItems = value
return value
There is a better way to write this script, which will make it more readable, more performant, and not have the error you're seeing.
This was written with only knowledge of the script you provided and so some assumptions were made about the shape of your data.
I have left some comments in it to help explain what's going on a bit.
def transform(self, value, quality, timestamp):
#convert value to a pyDataSet
table_data = system.dataset.toPyDataSet(value)
cur_val = self.getSibling("NumbericQtyPicked").props.value
#this is constant in the loop so no need to retrive it more than once.
lab_part = self.getSibling("LabPartNumber").props.text
#The main advantage of PyDatasets is that they allow you to use them in more pythonic ways
#anytime you write for something in range() there is probably a better way.
#create a variable to hold the qtyKitted
qty_kitted = 0
lab_part_row = 0
#enumerate will return both the actual row data and an iterated integer value.
#This takes advantage of a pydatasets iterable behavior while allowing us to
#also keep track of what row we find the part on.
for i,row in enumerate(table_data):
if row['itmeNo'] == lab_part
#Distribute currentValue to qtyKitted not exceeding PEG_QTY
#There is no need to loop here. What you're really trying to do
#is either setting the qty kitted to the current_val or the "PEG_QTY" if
#the current value is >= "PEG_QTY"
qty_kitted = table_data["qtyKitted"]
peg_qty = table_data["PEG_QTY"]
qty_kitted += cur_val if cur_val < peg_qty else peg_qty
#now that we've found the lab_part there is no need to go further
#save the lab_part_row and exit the loop
lab_part_row = i
break
#create a new dataset from the old one with the qtyKitted updated to the new value
newDataset = system.dataset.toDataset(system.dataset.setValue(value, lab_part_row, "qtyKitted", qtyKitted)
self.view.params.SelectedItems = newDataset
return newDataset
That looks super weird to me.
If that transform is in the binding on SelectedItems, you don't need to assign the dataset to the property, it will get the value returned by the script.
If it's on another property, don't assign it there, make another binding.
Thank you so much for taking the time to dissect your answer. I will optimize my routine and post it later. The internal loop is necessary because it manages sets of parts inside of other sets of parts. Your answer pointed me in the right direction. Thanks again!
I am sure it is weird, as I mentioned I am new to ignition.
This routine controls the current table and a dataset for another table, hence the reason I placed the resulting data both in self.view.params.SelectedItems and the current table. Subsequently both table/dataset are filtered further with distinctive criteria.
Peculiar solution maybe but it works the way I need it. Thank you for your time!
Then bind the view param SelectedItems to the table data. It will make it much easier later if you (or someone who inherits your project) needs to troubleshoot and determine where the data for that parameter comes from.