# Show array of strings

**URL:** <https://forum.inductiveautomation.com/t/show-array-of-strings/103238>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [March 4, 2025, 8:15pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238 "2025-03-04T20:15:06Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![aaaa](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@aaaa](https://forum.inductiveautomation.com/u/aaaa)\
**Post date:** [March 4, 2025, 8:15pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/1 "2025-03-04T20:15:06Z")

</div>

Hi,

I have a ring buffer I'm using as an event logger that I write to in the PLC. It has severity as an int, message, severity and time as strings. I'm wondering what's a good way to show this in vision with conditional color formatting, hiding acknowledged lines, etc. Any ideas?

Thanks!

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 4, 2025, 8:27pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/2 "2025-03-04T20:27:05Z")

</div>

A table? Probably a power table, for more advanced formatting options?

You "just" need to adapt your data into Ignition's dataset format, which basically just requires you to spread the rows into however many columns you need.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2025, 8:52pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/3 "2025-03-04T20:52:18Z")

</div>

If you can avoid using strings, avoid using strings. They are murder on PLC connection optimization.

---

<div class="post-metadata">

**Author:** ![aaaa](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@aaaa](https://forum.inductiveautomation.com/u/aaaa)\
**Post date:** [March 4, 2025, 9:11pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/4 "2025-03-04T21:11:53Z")

</div>

@pturmel Yikes that sounds terrifying. Even for Beckhoff? How bad does a big array of strings make things?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2025, 9:40pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/5 "2025-03-04T21:40:31Z")

</div>

Workload is bytes. Make them few, and organized consecutively in the target PLC. I would use an event sequence for handshaking, with message code and 64-bit long integer timestamp. (Like from Rockwell's Wallclock GSV instruction.) Embed the severity in the message code.

I have zero Beckhoff experience at this time, but if you are using its OPC server, you are adding even more performance-sucking overhead.

---

<div class="post-metadata">

**Author:** ![aaaa](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@aaaa](https://forum.inductiveautomation.com/u/aaaa)\
**Post date:** [March 4, 2025, 11:26pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/6 "2025-03-04T23:26:04Z")

</div>

Is the overhead on the PLC's memory or CPU or what exactly? I'm looking for a way to check the performance and see how badly impacted it is by this buffer on the OPCUA.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2025, 11:27pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/7 "2025-03-04T23:27:43Z")

</div>

Not sure about Beckhoff, but probably PLC CPU. I know that it certainly would be CPU (Class 3 message processing) on a Rockwell PLC.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 12, 2025, 6:04pm UTC](https://forum.inductiveautomation.com/t/show-array-of-strings/103238/9 "2025-03-12T18:04:54Z")

</div>

Ignition doesn't have any native functionality to convert your structure to a table-compatible format. I created an [add-on module](https://forum.inductiveautomation.com/t/automation-professionals-integration-toolkit-module/74934) to help with cases like this, but what you are after isn't simple. (Natively, Ignition expressions cannot perform any iteration.)

I would use a custom property to construct a dataset of the tagpaths you need. Something like this:

```python
unionAll(
	asMap('tagpath', 'str'),
	flatten(
		forEach(
			100,
			forEach(
				asList('eSeverity', 'sMessage', 'sSource', 'sTimestamp'),
				asList( // unionAll needs lists of lists.
					stringFormat(
						'[someProvider]stEvents/stEvents_%d_/%s',
						idx(1),
						it()
					)
				)
			)
		)
	)
)

```

Then I'd use `tags()` to monitor the live values of all of those, and wrap it in grouping to yield four columns. Something like this:

```python
unionAll(
	asMap(
		'tagFolder', 'str',
		'eSeverity', 'I',
		'sMessage', 'str',
		'sSource', 'str',
		'sTimestamp', 'str'
	),
	forEach(
		groupBy( // extract the four leaf tags together as groups
			forceQuality(
				tags({Root Container.eventsTags}), // yields two-column dataset, path and value
				192
			),
			left( // trim off the last name of the path
				it()[0], // path column
				lastIndexOf(it()[0], '/')
			)
		),
		transform(
			lastIndexOf(it()[0], '/'), // grouping key output
			asMap( // unionAll can also take a map with keys==colName
				asPairs(
					asMap('tagFolder', left(it()[0], value())),
					forEach(
						it()[1], // Nested dataset
						substring(it()[0], value()+1), // path from row of nested DS
						it()[1] // value from row of nested DS
					)
				)
			)
		)
	)
)

```

Then you can use my `where()` and/or `orderBy()` functions for additional operations.

(Untested. Tweak to suit.)
