Function 如何从包含易失性函数的单元格中正确引用工作簿?

Function 如何从包含易失性函数的单元格中正确引用工作簿?,function,excel,vba,Function,Excel,Vba,我对Excel VBA有一个相当愚蠢的问题。我试图实现一个函数,该函数返回工作簿的工作簿属性,该工作簿包含插入该函数的单元格。我在使函数不稳定并将其放入个人工作簿中时遇到了一个问题,因此它可以与任何打开的工作簿一起使用(也可以作为加载项)。我的职能基本上是- Function zSETSERVERMETADATA(ByVal metaTypeName As String, Optional ByVal newValue As String = "") As String 'Recalculate

我对Excel VBA有一个相当愚蠢的问题。我试图实现一个函数,该函数返回工作簿的工作簿属性,该工作簿包含插入该函数的单元格。我在使函数不稳定并将其放入个人工作簿中时遇到了一个问题,因此它可以与任何打开的工作簿一起使用(也可以作为加载项)。我的职能基本上是-

Function zSETSERVERMETADATA(ByVal metaTypeName As String, Optional ByVal newValue As String = "") As String
'Recalculate upon every time any cell changes
Application.Volatile

Dim wb As Workbook
Set wb = Application.ActiveWorkbook

On Error GoTo NoSuchProperty

'If value defined on newValue, set the value and showoutput
If newValue <> "" Then
    wb.ContentTypeProperties(metaTypeName).Value = newValue
    zSETSERVERMETADATA = wb.ContentTypeProperties(metaTypeName).Value
    Set wb = Nothing
    Exit Function
'If no value defined on newValue only show output but leave content type unchanged
Else
    zSETSERVERMETADATA = wb.ContentTypeProperties(metaTypeName).Value
    Set wb = Nothing
    Exit Function
End If

NoSuchProperty:
zSETSERVERMETADATA = CVErr(xlErrValue)
Set wb = Nothing
End Function
函数zSETSERVERMETADATA(ByVal metaTypeName作为字符串,可选ByVal newValue作为字符串=”“)作为字符串
'每次单元格更改时重新计算
应用程序。挥发性
将wb设置为工作簿
设置wb=Application.ActiveWorkbook
关于错误转到NoSuchProperty
'如果在newValue上定义了值,请设置该值并显示输出
如果newValue为“”,则
wb.ContentTypeProperties(metaTypeName).Value=newValue
zSETSERVERMETADATA=wb.ContentTypeProperties(metaTypeName).Value
设置wb=Nothing
退出功能
'如果newValue上未定义值,则仅显示输出,但保持内容类型不变
其他的
zSETSERVERMETADATA=wb.ContentTypeProperties(metaTypeName).Value
设置wb=Nothing
退出功能
如果结束
NoSuchProperty:
zSETSERVERMETADATA=CVErr(xlErrValue)
设置wb=Nothing
端函数
现在问题出在行Set wb=Application.ActiveWorkbook中,问题是如果打开两个或多个工作簿并激活另一个工作簿,volatile函数将使用“new”活动工作簿的值进行计算。但这当然不是我们想要的行为方式。 在这方面我需要一些帮助,使其始终显式地引用计算函数的工作簿,而不是根据工作簿(包含函数的单元格所在的工作簿)的活动来计算它。有什么想法吗

多亏了Gary的学生,编辑和解决方案
函数zSETSERVERMETADATA(ByVal metaTypeName作为字符串,可选ByVal newValue作为字符串=”“)作为字符串
'每次单元格更改时重新计算
应用程序。挥发性
'通过调用方父级设置wb指针
将wb设置为工作簿、r设置为范围、ws设置为工作表
Set r=Application.Caller
设置ws=r.Parent
设置wb=ws.Parent
'清除未使用的元素
设置r=无
设置ws=Nothing
关于错误转到NoSuchProperty
'如果在newValue上定义了值,请设置该值并显示输出
如果newValue为“”,则
wb.ContentTypeProperties(metaTypeName).Value=newValue
zSETSERVERMETADATA=wb.ContentTypeProperties(metaTypeName).Value
设置wb=Nothing
退出功能
'如果newValue上未定义值,则仅显示输出,但保持内容类型不变
其他的
zSETSERVERMETADATA=wb.ContentTypeProperties(metaTypeName).Value
设置wb=Nothing
退出功能
如果结束
NoSuchProperty:
zSETSERVERMETADATA=CVErr(xlErrValue)
设置wb=Nothing
端函数

也许您需要询问来电者:

Public Function lin()
    Dim r As Range, ws As Worksheet, wb As Workbook
    Set r = Application.Caller
    Set ws = r.Parent
    Set wb = ws.Parent
    lin = wb.Name
End Function

您可以将所需工作簿粘贴为函数调用中的可选参数

Function zSETSERVERMETADATA(ByVal metaTypeName As String, Optional ByVal newValue As String = "", Optional byval Wb as workbook) As String

谢谢这是一个完美的解决方案。我甚至没有想过要使用caller&parents,但它的工作方式很神奇!对于其他一些情况,这是一个不错的选择,但这需要始终传递工作簿名称,对于最终用户来说,可能很难解决这需要什么参数。同样如问题中所述,需要根据函数所在的单元格显式地计算函数。还是谢谢你的回答。
Function zSETSERVERMETADATA(ByVal metaTypeName As String, Optional ByVal newValue As String = "", Optional byval Wb as workbook) As String