How can you display a script dataset in a Perspective Table?

I have a script working in the script console that creates a dataset. The Perspective table doesn't seem to have a script binding.

I tried creating a Memory dataset and binding the table to it but I get an error when trying to write to the script dataset to the Memory dataset tag.

[Error_TypeConversion("class com.inductiveautomation.ignition.common.tags.paths.BasicTagPath: Invalid DataType for Dataset.")]

I found some posts saying this may have worked in the past but there are now checks to make sure the dataset matches the default format the Memory dataset expects?

TagPath = "[default]"
tags = system.tag.browse(TagPath, {'tagType': 'Folder', 'recursive': True})
SystemSectorList = []
for tag in tags:
    full_path = tag.get('fullPath', '')
    findLocale = str(system.tag.readBlocking(str(full_path) + ".locale"))
    if "Good" in findLocale:
	    import re
	    # Use a regular expression to extract the first value
	    match ='\[\[([^,]+),', findLocale)
	    if match:
	        locale_Value =
	        SystemSectorList.append([full_path, locale_Value])
	        print("No match found")
print SystemSectorList
SystemSectorHeaders = ['Path ID', 'locale ID']
SystemSector_Dataset = system.dataset.toDataSet(SystemSectorHeaders, SystemSectorList)
print SystemSector_Dataset
system.tag.writeBlocking(["[default]MemoryTags/Tag_locales/locales_dataset"], SystemSector_Dataset)

Bind the dataset code to the "data " property in the perspective table, I have definitely made this work just fine, normally I use it for modifying data coming out of an SQL query using a script transform. So long as the binding returns a dataset, it should display it in the table.

One of these? Use the expression to call a script and return a dataset or did you add a Change Script?

Bit of a hack, but you can use the Expression, and enter now(2000) and the binding will update at 2000ms rate, then just use the script transform under that, and return the dataset. Otherwise you can bind to any item that you want to trigger the dataset script with, and use that with a script transform.

Ok, thanks. I'm using one other script Transform somewhere else. I'll give that a shot.

The Memory Dataset Tag really had me going, like this should be easy and work. It's right in the name. :slight_smile:

Also, just noticed that you are passing a list of one tag path, and a dataset, I believe that you should be sending a list and a list.

system.tag.writeBlocking(["[default]MemoryTags/Tag_locales/locales_dataset"], [SystemSector_Dataset])

1 Like

Bit of a warning, you are calling system.tag.readBlocking on a single tag path inside of a for loop. This is going to give you poor performance. It is much better to do a single call to system.tag.readBlocking after putting together a list of tag paths.

Something like this should work much better:

tagPaths = [tag.get('fullPath', '') for tag in tags]
tagLocales = [
	str(qv.value) for qv in system.tag.readBlocking([
		"{}.locale".format(tagPath) for tagPath in tagPaths

for idx, tagLocale in enumerate(tagLocales):
	if "Good" in tagLocale:
		match ='\[\[([^,]+),', tagLocale)
		if match:
			locale_Value =
			full_path = tagPaths[idx]
			SystemSectorList.append([full_path, locale_Value])

You should also pull import re to outside of the for loop, you only need to import once, before anything else in the script.

Edit: Realized you needed tag paths on their own, put them into a separate list to be retrieved via index


Thanks, I missed that. I had meant to move it up. This is just my cobbled test script.

I had thought about that but there are very few folders. It's filtering for folders first then just checking only them. There are like 15 now and the script will not run that often. But every little bit helps. I’ll see if I can add this in.

This is a bit ugly, better to use:

findLocale = system.tag.readBlocking("{}.locale".format(full_path))[0]
if findLocale.quality.good:

You could also put the script in the library and call it with runScript.

Datasets, themselves, allow just about anything as a column type. But that freedom creates huge problems for Ignition's infrastructure when arbitrary datatypes are stored in tags. So the tag machinery of Ignition checks the columns types of any incoming dataset against a whitelist, and rejects any dataset that doesn't conform.

You have a couple options:

  • convert the troublesome columns to some other datatype (stringification is common, if you don't need the functionality of the object's true type), or

  • store the dataset in memory, typically in a top-level script library variable, and have your uses look for it there. (You might find my globalVarMap() functions in my Integration Toolkit module helpful.)

Thanks, I'm glad I slept on it. My next question was going to be how to perform stringification or define the column types and wasn't the list already strings? Just using the string function on the full_path variable lets the write of the dataset to the memory dataset tag complete successfully.

I'm now trying to make a change based on data in the Table. The cell event script works but I have to hard code the path of the tag I wish to change. I found an example of reading a cells value but I can't get it to work.[0]['Path ID']

When I type it in the auto complete doesn't show a "selection" after "self.props."

It gives me an error: line 7, in runAction KeyError: Path ID

There are just the two columns and when I edit the cell in the second column "locale ID" I take the value just entered "event.value" in the onEditCellCommit script. I just need a way to get the value from the same row in the first column "Path ID".

Looks like some things break if you have a space in the header/column name. After that[0].PathID still was not found until enableRowSelection was set.