Excel VBA中数组的查找模式
我试图在VBA中找到数组的模式 假设存在电影标题的动态列表。A:A,还有一个和B:B一样长的列表,这是一个电影“类型”列表 我试图找到某一类型重复次数最多的标题 注意:A:A是一个动态列表,我不知道它的长度Excel VBA中数组的查找模式,excel,vba,Excel,Vba,我试图在VBA中找到数组的模式 假设存在电影标题的动态列表。A:A,还有一个和B:B一样长的列表,这是一个电影“类型”列表 我试图找到某一类型重复次数最多的标题 注意:A:A是一个动态列表,我不知道它的长度 --------------------------------- -Finding Nemo - Cartoon -Finding Nemo - Cartoon -Finding Nemo - Cartoon -Finding Nemo - Cartoon -Finding Ne
---------------------------------
-Finding Nemo - Cartoon
-Finding Nemo - Cartoon
-Finding Nemo - Cartoon
-Finding Nemo - Cartoon
-Finding Nemo - Cartoon
-Inception - Action
-Inception - Action
-Inception - Action
-Dragon Ball - Cartoon
-Dragon Ball - Cartoon
-Dragon Ball - Cartoon
---------------------------------
以这张表为例,《海底总动员》是最常见的标题。但是现在我要写一个函数来返回那个结果吗
我假设的函数与此类似:
=movieMode(5)
其中5指定要返回的“top”结果数
这里的问题是,当A:A处于动态长度时,我不知道如何做到这一点。以及如何控制返回多少个结果。我应该设置一个过滤器,默认情况下只搜索“卡通”
请分享一些关于这方面的信息
更新
经过研究,我发现了这个公式
=INDEX(A2:A177,MATCH(MAX(COUNTIF(A2:A177,A2:A177)),COUNTIF(A2:A177,A2:A177),0))
在两种情况下,返回出现次数最多的标题
类型是卡通的,当A'x'不是空的时候。(当范围为空时,此公式似乎不起作用
这是我第一天使用excel公式,我已经遇到了这个问题。哈哈
进一步更新
考虑到我上面给出的场景,我希望使用
=电影模式(2)
结果应该是
----------------------------
-Finding Nemo - 5
-Dragon Ball - 3
----------------------------
我希望“卡通”过滤器默认设置在函数中。我不希望动作出现在任何点上,也不希望它成为变量
但是,如果我使用
-movieMode(1)
预期的结果是
-------------------
-Finding Nemo - 5
-------------------
使用此选项可返回仅包含不同值的数组。一旦获得该值,您就可以实现下面的逻辑(与您已有的公式类似)来生成结果。这些是工作表公式,但您应该能够在VBA中完成相同的任务。顺便说一句,是VBA的良好资源
title genre distinct cpearsonVBA count tieBreak rank #_of_results filter_array result
----------------------------------------------------------------------------------------------------------------------------------------------------
Finding Nemo Cartoon Finding Nemo =COUNTIFS(A:A,C:C) =ROW()^-9+D:D =RANK(E:E,E:E) 2 =IF(F:F<=$G$2,1,0) =IF(H:H,C:C,"")
Finding Nemo Cartoon Inception =COUNTIFS(A:A,C:C) =ROW()^-9+D:D =RANK(E:E,E:E) =IF(F:F<=$G$2,1,0) =IF(H:H,C:C,"")
Finding Nemo Cartoon Dragon Ball =COUNTIFS(A:A,C:C) =ROW()^-9+D:D =RANK(E:E,E:E) =IF(F:F<=$G$2,1,0) =IF(H:H,C:C,"")
Finding Nemo Cartoon
Finding Nemo Cartoon
Inception Action
Inception Action
Inception Action
Dragon Ball Cartoon
Dragon Ball Cartoon
Dragon Ball Cartoon
title体裁不同cpearsonVBA计数分阶段排名#(共)个结果过滤器(共)个数组结果
----------------------------------------------------------------------------------------------------------------------------------------------------
Finding Nemo卡通Finding Nemo=COUNTIFS(A:A,C:C)=ROW()^-9+D:D=RANK(E:E,E:E)2=IF(F:F这是一个使用脚本对象字典
的解决方案,但在最后处理范围
时效率不是很高。然而,我使用Application.screenUpdate=False
来保持一些性能提升,并消除闪烁的屏幕更新……这是一个子部分,您也可以使用它作为函数,为Top N
提供一个参数
Option Explicit
Sub getTopN()
Dim ws As Worksheet
Dim rng As Range
Dim vArr As Variant, d As Object, aL As Object
Dim i As Integer, j As Integer, lastRow As Long
Dim topN As Integer
Set d = CreateObject("Scripting.Dictionary")
Set ws = Sheets(1)
Set rng = ws.Range("A2")
topN = ws.Range("B2").Value '-- for testing it's 2
'-- get last used row dynamically
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'--since data starting with row 2
lastRow = lastRow - 1
vArr = WorksheetFunction.Transpose(rng.Resize(lastRow).Value)
For i = LBound(vArr) To UBound(vArr)
If Not d.Exists(RTrim(vArr(i))) Then
j = 1
d.Add RTrim(vArr(i)), j
Else
d.Item(RTrim(vArr(i))) = d.Item(RTrim(vArr(i))) + 1
End If
Next i
'-- screen updating false
Application.ScreenUpdating = False
'-- output items, keys in to sheet
Set rng = ws.Range("C2")
rng.Resize(UBound(d.keys) + 1) = Application.Transpose(d.keys)
rng.Offset(0, 1).Resize(UBound(d.items) + 1) = Application.Transpose(d.items)
'-- sort this new range , top N
Set rng = rng.Resize(UBound(d.items) + 1, 2)
rng.Sort key1:=Range("D2"), order1:=xlDescending, header:=xlNo
'-- copy topN rows into a temp range
ws.Range("E2").Resize(topN, 2) = rng.Resize(topN, 2).Value
'-- clean up everything other than top N rows
rng.ClearContents
rng.Resize(topN, 2).Value = ws.Range("E2").Resize(topN, 2).Value
ws.Range("C1").Value = "Top N Movies"
ws.Range("E2").Resize(topN, 2).ClearContents
'-- release memory
Set d = Nothing
Application.ScreenUpdating = True
End Sub
输出:
参数值5是否意味着给我看5次的电影?否。这意味着我想要出现次数最多的前5部电影。在我给出的场景中,它不起作用,因为只有2个不同的卡通。你能给出示例输出和示例输入来解释测试用例吗?搜索是否必须限于卡通ons?如果是,您在函数参数中的具体位置是什么?@shahkalpesh我已经更新了这个问题。请参考,谢谢您的帮助。@HeHui因为您谈论的是数组,这是否意味着您更喜欢VBA解决方案?谢谢您的尝试,但您遗漏了我提出的一个非常核心的问题。主要问题是动态性。我不知道有多少不同类型的标题。因此我不可能使用你的解决方案,因为它只固定在3个不同的标题上。我的意思是,当我只有查找尼莫
,盗梦空间
和龙珠
时,你的方法有效。如果我在中添加一个forth狮子王
,我将不得不重新调整我的模板,以阅读您生成的cpearsonVBA列表,这正是我试图避免的。我可以看到我的答案有多混乱,但这应该是可行的。您可以使用链接中的DistinctValues函数创建VBA数组,然后再从那里开始。这不是令人困惑的,但这不是我正在寻找的答案。我正在寻找一个可以我将动态检测所有标题,并生成我想要的最终结果。我不希望任何过程需要手动单击或生成第二个列表才能获得我的结果。我相信您的解决方案是有效的,因为有很多类似的解决方案与您的解决方案一样有效。啊……我假设您已经有了输入如果在VBA中执行此操作,则可以使用“范围”(“a1”).CurrentRegion.Resize(,1)选择a列中的所有数据正如我提到的,我实际上刚刚开始学习VBA。lol。我会尝试了解你在尝试什么,我会让你知道我是否在寻找它。什么是Sub
?我的意思是,我如何使用它?首先通过谷歌搜索理论和好奇心。然后,你可以问我们;-)没问题:)我注意到你把寻找尼莫
和卡通
放在同一个单元格中。它们实际上属于两个不同的单元格。这会让问题更简单吗?如果你不把流派
作为过滤标准来计算和列出前N名
,那么,电影名称和流派是否在同一单元格中并不重要。但如果这很重要的话,那么无论如何,把它们分成两个细胞。