如何等待xlwings在vba中完成python代码?
我使用下面的代码从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代码完全完成?
一些信息开始:Mac上的Excel只允许外部进程写入单元格,当Excel空闲,即没有macros正在运行。 这就是为什么Mac上的RunPython
调用作为后台进程运行,只有当调用macros完成运行时才真正启动。
我会build议以下两个解决scheme之一:
1)用Python scipy.optimize
求解器部分,例如使用scipy.optimize
。
2)把求解器VBA放到它自己的Sub中,并从Python中调用它。 这是目前xlwings下一版本的计划function,请参阅此处 ,但现在可以像现在这样工作(假设wb
是您的工作簿):
app = xlwings.Application(wkb=wb) app.xl_app.run_VB_macro('SolverMacro')
更新 ,自v0.7.1以来,这是现在正确支持:
>>> solver_macro = wb.macro('SolverMacro') >>> solver_macro()
也许有点笨重,但也看看Application.OnTime
方法,它可以让你安排代码在设定的时间运行。 所以把你的解算器代码放到另一个proc中,调用RunPython
,然后安排求解器的处理时间为10秒钟。
或者,可能是一个更好的答案,得到的Python代码写入一个Range
或文本文件时完成。 具有解算器代码的proc将查看范围或文件,以查看是否完成了python。 如果python没有完成,则安排自己在N秒内重新运行,否则运行求解器。
另一种方法是在Python代码末尾的隐藏工作表中更改一个值,并用一个Worksheet_Change
代码片段来启动一些vba代码。 如果隐藏表是“补充”,那么在Python代码的末尾添加这样的内容:
范围('补充','A1')。值=范围('补充','A1'),值+1
而“补充”表中的vba可以是:
私人小组Worksheet_Change(BYVAL目标作为范围)
如果不相交(Target,Me.Range(“A1”))是Nothing
工作表(“Main1”)。范围(“A1”)。WrapText = True
万一
结束小组
请记住, Application.EnableEvents
需要= True