5 Replies Latest reply on Nov 15, 2017 4:36 PM by kbobeck

    Macro Linking button from PIW to another display on the same PIW with element relative changing based on the button

    MPCPRO

      Is it possible to link a button from a display on a PIW to another display on the same PIW and have the same element  relative as the previous display button?

       

      Example:

       

      We have a PIW with a few displays in them. Display P Template: has trends with a button over them (P-2)

       

       

      If we click on the button top right P-2, I want it to navigate the user from the "P Template" display to for example "Well Monitor K display".

       

       

      And keep the element relative  information during that transfer. So when the Well Monitor K display opens it has the relative element information taken from the "P Template"  P-2 button.

       

      Is this possible in PIW? If it is, anyone know exactly how?

       

      Thanks.

        • Re: Linking button from PIW to another display on the same PIW with element relative changing based on the button
          kbobeck

          Hi Matthew,

           

          I believe the section on passing the context from Parent to Child (Element Relative Display) in this White Paper may be what you're looking for:

           

          White Paper - A Few PI ProcessBook VBA Tips

           

          There is also this KB article: KB01082

           

          -Kelsey

            • Re: Linking button from PIW to another display on the same PIW with element relative changing based on the button
              MPCPRO

              Hi Kelsey!

               

              Thanks for the reply.

               

              I tried using this bit of code I found but it does not work, and ends with "Automation error, unspecified error":

              I changed the .pdi to .piw where applicable in the code, since I am working strictly in PIW and have no outside .pdi displays, but I guess the code only works for PDI?

               

              Sub WellP2()
                  GoToDisplay "PI Processbook HTM.piw!Well Monitor Kristin", "\\Operation Hell\Kristin AF Tool\Kristin Subsea Wells\P-2"
              End Sub
              
              
              
              
              'Function for setting context on given display
              Function GoToDisplay(piw As String, ctxt As String)
                
                
                  Dim strCurrentPath As String
                  Dim PBDisplay As PBObjLib.Display
                    
                    
                  strCurrentPath = Left(ThisDisplay.Path, (InStrRev(ThisDisplay.Path, "\")))
                  strCurrentPath = strCurrentPath & piw
                  Set PBDisplay = Application.Displays.Open(strCurrentPath, True)
                  Application.ContextHandlers("E").CurrentContext(PBDisplay) = ctxt
                    
                  Application.DockWindows.Item("Element Relative Display").Visible = False
                    
              End Function
                
                
              Private Sub CleanBadData()
                
                
                  Dim vrDate As Variant
                  Dim vrStatus As Variant
                  Dim vrVal As Variant
                  Dim oVal As Symbol
                
                
                  For Each oVal In ThisDisplay.Symbols
                      If oVal.Type = pbSYMBOLTYPE.pbSymbolValue Then
                        
                          vrVal = oVal.GetValue(vrDate, vrStatus)
                          If vrStatus = 247 Then
                              oVal.Visible = False
                          Else
                              oVal.Visible = True
                            
                          End If
                      End If
                  Next oVal
                
                
              End Sub
              

               

               

               

              The original code:

               

               

              'Function for setting context on given display  
              Function GoToDisplay(pdi As String, ctxt As String)  
                
                
                  Dim strCurrentPath As String  
                  Dim PBDisplay As PBObjLib.Display  
                    
                    
                  strCurrentPath = Left(ThisDisplay.Path, (InStrRev(ThisDisplay.Path, "\")))  
                  strCurrentPath = strCurrentPath & pdi  
                  Set PBDisplay = Application.Displays.Open(strCurrentPath, True)  
                  Application.ContextHandlers("E").CurrentContext(PBDisplay) = ctxt  
                    
                  Application.DockWindows.Item("Element Relative Display").Visible = False  
                    
              End Function  
                
                
              Private Sub CleanBadData()  
                
                
                  Dim vrDate As Variant  
                  Dim vrStatus As Variant  
                  Dim vrVal As Variant  
                  Dim oVal As Symbol  
                
                
                  For Each oVal In ThisDisplay.Symbols  
                      If oVal.Type = pbSYMBOLTYPE.pbSymbolValue Then  
                        
                          vrVal = oVal.GetValue(vrDate, vrStatus)  
                          If vrStatus = 247 Then  
                              oVal.Visible = False  
                          Else  
                              oVal.Visible = True  
                            
                          End If  
                      End If  
                  Next oVal  
                
                
              End Sub  
              
                • Re: Linking button from PIW to another display on the same PIW with element relative changing based on the button
                  kbobeck

                  Hi Matthew,

                   

                  I did some searching and it seems you may need to refer to the Entry rather than the Display. From this thread Opening a Display with a VBA Command Button:

                   

                  "The correct way to switch from one display to another in a workbook is to execute the display "entry" that you want to open.

                   

                  Dim oBook As ProcBook  
                  Dim oEntry As Entry  
                  Dim strAction As String  
                    
                  Set oBook = Application.ProcBooks.Application.ActiveProcBook  
                  Set oEntry = oBook.Entries.Item(2)  
                  strAction = oEntry.Action  
                  Entry.Execute (False) 
                  
                  

                   

                  The #2 item number represents the display as it falls in the list of displays in your workbook outline. The above code will open the second display and close your current display, just like you had created a navigational button within ProcessBook itself."

                   

                  From Rick Davin's reply in this thread Hello everyone, I need your help to add a trend in a VBA6 form:

                   

                  You would have a ProcBook object:

                  Dim pBook As ProcBook

                  Set pBook = pbApp.ProcBooks.Open("directory and file path to your procbook.PIW")

                   

                  Open a specific display in the ProcBook takes an Entry object and then a Display:

                  Dim myEntry As PBObjLib.Entry

                  Dim myDisplay As PBObjLib.Display

                   

                  'Open the Display

                  Set myEntry = pBook.Entries.Item("desired display name")

                  myEntry.Execute (False)

                   

                  'Get the display that was opened

                  Set myDisplay = myEntry.Application.ActiveDisplay

                   

                  I'm not very familiar with VBA, but I would assume for you it'd be something along these lines:

                   

                  Dim pBook As ProcBook
                  Set pBook = pbApp.ProcBooks.Open("<filepath>\PI Processbook HTM.piw")
                  
                  Dim myEntry As PBObjLib.Entry
                  Dim myDisplay As PBObjLib.Display
                  
                  'Open the Display
                  Set myEntry = pBook.Entries.Item("Well monitor Kristin")
                  myEntry.Execute (True)
                  
                  'Get the display that was opened
                  Set myDisplay = myEntry.Application.ActiveDisplay
                  
                  Application.ContextHandlers("E").CurrentContext(myDisplay) = "\\Operation Hell\Kristin AF Tool\Kristin Subsea Wells\P-2"
                  ThisDisplay.Close (False) 
                  

                   

                  I hope this is helpful!

                   

                  -Kelsey

                  1 of 1 people found this helpful
                    • Re: Linking button from PIW to another display on the same PIW with element relative changing based on the button
                      MPCPRO

                      Hi Kelsey.

                       

                      Thanks for the help, I'm also not familiar with VBA (or any other programming languages) so I have just been playing around without knowing exactly what I am doing

                       

                      Based on your recipe I made this:

                       

                      Button:

                       

                       

                      
                      
                      
                      Sub WellP2()
                      
                      
                      Dim pBook As ProcBook
                      Set pBook = pbApp.ProcBooks.Open("F:\PI Processbook HTM.piw")
                        
                      Dim myEntry As PBObjLib.Entry
                      Dim myDisplay As PBObjLib.Display
                        
                      'Open the Display
                      Set myEntry = pBook.Entries.Item("Well Monitor Kristin")
                      myEntry.Execute (False)
                        
                      'Get the display that was opened
                      Set myDisplay = myEntry.Application.ActiveDisplay
                      
                      
                      Application.ContextHandlers("E").CurrentContext(myDisplay) = "\\Operation Hell\Kristin AF Tool\Kristin Subsea Wells\P-2"
                      
                      
                      End Sub
                      
                      
                      
                      
                      
                      
                      
                      
                      

                       

                      The message I am getting is: Failed to find object

                       

                      Do you have any idea what I am doing wrong?

                       

                      EDIT: NVM! Got it working! Thanks a lot Kelsey! Final Code:

                       

                      Sub WellP2()
                      
                      
                          Dim pBook As ProcBook
                          Set pBook = Application.ProcBooks.Open("F:\PI Processbook HTM.piw")
                            
                          Dim myEntry As PBObjLib.Entry
                          Dim myDisplay As PBObjLib.Display
                            
                          'Open the Display
                          Set myEntry = pBook.Entries.Item("Well monitor Kristin")
                          myEntry.Execute (True)
                            
                          'Get the display that was opened
                          Set myDisplay = myEntry.Application.ActiveDisplay
                          
                          Application.ContextHandlers("E").CurrentContext(myDisplay) = "\\Operation Hell\Kristin AF Tool\Kristin Subsea Wells\P-2"
                          ThisDisplay.Close (False)
                      End Sub
                      

                       

                      VBA is very picky about large/small letters, so be sure that is correct

                       

                      Asle Frantzen helped me look over the code. Seems like I had to edit bpApp in the 5th line to "Application.ProcBooks.Open("F:\PI Processbook HTM.piw")"

                       

                      I also had a small problem that the display would close before getting the last line of code (the important part where it tells the display to get the right relavant element).

                       

                      To fix this Asle changed myEntry.Execute from (False) to (True).

                       

                      To make sure the display closes after getting the right relavant element, we added: ThisDisplay.Close (False) at the end.

                       

                      Once again Thanks!

                      1 of 1 people found this helpful