Home  |   French  |   About  |   Search  | mvps.org  

What's New
Table Of Contents
Credits
Netiquette
10 Commandments 
Bugs
Tables
Queries
Forms
Reports
Modules
APIs
Strings
Date/Time
General
Downloads
Resources
Search
Feedback
mvps.org

In Memoriam

Terms of Use


VB Petition

API: Bypassing Autoexec

Author(s)
Dev Ashish
  Often times, when writing code that automates Access over one or more databases, it's necessary to bypass the Autoexec macro, especially if the developer is trying to get to the Access Object Model, rather than Jet's (which can be obtained through both DAO and ADO). However, Access does not provide any built-in way to conditionally bypass the macro.  If a database contains the macro, it will run! It can be only be bypassed at startup time (from the User Interface) with the shift key, provided the AllowBypassKey property has not been set.

  If the AllowBypassKey has not been set, then the 'Shift' key can be programmtically pressed when the database is opened programmatically through Automation code.  To get a reference to a hidden instance of Access with the database in which you wanted to bypass the Autoexec macro, you can use this function.

'********* Code Start ***********
' This code was originally written by Dev Ashish.
' It is not to be altered or distributed,
' except as part of an application.
' You are free to use it in any application,
' provided the copyright notice is left unchanged.
'
' Code Courtesy of
' Dev Ashish
'
'
Private Declare Function SetKeyboardState _
    Lib "user32" _
    (lppbKeyState As Any) _
    As Long
    
Private Declare Function GetKeyboardState _
    Lib "user32" (pbKeyState As Any) _
    As Long

Private Declare Function GetWindowThreadProcessId _
    Lib "user32" _
    (ByVal hWnd As Long, _
    lpdwProcessId As Long) _
    As Long

Private Declare Function AttachThreadInput _
    Lib "user32" _
    (ByVal idAttach As Long, _
    ByVal idAttachTo As Long, _
    ByVal fAttach As Long) _
    As Long

Private Declare Function SetForegroundWindow _
    Lib "user32" _
    (ByVal hWnd As Long) _
    As Long

Private Declare Function SetFocusAPI _
    Lib "user32" Alias "SetFocus" _
    (ByVal hWnd As Long) _
    As Long

Private Const VK_SHIFT = &H10
Private Const VK_LSHIFT = &HA0
Private Const VK_RSHIFT = &HA1

Function fGetRefNoAutoexec( _
                        ByVal strMDBPath As String) _
                        As Access.Application
On Error GoTo ErrHandler
Dim objAcc As Access.Application
Dim TIdSrc As Long, TIdDest As Long
Dim abytCodesSrc(0 To 255) As Byte
Dim abytCodesDest(0 To 255) As Byte

    If (Len(Dir$(strMDBPath, vbNormal)) = 0) Then
        Err.Raise 53
    End If

    Set objAcc = New Access.Application
    With objAcc
        .Visible = True

        ' attach to process
        TIdSrc = GetWindowThreadProcessId( _
                            Application.hWndAccessApp, ByVal 0)
        TIdDest = GetWindowThreadProcessId( _
                            .hWndAccessApp, ByVal 0)
                
        If CBool(AttachThreadInput(TIdSrc, TIdDest, True)) Then
            Call SetForegroundWindow(.hWndAccessApp)
            Call SetFocusAPI(.hWndAccessApp)
            
            ' Set Shift state
            Call GetKeyboardState(abytCodesSrc(0))
            Call GetKeyboardState(abytCodesDest(0))
            abytCodesDest(VK_SHIFT) = 128
            Call SetKeyboardState(abytCodesDest(0))
        
            ' Open a mdb with Autoexec
            Call .OpenCurrentDatabase(strMDBPath, False)
            
            ' Revert back keyboard state
            Call SetKeyboardState(abytCodesSrc(0))
        End If
        ' release
        Call AttachThreadInput(TIdSrc, TIdDest, False)
        Call SetForegroundWindow(Application.hWndAccessApp)
        Call SetFocusAPI(Application.hWndAccessApp)
        
    End With
    Set fGetRefNoAutoexec = objAcc
    Set objAcc = Nothing

    Exit Function
ErrHandler:
    If (TIdDest) Then Call AttachThreadInput(TIdSrc, TIdDest, False)
    Call SetForegroundWindow(Application.hWndAccessApp)
    With Err
        .Raise .Number, .Source, .Description, .HelpFile, .HelpContext
    End With
End Function
'********* Code End ***********

© 1998-2010, Dev Ashish & Arvin Meyer, All rights reserved. Optimized for Microsoft Internet Explorer