Dataset and loops

Hi all,

I am new to Ignition and scripting and I am stuck again.

I am trying to get the value of one cell and use that value in another cell.

This is what I have:

        
        newDataSet = system.dataset.toPyDataSet(tabStrip.tabData)		
	
	for row in range(newDataSet.getRowCount()):
		#get the value of column 1 of each row.
                value = newDataSet.getValueAt(row, 1)
                #set value of mouseover_text to value.
		system.dataset.setValue(newDataSet, row, 'MOUSEOVER_TEXT', 'value') 
	#convert back to dataset			
	tabStrip.tabData = system.dataset.toDataSet(newDataSet)
	

I don’t get any errors but it just does not change the value of mouseover_text in each row.

What am I missing here?

Thanks, Steven

You have to take and use the return value from system.dataset.setValue(). It doesn’t modify in place, it returns a new dataset with the requested change. Datasets are not intended to be modified in place.

@pturmel,

So how do I do this in a loop?

or are you sayng I cannot do this looping through the dataset? Maybe do it as list?

Thanks, Steven

Datasets are Immutable objects. This means that once they are created they can not be changed. Ignition provides functions that take in a dataset to use as a base, perform an operation, and then return a new dataset with the intended change.

This is one way you can do that in a loop:

#Declare a variable to hold the existing dataset to be modified    
newDataSet = tabStrip.tabData
    
for row in range(newDataSet.rowCount()):
    #get the value of column 1 of each row.
    value = newDataSet.getValueAt(row, 1)
    #set value of mouseover_text to value.
    newDataSet = system.dataset.setValue(newDataSet, row, 'MOUSEOVER_TEXT',value) 
#write the modified dataset back to the data property of the component			
tabStrip.tabData = newDataSet

Notice that I ommited the convertion to a PyDataset, it was really not needed here, in fact I have found that most of the time, it’s just as easy to work with a standard dataset as you invariably end up converting it back from a PyDataset to a Standard Dataset at the end. So its a fairly simple optimization to just remove the two conversions all together.

2 Likes

In case you need more info…
https://docs.inductiveautomation.com/display/DOC/Working+with+Datasets

1 Like

@lrose,

I had to add () behind rowCount but that is exactly what I was trying to do.

So newDataSet gets replaced during each iteration with the new values?

Thanks so much for the help!!

Steven

@jlandwerlen,

Thanks.

oops, post edited to correct that error.

Technically, newDataSet gets replaced during each iteration with a new DataSet that contains the new values at the row and column specified.

It's much easier to to think of it as "editing" a dataset, but it's important that you as the programmer understand what is actually happening.

YES!! I need to understand what is actually happening because that is the way I think.

Thank you for the explanation.

Steven

1 Like

Do note that regenerating a new dataset in every iteration isn’t very efficient. Works fine for small datasets, but is something like O(N³). For anything substantial, use lists of rows and construct the single new dataset at the end. If you need to be careful to preserve column datatypes, use the DatasetBuilder class instead.

2 Likes

I originally wanted to do it as a list because the dataset is built up as list earlier in the script but I could not make it work. I would like to understand what I was doing wrong.

This is where the dataset is being built…

         #Iterate through the tabs and add the format to it.
	for row in pageDataSet:
		dataOut.append(list(row) + format)
	
	# Write the new tabData
	tabStrip.tabData = system.dataset.toDataSet(tabDataHeaders, dataOut)

I though I could do this…

         for row in pageDataSet:
                tabName = list(row)[1]
		dataOut.append(list(row) + format + tabName)
	

The tabName list is not correct and I never could figure it out. I printed to the console and it was printing each letter of some of the collections instead of printing the word itself which made it too long for the row it was going into.

So how do I get just the entry at index 1 in a given row?

Thanks for the help,

Steven

It's this sort of thing that appears to be getting you in trouble. You can't just "add" a list and a string. You can add two lists together, though. Like list(row) + [format]. These are really problems you are having with python, not Ignition itself. A python tutorial might be in order. (Just pick a tutorial for legacy python 2, not python 3.)