可以分辨哪个工作簿调用了Excel外接程序(xla)中的函数

gopyfrb3  于 2023-04-22  发布在  其他
关注(0)|答案(5)|浏览(135)

我想在excel插件中写一个小的日志函数,我将从许多不同的工作簿中调用它。我希望能够通过只传递日志文本来调用它,并且日志函数本身可以处理时间戳,workbookname等。
但是,我不能使用ThisWorkbook或ActiveWorkbook来确定哪个工作簿负责进行调用,因为Thisworkbook将返回对加载项本身的引用,而在Excel中具有活动焦点的工作簿以外的工作簿中运行的VBA代码可以进行调用,但ActiveWorkbook将返回在窗口中具有焦点的工作簿。
Caller看起来是一个可行的解决方案,但这似乎只在从单元格调用函数时有效,而不是从VBA调用。
我想做的事是不可能的吗?

更新

根据〉1人的说法,这实际上是不可能的。如果有人碰巧知道一些聪明的变通方法,请说出来。

tjvv9vkg

tjvv9vkg1#

好的,正确阅读问题后,我再试一次……
所以,为了说明问题:
你想要一个写在插件中的例程,当从另一个工作簿中的vba调用时,它可以计算出(除了其他事情之外)哪个工作簿包含进行调用的vba,而不必显式地传递此信息。
如上所述,这是不可能的(这是一个类似于从代码访问调用堆栈的问题:(据我所知不可能)
然而你几乎可以得到你想要的像这样
像这样声明你的log函数:

Sub MyLogger(wb as Workbook, LogText as String)
    Dim CallerName as String
    CallerName = wb.name
    ' your code...
End Sub

然后无论你叫潜艇用什么

MyLogger ThisWorkbook, "Log Text"

虽然不像什么都不传那么好,但至少总是一样的

j1dl9f46

j1dl9f462#

若要获取调用工作簿的名称,请使用

Application.Caller.Worksheet.Parent.Name

调用者返回有关如何调用VisualBasic的信息。如果从单个单元格中输入的自定义函数调用,则返回指定该单元格的Range对象
获得对单元格的引用后,.Worksheet.Parent.Name将提供工作簿的名称
请注意,Application.Caller将根据函数的调用方式返回其他内容(有关详细信息,请参阅VBA帮助)

u0sqgete

u0sqgete3#

在由Excel Worksheet Array Entered Function Call调用的外接程序函数中,我发现“Application.Caller.Parent.name”给出了工作表名称(选项卡名称,而不是工作表编号)。

sz81bmfz

sz81bmfz4#

我在编写自定义函数时也遇到了同样的问题。函数运行良好,但每当计算或激活另一个工作簿时,使用该函数的所有单元格都会恢复为#value。使用此公式处理多个文件时可能会非常令人沮丧。
获取我使用的工作簿:

Dim CallingWb As Workbook
Set CallingWb = Application.Caller.Parent.Parent

如果你的函数在一个单元格中,这应该是可行的。
对于最初的帖子来说太晚了,但可能会帮助其他人!

doinxwow

doinxwow5#

我知道这个答案大约晚了12年,但我最近也遇到了同样的问题,并有一个解决方案,可能会帮助其他人在这种情况下。
我的解决方案是将记录器接口编码为一个类。要使用记录器,调用应用程序必须获得该类的新示例,然后调用该示例的log方法,而不是调用外接程序的全局log方法。
要提供logger类的新示例,请编写一个全局工厂函数(例如:set myLogger = loggerAddin.newLogger(workbook),或类似的),其中workbook是对调用者的引用。该引用保存在日志记录器示例中,然后可以在日志记录函数(例如myLogger.log(message))中引用,而无需为这些日志记录函数提供对工作簿的引用。

相关问题