Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

Referencing variables via strings representations at runtime


Gav Sep 5, 2012 07:25 AM

Hi,
Is it possible to reference variables via the string representation of their names in another public variable at runtime?
I have quickly looked into the GetVariables() Instruction but have been unable to achieve this functionality in testing.
i.e.
Public x, Resultcode, batt_volt, tablename, fieldname
Battery (batt_volt)
tablename = "Public"
fieldname = "batt_volt"
' Retrieve the batt_volt value into variable x
'(logger pakbus add: 1)
GetVariables(Resultcode,ComRS232,0,1,0,1,tablename,fieldname,x,1)

The GetVariables() instruction would be ideal if you could specify the pakbus address parameter as the pakbus address of the logger running the program.
Application is being developed on the CR1000 (OSv24).
Any ideas / options would be greatly appreciated.

* Last updated by: Gav on 9/5/2012 @ 1:26 AM *


ChipsNSalsa Sep 5, 2012 05:54 PM

From the CRBasic help:

TableName.FieldName Example

This example uses Tablename.fieldname to populate a text string with the latest value from the table Test.

Public PTemp, TCTemp(2)
Public Text As String * 25

DataTable (Test,True,-1)
DataInterval (0,1,Min,10)
Sample (2,TCTemp(1),FP2)
EndTable

BeginProg
Scan (1,Sec,3,0)
PanelTemp (Ptemp,250)
TCDiff (TCTemp(),2,mV2_5,1,TypeT,PTemp,True ,0,250,1.0,0)
Text="Current temperature is " + Test.TCTemp(1)
calltable (Test)
NextScan
EndProg

This can just as easily be done with the Public table (e.g. VarTwo=Public.VarOne).

* Last updated by: ChipsNSalsa on 9/5/2012 @ 11:58 AM *


Gav Sep 5, 2012 07:56 PM

Thanks for your speedy response ChipsNSalsa,

I am familiar with the Tablename.Fieldname syntax to access variables, however this must be coded into the program before it is compiled in the data logger.

I am looking for a solution to reference variables by their string representation during run time; from the example below, tablename and fieldname are public variables that could be changed during runtime (e.g. in the numeric screens of LoggerNet).


Public x, Resultcode, batt_volt, tablename, fieldname
Battery (batt_volt)
tablename = "Public"
fieldname = "batt_volt"
' Retrieve the batt_volt value into variable x
GetVariables(Resultcode,ComRS232,0,1,0,1,tablename,fieldname,x,1)

Thanks again,
Gav


kirving Sep 5, 2012 08:26 PM

Just a thought, but a workaround might be to pull data into an array, then manipulate the array index. For instance, if you define data_in(), aliases can be set to map variables by name so they can be used in the program and tables as if regular variables. Then define index variables to point to those entries, e.g.,batt_volt_index=5. That probably doesn't quite get there... You could define a string array with the target names in the same index positions as the data array, then do a look-up to dereference the index from the name. That ought to do it. Effectively it's a way to implement associative arrays, which perhaps don't exist in CRBasic.


Gav Sep 12, 2012 07:58 AM

Hi All,

Thanks again for all the advice; after spending a few more minutes in the help file, (after further assistance from a past work colleague) I found that it is possible to use the GetVariables() instruction to do exactly what I was after...

Using -1 in the neighbour address in the instruction forces the auto-discovery of the route to the pakbus address specified (in this case your own).

Additionally the timeout should be set to 0 (uses the time based on the known route); in my example above I used "1" which was too quick and resulted in a failure to 'getVariables'.

So, a working example looks like this:

' Load x with variable defined in variables tablename and fieldname
Public x, Resultcode, batt_volt, tablename, fieldname
Battery (batt_volt)
tablename = "Public"
fieldname = "batt_volt"
' Retrieve the batt_volt value into variable x
GetVariables(Resultcode,ComRS232,-1,1,0,0,tablename,fieldname,x,1)

Thanks again for all the assistance.
Gav


simon Jan 30, 2013 05:46 AM

After doing some work with exactly this application - using GetVariables to load a generic array with values from source variables in Public table, referenced via strings, I have identified a significant limitation here.
This works successfully when the logger has an active route to a Pakbus device, but does not work when there is no active route.
When the GetVariables instruction executes and the logger is not attached to any comms equipment, the GetVariables returns -21 (unable to autodiscover route).
When the connection to Loggernet is established again, the GetVariables instruction begins working again.
Furthermore, the GetVariables instruction failed when I had the logger set as a router (IsRouter = True), when when I had active comms with Loggernet.

So, why does the auto-discover fail when there is nothing to answer the Beacon/Hello message process?

Is it possible to have a method to refer to public variables by a string? This would be a handy addition to the OS as it would allow programs to be written in a far more generic way, to allow for a powerful and simple user interface (eg. changing the value which is the source of an alarm decision, by typing the name of the variable into another location).
Thanks


WeetbixKid Mar 25, 2013 10:20 AM

I have been asking Campbell Scientific about the ability to include a way of referencing public variables by a string representation of the variable name. I agree with Simon that this would be a very powerful inclusion in the OS.

Is it possible for a Campbell representative to tell me why this could or could not be achieved??


ross Apr 10, 2024 03:24 PM

In case anyone else is looking for a way to reference public variables by a string representation of the variable name, you might want to try:

 

Public x, varName As String, ptr As Long, value

x=3
varName="x"
ptr=@(varName)
value=!ptr 'This should be the value of x

Or as a short function

Function getValByStr(name As String) As Float
  Dim ptr As Long
  ptr=@(name)
  Return !ptr
EndFunction

'Then just use...
val=getValByStr("nameOfVarible")

 

Log in or register to post/reply in the forum.