4 Replies Latest reply on Jun 2, 2015 11:43 AM by James.DeMarco

    Finding PI Tags in PBObjLib.Symbols

    helgesonc

      Hello - just started development on a ProcessBook Add-In and had a question.  I need to find out which PI tags are in certain controls (ex Trend, Value, etc).  I can access the Trend and Value objects but don't know what's next - is there a list of traces with the server and tagname/pointid for each tag on the trend?  Is there a way to tell if the trace is actually a PE eqn?  This is what I have so far which gives me (I think) the Trend and Value objects.  Haven't tried others yet.

      Private theApp As PBObjLib.Application

      ---
      If theApp IsNot Nothing Then
          disp = theApp.ActiveDisplay

          For Each sy As PBObjLib.Symbol In disp.Symbols

              Select Case sy.Type

                  Case PBSymLib.pbSYMBOLTYPE.pbSymbolTrend
                      Dim mytrend As PBSymLib.Trend = CType(sy, PBSymLib.Trend)
                      'this for loop doesn't actually work - trying to figure out how to loop through traces in a trend
                      For i As Integer = 0 To mytrend.TraceCount - 1

                      Next

                  Case PBSymLib.pbSYMBOLTYPE.pbSymbolValue

                      Dim myVal As PBSymLib.Value = CType(sy, PBSymLib.Value)
                      'trying to figure out how to get the server/tag information from the Value object

              End Select

          Next

      End If

      I am using VS 2008 and would like this to work for ProcessBook 3.0.x and 3.1.x

      Thanks!

        • Re: Finding PI Tags in PBObjLib.Symbols
          andreas

          Hi Caleb,

           

          usually you have two types of symbols. Symbols with one and symbols with multiple tags. Here is an example in PB VBA - but that should be just the same once you properly have the symbol object:

          Private Sub Trend1_Click(ByVal lvarX As Long, ByVal lvarY As Long)
              For i = 1 To Trend1.TraceCount
                  MsgBox Trend1.GetTagName(i)
              Next i
          End Sub

          Private Sub Value1_Click(ByVal lvarX As Long, ByVal lvarY As Long)
              MsgBox Value1.GetTagName(1)
          End Sub

          and here is a discussion thread that discusses how to get hold of the symbol. Once you have the name of the tag, it is easy to find out if it is a PI tag or not: the fromat of the PI Tag is \\<servername>\<tagname> while the dataset looks quite different: <datasetname>.<attribute>.

           

          regards,

          • Re: Finding PI Tags in PBObjLib.Symbols

            Hi Caleb,

             

            Many moons ago I did exactly what you are doing, only I did it within VBA.
            Here is the most generic part of the code, I enhanced it to do a similar & more specific job to the ProcessBook Status Window.  Feel free to butcher the code to what you need to do for your addin.

             

            Couple of points I remember from when I did.
            - Multistate symbols need a PI tag, don't forget to check for tags here.
            - Composite symbols can be made up of composite symbols so don't forget to recursively parse them.
            - XYPlot is newish control, I forgot this one first time round.

            Might be some new objects that can contain PI tags but I haven't revisited this for a while (ProcessBook 3.0.15).


            Private Sub ParseSymbolsForTags()

            Dim Sym As Symbol
            For Each Sym In ThisDisplay.Symbols
                Call ParseSymbol(Sym, "")
            Next Sym

            End Sub

            Private Sub ParseSymbol(ByVal TheSymbol As Symbol, ByVal CompName As String)

            If TheSymbol.IsMultiState Then
                Debug.Print CompName & TheSymbol.Name & " *MultiState* | " & "\\" & TheSymbol.GetMultiState.GetPtServerName & "\" & TheSymbol.GetMultiState.GetPtTagName
            End If

            Select Case TheSymbol.Type
                Case pbSymbolComposite
                    Call ParseComposite(TheSymbol, CompName)
                Case pbSymbolValue
                    Debug.Print CompName & TheSymbol.Name & " | " & TheSymbol.GetTagName(1)
                Case pbSymbolBar
                    Debug.Print CompName & TheSymbol.Name & " | " & TheSymbol.GetTagName(1)
                Case pbSymbolTrend
                    Dim TheTrend As Trend, iTrace As Integer
                    Set TheTrend = TheSymbol
                    For iTrace = 1 To TheTrend.TraceCount
                        TheTrend.CurrentTrace = iTrace
                        Debug.Print CompName & TheTrend.Name & " *Trace" & iTrace & "* | " & TheTrend.GetTagName(1)
                    Next iTrace
                    Set TheTrend = Nothing
                Case pbSymbolXYPlot
                    Dim TheXY As XYPlot, iTags As Integer
                    Set TheXY = TheSymbol
                    For iTags = 1 To TheXY.PtCount
                        Debug.Print CompName & TheXY.Name & " | " & TheXY.GetTagName(iTags)
                    Next iTags
                    Set XYPlot = Nothing
            End Select
            End Sub

            Private Sub ParseComposite(ByVal TheComposite As Composite, ByVal CompName As String)

            Dim Sym As Symbol
            For Each Sym In TheComposite.GroupedSymbols
                Call ParseSymbol(Sym, CompName & TheComposite.Name & " - ")
            Next Sym

            End Sub

              • Re: Finding PI Tags in PBObjLib.Symbols
                helgesonc

                Thanks guys - I was close!  myTrend.GetTagName(i) works.  It's worth noting that it seems OSI object arrays/collections are 1-based and not 0-based.

                • Re: Finding PI Tags in PBObjLib.Symbols
                  James.DeMarco

                  Rhys,

                   

                  Thanks for the solution for the composites!  Folks may also be interested in parsing SQCs, so I'd like to add a code snippet here for a function that returns the tags (I think this is all of them!) that could be associated to an SQCSymbol.  Note this is a function, not a subroutine, so you'd need to dimension a string array and call it with something like:

                   

                  Dim sqcTagArray() As String
                  Dim anSqcSymbol As SQCSymbol
                  ...
                  sqcTagArray = ParseSQC(anSqcSymbol)
                  

                   

                  Here is the function itself:

                   

                  Private Function ParseSQC(ByVal whichSQC As SQCSymbol) As String()
                      Dim tagCount As Long
                      Dim i As Long
                      Dim sqcDef As SQCSymbolDefinition
                      Dim limVal As Variant
                      Dim limType As LimitTypeEnum
                      Dim thisTagName As String
                      Dim theseTags() As String
                      
                      tagCount = 0
                      For i = 1 To 8 'Looped to avoid excess redundant code.
                          Select Case i
                          Case 1 'sqcCL
                              Set sqcDef = whichSQC.GetDefinition()
                              Call sqcDef.GetLimit(sqcCL, limType, limVal)
                              If limType = sqcPITag Then
                                  thisTagName = CStr(limVal)
                              End If
                          Case 2 'sqcLCL
                              Set sqcDef = whichSQC.GetDefinition()
                              Call sqcDef.GetLimit(sqcLCL, limType, limVal)
                              If limType = sqcPITag Then
                                  thisTagName = CStr(limVal)
                              End If
                          Case 3 'sqcLSL
                              Set sqcDef = whichSQC.GetDefinition()
                              Call sqcDef.GetLimit(sqcLSL, limType, limVal)
                              If limType = sqcPITag Then
                                  thisTagName = CStr(limVal)
                              End If
                          Case 4 'sqcUCL
                              Set sqcDef = whichSQC.GetDefinition()
                              Call sqcDef.GetLimit(sqcUCL, limType, limVal)
                              If limType = sqcPITag Then
                                  thisTagName = CStr(limVal)
                              End If
                          Case 5 'sqcUSL
                              Set sqcDef = whichSQC.GetDefinition()
                              Call sqcDef.GetLimit(sqcUSL, limType, limVal)
                              If limType = sqcPITag Then
                                  thisTagName = CStr(limVal)
                              End If
                          Case 6 'SQC Chart Tag
                              thisTagName = CStr(sqcDef.ChartTag)
                          Case 7 'SQC Alarm-Reset Tag
                              thisTagName = CStr(sqcDef.ResetTag)
                          End Select
                          
                          If Not thisTagName = "" Then
                              tagCount = tagCount + 1
                              ReDim Preserve theseTags(1 To tagCount)
                              theseTags(tagCount) = thisTagName
                          End If
                      Next i
                      ParseSQC = theseTags
                      
                  End Function
                  
                  1 of 1 people found this helpful