A customer recently asked about generating a list of tag names within a strategy. This example parses the idb.txt file generated when you compile your strategy, and reads those names (and other info) into some tables.
I’ll attach the 9.3 PAC Control Basic strategy, but here’s the OptoScript:
// Note: this example used SoftPAC with the path of this compiled idb.txt the same as the strategy location on the PC:
// ********************************* Change to your strategy's idb.txt file here \/ \/ \/
SetCommunicationHandleValue("file:r,\Opto22\Projects\idb.txt.ParserV1.0\Parse_idb.idb.txt", chIDBtxtFile);
nCHResult = OpenOutgoingCommunication( chIDBtxtFile );
if (nCHResult == 0) then // we opened the file okay
// Initialize some values
nTagTableLength = GetLengthOfTable( stTagNameTable );
nCharsWaiting = GetNumCharsWaiting( chIDBtxtFile );
nTagTableIndex = 0;
// Set the EOM to LF since each line ends with CRLF
SetEndOfMessageTerminator( chIDBtxtFile, 0xA );
// Loop through all the file and load up the tag table
while ( (nCharsWaiting > 0) and (nTagTableIndex < nTagTableLength) and (nCHResult == 0) )
nCHResult = ReceiveString(sLineInFile, chIDBtxtFile);
if (nCHResult == 0) then // we read something ending with a LF
if (GetStringLength(sLineInFile) >= 109) then // we might have a tag
if ( (sLineInFile[0] == 'T') and
(sLineInFile[1] == 'A') and
(sLineInFile[2] == 'G') and
(sLineInFile[3] == '1') ) then // this line has tag data in it
// get the substring that is the tag name
GetSubstring(sLineInFile, 5, 50, stTagNameTable[nTagTableIndex]);
// This is a relatively new command, may require a firmware upgrade
// (or a different method)
TrimString(stTagNameTable[nTagTableIndex], 3);
// Get the table length/width in case we need that
GetSubstring(sLineInFile, 98, 10, stTagInfoTable[nTagTableIndex]);
IncrementVariable(nTagTableIndex);
endif
endif
endif
wend
endif
CloseCommunication( chIDBtxtFile );
I’ve got another example I’ll post that’s related (especially for those of you using commands like GetPointerFromName and GetValueFromName)…
I know this is a very old thread, but…
I’m attempting to replicate something like this in Pac Control Pro 9.6 and I’m having some trouble! I’ve successfully added the comm handle and accessed my IDB file (and ‘nCharsWaiting’ is passed a value), but no parsing ever occurs. I’m also not 100% clear on what the ‘sLineInFile’ string is doing? It never seems to be populated with anything when I attempt to inspect it - does it need some initial value that I’ve missed?
EDIT: I removed the TrimString(stTagNameTable[nTagTableIndex], 3);
line and things seem to be populating appropriately! Now I just need to fine tune the parser to eliminate the things I don’t want / need.
Nothing wrong w/posting to an old thread!
Just curious, what are you up to where you need this list of tag names?
Also, since it has been a few years, you now have more options along these lines via our REST API (if your hardware has firmware version 9.5 or newer).
Via the API you can get…lists of tags by type, for example, you can see all my float tables when you hit this endpoint on the PAC we’ve put on the internet, here (use ro for both the Username and Password, when prompted): http://restpac.groov.com/api/v1/device/strategy/tables/floats
First - thanks for the code above! It’s definitely given me something solid to build on.
Second - I’m in the middle of upgrading an old Factory Floor 4.1 strategy which relied very heavily on references to the serial addresses of our I/O Units - unfortunately, most of PAC Project relies more on unit names rather than addresses. Philip has already provided me some help in attaching tag names to indices in a pointer table, but that currently relies on manually assigning (I.e., hard-coding) each I/O Unit to a table index by name. I figured it would be easiest to just grab a list of my I/O Unit names dynamically and chuck them into a table via a loop.
FWIW, I’m going to attempt this by parsing one of my .CRN files (I believe it was .CRN3) since it has information closer to what I need, and less of what I don’t want (so the parser will be much easier to narrow down). If this works, I may post my code here if anybody wants it.
Now, it’s probably worth mentioning that I have about 72 hours of OptoScript experience under my belt and that there are likely a dozen ways to do what I’m after…so I do apologize if my solution is janky or if I’ve missed something incredibly obvious.
Once again, I really appreciate all of the help from this forum!