试图在函数中使用命名范围作为参数,但是当我在与命名范围所在位置不同的工作表中执行该函数时遇到问题。
试图在论坛中进行搜索,但找不到解决方案,因为大多数帖子的命名范围或工作表均在VBA中进行了硬编码。希望避免此限制,因为该功能应该与来自不同工作表的不同命名范围一起使用...
在与选定的命名范围相同的工作表中输入以下代码时,效果很好。不幸的是,当选定的“命名范围”在另一个工作表中时,它就崩溃了(即使我用作参数的所有范围都是“特定于工作簿的”)。
在此特定行中:
Promise.all
已经尝试了一段时间,试图创建一个可以在任何工作表上工作的引用,但是不幸的是,没有运气...
任何帮助将不胜感激!
概念是声明一个命名范围作为参数。反过来,该函数会找到此命名范围,并从其中的一部分创建一个新范围(请参见SpecificRange)。最后,它使用该新范围内的数据执行某些计算。所有这些都可以正常工作,但只能在同一个工作表中...这是代码:
Set FullRange = NamedRange
非常感谢!
+++++
要添加更多详细信息,请注意,当在与NamedRange所在位置不同的工作表中输入该函数时,该函数将返回零(0.00),而不是错误。
此外,当我在工作表中具有完全相同的功能时(a)NamedRange所在的位置(例如“ Sheet1”),在另一个工作表中具有(b)(例如“ Sheet2”),那么当我运行该功能时在Sheet1中,Sheet2中的功能已正确更新!但是当我直接在Sheet2中运行该函数时,它返回零...
当相关工作表处于非活动状态时,它似乎无法找到NamedRange ...
这是一个场景:https://i.stack.imgur.com/RpHf3.png
用户在函数中将命名范围作为参数输入(请参阅第一个参数) 函数中的第二个参数(即Vessel为String)是指屏幕快照中显示的第一列。
因此,当用户输入公式时,该函数将找到NamedRange,然后创建另一个范围(即SpecificRange),该范围实际上是找到第二个参数的行(示例屏幕快照中的条件4)。
那只是基于其余两个参数的计算问题,但这似乎与该问题无关。
答案 0 :(得分:0)
您正在成功收集命名范围,您的问题是,稍后在代码中您将基于Address设置范围,但未指定工作表。换句话说,您的代码正在查看ActiveSheet.Range(.ADDRESS)
。
您实际上可以从范围变量中收集工作表,例如:Set WS = ThisWorkbook.Sheets(NamedRange.Parent.Name)
更新了v3,并添加了一些注释(PGC:)
Function myResult(NamedRange As Range, Vessel As String, FromDate As Date, ToDate As Date)
'declare variables in addition to the function parameters declared above
Dim SpecificRange As Range
Dim FullRange As Range 'PGC: not sure you need this
Dim Result As Double
Dim i As Long 'PGC: use long instead of byte https://stackoverflow.com/questions/26409117/why-use-integer-instead-of-long/51689021#51689021
Dim WS As Worksheet 'PGC: this will be used to narrow your approach.
'find the row within the declared "NamedRange" range which contains information for the declared "Vessel"
Set FullRange = NamedRange 'I don't think you need to change this variable. Using NamedRange should work if you use below.
'PGC: set the WS to be the parent of the range you're working with:
Set WS = ThisWorkbook.Sheets(NamedRange.Parent.Name)
'PGC: since you're using the address text to set the range (probably not ideal), you'll need to specify which WS this Range is on.
Set SpecificRange = WS.Range(FullRange.Find(Vessel, , xlValues, xlWhole).Address, FullRange.Find(Vessel, , xlValues, xlWhole).Offset(0, FullRange.Columns.Count - 1).Address)
'PGC: alternative untested approach that avoids using the address property that is probably best method:
'Set SpecificRange = Range(FullRange.Find(Vessel, , xlValues, xlWhole), FullRange.Find(Vessel, , xlValues, xlWhole).Offset(0, FullRange.Columns.Count - 1))
i = 1
Result = 0
For i = 1 To FullRange.Columns.Count - 2
If FullRange(2, i) = "Date" Then
With WorksheetFunction
Result = Result + .Max(0, .Min(ToDate, SpecificRange(1, i + 2).Value) - .Max(FromDate, SpecificRange(1, i).Value)) * SpecificRange(1, i + 1).Value
End With
End If
Next
myResult = Result
End Function