I am trying to read a macro in excel through python code but not able to do so as it is not able to find the macro. Also apart from the code if I try to view the macro just by opening Excel > Alt + F11 then I am supposed to enter the password. Is this the reason that the python code is not able to read the macro as I am trying to read a password protected macro using python. If so, please suggest what should be the workaround to read it. Thanks! Attaching the code snippet and error below :
Code :
import os
import win32com.client
os.chdir("C:\new folder\Input folder")
if os.path.exists("Input excel.xlsm"):
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(os.path.abspath("Input excel.xlsm"))
xl.Application.Run("Input excel.xlsm!module1.mymethod") #mymethod is of type sub
xl.Application.Save()
xl.Application.Quit()
del xl
Error :
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, u'Microsoft Excel', u"Cannot run the macro 'Input excel.xlsm!module1.mymethod'. The macro may not be available in this workbook or all macros may be disabled.", u'xlmain11.chm', 0, -2146827284), None)
I have tried all the below possible solutions but the issue is still there :
1) Using the correct convention to call the macro : xl.Application.Run("excelsheet.xlsm!modulename.macroname")
2) Changing the excel settings :
1.File > Options > Trust Center
2.Click on Trust Center Settings... button
3.Macro Settings > Check Enable all macros
Related
I am working with legacy access code and am using pywin32 to automate batch processing.
This python code:
import win32com.client as win32
access = win32.Dispatch('Access.Application')
db = access.OpenCurrentDatabase(r'C:\test\PN.mdb')
access.Forms('frm_PN_Startup').cmdScenarioExport_Click()
sucessfully executes this Access VBA sub
Public Sub cmdScenarioExport_Click()
Export_Scenario_To_ScenarioDB
End Sub
I would like to pass an optional text string to fill the Access InputBox that opens in Export_Scenario_To_ScenarioDB. However, when I try
Python
import win32com.client as win32
access = win32.Dispatch('Access.Application')
db = access.OpenCurrentDatabase(r'C:\test\PN.mdb')
access.Forms('frm_PN_Startup').cmdScenarioExport_Click("hello")
Vba
Public Sub cmdScenarioExport_Click(Optional strTest As String = "")
Export_Scenario_To_ScenarioDB (strTest)
End Sub
I get the following error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Users\RS\miniconda3\envs\PN_PY\lib\site-packages\win32com\client\dynamic.py", line 197, in __call__
return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2146788252), None)
win32api tells me that the error is
win32api.FormatMessage(-2147352567)
'Exception occurred.\r\n'
After numerous hours spinning my wheels, I'm asking for any ideas to make this work. Thank you! This is my first foray into VBA.
I am using python to run excel macros but the problem I am getting is that an error is popping up when I run the macros.
How can hide this error pop up?
Following are the piece of code :
try:
if os.path.exists("C:\\test.xlsm"):
# DispatchEx is required in the newest versions of Python.
excel_macro = win32com.client.DispatchEx("Excel.application")
excel_path = os.path.expanduser("C:\\test.xlsm")
workbook = excel_macro.Workbooks.Open(Filename=excel_path,ReadOnly=1)
excel_macro.Application.DisplayAlerts = False
excel_macro.Application.Run("Macro1")
# Save the results in case you have generated data
workbook.Save()
excel_macro.Application.Quit()
del excel_macro
except:
print("Error found while running the excel macro!")
excel_macro.Application.Quit()
I am trying to pass the variable Nothing in VBA using Python's win32com. I tried to use None but it returned 'Type dismatch.'
Could anyone please help?
Thank you!
An example:
' Book1.xlsm!Module1
Function test(arg As Object) As String
If arg Is Nothing Then
test = "Success"
Exit Function
Else
test = "Failure"
Exit Function
End If
End Function
And in Python:
import win32com.client
import os
import pythoncom
xl = win32com.client.Dispatch('Excel.Application')
xl.Visible = True
xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm'))
test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty)
The REPL says:
runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads')
Traceback (most recent call last):
File "<ipython-input-22-301693920f2c>", line 1, in <module>
runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads')
File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
execfile(filename, namespace)
File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/shwang/Downloads/untitled0.py", line 16, in <module>
test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty)
File "<COMObject <unknown>>", line 14, in Run
File "C:\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352561), None)
In VBA, Nothing is used as the uninitialized default value Object type which usually references COM objects (i.e., Excel object library or external application's object library). VBA's primitive integer, long, and string types cannot be assigned the Nothing value. And usually programmers use this at the end of code block to release objects from memory.
Hence, there is no strict translation between VBA's Nothing (a special value for COM types) and Python's value types including None which crudely means empty or no value for any type.
With that said, your code will not err out if you pass a COM object which you already initialize with xl. Below outputs FAILURE. If somehow you can declare an uninitialized COM object which then will carry Nothing then you can pass that into your function. But to call Dispatch requires a named object. Catch-22!
import win32com.client
import os
try:
xl = win32com.client.Dispatch('Excel.Application')
xl.Visible = True
wb = xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm'))
test_str = xl.Application.Run('test', xl)
print(test_str)
# FAILURE
wb.Close(False)
xl.Quit
except Exception as e:
print(e)
finally:
wb = None
xl = None
Here is a working example (in python) that passes VBA Nothing object to SolidWorks API.
import win32com.client
import pythoncom
swApp = win32com.client.Dispatch('SldWorks.Application')
Part = swApp.ActiveDoc
boolstatus = Part.Extension.SelectByID2("", "SKETCHCONTOUR", 75e-3, -4e-3, 0, False, 0, pythoncom.Nothing, 0)
print(boolstatus)
Here is the output in Sublime Text 3:
True
[Finished in 0.7s]
The script tries to select a sketch contour with the coordinates (75mm, -4mm). The "Callout" argument of the SolidWorks API "SelectByID2" is assigned as pythoncom.Nothing. For the script to work, the premise is that you are editing a sketch as shown in the attached figure below.
The attached figure shows what happens in SolidWorks (before | after).
Pass Nothing to SW API SelectByID2
Some background. I want to draw some electric motor geometry in SolidWorks via python because I already have the working python codes with other drawing tools (such as JMAG Designer, FEMM, or PyX).
Thanks for the post! Your discussion helps me find this.
I am trying to save the chart from Excel as an image file in Python. I am using WIn32com, the chart is getting exported as required but when I am trying to delete the ActiveSheet,it is giving me the error.
excel.ActiveSheet().Delete()
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 192, in __call__
return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
pywintypes.com_error: (-2147352573, 'Member not found.', None, None)
Any help to overcome this error?
Below is my code:
import win32com.client as win32
def saveChart():
excel = win32.Dispatch("Excel.Application")
wb = excel.Workbooks.Open(r'C:\Users\projects\Rating.xlsx')
selection = "A1:K16"
xl_range = wb.Sheets("Categories").Range(selection)
excel.ActiveWorkbook.Sheets.Add().Name="image_sheet"
cht = excel.ActiveSheet.ChartObjects().Add(0,0,xl_range.Width, xl_range.Height)
xl_range.CopyPicture()
cht.Chart.Paste()
cht.Chart.Export(r'C:\Users\projects\MyExportedChart.png')
excel.DisplayAlerts = False
cht.Delete()
excel.ActiveSheet.Delete()
excel.DisplayAlerts = True
excel.ActiveWorkbook.Close()
I took the code from Export Charts from Excel as images using Python
Updated the code,which worked
Is ActiveSheet a field, like you're using it here:
cht = excel.ActiveSheet.ChartObjects().Add(0,0,xl_range.Width, xl_range.Height)
Or a method like you're using it here:
excel.ActiveSheet().Delete()
Since the first call doesn't give you the error, and the error says that the member is not found, I'm going to guess that the second one is wrong, and should be:
excel.ActiveSheet.Delete()
I am using PIOLEDBENT provider, i need to extract list of databases in my PIAF Server when i call oConn.GetSchema i throws exception mention bellow. please guide me what is wrong with my code.
from win32com.client import Dispatch
oConn = Dispatch('ADODB.Connection')
oRS = Dispatch('ADODB.RecordSet')
oConn.ConnectionString = "Provider=PIOLEDBENT; Data Source=localhost; Integrated Security=True; Integrated Security=True;User ID=abubakr;Password=#Spark123!"
oConn.Open()
oConn.GetSchema();
Exception :
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, u'ADODB.Connection', u'Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.', u'C:\\Windows\\HELP\\ADO270.CHM', 1240641, -2146825287), None)