xlwings:如何检测是否从 VBA 模块调用了 python 函数?
xlwings: how to detect whether a python function is being called from VBA module?
情况
xlwings 包提供了 call python functions from an excel VBA module 的便捷方式。 xlwings 文档给出了以下基本示例:
Write the code below into a VBA module.
Sub HelloWorld()
RunPython ("import hello; hello.world()")
End Sub
This calls the following code in hello.py
:
# hello.py
import numpy as np
import xlwings as xw
def world():
wb = xw.Book.caller()
wb.sheets[0].range('A1').value = 'Hello World!'
尝试 运行 python 函数 world()
直接(而不是从 excel VBA 调用它)给出以下错误消息:
Exception: Book.caller() must not be called directly. Call through
Excel or set a mock caller first with Book.set_mock_caller().
问题
我想修改 world()
函数,使其在直接 运行 时引发自定义异常。为了实现这一点,我首先需要以编程方式确定 world()
函数是直接被 运行 调用还是从 excel VBA 调用(至少我是这么想的).我该怎么做?
您可以捕获异常然后引发您自己的异常:
def world():
try:
wb = xw.Book.caller()
except Exception:
raise CustomException(custom_message)
wb.sheets[0].range('A1').value = 'Hello World!'
您担心 Exception
过于笼统,这是正确的。但那是 xlwings 的错,不是你的错。如果它引发了一个通用的 Exception
,那么你就只能抓住它了。您可以检查异常消息以确保您没有捕捉到错误的异常,但这会很脆弱。错误信息通常是未记录的,不被视为 public,稳定 API.
或者,您可以解决问题所在,xlwings' source code,并让它做我认为正确的事情:引发更具体的异常。
class NotFromExcelError(Exception):
pass
并且在 caller
结束时:
raise NotFromExcelError('Book.caller() must not be called directly. Call through Excel '
'or set a mock caller first with Book.set_mock_caller().')
我希望像这样的拉取请求能够被接受,因为像现在这样提出一个裸 Exception
看起来确实是错误的。
情况
xlwings 包提供了 call python functions from an excel VBA module 的便捷方式。 xlwings 文档给出了以下基本示例:
Write the code below into a VBA module.
Sub HelloWorld() RunPython ("import hello; hello.world()") End Sub
This calls the following code in
hello.py
:# hello.py import numpy as np import xlwings as xw def world(): wb = xw.Book.caller() wb.sheets[0].range('A1').value = 'Hello World!'
尝试 运行 python 函数 world()
直接(而不是从 excel VBA 调用它)给出以下错误消息:
Exception: Book.caller() must not be called directly. Call through Excel or set a mock caller first with Book.set_mock_caller().
问题
我想修改 world()
函数,使其在直接 运行 时引发自定义异常。为了实现这一点,我首先需要以编程方式确定 world()
函数是直接被 运行 调用还是从 excel VBA 调用(至少我是这么想的).我该怎么做?
您可以捕获异常然后引发您自己的异常:
def world():
try:
wb = xw.Book.caller()
except Exception:
raise CustomException(custom_message)
wb.sheets[0].range('A1').value = 'Hello World!'
您担心 Exception
过于笼统,这是正确的。但那是 xlwings 的错,不是你的错。如果它引发了一个通用的 Exception
,那么你就只能抓住它了。您可以检查异常消息以确保您没有捕捉到错误的异常,但这会很脆弱。错误信息通常是未记录的,不被视为 public,稳定 API.
或者,您可以解决问题所在,xlwings' source code,并让它做我认为正确的事情:引发更具体的异常。
class NotFromExcelError(Exception):
pass
并且在 caller
结束时:
raise NotFromExcelError('Book.caller() must not be called directly. Call through Excel '
'or set a mock caller first with Book.set_mock_caller().')
我希望像这样的拉取请求能够被接受,因为像现在这样提出一个裸 Exception
看起来确实是错误的。