Dataset - Looping through - How to get current rowIndex while in loop

I want to loop through a dataset and when I find my if statement is true to get that current rowIndex and then use it to do a system.dataset.setValue().

def runAction(self, event):
	newDataSet = system.dataset.toPyDataSet(self.custom.LowLevelDS)
	ITEMNMBR = self.props.selection.data[0].ITEMNMBR
	sp = event.value
	rowIndex = 0

	for row in newDataSet:		
		if row["ITEMNMBR"] == ITEMNMBR:
			newDataSet = system.dataset.setValue(newDataSet, rowIndex, 'LowLevelSP', sp)
		

	self.custom.LowLevelDS = newDataSet
	
	self.getSibling("Table_3").refreshBinding("props.data")

This is on a table component in perspective and when I edit the cell use an Component event and onEditCellCommit run this script to update a dataset with the new value.

Any help would be greatful.

Use enumerate:

for ndx, row in enumerate(newDataSet):
	if row["ITEMNMBR"] == ITEMNMBR:
		newDataSet = system.dataset.setValue(newDataSet, ndx, 'LowLevelSP', sp)

I'd be very cautious about assigning the modified dataset back to the original dataset you are iterating through. I would recommend breaking from the loop as soon as you have found the row you need to modify.

2 Likes

Thanks ryan this worked great then I added some code to change the row red if was below the LowLevelSP after changing it to a JSON.

def runAction(self, event):
	newDataSet = system.dataset.toPyDataSet(self.custom.LowLevelDS)
	ITEMNMBR = self.props.selection.data[0].ITEMNMBR
	sp = event.value
	rowIndex = 0
	
	
	for ndx, row in enumerate(newDataSet):
		if row["ITEMNMBR"] == ITEMNMBR:
			newDataSet = system.dataset.setValue(newDataSet, ndx, 'LowLevelSP', sp)
	
	
	self.custom.LowLevelDS = newDataSet
	
	self.getSibling("Table_3").refreshBinding("props.data")

def transform(self, value, quality, timestamp):
	pds = system.dataset.toPyDataSet(value)
	columnNames = pds.columnNames
	ret = [
		{
			col: row[col]
			for col in columnNames
		} for row in pds
	]
	
	output = []
	for row in ret:
		newRow = {}
		bgColor = "pink" if row['QTYONHND'] < row['LowLevelSP'] else ""
		weight = "bold" if row['QTYONHND'] < row['LowLevelSP'] else ""
		for col in row:
				if col == "QTYONHND":
						newRow[col] = {"value": row[col], "style":{"background-color":bgColor,"font-weight":weight}}
				else:
						newRow[col] = row[col]
		output.append(newRow)
	return output
1 Like

Doesn't change much, but I'd write this part:

for ndx, row in enumerate(newDataSet):
	if row["ITEMNMBR"] == ITEMNMBR:
		newDataSet = system.dataset.setValue(newDataSet, ndx, 'LowLevelSP', sp)

like this:

row = ds.getColumnAsList(ds.getColumnIndex('ITEMNBR')).index(ITEMNBR)
data = system.dataset.setValue(ds, row, 'LowLevelSP', sp)

That said, if you're gonna end up with json in the end, it might be easier to start with json instead:

headers = ds.columnNames
data = [dict(zip(headers, row)) for row in ds]
row = next(row for row in data if row['ITEMNBR'] == search_term)
row['LowLevelSP'] = sp
def transform(self, value, quality, timestamp):
	for row in value:
		row['QTYONHND'] = {
			'value': row['QTYONHND'],
			'style': {
				'background-color': "pink" if row['QTYONHND'] < row['LowLevelSP'] else "",
				'font-weight': "bold" if row['QTYONHND'] < row['LowLevelSP'] else ""
			}
		}
	return value

Also note that if the table's data prop is bound to custom.LowLevelDS, you don't need to refresh it manually with refreshBinding, it will update automatically when it source data (your custom prop) is updated.

2 Likes