我想在excel插件中写一个小的日志函数,我将从许多不同的工作簿中调用它。我希望能够通过只传递日志文本来调用它,并且日志函数本身可以处理时间戳,workbookname等。
但是,我不能使用ThisWorkbook或ActiveWorkbook来确定哪个工作簿负责进行调用,因为Thisworkbook将返回对加载项本身的引用,而在Excel中具有活动焦点的工作簿以外的工作簿中运行的VBA代码可以进行调用,但ActiveWorkbook将返回在窗口中具有焦点的工作簿。
Caller看起来是一个可行的解决方案,但这似乎只在从单元格调用函数时有效,而不是从VBA调用。
我想做的事是不可能的吗?
更新
根据〉1人的说法,这实际上是不可能的。如果有人碰巧知道一些聪明的变通方法,请说出来。
5条答案
按热度按时间tjvv9vkg1#
好的,正确阅读问题后,我再试一次……
所以,为了说明问题:
你想要一个写在插件中的例程,当从另一个工作簿中的vba调用时,它可以计算出(除了其他事情之外)哪个工作簿包含进行调用的vba,而不必显式地传递此信息。
如上所述,这是不可能的(这是一个类似于从代码访问调用堆栈的问题:(据我所知不可能)
然而你几乎可以得到你想要的像这样
像这样声明你的log函数:
然后无论你叫潜艇用什么
虽然不像什么都不传那么好,但至少总是一样的
j1dl9f462#
若要获取调用工作簿的名称,请使用
调用者返回有关如何调用VisualBasic的信息。如果从单个单元格中输入的自定义函数调用,则返回指定该单元格的Range对象
获得对单元格的引用后,.Worksheet.Parent.Name将提供工作簿的名称
请注意,Application.Caller将根据函数的调用方式返回其他内容(有关详细信息,请参阅VBA帮助)
u0sqgete3#
在由Excel Worksheet Array Entered Function Call调用的外接程序函数中,我发现“Application.Caller.Parent.name”给出了工作表名称(选项卡名称,而不是工作表编号)。
sz81bmfz4#
我在编写自定义函数时也遇到了同样的问题。函数运行良好,但每当计算或激活另一个工作簿时,使用该函数的所有单元格都会恢复为#value。使用此公式处理多个文件时可能会非常令人沮丧。
获取我使用的工作簿:
如果你的函数在一个单元格中,这应该是可行的。
对于最初的帖子来说太晚了,但可能会帮助其他人!
doinxwow5#
我知道这个答案大约晚了12年,但我最近也遇到了同样的问题,并有一个解决方案,可能会帮助其他人在这种情况下。
我的解决方案是将记录器接口编码为一个类。要使用记录器,调用应用程序必须获得该类的新示例,然后调用该示例的log方法,而不是调用外接程序的全局log方法。
要提供logger类的新示例,请编写一个全局工厂函数(例如:
set myLogger = loggerAddin.newLogger(workbook)
,或类似的),其中workbook
是对调用者的引用。该引用保存在日志记录器示例中,然后可以在日志记录函数(例如myLogger.log(message)
)中引用,而无需为这些日志记录函数提供对工作簿的引用。