Повторное использование возвращенного пользовательского объекта в 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
Другие вопросы по тегам