Excel 用户定义函数:Nth_Occurence
Posted
技术标签:
【中文标题】Excel 用户定义函数:Nth_Occurence【英文标题】:Excel user defined function: Nth_Occurence 【发布时间】:2014-12-29 17:45:29 【问题描述】:我发现了一个很好的用户定义函数,叫做 Nth_Occurence;它在一个范围内查找给定值的“第 N 次”出现。它工作得很好,但在某些情况下它的行为很奇怪。以下是详细信息:
公式中的语法:=Nth_Occurence(Range,Value,Occurence,offset_row,offset_col)
=Nth_Occurence(A1:A100,8,6,3,7) 这将在 A1:A100 范围内查找数字 8 的第 6 次出现,并返回向下 3 行和 7 的单元格的内容右侧的列
这是VB代码:
Function Nth_Occurrence(range_look As Range, find_it As String, occurrence As Long, offset_row As Long, offset_col As Long)
Dim lCount As Long
Dim rFound As Range
Set rFound = range_look.Cells(1, 1)
For lCount = 1 To occurrence
Set rFound = range_look.Find(find_it, rFound, xlValues, xlWhole)
Next lCount
Nth_Occurrence = rFound.Offset(offset_row, offset_col)
End Function
以下是问题:
1 - 如果查找范围的显示不可见(隐藏列,######(部分隐藏值),;;;(在单元格属性中不显示),查找失败并返回#VALUE。
***由 Ron 修复:2-该函数忽略范围内的第一个单元格
***由 Ron 修复:3-如果目标单元格的值(在我的示例中为第 3 行,第 7 列)更改,结果不会自行更新;我需要运行:ActiveSheet.EnableCalculation = False ActiveSheet.EnableCalculation = True
我的 VB 水平是“复制/粘贴”,更改值,希望最好...
谢谢大家
查看问题1的更新示例:
在A1单元格输入公式:=D1并下拉到A10(所以A1:A10指的是D1:D10)
用以下值填充单元格 D1:D10:1,2,3,1,2,3,1,2,3,1
用值填充单元格 B1:B10:99,98,97,96,95,94,93,92,91,90
在单元格 C2 中输入“3”
在C1单元格输入公式:=Nth_Occurrence(A1:A10,c2,2,0,1)
结果应为 94,在单元格 C2 中输入“2”,结果应为 95
**将 A:A 列的宽度设置为 5 像素...
在单元格 C2 中输入“3”,结果现在是:#VALUE
修复:将 A:A 列的宽度重置为显示内容并更改 C2 值的级别。
【问题讨论】:
没有理由忽略第一个单元格,但直到最后一个单元格才会检查它(有关 range.find,请参阅帮助)。此外,您可能需要检查环绕搜索。当不在参数列表中的单元格发生更改时,请尝试“Application.Volatile”进行更新。不确定隐藏数据。您需要提供一些失败的示例。 感谢 Ron 解决了问题 2 对于问题 #1,尝试寻找 xlFormulas 而不是 xlValues 将“Application.Volatile”添加到代码修复问题3的第2行;并在第 6 行将 xlValues 更改为 xlFormulas 已解决问题 1.. 谢谢 【参考方案1】:以下代码似乎可以解决您提到的问题。请注意您的代码
不检查环绕。 IE。如果只有两个实例,而您正在寻找第三个,代码将返回第一个实例。
如果 findit 不存在,将返回 #VALUE!
注意我们如何更改为从最后一个单元格开始搜索,以便更正您的问题#2
EDIT OP 补充说,正在搜索的数据来自公式,而不是来自他最初问题中指出的值。因此,下面的代码已被修改为 .Find 不再适用于隐藏列。
此外,如果出现 > find_it 实例数(必要时可以更改),此代码将返回错误
EDIT2: OP 现在添加了一个附加规范,即要返回的值可能需要负列偏移。下面的代码应该通过设置第二个数组来处理该问题,从该数组中返回适当的值。
Option Explicit
Function Nth_Occurrence(range_look As Range, find_it As String, occurrence As Long, offset_row As Long, offset_col As Long)
Application.Volatile
Dim lCount As Long
Dim V1 As Variant, V2 As Variant
Dim I As Long
V1 = range_look
V2 = range_look.Offset(0, offset_col)
For I = 1 To UBound(V1, 1)
If V1(I, 1) = find_it Then lCount = lCount + 1
If lCount = occurrence Then Exit For
Next I
Nth_Occurrence = V2(I + offset_row, 1)
End Function
【讨论】:
解决方案解决了示例中的问题 1;但是在我的主工作表中,范围内的值来自公式,因此无法应用 xlFormulas 替换 xlValues @Simon 最好提供您实际问题的相关数据,但在这种情况下,一种解决方法是循环数据。查看修改后的答案 我更新了示例以正确反映您的答案非常感谢.. 完美运行 似乎新代码不接受列偏移的负值(它接受行)可以添加吗? @Simon 当提供的数据不能真正代表真实数据时会发生困难的另一个例子以上是关于Excel 用户定义函数:Nth_Occurence的主要内容,如果未能解决你的问题,请参考以下文章