Повторное использование возвращенного пользовательского объекта в Python-xlwings
Вопрос довольно концептуальный: при использовании xlwings и UDF функции python вызываются из Excel, а возвращаемое значение возвращается в Excel.
Теперь рассмотрим функцию, которая получает некоторый ввод из Excel, ее возвращаемое значение является пользовательским объектом, и это возвращаемое значение следует использовать во многих последующих вычислениях, которые должны быть показаны на листе Excel.
Можно ли использовать этот возвращенный пользовательский объект в последующем вызове Excel или отображаемые результаты являются своего рода "концом пути", если не возвращается встроенная переменная?
Под доступом я подразумеваю либо использование его в качестве входной переменной для последующего вызова Excel (в качестве адреса ячейки), либо в качестве переменной, которая хранится в скрипте pyhon перед возвратом чего-либо, чтобы к нему можно было получить доступ в скрипте python в паре с Excel простынь.
Я надеюсь, что мой вопрос ясен, но АМА, если нет.
1 ответ
Эту проблему я решил уже давно.
В коде ниже@xw.arg('x', ExcelVar)
означает, что аргумент с именемx
соответствующее имя переменной, ранее возвращенное в Excel другой функцией, будет заменено тем, что хранится в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 not isinstance(var_name, str):
return 'ExcelVar needs to be a string'
if var_name not in ExcelVar.var_values:
return f"{var_name} undefined"
return ExcelVar.var_values[var_name]
@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 not in ExcelVar.var_values:
return f"{var_name} undefined"
del ExcelVar.var_values[var_name]
return f"{var_name} deleted"
@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