如何等待xlwings在vba中完成python代码?

时间:2015-06-19 05:00:05

标签: python excel vba xlwings

我使用以下代码从xlwings模块调用VBA中的RunPython:

Sub Portfolio_Optimze()
RunPython ("import quotes; quotes.get_quote()")
SolverAdd CellRef:="$H$18:$H$24", Relation:=1, FormulaText:="$J$18:$J$24"
SolverAdd CellRef:="$B$15:$G$15", Relation:=4
SolverOk SetCell:="$H$16", MaxMinVal:=1, ValueOf:=0, ByChange:="$B$15:$G$15", _
    Engine:=1, EngineDesc:=" GRG Nonlinear "
SolverSolve

如何让SolverAdd代码等到RunPython代码完全结束?

2 个答案:

答案 0 :(得分:1)

开始时的一些信息:Mac上的Excel仅允许外部进程在Excel空闲时写入单元格,即没有运行宏。这就是为什么Mac上的RunPython调用作为后台进程运行,只有在调用宏完成运行时才真正启动。

我建议采用以下两种解决方案之一:

1)也可以用Python编写求解器部分,例如使用scipy.optimize

2)将求解器VBA放入自己的Sub中,并从Python中调用它。这是xlwings下一版本的计划功能,请参阅here,但您可以暂时解决此问题(假设wb是您的工作簿):

app = xlwings.Application(wkb=wb)
app.xl_app.run_VB_macro('SolverMacro')

更新,自v0.7.1起,现在已正确支持:

>>> solver_macro = wb.macro('SolverMacro')
>>> solver_macro()

答案 1 :(得分:0)

有点笨拙,也许,但也看看Application.OnTime方法,它允许您安排代码在设定的时间运行。所以把你的求解器代码放到另一个proc中,调用RunPython,然后安排解算器proc,比如10秒钟。

或者,可能是一个更好的答案,让python代码在完成后写入Range或文本文件。带解算器代码的proc将查看范围或文件以查看是否已完成python。如果python没有完成,那么安排自己在N秒内再次运行,否则运行解算器。