LikeLike

]]>LikeLike

]]>LikeLike

]]>All the functions should then be available from any open workbook.

LikeLike

]]>movav(AvData,5), entering =MAvg5 in a cell results in an error message #VALUE. Do you have any idea what could be going on?

LikeLike

]]>LikeLike

]]>In the case given in your example, I agree that using optional arguments in Python is now the easiest way to go, since xlwings will now generate the required optional arguments in the VBA UDF, and generate the correct input for the Python function.

However for this to work we need to know the number of required and optional arguments. The purpose of the procedures given in the article is to use a single VBA UDF

to call Python functions that have a variable number of optional arguments, or to use a single VBA function to call a large number of different Python functions, which may have different numbers of required and optional arguments. An example of the latter is calling the Scipy statistics functions (see https://newtonexcelbach.com/2018/07/10/scipy-statistics-functions-coding-and-getting-help/ for details).

Another use is when the Python function has a large number of optional arguments, which is the case for many Scipy functions. This procedure allows the optional arguments to be passed as kwargs, rather than having to define them all as optional arguments in the wrapper function.

LikeLike

]]>scipy.optimize.brentq(f, a, b, xtol=1e-12, rtol=4.4408920985006262e-16, maxiter=100, full_output=False, disp=True, *args

and assume the function is exposed in Excel clarifying there are default values for some arguments. Unfortunately, while Python is passing arguments by keyword, and it can skip those with a defaul valuet, Excel is only positional. If we call brentq from Excel with xtol and rtol unset:

scipy.optimize.brentq(f,a,b,,,50)

what Python will see is

scipy.optimize.brentq(f,a,f,None,None,50)

and of course this will result in an error, because xtol and rtol must be numbers (actually we wanted to keep their default values). The approach to build a dictionary in Excel with vba to solve the problem seems too much to me. My preferred way is to wrap brentq in Python

def xl_brentq (f, a, b, xtol=None, rtol=None, maxiter=None, full_output=None, disp=None,*args):

return scipy.optimize.brentq (**{k: v for k, v in locals().items() if v!=None})

Now you can call it from Excel as xl_brentq(f,a,b,,,50) and it will work: the wrapper function is building the call to scipy.optimize.brentq using only arguments different from None; xtol and rtol are not given, and so scipy.optimize.brentq will use its defaults. In other words, the wrapper is building the right dictionary for us.

LikeLike

]]>LikeLike

]]>LikeLike

]]>