• Trouble with a class module (VBA Word 2000)

    Home » Forums » AskWoody support » Productivity software by function » Visual Basic for Applications » Trouble with a class module (VBA Word 2000)

    Author
    Topic
    #374922

    Edited by TroyWells on 13-Aug-02 14:29.

    I followed the instructions in online help (Topic “Using Events with the Application Object”) for using a class module to access the Windows_Activate event. But I’m having a couple of problems:

    1) The class module is located in a global template file. When the file is loaded, I would think it is considered to be open. In fact, I have an AutoOpen macro that I have confirmed does fire (I see a msgbox). However, only when I have the global template file open (by going to the file menu and then open) does the event seem to work. I run a procedure during the AutoOpen to initialize the declared object.

    2) When it does fire (when I have the global template file open using the File menu and then Open), the action I am performing is the installing and uninstalling of addins, each of which has a custom menu. It seems to be uninstalling/installing correctly, but the menus don’t reflect that until I go to a different document. If I am uninstalling some addins, Application.ScreenRefresh seems to work. But if I am reinstalling addins. Nothing I’ve tried seems to work.

    Any ideas for what I am doing wrong?

    Thanks for the help!!
    Troy

    P.S. OK I was lazy. here is the code:

    Class Module:

    Public WithEvents App As Word.Application
    Public GlobalTemplatePath As String

    Private Sub App_WindowActivate(ByVal Doc As Document, ByVal Wn As Window)

    ‘ClassModuleProcedures.UnloadInappropriateAddins

    Dim ArrayAddins()
    Dim I, J, AddinsCount As Integer
    Dim AddinPath, AddinName As String
    Dim PropExists As Boolean

    PropExists = False
    ReDim ArrayAddins(2, 0)
    AddinsCount = AddIns.Count
    For I = 1 To ActiveDocument.CustomDocumentProperties.Count
    If ActiveDocument.CustomDocumentProperties.Item(I).Name = “Document Type” Then
    PropExists = True
    Exit For
    End If
    Next I
    If PropExists = False Then
    With ActiveDocument.CustomDocumentProperties
    .Add Name:=”Document Type”, _
    LinkToContent:=False, _
    Type:=msoPropertyTypeString, _
    Value:=””
    End With
    End If
    If ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech Cover” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech Chapter” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech CoverE” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech TOC” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech Chapter” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech Index” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech Glossary” Or _
    ActiveDocument.CustomDocumentProperties(“Document Type”).Value = “Tech All” Then

    For I = 1 To AddinsCount
    ReDim Preserve ArrayAddins(2, UBound(ArrayAddins, 2) + 1)
    ArrayAddins(2, UBound(ArrayAddins, 2)) = AddIns.Item(I)
    ArrayAddins(1, UBound(ArrayAddins, 2)) = AddIns.Item(I).Path & “”
    Next I
    ‘ AddIns.Unload RemoveFromList:=False
    For J = 1 To AddIns.Count
    If AddIns.Item(J) “TechTemplate.dot” Then AddIns.Item(J).Installed = False
    Next J
    For I = 1 To UBound(ArrayAddins, 2)
    If ArrayAddins(2, I) “FormatDocuments.dot” And _
    ArrayAddins(2, I) “2WebTemplate.dot” And _
    ArrayAddins(2, I) “TGPChap.dot” And _
    ArrayAddins(2, I) “BizDoc.dot” And _
    ArrayAddins(2, I) “UserDoc.dot” Then
    On Error GoTo StartErrorHandler1
    AddIns.Add FileName:=ArrayAddins(2, I), Install:=True
    GoTo StopErrorHandler1
    StartErrorHandler1:
    If Err.Number = 4160 Then
    AddinPath = ArrayAddins(1, I)
    AddIns.Add FileName:=AddinPath & ArrayAddins(2, I), Install:=True
    Else
    MsgBox Err.Number
    Exit Sub
    End If
    StopErrorHandler1:
    On Error GoTo 0
    End If
    Next I
    Else
    EElse:
    For J = 1 To AddIns.Count
    AddIns.Item(J).Installed = True
    Next J
    End If
    Application.ScreenRefresh
    End Sub

    Registering Sub:

    Dim X As New EventClassModule

    Sub Register_Event_Handler()
    Set X.App = Word.Application
    End Sub

    Viewing 0 reply threads
    Author
    Replies
    • #608235

      Couple of things:

      1) Is App_Window Activate the best event for loading addins? Why not consider putting code in a sub called by an AutoExec sub in your global?

      2) Adding Addins (and then “installing” them) can be problematic if their location on disk changes. I offer this this technique gleaned from Robin Trew ideas (a smart guy who used to hang out here):

      Sub LoadAddin(strName As String, strPath As String)
      Dim oAddin As AddIn
      Dim i As Long
      Dim fFound As Boolean
      On Error Resume Next
      If Right$(strPath, 1) “” Then
      strPath = strPath & “”
      End If
      With oFso
      If .FileExists(strPath & strName) Then
      For Each oAddin In Application.AddIns
      ‘Debug.Print oAddin.Name
      If oAddin.Name = strName Then
      If oAddin.Path & “” strPath Then
      oAddin.Delete
      Else
      fFound = True
      Exit For
      End If
      End If
      Next
      If Not fFound Then
      Set oAddin = AddIns.Add(strPath & strName)
      End If
      On Error Resume Next
      If Not oAddin.Installed Then
      oAddin.Installed = True
      End If
      Else
      ‘Debug.Print strName & “The file named “”” & strName & “”” is not in ” & _
      strPath & “. Cannot load this addin template.”, vbExclamation, “Load Addin Template”
      End If
      End With

      End Sub

      I use the FSO object to test for fileexists. There a plenty of other methods, so you’ll need to change that code to your preference.

      • #608240

        1) Perhaps I wasn’t clear. I need to load and unload addins based on the document that is displayed. I’ve found that sometimes the wrong procedure runs if I have more than one addin loaded with similar procedures. Thus, I have a customdocumentproperty that identifies the kind of document. When a different window is activated, the code checks the document property and loads the correct addin. Thus I cannot use AutoExec to load/unload the addin since this only runs once when Word is started.

        2) Thanks for the thoughts on loading addins, but since you can determine the path of the addin even when it is uninstalled, I don’t think that is an issue.

        I still need to understand why this file gets registered when you open the file from the File menu, but not when it is opened as a global template as mentioned in the original thread, and how I can refresh the screen to show the actual available menus when addins are reinstalled.

        Thanks for helping me clarify my needs!!
        Troy

        • #608242

          Ok, I understand now. You do need app_activate.

          Don’t know if this applies to Word 2000, but using App Events in 97 requires that you instantiate the app object class:

          In Declare:
          Public YourAppObjectName As New YourClassName

          In AutoExec:
          Set YourAppObjectName.App = Word.Application

          • #609274

            OK. I finnally got back around to this and found that my intiation statement was a dim statement, not a public (if that was the problem, the online help is incorrect). I don’t know if that’s what the problem was or something else, but it is the WindowsActivate event is working fine now.

            One question, my WindowsDeactive event does not seem to be working. I have the following code:

            Private Sub App_WindowDeactivate(ByVal Doc As Document, ByVal Wn As Window)
            If Windows.Count = 0 Then
            ActiveDocument.CommandBars(“Menu Bar”).Controls(“Tech Doc”).Visible = False
            ActiveDocument.CommandBars(“Menu Bar”).Controls(“Enable Template Macros”).Visible = False
            End If
            End Sub

            I’m trying to disable two of my custom menus if no documents are open, but he Word Application is still open. This isn’t crucial, but I just want to clean up after myself. As it is now, whatever custom menus were displayed with the last document I closed are the menus that remain. Any clues?

            Thanks for the help!!
            Troy

            • #609280

              I can’t see why your app_WindowDeactivate isn’t working, but I achieve the effect you want by disabling controls in the app_DocumentChange event (well actually in a Sub in a normal module called from the app_DocumentChange event).

              StuartR

            • #609410

              Sorry, but I don’t think the app_DocumentChange event works for this. I keep getting an error when I test that says:

              This command is not available because no document is open.

              I think it can handle everything except when Windows.Count=0.

              ADDITIONALLY, upon further testing, it seems that the code stored in the class module is not run until I close and reopen Word. The code to register the app is in the AutoExec module in the global template, but I would think that would be initiated when loaded at installation.

              This is my installation process:

              1. Find the global template you want to load.
              2. Look for, uninstall, and delete any global templates with the same name in the WordStartup folder.
              3. Copy the selected global template into this folder and install. I have confirmed that the AutoExec code is run at this point (added a msgbox to the code which displays at installation).

              Any clues?

              Thanks!!
              Troy

            • #609468

              What I have done is to use the app_DocumentChange event to trigger a standard sub that does the work. In that sub I check Documents.Count (amongst other things) to decide what needs doing to my toolbars.

              I have also noticed that editing code in Class Modules seems to require a complete Exit from word before the new code is picked up.

              StuartR

            • #609611

              I tried using the app_DocumentChange event as you mention, but can’t seem to get it to work as you say.

              Regarding “require a complete Exit from word”, I’ll add a message box warning them they need to close Word for changes to take affect and offering them the option to do so no (using the Application.Quit method). Sure wish there was a way to restart Word after that, but once Word is exited, Word obviously doesn’t exist to run code to open Word. Not a big deal. Surely the user can just reopen Word themselves.

              Thanks for the help!!
              Troy

            • #610324

              One last (maybe) question: I seem to be having “menu madness”. When I try to display one menu, another comes up. The scary thing is that the menus do not even have close to the same name and are not even in the same global template file. The code I’m using is:

              ActiveDocument.CommandBars(“Menu Bar”).Controls(“Tech Doc”).Visible = True
              ActiveDocument.CommandBars(“Menu Bar”).Controls(“Enable Template Macros”).Visible = False

              Doing this enables a menu named “Branding” from another global template file. This is only one sample of the behavior I am now seeing. Other menus are coming up with the right name, but the wrong contents. Its nuts

              What’s up? Is there a better way to refer to a custom menu, some index number I can find or something?

              Thanks for the help!!
              Troy

            • #611308

              I just got back from a week away, very restful, to find your plaintive messages.

              I have absolutely no idea what could be causing the wrong menus to display, it seems very wrong to me. I’d start to worry about document corruption with symptoms like that. Can you copy your code to a new blank template and recreate the toolbars?

              StuartR

            • #611385

              Thinking about your problem a bit more…

              Why are you doing this in such a complicated way? The normal way to use a different toolbar and Macro set for each document type is to put them in a template that is attached to the document.

              It would be very easy to create a template for each of your document types and then to make sure that the correct template was attached to each document, what disadvantage would this approach have for you, and could we help you to solve any problems that it introduces?

              StuartR

            • #611418

              Stuart,
              Thanks for getting back to me!! I’m glad you had a good rest. We all deserve a life outside the forum.

              Regarding attaching templates, I guess that could work. In the past I shied away from it because of problems caused when someone opened a file who had not installed the attached template or had moved the attached template to a new location. However, with the approach I am taking where the user installs this template is a specific location, and an AutoOpen macro in the doc files that checks for its existence, I’d say this could work. I could see this as being the cleanest and most stable approach.

              Not that it keeps me up nights, but I still wish I understood why what I am doing is not working. I tried the suggestion in you other post about copying the code to a new file and recreating the toolbar. The toolbars still got mixed up. I saw “Menu1” show up twice. One of these instances was attached to a document that was supposed to show “Menu2”. All of these were loaded as global templates. Even turning one off (uninstalling a global template) at a time only helped with one of the menus. Oh well, I wouldn’t spend a lot of time worrying about that. If something comes to mind, I’d love to hear it. Otherwise, I’m going to give the “Attached template” method a try. I’ll let you know if I have any other strange affects. Sometimes the best solutions are the simplest.

              Thanks for your help!!
              Troy

    Viewing 0 reply threads
    Reply To: Trouble with a class module (VBA Word 2000)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: