Best way to dynamically create a 'header' row for conversion to csv file using UDT tag name

I have created a csv file from a tag history query but want to change the header row. I was thinking I could not show the header when converting to csv file using system.dataset.toCSV and then insert a custom row in the dataset before I convert to a csv.

I want to dynamically read in 'DeviceName' from each UDT instance, then add an element for datetime by using system.dataset.addRow command,

I am able to create a list of tagpaths for the device names I want to read in. How would I go about reading in the values of each item in the list so its in a dataset vs with a pywrapper?

Here is what I have in the script console and its basically what I want but how would I go about adding an element in the beginning of the list that says Date?

Is there an easier way to do this by altering the column headers somehow without having to create/edit a header row?

Here is my functioning code which gives me what I want except I want to replace/rename the header row values in the csv file

def create_analogin():
	#get tag paths
	
	
	#dynamically create list of analog input tag paths including filter to only look at UDT instance tags
	path = '[PLC]AnalogInputs'
	fltr = {'tagType': "UdtInstance"}
	tags = system.tag.browse(path,fltr)
	tagPaths = [str(tag['fullPath']) + "/InputValue" for tag in tags]
	
	endTime = system.date.now()
	startTime = system.date.addHours(endTime,-24)
	
	AIdataset = system.tag.queryTagHistory(paths=tagPaths, startDate=startTime,
		endDate=endTime, returnSize=-1, aggregationMode="LastValue", returnFormat='Wide')
	
	AInInfoTag = '[PLC]AnalogInputCSV'
	system.tag.writeBlocking(AInInfoTag, AIdataset)
	
	csv = system.dataset.toCSV(dataset = AIdataset, showHeaders = True)
	
	filePath = "C:\\DailyCSVFiles\\analogin.csv"
	system.file.writeFile(filePath, csv)

This is what I am getting for the csv file. I want to replace the top row with different data

1 Like

Probably the simplest way is to use the columnNames parameter of the system.tag.queryTagHistory function. You can pass a list of strings that will replace the default headers in the returning dataset.

3 Likes

There's something slightly wrong with this code.
You're doing the same loop twice, once with a for loop, and once inside it with a list comprehension.
You can just remove line 9 and have the exact same result.
If you want to add an item to that list, it's easy, just use +:

headers = ['date'] + [h.value for h in system.tag.readBlocking(hTagPaths)]

Note that I changed system.tag.readAll to system.tag.readBlocking, which is the newer version.

He'll still need to obtain the strings, which I believe is what he was asking.
But your method is much simpler than adding the headers manually to the csv.

2 Likes

Unless I'm misunderstanding something, the list of strings is obtained with the piece of code that you fixed:

headers = ['date'] + [h.value for h in system.tag.readBlocking(hTagPaths)]

All that has to be done is pass headers to the columnNames parameter.

1 Like

No misunderstanding here, we were both answering two different things: I answered the title of the thread, and you answered the content of the post.

1 Like

Thanks! I did implement your suggestions and did get what I wanted as a result. Now when I try to convert this to a csv file I get the following error. It doesn't make sense to me though considering both rows 1 and 2 have three columns each?

system.dataset.toDataSet() expects that the data is a List of Lists. You are only providing a list.

dataset = system.dataset.toDataSet(headers, [totalizers])

This will work for the script you have in the image, but in reality you will probably need to produce a list of lists, where each row is represented by a list of columns.

P.S. It is really dificult to help with scripts when they are posted as screen shots. Please use the pre-formatted text option </>.

1 Like

They don't.
Your header is a 3 items list. And so is totalizer.

But totalizer's first row, on the other hand...

You need to make it a list of lists. Just surround it in brackets and you'll be fine.

1 Like

Ah, thanks! I see.

Thanks!