11-26-2019 10:17 AM - edited 11-26-2019 10:40 AM
Hello everybody,
While developing some generic scripting tools, I had the need of a function to read/write a property of a class type by its name. For example, given a refnum to a control, read the value of the property "Caption.Text", or given an LVClass "MyDevice.lvclass", set the property "Timeout (ms)" to "1000". Basically read/write dynamically any property of any type that supports property nodes, given the property name.
After some research, I concluded there is no generic way of doing that. So, as such functionality has already been asked and declined (https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Set-Get-Property-By-Name/idi-p/2762750), my idea was to share my first attempt of implementation here, so anyone needing this functionality could get, improve and share the code with others.
I came up with a VI that can read any property of the "Generic" class (and subclasses) by generating property accessors on-the-fly in a temp directory using VI Scripting and reusing them if the property has already been requested. The main issues I would like to improve are the following (by order of priority):
1. Optimize execution speed and memory consumption (sometimes gets slow, need to restart LV to make it faster again)
2. Generalize it to all classes that can be selected for a property node, also including user LVClasses...
3. Add full support for nested properties (maybe by cascading several accessors)
...
4. Make it work within the runtime engine ??? (so not generating VIs at runtime anymore)
So, any idea to improve the code ? (LV 2018)
Solved! Go to Solution.
11-27-2019 04:09 AM - edited 11-27-2019 04:11 AM
No need to script the action in a new VI!
There are two methods GetProperty\SetProperty that gets\sets a property on any class by it's ID. It's inputs are the ID and a variant.
You can get all supported property IDs from a class node.
So, make a LUT for each class in the entire hierarchy, and all it's properties vs it's IDs. So, classname+property vs ID. Use a map or old school variant attributes.
Look up a class's property ID by it's name, and invoke Get\SetProperty.
BTW this only works for Generic and it's children. Other VI server classes (Project, ProjectItem, etc.) don't have these methods.
11-27-2019 12:53 PM
This might be helpful.
04-28-2023 08:48 AM - edited 04-28-2023 08:58 AM
Has there been any development on this since you posted this / or an example VI?
I've had an attempt myself (by editing OPs code) but can't seem to grasp how I would implement the use of GetProperty\SetProperty. Would your method work in the runtime engine?
Cheers
04-28-2023 12:04 PM - edited 04-28-2023 12:07 PM
At this time, it was just for recreational purpose, so I have not tested how it performs in production or in the runtime engine.
Here is my implementation of the accepted solution where I can do something like this:
I can also traverse sub-objects and cluster elements by using a dotted notation.
Also, keep in mind that you have to run the given script at least once to allow the creation of a property look-up table for your current version of LabVIEW.
05-01-2023 03:41 AM
Since you're now in LV20,why not use a map?
05-01-2023 04:50 AM - edited 05-01-2023 04:52 AM
05-02-2023 02:13 AM
@raphschru wrote:
If you look at my code, you'll see that I have used a map of map to store all property names and ids for each class.
I did look at the code you provided an image of, and you can use a map there too.
So, now I see it's just the example you've made that indeed doesn't need performance...
05-02-2023 03:18 AM
This is perfect thanks. Used it for a fire and forget animation library.