VBA 用户定义函数仅处理工作簿中的一个工作表
VBA User Defined Function only Working on one Worksheet in Workbook
我有下面的代码,它从 excel 中的 table 创建一个数组,然后根据输入的多个条件搜索该数组。
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
工作表。当我输入完全相同的输入时,所有其他工作表 return 出现 #VALUE!
错误。该函数的参数可以是来自其他工作表的单元格引用而不会出错。
此外,Data Source
选项卡上的工作函数每隔一段时间(看似随机)也会从正确值转换为 #VALUE!
。
我正在使用的同一工作簿中的常规模块中有该函数。该模块中还有一个子程序。
我真的被这个难住了。有没有人看过这个 before/do 你知道解决办法吗?
正如您在此处的评论中提到的,这一行导致了问题:
'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)
是范围对象,它们的工作sheet 没有得到适当的限定。我知道这似乎违反直觉,因为你已经在这里说 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
作为默认值,这可能是 sheet 在您所在的 UDF 上下文中充当 Application.Caller.Parent
。所以它试图在 ws
中创建一个由 activesheet
中的开始和结束单元格组成的范围,这是无稽之谈。
我有下面的代码,它从 excel 中的 table 创建一个数组,然后根据输入的多个条件搜索该数组。
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
工作表。当我输入完全相同的输入时,所有其他工作表 return 出现 #VALUE!
错误。该函数的参数可以是来自其他工作表的单元格引用而不会出错。
此外,Data Source
选项卡上的工作函数每隔一段时间(看似随机)也会从正确值转换为 #VALUE!
。
我正在使用的同一工作簿中的常规模块中有该函数。该模块中还有一个子程序。
我真的被这个难住了。有没有人看过这个 before/do 你知道解决办法吗?
正如您在此处的评论中提到的,这一行导致了问题:
'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)
是范围对象,它们的工作sheet 没有得到适当的限定。我知道这似乎违反直觉,因为你已经在这里说 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
作为默认值,这可能是 sheet 在您所在的 UDF 上下文中充当 Application.Caller.Parent
。所以它试图在 ws
中创建一个由 activesheet
中的开始和结束单元格组成的范围,这是无稽之谈。