开发者

Calling Excel macros/Excel Solver from Python over com

I have a macro inside a 2007 xlsm file that, when called, creates a solver configuration (target, constraints, ...) and performs the solve without any user interaction. When run manually from Excel, this works fine.

I now want to script this from Python over com. However, when the Python code calls the solver macro:

app.Run("runSolver()")

It fails with:

foobar.xlsm failed to solve, error message: Error in model. Please verify that all cells and constraints are valid.

If I set a breakpoint in my Python environment at the call to Run() and then run the macro manually from Excel, it works fine, so the solver configuration can't be wrong.

The error message is listed on the solver website but I don't think it applies as the sheet solves fine manually.

This page suggests that the solver environment is not yet set up when calling through com. However, adding

Application.Run "Solver.xla!Solver.Solver2.Auto_open"

As the first line of my solver macro results in the more generic:

  File "c:\python26\lib\site-packages\win32com\gen_py\00020813-0000-0000-C000-000000000046x0x1x6.py", line 35061, in Run
    , Arg26, Arg27, Arg28, Arg29, Arg30
  File "c:\python26\lib\site-packages\win32com\client\__init__.py", line 456, in _ApplyTypes_
        self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),
com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2146827284), None)

So what is the right thing to do?


Edit:

I isolated it dow开发者_运维问答n to a reproducable test case:

Python code:

from win32com.client import Dispatch
if __name__ == '__main__':
    app = Dispatch("Excel.Application")
    app.Visible = True
    app.Workbooks.Open(r'C:\path\to\testsolver.xlsm')
    app.Run("runsolver()")

Excel file: http://dl.dropbox.com/u/3142953/testsolver.xlsm (you can open it with Macros disabled and inspect the simple sub in module1 to verify it's safe).


I finally found a solution after posting on the MSDN Excel Developers forum. And the solution was maddingly trivial:

Instead of running the solver like so:

app.Run("runsolver()")

You apparently have to drop the brackets and run it like so:

app.Run("runsolver")

Go figure.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜