This example is meant to show alternatives to the GetValueFromName command. That command takes the name of a tag/variable (as a string) and returns a string representation of that tag’s value.

However, GetValueFromName uses scientific notation for float values, which might not be what you want.

Also, you may want to format the value based on some naming convention you set up for your tags (rather than the type of tag). This shows how you might look for a substring in the tag name and use another formatting method, like hex.

Here’s the OptoScript:

// initialize some values
stSomeTagNames[0] = "fMyFloat";
stSomeTagNames[1] = "aiMyStoreTemp";
stSomeTagNames[2] = "Two";
stSomeTagNames[3] = "nMyTagType";
stSomeTagNames[4] = "fTagWithTypeInName_non_Int32"; // test the "error handling"
// Loop through all the tags we care about for this
for nTagIndex = 0 to 4 step 1
// see if this tag as the word "Type" in it, if so we're going to format the value as hex
if (FindSubstringInString("Type", 0, stSomeTagNames[nTagIndex]) >= 0) then // "Type" is in the name
// here we're making the assumption that if this tag has Type in the name then
// it's an int32 type
GetPointerFromName(stSomeTagNames[nTagIndex], pInt32);
if (not (pInt32 == NULL)) then // in was an Int32, we want this in hex
NumberToFormattedHexString(*pInt32, 8, stSomeTagValues[nTagIndex]);
else
// do some kind of error handling
stSomeTagValues[nTagIndex] = "???? " + stSomeTagNames[nTagIndex];
endif
else
// Check the type of the tag named in the list
nMyTagType = GetTypeFromName(stSomeTagNames[nTagIndex]);
// We don't care if it's persistent or local, so let's toss those bits (30 & 28)
nTypeMask = 0xFFFFFFFF;
nTypeMask = BitClear( nTypeMask, 30 );
nTypeMask = BitClear( nTypeMask, 28 );
nMyTagType = nMyTagType bitand nTypeMask;
if ((nMyTagType == 0x00800002) or // we have a we have a float type,
(nMyTagType == 0x00020010)) then // or analog point, let's format this one ourselves
if (nMyTagType == 0x00800002) then // it's a float, use the float pointer
GetPointerFromName(stSomeTagNames[nTagIndex], pFloat);
FloatToString(*pFloat, 10,3, stSomeTagValues[nTagIndex]);
else // we have an analog value, not sure if it's input or output
// most likely for this application, it's an input, let's try that first
GetPointerFromName(stSomeTagNames[nTagIndex], pAin);
if (not (pAin == NULL)) then // we have an input
FloatToString(*pAin, 10,3, stSomeTagValues[nTagIndex]);
else // try getting it as an analog output
GetPointerFromName(stSomeTagNames[nTagIndex], pAout);
if (not (pAout == NULL)) then // in was an output
FloatToString(*pAout, 10,3, stSomeTagValues[nTagIndex]);
else
// do some kind of error handling
stSomeTagValues[nTagIndex] = "???? " + stSomeTagNames[nTagIndex];
endif
endif // checking for analog points
endif // we had a float or analog value
else
nResult = GetValueFromName(stSomeTagNames[nTagIndex], stSomeTagValues[nTagIndex] );
if (nResult <> 0) then
// do some kind of error handling
stSomeTagValues[nTagIndex] = "???? " + stSomeTagNames[nTagIndex];
endif
endif
endif
next

A note of caution on using this (and other GetXFromName) commands – they’re not necessarily a good idea for a huge system in a chart that needs to be fast, since the lookup takes some time.

For example, this code took on the order of milliseconds to execute. When I ran that 5-tag lookup x 1000 times, it took about 6 seconds total (on my R1, in debug mode, closer to 4 seconds when NOT running PAC Control’s debugger).