如何确保Excel持续连接Bloomberg实现自动化,支持后台及锁屏运行?
后台运行Excel宏刷新Bloomberg公式的问题处理
现有实现代码
import time import win32com.client as win32 import gc def update_excel_and_send_email(): excel = win32.gencache.EnsureDispatch('Excel.Application') excel.Visible = False try: wb = excel.Workbooks.Open('mypath') wb.RefreshAll() time.sleep(10) excel.Application.Run("Send2") except Exception as e: print("Error: " + str(e)) finally: wb.Close(SaveChanges=False) excel.Quit() excel = None gc.collect() if __name__ == '__main__': update_excel_and_send_email()
Bloomberg公式示例:
需求与问题
- 核心需求:无界面后台运行Excel宏,支持电脑锁屏时通过调度器自动执行
- 当前异常:锁屏后代码能正常运行1-2小时,但之后宏发送的邮件里所有Bloomberg公式都显示#N/A;手动刷新无效,必须完全重启Excel才能恢复;后台运行时公式偶尔也无法刷新,希望不用等宏执行完就能继续后续操作
问题根源
- Excel崩溃后,Bloomberg插件的会话或残留进程未彻底释放,导致后续公式无法正常拉取数据
- 固定10秒的
time.sleep()不可靠,Bloomberg数据刷新耗时受网络和服务器影响,等待时间可能不足或冗余 - 无界面后台模式下,Excel与Bloomberg插件的交互可能出现会话异常,导致刷新失败
解决方案
1. 优化刷新逻辑,确保数据加载完成
替换固定等待时间,改用Excel原生方法等待异步查询完成,再触发计算:
import time import win32com.client as win32 import gc def update_excel_and_send_email(): excel = win32.gencache.EnsureDispatch('Excel.Application') excel.Visible = False # 切换手动计算,避免自动计算干扰刷新流程 excel.Calculation = win32.constants.xlCalculationManual try: wb = excel.Workbooks.Open('mypath') # 触发所有数据连接刷新(含Bloomberg) wb.RefreshAll() # 等待所有异步查询完成(专门针对Bloomberg这类异步数据源) excel.CalculateUntilAsyncQueriesDone() # 额外留几秒缓冲,确保插件处理完毕(可根据实际情况调整) time.sleep(3) # 手动触发全表计算,保证公式更新 wb.Worksheets.Calculate() # 执行宏 excel.Application.Run("Send2") except Exception as e: print(f"Error: {str(e)}") finally: # 确保工作簿关闭,即使中间出错 if 'wb' in locals(): wb.Close(SaveChanges=False) # 彻底退出Excel并清理资源 excel.Quit() del excel gc.collect() if __name__ == '__main__': update_excel_and_send_email()
2. 彻底清理Excel残留进程
如果Excel崩溃后残留进程导致后续异常,可以在finally块中强制清理:
import psutil # 在finally块中添加以下代码(注意:会杀死所有Excel进程,谨慎使用) for proc in psutil.process_iter(['name']): if proc.info['name'] == 'EXCEL.EXE': try: proc.kill() except: pass
3. 调整后台运行配置
- 启用Excel忽略远程请求,避免锁屏时系统限制:
excel.IgnoreRemoteRequests = True
- 检查Bloomberg Excel插件设置,确保允许后台刷新,不需要用户交互确认
4. 异步执行宏,无需等待完成
如果希望不用等宏执行完就能继续操作,可以把宏放到线程中运行:
import threading def run_macro(excel): try: excel.Application.Run("Send2") except Exception as e: print(f"Macro Error: {str(e)}") # 在主函数中替换excel.Application.Run("Send2")为: macro_thread = threading.Thread(target=run_macro, args=(excel,)) macro_thread.start() # 这里可以添加其他需要立即执行的逻辑,不用等宏结束
注意事项
- 锁屏时系统可能限制后台进程的网络资源,确保Bloomberg终端在锁屏状态下仍能保持正常连接
- 定期重启Excel进程,避免长时间运行导致插件内存泄漏或会话异常
- 调试时可以临时设置
excel.Visible = True,直观观察刷新过程是否有错误提示
内容的提问来源于stack exchange,提问作者quantymacromarco
相关产品推荐
相关产品推荐

