# Reading / writing Logix data structure of 500 rows containing an Int and a String column

**URL:** <https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672>\
**Category:** Ignition\
**Created:** [April 29, 2025, 11:18am UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672 "2025-04-29T11:18:43Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 11:18am UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/1 "2025-04-29T11:18:43Z")

</div>

I feel I should know how to approach this but don't!

 ![CELL_RECIPE_DATA](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/4/e47365bebcd1ec359284673f96c93e1274b030f1.png)

The data is in the form,

| Array index | RECORD\_NUM | SKU\_NAME |
| --- | --- | --- |
| 0 | 0 | "Product 1" |
| 1 | 1 | "Product 2" |
| 2 | 2 | "Product 3" |

Since the RECORD\_NUM is the same as the array index, I don't need to read that - so I only need to read the 500 SKU\_NAME entries.

I also only need to read and write the whole array by script (so no direct component bindings to each SKU\_NAME).

Any suggestions for how to do this efficiently?

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 29, 2025, 11:24am UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/2 "2025-04-29T11:24:58Z")

</div>

Is `SKU_NAME` a quasi-string UDT that is defined by your program? Why isn't it a "regular" string?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 11:27am UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/3 "2025-04-29T11:27:28Z")

</div>

You're up very early or very late, Kevin!

I don't know. I can find out tomorrow and will post here.

Thanks.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 29, 2025, 11:28am UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/4 "2025-04-29T11:28:18Z")

</div>

I think whoever programmed this screwed up.

If the two members were named `LEN` and `DATA` the driver would recognize this is a String and reading all of these values would be _much_ more straight forward.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 11:39am UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/5 "2025-04-29T11:39:24Z")

</div>

I don't know if it's relevant, but the data is downloaded to the PLC from a C-More HMI. There might be some quirky requirement on the structure for that reason.

---

<div class="post-metadata">

**Author:** ![MMaynard](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mmaynard/32/3366_2.png) [@MMaynard](https://forum.inductiveautomation.com/u/MMaynard)\
**Post date:** [April 29, 2025, 12:32pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/6 "2025-04-29T12:32:12Z")

</div>

That looks like a pre v21 AB Firmware?  
If the entire array is being read and written to you can just use system.opc.readValues and system.opc.writeValues and it will work to the actual OPC paths, usually the array name gets doubled up and you just put .STRING on the end of the path.

Or get the PLC upgraded to a newer firmware and use the newer ControlLogix driver.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 3:30pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/7 "2025-04-29T15:30:31Z")

</div>

> [@MMaynard](#):
>
> That looks like a pre v21 AB Firmware?

Well spotted. It's V16, I think.  
What's the significance of that? What did Rockwell change in V21?

> If the entire array is being read and written to you can just use system.opc.readValues and system.opc.writeValues and it will work to the actual OPC paths, ...

Oooh, I've never had to use those before. The manual isn't quite clear: can I use that to read from and write to the PLC without having to create 500 Ignition OPC tags per machine? (I'd like this to be true!)

> Or get the PLC upgraded to a newer firmware and use the newer ControlLogix driver.

It's validated medical device manufacturing equipment. 15 minute firmware upgrade + several days of validation and paperwork.  
Or an Ignition script?  
Guess which!

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [April 29, 2025, 3:35pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/8 "2025-04-29T15:35:03Z")

</div>

> [@Transistor](#):
>
> without having to create 500 Ignition OPC tags per machine

Correct, you just feed it the raw opc paths. I normally use list comprehension to build out my paths when I use this in scripted transactions.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 4:49pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/9 "2025-04-29T16:49:35Z")

</div>

What happens if I update `CELL_RECIPE_DATA.CELL_RECIPE_DATA[12].SKU_NAME.STRING` with a longer string? (They vary between four and about ten characters long.)  
Does `SKU_NAME.LEN` get updated by the PLC?  
Are there any traps for the unwary (or ignorant)?

---

<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:** [April 29, 2025, 4:55pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/10 "2025-04-29T16:55:41Z")

</div>

> [@Transistor](#):
>
> Does `SKU_NAME.LEN` get updated by the PLC?

No. For proper automation, those inner structures are supposed to be actual Logix String types. (You can make additional string types that have different max lengths.)

When made properly, the string type will have LEN and DATA members and you would point Ignition at the structure, not the array of bytes.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 5:03pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/11 "2025-04-29T17:03:23Z")

</div>

So how would I write safely to the string using [system.opc.writeValues | Ignition User Manual](https://www.docs.inductiveautomation.com/docs/8.1/appendix/scripting-functions/system-opc/system-opc-writeValues) given the current PLC data structure?

---

<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:** [April 29, 2025, 5:05pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/12 "2025-04-29T17:05:24Z")

</div>

You will have to write the length and the individual bytes of the string in a single call.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [April 29, 2025, 5:08pm UTC](https://forum.inductiveautomation.com/t/reading-writing-logix-data-structure-of-500-rows-containing-an-int-and-a-string-column/105672/13 "2025-04-29T17:08:50Z")

</div>

That I can do.  
Thanks.
