问题相当概念性:使用xlwings和UDF时,从Excel调用python函数并将返回值返回给Excel。
现在考虑一个从 Excel 获取一些输入的函数,其返回值是一个自定义对象,并且该返回值应该在 Excel 工作表中显示的许多后续计算中使用。
是否可以在后续 Excel 调用中使用此返回的自定义对象,或者如果未返回内置变量,则显示的结果是否是“路的尽头”?
通过访问,我的意思是要么将其用作后续 Excel 调用的输入变量(作为单元格地址),要么用作返回任何内容之前存储在 pyhon 脚本中的变量,以便可以在与Excel 表格。
我希望我的问题很清楚,但如果没有,请AMA。
我很久以前就解决了这个问题。
在下面的代码中,
@xw.arg('x', ExcelVar)
表示与先前在 Excel 中由另一个函数返回的变量名相对应的名为 x
的参数将在函数体执行之前被存储在 var_values
静态字典中的内容替换。那么这意味着你可以在Python或Excel中使用相同的函数。在 Python 中传递任何对象,在 Excel 中传递变量名称。
这非常有用,它甚至可能包含在 xlwings 库中,但我还没有关注是否有人做了类似的事情。
# excel wings functions for reading an object in excel, can be uncommented if needed
import xlwings as xw
from xlwings.conversion import Converter
#http://docs.xlwings.org/en/stable/converters.html
class ExcelVar(Converter):
var_names = {}
var_values = {}
#CRUD methods (create, read, update, delete)
@staticmethod
def write_value(value, options):
var_name = options.get('name', 'var')
if var_name in ExcelVar.var_names:
ExcelVar.var_names[var_name] += 1
else:
ExcelVar.var_names[var_name] = 0
used_var_name = f"{var_name}_{ExcelVar.var_names[var_name]}"
ExcelVar.var_values[used_var_name] = value
return used_var_name
@staticmethod
def read_value(var_name, options):
#allows to pass a variable string name or a value directly from Excel
if isinstance(var_name, str):
if var_name in ExcelVar.var_values:
return ExcelVar.var_values[var_name]
else:
return f"{var_name} undefined"
else:
return 'ExcelVar needs to be a string'
@staticmethod
def update_value(var_name, value):
ExcelVar.var_values[var_name] = value
return var_name
@staticmethod
def delete_value(var_name):
if var_name in ExcelVar.var_values:
del ExcelVar.var_values[var_name]
return f"{var_name} deleted"
else:
return f"{var_name} undefined"
@staticmethod
def var_exists(var_name):
return var_name in ExcelVar.var_values
#helper functions to be used in Excel or in python code
@xw.func
def create_excel_var(var_name, value):
#returns an incremented variable like in excel
return ExcelVar.write_value(value, dict(name=var_name))
@xw.func
def read_excel_var(var_name):
return ExcelVar.read_value(var_name, {})
@xw.func
def update_excel_var(var_name, value):
#updates or writes a new non incremented variable
return ExcelVar.update_value(var_name, value)
@xw.func
def delete_excel_var(var_name):
return ExcelVar.delete_value(var_name)
@xw.func
def excel_var_exists(var_name):
return ExcelVar.var_exists(var_name)
#practical examples of ExcelVar for excel
@xw.func
@xw.ret(ExcelVar, name='test_var')
def test_excel_var(x):
return x + 1
@xw.func
@xw.arg('x', ExcelVar)
def test_read_excel_var(x):
return x