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.
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
TIdSrc = GetWindowThreadProcessId( _
Application.hWndAccessApp, ByVal 0)
TIdDest = GetWindowThreadProcessId( _
.hWndAccessApp, ByVal 0)
If CBool(AttachThreadInput(TIdSrc, TIdDest, True)) Then
Call SetForegroundWindow(.hWndAccessApp)
Call SetFocusAPI(.hWndAccessApp)
Call GetKeyboardState(abytCodesSrc(0))
Call GetKeyboardState(abytCodesDest(0))
abytCodesDest(VK_SHIFT) = 128
Call SetKeyboardState(abytCodesDest(0))
Call .OpenCurrentDatabase(strMDBPath, False)
Call SetKeyboardState(abytCodesSrc(0))
End If
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
|