是否有可能得到作为filter结果的列的最常见的值(string)? VBA

我有点卡在这里 我在应用filter之后,在表单中应用了一个类似于此的filter(示例项目999)

项目投入 数量Avi。 数量标志框

999 12 9 N X1 999 23 17 Y X2 999 1 1 N X14 999 21 3 N X113 

我试图得到“标志”列的价值,(在filter,它坠毁)代码:

 With InventorySheet .AutoFilterMode = False LRowOnQ = .Cells(Rows.Count, "Q").End(xlUp).Row .Range("B1").AutoFilter Field:=2, Criteria1:=Project .Range("D1").AutoFilter Field:=4, Criteria1:=ContractNumber .Range("N1").AutoFilter Field:=14, Criteria1:=Code .Range("Q1").AutoFilter Field:=17, Criteria1:=">0" Set rangeFilteredInventory = .Range("Q1:Q" & LRowOnQ) ControlFlag = .Range("L2").Value End With 

过滤后,它总是采取相同的价值。 码:

 With InventorySheet .AutoFilterMode = False LRowOnQ = .Cells(Rows.Count, "Q").End(xlUp).Row .Range("B1").AutoFilter Field:=2, Criteria1:=Project .Range("D1").AutoFilter Field:=4, Criteria1:=ContractNumber .Range("N1").AutoFilter Field:=14, Criteria1:=Code .Range("Q1").AutoFilter Field:=17, Criteria1:=">0" Set rangeFilteredInventory = .Range("Q1:Q" & LRowOnQ) End With ControlFlag = InventorySheet.Range("L2").Value 

有什么方法可以采取结果范围的最常见的字母? 我知道在小计中有一个平均的选项,但我认为这只是数字。

编辑 :试验代码:

  With InventorySheet .AutoFilterMode = False LRowOnQ = .Cells(Rows.Count, "Q").End(xlUp).Row .Range("B1").AutoFilter Field:=2, Criteria1:=Project .Range("D1").AutoFilter Field:=4, Criteria1:=ContractNumber .Range("N1").AutoFilter Field:=14, Criteria1:=Code .Range("Q1").AutoFilter Field:=17, Criteria1:=">0" Set rangeFilteredInventory = .Range("Q1:Q" & LRowOnQ) Set ControlRange = .Range("L1:L" & LRowOnQ) End With ControlFlag = WorksheetFunction.Subtotal(1, ControlRange.SpecialCells(xlCellTypeVisible)) 

而且它甚至不做循环。

这可以使用MODEfunction来实现。 所以不需要VBA。


数字的例子

 =MODE(IF(SUBTOTAL(3,OFFSET(Range,ROW(Range)-MIN(ROW(Range)),0,1)),Range*{1,1})) 

文本的例子

 =INDEX(A3:A21,MODE(IF(SUBTOTAL(3,OFFSET(A3,ROW(A3:A21)-ROW(A3),0)),MATCH(A3:A21,A3:A21,0)*{1,1}))) 

按Ctrl + Shift + Enter(因为它是一个数组公式)

你可以阅读关于这个HERE的讨论


这是使用纯粹的VBA的另一个解决scheme:

 Public Function ModeSubTotal(rng As Range) As String Dim Dn As Range Dim oMax As Double Dim K As Variant Dim val As String With CreateObject("scripting.dictionary") .CompareMode = vbTextCompare For Each Dn In rng If Dn.Rows.Hidden = False Then If Not .Exists(Dn.Value) Then .Add Dn.Value, 1 Else .Item(Dn.Value) = .Item(Dn.Value) + 1 End If End If Next oMax = Application.Max(Application.Transpose(.Items)) For Each K In .keys If .Item(K) = oMax Then val = val & K & "," End If Next K ModeSubTotal = Left(val, Len(val) - 1) End With End Function 

因为它是一个UDF,你可以像工作表一样使用正常的函数:

ModeSubtotal

或者你可以很容易地在代码中调用它:

 Public Sub test() Sheet1.Cells(1, 1).Value = ModeSubTotal(Range("C1:C20")) End Sub 

这个函数现在将空值作为值计算,所以如果空白值是返回值最大的值,这个值可以很容易地改变。