【问题标题】:VBA User Defined Function only Working on one Worksheet in WorkbookVBA 用户定义函数仅在工作簿中的一个工作表上工作
【发布时间】:2017-12-12 16:38:31
【问题描述】:

我有以下代码,它从 excel 中的表创建一个数组,然后根据输入中的多个条件搜索该数组。

Function output_string(id As Long, dt As Date, descr As String)

'set variables
Dim myarray As Variant
Dim ws As Worksheet
Dim col_count As Integer
Dim row_count As Long
Dim source_range As Range

'set worksheet
Set ws = Worksheets("Data Store")

dt = DateValue(app_dt)

'set up column and row counts for populated range
col_count = ws.Range("A2").End(xlToRight).Column
row_count = ws.Range("A2").End(xlDown).Row

'set range for populated cell space
Set source_range = ws.Range(Cells(2, 1), Cells(row_count, col_count))

'create the dimensions of the array that will store the table
ReDim myarray(1 To source_range.Rows.Count, 1 To source_range.Columns.Count)

'load data from excel table into array
myarray = source_range.Value


'get row with matching criteria
For i = LBound(myarray) To UBound(myarray)
    If myarray(i, 1) = id And dt >= myarray(i, 2) And dt <= myarray(i, 4) _
       And descr = myarray(i, 5) Then
       output_string = myarray(i, 3)
       Exit For
    End If
Next i

End Function

函数给出正确的输出。问题是该函数仅适用于Data Store 工作表。当我输入完全相同的输入时,所有其他工作表都会返回 #VALUE! 错误。该函数的参数可以是来自其他工作表的单元格引用,而不会出错。

此外,每隔一段时间(似乎是随机的)Data Source 选项卡上的工作函数也会从正确的值转换为 #VALUE!

我在使用的同一个工作簿中的常规模块中具有该功能。该模块中还有一个子程序。

我真的被这个难住了。有没有人见过这个/你知道解决方案吗?

【问题讨论】:

    标签: excel user-defined-functions vba


    【解决方案1】:

    正如您在此处的评论中提到的,这一行导致了问题:

    'set range for populated cell space
    Set source_range = ws.Range(Cells(2, 1), Cells(row_count, col_count))
    

    问题在于Cells(2,1)Cells(row_count, col_count) 是范围对象,它们的工作表没有正确限定。我知道这似乎违反直觉,因为您已经在这里说 ws.range,但是这些 range 对象也必须用 ws 限定:

    'set range for populated cell space
     Set source_range = ws.Range(ws.Cells(2, 1), ws.Cells(row_count, col_count))
    

    如果没有该限定,它将使用Application.Activesheet 作为默认值,这可能是您所在的此UDF 上下文中充当Application.Caller.Parent 的工作表。因此它试图在ws 中创建一个范围由activesheet 中的开头和结尾单元格组成,这是无稽之谈。

    【讨论】:

    • 这很有趣,谢谢分享。我的问题在这一点上可能还不清楚:我需要从Data Source 工作表生成数组,无论在哪个工作表中使用 UDF。如果我理解正确,这条线Set ws = Application.Caller.Parent 将在函数所在的同一张表。您知道有什么方法可以让数组每次都在Data Source 表上生成,并且该函数仍然可以在其他表中工作吗?也许我只需要将数组设为全局并对其进行函数调用?
    • 明白了。那就更有意义了。因为真的很难说为什么你可能会从这个东西中得到一个#value,所以也许在你的代码中设置一些断点并重新计算。查看 Locals 窗格,查看分配给变量的值是否与预期匹配。在 UDF 中引用其他工作表没有问题。
    • 在另一个工作表中使用时,Set source_range = ws.Range(Cells(2, 1), Cells(row_count, col_count)) 似乎在这条线上崩溃,但在 ws 工作表中使用时却没有。你知道为什么会这样吗?代码太简单了,不知道哪里出错了。
    • 就是这样!对不起,我错过了。我已经更新了我的答案。
    • 是的!奇迹般有效。非常感谢,你救了我!有趣的是,这么小的东西怎么会引起如此头痛。再次感谢!
    猜你喜欢
    • 2020-07-17
    • 2019-04-04
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    相关资源
    最近更新 更多