9 Replies Latest reply on Oct 14, 2010 6:43 PM by RJKSolutions

    Get VBA modules in current display

    AlistairFrith

      How do I get the VBA modules that are linked to the current display?

       

      I have a utility function in my C# addin called LoadVBAModule that checks whether the given module is loaded and, if not, loads it. The trouble is, if there are 2 displays open and one of them has the module loaded, it fails to get the other display. Both displays are new and may not have been saved at this point. Here's the relevant part of my function:

       

       

      // ***********
      // Here I want to find the project relating to the active (or a provided) display
      // ***********
      foreach (VBIDE.VBProject tmpVBProj in m_VBEnv.VBProjects)
      {
          VBProj = tmpVBProj;
      }

      if (VBProj == null)
      {
          Utils.ShowMsg(0, "LoadVBAModule()", "Failed to load VB project");
          return null;
      }

      // Don't reload it if it's already there
      foreach ( VBIDE.VBComponent tmpVBComp in VBProj.VBComponents)
      {
          if (tmpVBComp.Name == moduleName)
          {
              HideVBWindow();
              return tmpVBComp;
          }
      }

      It's the first bit that I want to change so that it stops when it gets to the project relating to the active (or a specific) display but I can't see anything in the project properties that gives me that.

       

      Any suggestions?

       

      --- Alistair.

       

       

       

       

       

       

        • Re: Get VBA modules in current display
          Ahmad Fattahi

          Maybe I'm not understanding well what you are trying to achieve but I can't see why your "if" is outside the loop. Don't you want to check them one by one inside the loop?

            • Re: Get VBA modules in current display
              AlistairFrith

              Let me re-phrase it then.

               

              foreach (VBIDE.VBProject tmpVBProj in m_VBEnv.VBProjects)
              {
                  // ***********
                  // Here I want to find the project relating to the active (or a provided) display
                  // ***********
                  if (this_project_is_for_the_active_or_specified_display)
                  {
                      VBProj = tmpVBProj;
                      break;
                  }
              }

              if (VBProj == null)
              {
                  Utils.ShowMsg(0, "LoadVBAModule()", "Failed to load VB project");
                  return null;
              }

              // Don't reload it if it's already there
              foreach ( VBIDE.VBComponent tmpVBComp in VBProj.VBComponents)
              {
                  if (tmpVBComp.Name == moduleName)
                  {
                      HideVBWindow();
                      return tmpVBComp;
                  }
              }




               

              The bit that I don't know how to implement is the test

               
              if (tmpVBProj_is_for_the_active_or_specified_display)

              Can I just cast tmpVBProj.Parent as an PBObjLib.Display and then compare it with the active display? I will try that but in the watch window, tmpVBProj.Parent evaluates to an exception so I am dubious that it would work.

               

              --- Alistair.

               

                • Re: Get VBA modules in current display
                  AlistairFrith

                  Turns out that no I can't. Here is my code now:

                  public VBIDE.VBComponent LoadVBAModule(string moduleName, PBObjLib.Display currentDisplay )
                  {
                      try
                      {
                          VBIDE.VBComponent VBComp;
                          VBIDE.VBProject VBProj = null;
                          //VBIDE.VBComponent  VBComp = Nothing;
                          String path;

                          // Find the project corresponding to the given display.
                          foreach (VBIDE.VBProject tmpVBProj in m_VBEnv.VBProjects)
                          {
                              if ((PBObjLib.Display)tmpVBProj.Parent == currentDisplay)  <-- exception raised here
                              {
                                  VBProj = tmpVBProj;
                              }
                          }

                   

                   

                  The exception that gets raised is this:

                   

                  o cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Vbe.Interop.Application'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{0002E158-0000-0000-C000-000000000046}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

                   

                  I expect that the parent of the Project is probably the VBA Environment and the parent of that is the Processbook application. So I am still stuck with how to get the particular display associated with a given Project (or more acurrately, how to get the VBA project associated with a specific display).

                   

                  --- Alistair.