01-25-2013 09:33 PM
Sounds like a simple question, right?
Apparently not.
LV 2010
I have a huge data structure, stored in DataLog files (thousands of them).
I want to convert this structure to Name/Value pairs ("Operator_Name", "Joe Smith"), for use in a TDMS file.
The structure is a cluster, with various clusters inside that, and inside those are DBLs, strings, BOOLs, other clusters, arrays, you name it.
My strategy is to obtain the CONTROLS[ ] property of the outermost cluster and call this VI.
The VI processes each control, decoding what type it is and handling it accordingly.
It works fine for STRINGs, NUMERICs, ENUMs, BOOLEANs, COMBOBOXes, TIMESTAMPS, and CLUSTERs.
For those simple ones, I use the LABEL.TEXT as the NAME and get the value (based on what type it is) as the VALUE.
For a CLUSTER, I get the CONTROLS[ ] array of the cluster and call myself recursively, to handle all the elements within the sub-cluster.
That all works fine.
But to handle an ARRAY, I'm stumped.
Attached is the code showing the case for an ARRAY.
What I'm doing is getting the CLASS NAME of the current control.
I LEGALIZE the label name (turn spaces into underscores, and maybe other special handling later).
For an ARRAY, I cast the generic CTL reference into an ARRAY reference, and get its VALUE.
I want to loop over each element of the array, and modify the name by the index number, and process each element.
There are arrays of STRINGS, arrays of DBLs, arrays of CLUSTERs - all types.
The question is - how many array elements are there?
The constant "10" in this diagram is a dummy - just there to see if it works.
it does work, except that I get 10 sets of answers, whether the real array has 2 or 20 elements.
I thought the array's VALUE would be an ARRAY of VARIANTs, but no - it's a single VARIANT.
I can't use VARIANT to DATA on the array's VALUE - I don't know what TYPE the array is.
I thought maybe the ARRELEM refnum would be NIL if I was past the end, but that's not the case - there's only one refnum for any array element, whether it exists or not.
If I check for errors, it complains that I cannot set the INDEXVALS property of a strict typedef array, even though it works just fine.
If there was a method to SELECT ALL on the array, I could use the SELECTION SIZE to figure out how many elements there are, but I see no such method.
The NUMBER OF ROWS / COLUMNS refers to the number of VISIBLE rows/columns, and has nothing to do with how much data is present.
So... How do I find out how many elements are in the array?
Blog for (mostly LabVIEW) programmers: Tips And Tricks
01-25-2013 10:11 PM
Steve,
The ArrElem reference property is not a reference to any particular element of the array. It is a reference to the element that defines the array. Just like when you take an empty array container and drop in another control like a boolean or numeric, the reference is to the control that you drop in. (Check context help and detailed help on the ArrElem property.)
01-26-2013 07:37 AM
The ArrElem reference property is not a reference to any particular element of the array.
On the contrary, it is a reference to the element addressed by the current ARRAY INDEX(es).
That's why my code above can read out the values for element 0, element 1, etc. I've verified that this works.
There is only one set of PROPERTIES for the array elements; if you use the ArrElem refnum to set a background color of blue, then ALL elements turn blue, but you can obtain the VALUE of a given element by setting the ARRAY INDEX(es) and accessing via the ArrElem.
I was thinking that maybe LabVIEW did a trick by setting this to NIL to indicate "no such element", but that's not the case.
In any case, the question remains: How do I determine how many elements there are?
The VALUE of the array is a variant: just what is in that package?
As I said, I don't see how to use VARIANT TO DATA; I don't know what kind of data it is.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
01-26-2013 08:54 AM - edited 01-26-2013 08:55 AM
OK, here's one way to make it work, although it feels a bit like Return of the Son of Ugly Hack.
There's a function called VARIANT to FLATTENED STRING.
If I use that on the ARRAY VALUE, then UNFLATTEN that string as an I32, then I get the size of dimension 0.
In my case, that is sufficient, as I think (I'll soon find out) that all my arrays are 1-D.
Obviously, this is NOT very robust.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
01-26-2013 09:59 AM
Here's an approach you might like better: use Variant to Data to convert the variant to an array of variants.
01-26-2013 10:24 AM
Here's an approach you might like better:
--- That sufferes from the same limitation: the assumption that the array is 1-D.
My solution above produces a TYPE string. The third element of that is the number of dimensions. That COULD be used to provide a more general solution. For me, that assumption is valid in my case.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
01-26-2013 10:46 AM
Look at the other posts in the thread Nathan linked to. It shows where you can find a vi.lib VI which returns the number of dimensions and their sizes from a variant.
01-26-2013 10:47 AM
If you look through the thread that I linked, there's a comment further down about a VI included with LabVIEW that will give you the number of dimensions in an array from a variant. With those two tricks you can easily cover the common cases, unless you think you might randomly have a 50-dimension array.
01-26-2013 11:37 AM
OK, I found the VI <..\vi.lib\Utility\VariantDataType\GetArrayInfo.vi>
But the only USEFUL info that gives me is NDims - the number of dimensions.
The ARRAY LENGTHS output offers a SIZE firld, but that is always zero, it seems.
The code is protected, but my guess is it's just interpreting the TYPE STRING that you get from VARIANT to FLATTENED STRING.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
01-26-2013 01:37 PM
If I'm understanding all of this correctly you just needed to read a few more posts down in that thread, specifically here:
They combined the two methods talked about in that thread to get both the number of dimensions and the lengths of each of those dimensions.