0

I am trying to run a sub in Access VBA from Python but it looks like I am facing an issue I do not quite manage to understand. Below the code that correctly opens the database (Access) but fail to run the VBA code

import os, os.path
import win32com.client

ac = win32com.client.Dispatch("Access.Application")
ac.Visible=True
ac.OpenCurrentDatabase(os.path.abspath("C:\Database.accdb"))
ac.Application.Run("Database.accdb!module3.subpycall")

The sub I am calling is quite straight forward and it is calling a click event of a button. The code of the sub can be found below

Sub subpycall()
    Call cmdUniverse_Click
End Sub

When running python,as per the above code, Access opens correctly, the main forms opens correctly but it returns the following error. Can anyhone help fixing this error?

File "C:\ON_CHAV.py", line 7, in ac.Application.Run("Database.accdb!module3.subpycall") File "<COMObject >", line 14, in Run File "C:\Users\PC\AppData\Local\Programs\Python\Python36\lib\site-packages\win32com\client\dynamic.py", line 287, in ApplyTypes result = self.oleobj.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args) pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, "Database cannot find the procedure 'Database.accdb!module3.subpycall.'", None, -1, -2146825771), None)

3 Answers 3

1

I have done this via VBS before (not sure if this is an option for you), but it's simple and can be scheduled in the Win TaskScheduler.

Step1:
In your Access module1 (?), make your 'calling' proc 'public' and (not needed), qualify where the button on a form is:

Public Sub subpycall()
    Call Form_frmMain.cmdUniverse_Click
End Sub

Step2:
Create a VBS file and put this code in it.  Use the Access object to open your database, wait for it to load 60 secs, and then call the subpycall proc.  Save as eg, subpycall.vbs:

Dim accessApp
set accessApp = createObject("Access.Application") 
accessApp.OpenCurrentDataBase("C:\CHAV.accdb")
accessApp.Visible = True
accessApp.DoCmd.OpenForm "FrmMain"
WScript.Sleep 60000
accessApp.Run "subpycall"
accessApp.Quit
Set accessApp = Nothing

Step3:
Create a bat file and put these lines in and save as subpycall.bat :

@echo off
cscript "C:\subpycall.vbs"

Step 4 (optional):
Schedule the subpycall.bat

Hope this helps.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @suki this is a nice workaround which works, but would love to call it from python as I already have a py code calling an xlsx vba code so has to be a way to call a VBA code in Access. In the meantime will test your solution and keep you posted. Thanks for the whole code!
1

I'm not really sure how to solve your main question... but when I need to run VBA from python I create a VBS (VB script file) and call it from Python.

It may be an alternative to solve your problem, and will also release you from using msaccess.

Example Python calling:

  os.system('CSCRIPT my_script.vbs "' + os.getcwd() + '\\' + filename + '"')#filename is a paramenter I send to the scrit

Example VBS:

Dim filename, objWorkBook
'On Error Resume Next
filename = WScript.Arguments(0)
Set fso = CreateObject("Scripting.FileSystemObject")
temp_filename = Left(filename,InstrRev(filename,"\")) & "3A4Output.xlsb"
fso.CopyFile "my_file.xlsb", filename
'and so on...

1 Comment

Thanks @Fabrico this seems to be the same workaround proposed by Suki (below) which seems to work
1

There are a lot of things to address here:

  1. Run needs a function that's not scoped, thus Database.accdb!module3. is not needed
  2. Run needs a function name, and subpycall is a sub
  3. subpycall needs to be public, which is default, but imo should be specified nonetheless
  4. ac is already the application, so no need to do .Application

Thus:

ac.Run("subpycall")

and:

Public Function subpycall() 'Implicit As Variant
    Call cmdUniverse_Click
End Sub

1 Comment

Unfortunately this solution doesn't seem to work ac.Run("subpycall") File "<COMObject Access.Application>", line 14, in Run File "C:\Users\PC\AppData\Local\Programs\Python\Python36\lib\site-packages\win32com\client\dynamic.py", line 287, in ApplyTypes result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args) pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352562), None)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.