19 Replies Latest reply on Mar 2, 2010 1:47 PM by zglenskij

    ProcessBook ModuleContext - dynamic loading

    fraser

      Hi,

       

      I'm trying to get the module context to dynamically load based on a slection from a dropdown that acts as a starting point for the modulecontext.  Is there any good ProcessBook script examples of using the ContextHandler to clear the current modules in the ContectWindow and then dynamically load using the contextdata property?

       

      Cheers

       

      Fraser

        • Re: ProcessBook ModuleContext - dynamic loading
          andreas

          Hi Fraser,

           

          the code below clears the module context and adds new module contexts to it, is this what you are looking for?

          Dim SelectedContext As String
          Dim ModuleToken As String
          Dim Server As String
          Dim PersistedModule As String
          Dim TheNamedValues As PBNamedValues

          Server = "ASNOTE"
          ModuleToken = "|Module`" ' This must be exactly as it is here

          Dim MrdContextHandler As ContextHandler
          Set MrdContextHandler = Application.ContextHandlers("ModuleContext")
          Dim AliasContextHandler As ContextHandler
          Set AliasContextHandler = Application.ContextHandlers("Alias")
          Dim PropContextHandler As ContextHandler
          Set PropContextHandler = Application.ContextHandlers("Property")

          ' The "PersistedModule" string represents a module that get's saved to the display
          ' The "TheNamedValues" collection has a key-value list of the modules that will be persisted
          ' The form of these key-value pairs is very specific to the module context add-in
          Set TheNamedValues = MrdContextHandler.ContextData(ThisDisplay)
          ' Clear the current list
          TheNamedValues.Clear
                
          Module = "vCampus\311_1276\Module1"
          PersistedModule = "\\" & Server & ModuleToken & Module
          TheNamedValues.Add "ModuleContext.Context1", PersistedModule

          Module = "vCampus\311_1276\Module2"
          PersistedModule = "\\" & Server & ModuleToken & Module
          TheNamedValues.Add "ModuleContext.Context2", PersistedModule
            
          MrdContextHandler.ContextData(ThisDisplay) = TheNamedValues
          AliasContextHandler.ContextData(ThisDisplay) = TheNamedValues
          PropContextHandler.ContextData(ThisDisplay) = TheNamedValues

          SelectedContext = "\\" & Server & "\vCampus\311_1276\Module2"
          MrdContextHandler.CurrentContext(ThisDisplay) = SelectedContext
          AliasContextHandler.CurrentContext(ThisDisplay) = SelectedContext
          PropContextHandler.CurrentContext(ThisDisplay) = SelectedContext

          regards,

            • Re: ProcessBook ModuleContext - dynamic loading
              fraser

              Yes - thanks for that - was able to clean up some code bassed on this.

              • Re: ProcessBook ModuleContext - dynamic loading
                fraser

                Andreas,

                 

                Further to previous posts - I am also trying to dynamically load aliases into a trend control.  However when I load them into the trend the order does not match the order I see them in SMT which seems to always put them in alphanumeric order.

                 

                Would you know if something is being handled differently with SMT to get the order alphanumeric for aliases?

                 

                My code uses the following method to add Aliases to a Trend:

                For each tmpAliass in tmpModule.PIAliases

                    t.AddTrace "ALIAS.|" & tmpAlias.Name

                Next tmpAlias

                Version of PI SDK 1.3.6 Build 361 and SMT 3.2.4

                • Re: ProcessBook ModuleContext - dynamic loading
                  Clint.Ostby

                  Hi folks - I am working on a similar problem and have noticed that when adding in module context dynamically, the module context addin window does not display  parent nodes

                   

                  ex. if I load up module context manually for 2 modules under a parent, I see:

                   

                  + Parent

                   

                     - Child 1

                   

                     - Child 2

                   

                  .......whereas if the modules Child 1 and Child 2 are loaded dynamically, I get a flat module context addin window showing simply

                   

                  - Child 1

                   

                  - Child 2

                   

                  Any ideas you have are appreciated!

                    • Re: ProcessBook ModuleContext - dynamic loading
                      andreas

                      Hi Clint,

                       

                      I can not really replicate this. After running the following code:

                      Dim SelectedContext As String
                      Dim ModuleToken As String
                      Dim Server As String
                      Dim PersistedModule As String
                      Dim TheNamedValues As PBNamedValues

                      Server = "ASNOTE2"
                      ModuleToken = "|Module`" ' This must be exactly as it is here

                      Dim MrdContextHandler As ContextHandler
                      Set MrdContextHandler = Application.ContextHandlers("ModuleContext")
                      Dim AliasContextHandler As ContextHandler
                      Set AliasContextHandler = Application.ContextHandlers("Alias")
                      Dim PropContextHandler As ContextHandler
                      Set PropContextHandler = Application.ContextHandlers("Property")

                      ' The "PersistedModule" string represents a module that get's saved to the display
                      ' The "TheNamedValues" collection has a key-value list of the modules that will be persisted
                      ' The form of these key-value pairs is very specific to the module context add-in
                      Set TheNamedValues = MrdContextHandler.ContextData(ThisDisplay)
                      ' Clear the current list
                      TheNamedValues.Clear

                      Dim i As Integer
                      i = 1

                      Module = "vCampus\ModuleA"
                      PersistedModule = "\\" & Server & ModuleToken & Module
                      TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                      i = i + 1

                      Module = "vCampus\ModuleA\ModuleAA"
                      PersistedModule = "\\" & Server & ModuleToken & Module
                      TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                      i = i + 1

                      Module = "vCampus\ModuleA\ModuleAB"
                      PersistedModule = "\\" & Server & ModuleToken & Module
                      TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                      i = i + 1

                      Module = "vCampus\ModuleA\ModuleAC"
                      PersistedModule = "\\" & Server & ModuleToken & Module
                      TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                      i = i + 1

                      Module = "vCampus\ModuleB"
                      PersistedModule = "\\" & Server & ModuleToken & Module
                      TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                      i = i + 1

                      Module = "vCampus\ModuleC"
                      PersistedModule = "\\" & Server & ModuleToken & Module
                      TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                      i = i + 1

                      MrdContextHandler.ContextData(ThisDisplay) = TheNamedValues
                      AliasContextHandler.ContextData(ThisDisplay) = TheNamedValues
                      PropContextHandler.ContextData(ThisDisplay) = TheNamedValues

                      SelectedContext = "\\" & Server & "\vCampus\ModuleB"
                      MrdContextHandler.CurrentContext(ThisDisplay) = SelectedContext
                      AliasContextHandler.CurrentContext(ThisDisplay) = SelectedContext
                      PropContextHandler.CurrentContext(ThisDisplay) = SelectedContext

                      I do get the hierarchy:

                       

                      311_5F00_Pic01.jpg_2D00_600x450.jpg

                        • Re: ProcessBook ModuleContext - dynamic loading
                          Clint.Ostby

                          Andreas, thanks again - I had misunderstood the purpose of the Module Token. After having reviewed your code I was able to correct our and now it works as expected.

                           

                          - Clint

                          • Re: ProcessBook ModuleContext - dynamic loading
                            Clint.Ostby

                            Andreas,

                             

                            One additional question - is there an easy way to pick up the Current Context from another open ProcessBook?

                             

                            Using your heirarchy as an example - we have a complex display representing Module AA. Module AA has several submodules (let's say Module AAA, AAB, AAC...). I would like a user to be able to click a button on the "Parent" display for Module AA which will open a "Child" display that will be dynamically loaded with Module Context selections for all of Module AA's children.

                             

                            In order to do this, the Child display must be able to read the current context of the Parent display. Is this possible?

                             

                            Regards,

                             

                            - Clint

                              • Re: ProcessBook ModuleContext - dynamic loading
                                andreas

                                Clint,

                                 

                                I would say do it the other way, modify the child display from the parent. First a simple example to open a display from another one:

                                Dim myd As Display    
                                Set myd = Application.Displays.Open("C:\Documents and Settings\Andreas\Desktop\vCampus_Forum\PB_311\ChildDisplay.PDI", True)

                                now we have the "myd". Let us now add the following code to the calling display (the one that executes the above code)

                                
                                

                                Private Sub TestD(d As Display)
                                    Dim SelectedContext As String
                                    Dim ModuleToken As String
                                    Dim Server As String
                                    Dim PersistedModule As String
                                    Dim TheNamedValues As PBNamedValues
                                   
                                    Server = "ANDREASPC"
                                    ModuleToken = "|Module`" ' This must be exactly as it is here
                                   
                                    Dim MrdContextHandler As ContextHandler
                                    Set MrdContextHandler = Application.ContextHandlers("ModuleContext")
                                    Dim AliasContextHandler As ContextHandler
                                    Set AliasContextHandler = Application.ContextHandlers("Alias")
                                    Dim PropContextHandler As ContextHandler
                                    Set PropContextHandler = Application.ContextHandlers("Property")
                                   
                                    ' The "PersistedModule" string represents a module that get's saved to the display
                                    ' The "TheNamedValues" collection has a key-value list of the modules that will be persisted
                                    ' The form of these key-value pairs is very specific to the module context add-in
                                    Set TheNamedValues = MrdContextHandler.ContextData(d)
                                    ' Clear the current list
                                    TheNamedValues.Clear
                                   
                                    Dim i As Integer
                                    i = 1
                                   
                                    Module = "vCampus\ModuleA"
                                    PersistedModule = "\\" & Server & ModuleToken & Module
                                    TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                                    i = i + 1
                                   
                                    Module = "vCampus\ModuleB"
                                    PersistedModule = "\\" & Server & ModuleToken & Module
                                    TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                                    i = i + 1
                                   
                                    Module = "vCampus\ModuleC"
                                    PersistedModule = "\\" & Server & ModuleToken & Module
                                    TheNamedValues.Add "ModuleContext.Context" & i, PersistedModule
                                    i = i + 1
                                   
                                    MrdContextHandler.ContextData(d) = TheNamedValues
                                    AliasContextHandler.ContextData(d) = TheNamedValues
                                    PropContextHandler.ContextData(d) = TheNamedValues
                                   
                                    SelectedContext = "\\" & Server & "\vCampus\ModuleC"
                                    MrdContextHandler.CurrentContext(d) = SelectedContext
                                    AliasContextHandler.CurrentContext(d) = SelectedContext
                                    PropContextHandler.CurrentContext(d) = SelectedContext

                                End Sub

                                what you have to do now is add

                                 

                                Call TestD(myd)
                                to the Sub that opens the child display and you are done. Note that the only thing in the VBA that is changed from my previous post is that I am not using ThisDisplay but refering to a particular display.

                                 

                                So that is what you have to do to define the Module Context in a different Display than your own. Now you only have to define wich modules you want to display in your child

                                 

                                Hope this helps,

                                 

                                 

                          • Re: ProcessBook ModuleContext - dynamic loading
                            PDVPlewa

                            Hi Andreas!

                             

                            I'm using contexthandlers and context switching from VBA for quite a time and it works fine.

                             

                            But yesterday it failed due to the missing addin "Module Context". [:'(] Don't ask me why, I have no idea...

                             

                            Can I load an addin from VBA and if so, is there example code available?

                             

                            Jost

                              • Re: ProcessBook ModuleContext - dynamic loading
                                andreas

                                Hi Jost,

                                 

                                just the usual question  - what version of ProcessBook?

                                 

                                I have seen the missing "Module Context" only on some beta versions of PI PB 3.2. However, another option would be that someone removed the registration of that add in.

                                 

                                To answer your question - yes and no. You cannot load an Add In from VBA that is not already registered, but you can load/unload an Add In from VBA that is registered.

                                 

                                To register the Add In the DLL providing the Add In needs to be registered with regsvr32 and the registry entries in ProcessBook\Addins need to exist. Than you can use the Application.Addins collection to load/unload the Add In.

                                 

                                hope this helps,

                                  • Re: ProcessBook ModuleContext - dynamic loading
                                    PDVPlewa

                                    Hi Andreas!

                                     

                                    I don't know how or even why someone deselected "Load on Startup" but I suppose that this happened because the AddIns are installed with the installation package, provided by our IT staff.

                                     

                                    To avoid a situation like this I will "poison" my PDIs with the following code:

                                    Private Sub Display_Open()
                                    Dim oAddin As Object

                                    Set oAddin = Nothing

                                    On Error Resume Next

                                    Set oAddin = Application.Addins("ModuleContext.Connect")

                                    If Err Then
                                        Beep
                                        MsgBox Err.Description, vbCritical + vbOKOnly, "Module Context"
                                    Else
                                        If Not oAddin.connect Then oAddin.connect = True
                                    End If

                                    On Error GoTo 0

                                    End Sub

                                      • Re: ProcessBook ModuleContext - dynamic loading
                                        ldieffenbach

                                        Hi everyone, this is Laurie (Product Manager for PI ProcessBook and other things). I notice there is a lot of interest in this thread, so I wanted to ask some quick questions.

                                         

                                        Are you (or your customers) using this type of solution to create faceplace-type displays? (That is, the visualization is mostly fixed, but the data to display is very changeable in terms of the Aliases (or AF element.attributes) that apply?

                                         

                                        And, a related question: Are any of you also using this type of solution with PI ActiveView? If so, have you run into any performance bottlenecks there?

                                         

                                        Thanks for your continued interest in PI ProcessBook extensibility. Please post any responses directly here.

                                  • Re: ProcessBook ModuleContext - dynamic loading
                                    zglenskij

                                    Does this code actually add/load a whole new set of modules?  What if I had a PB display saved with some trends and the 'Available Modules' was already configured with the appropriate list of modules... does there exist some sample code to choose the default selected module upon display launch?  I know this can be easily configured using PI WebParts.  VBA is the way to go for PB.

                                      • Re: ProcessBook ModuleContext - dynamic loading
                                        fraser

                                        Jennifer,

                                         

                                         

                                         

                                        Yes - Basically what this code allows us to do is to design a generic screen showing similar trends for different equipment or porcess vartiables... For example if you have a set of wells in an an oil field that have different equipment and types of information you can still use the same treeview and trend to display the different types of data using the Module Database Aliases by dynamically loading them into the trend as the user sleects each Well in the Treeview.

                                         

                                        And yes on load you can set the default treeview node to set up starting context.

                                         

                                        The sample below would set the current context to whatever path is defined by the variables to go 3 levels in to the module heriarchy... obviously you could hava hardcoded settings for this if you just wanted an always existing starting point...

                                        Dim MCH As ContextHandler   'Module Context Handler
                                        Set MCH = Application.ContextHandlers("ModuleContext")

                                        MCH.currentcontext(ThisDisplay) = "\\" & PISDK.Servers.DefaultServer.Name & "\" & RootNode & "\" & FieldNode & "\" & ProcessNode & FirstWell

                                        All the best!