0
votes

I'm trying to Close the OneNote Application from VBA excel with this piece of code:

Sub closeOneNote()
                Dim oneNoteApp As Object
                On Error Resume Next
                Set oneNoteApp = GetObject(, "OneNote.Application")
                If Err.Number = 0 Then
                oneNoteApp.Quit
                Else
                Err.Clear
                End If
End Sub

When I try with Outlook instead of OneNote, it works fine and Outlook closes. I was wondering if it was because OneNote is not an application that supports automation through VBA. As shown in the below link, the table at the bottom of the page lists all the top-level Office objects Ican reference and their class names and OneNote is not among them:

Creation of Object Variables to Automate Another Office Application

Any ideas, suggestions on how to close the application (not the notebooks themselves, only the application running.. )

Thanks

2
Have you tried to get rid of On Error Resume Next you might be able to debug this...David Zemens
gives me error 429: ActiveX component can't create object or return reference to this object. Does that mean that OneNote is an Office object I can't reference ?Sebastien
Which line raises taht error? GetObject or .Quit?David Zemens
.GetObject raises the errorSebastien
Use CreateObject to get OneNote application, or dimension it as an object variable and use the CreateObject or Dim as New` methods. Quit will still fail. It is simply not supported.David Zemens

2 Answers

0
votes

OneNote Application interface (documented here) does not have a Quit method. That is why it won't work. What you can do instead is to close the OneNote window, which is somewhat tricky. Here are some instructions and sample code:

  • Get the OneNote window handle: The application object has a CurrentWindow member which then has a WindowHandle member that is a HWND to the current OneNote window.

  • Get the top level window: This handle is typically a child window of the OneNote window so you need to call GetAncestor with GA_ROOT to get the top level window

  • Close the window: You can send WM_CLOSE to the top level window to close it. Of course if it is displaying a dialog box or busy in another way, it may not respond to this.

    Option Explicit
    
    Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
    (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    
    Private Declare PtrSafe Function GetAncestor Lib "user32.dll" _
    (ByVal hwnd As Long, ByVal gaFlags As Long) As Long
    
    Private Const GA_ROOT As Long = 2
    Private Const WM_CLOSE = &H10
    
    Sub test()
        ' Create Application Object
        Dim app As Object
        Set app = CreateObject("OneNote.Application")
    
        ' Get the window handle
        Dim hwnd As Long
        hwnd = app.Windows.CurrentWindow.WindowHandle
    
        ' Get the top level window
        Dim hwndRoot As Long
        hwndRoot = GetAncestor(hwnd, GA_ROOT)
    
        ' Close it
        PostMessage hwndRoot, WM_CLOSE, 0&, 0&
    End Sub
    

This won't be enough if there are multiple OneNote windows around. For that case you can enumerate the Windows collection and do this for each Window object in it.