【发布时间】:2015-11-18 16:35:48
【问题描述】:
(首先,我知道this 可能对我很有效 - 我正试图了解其他地方的一段代码发生了什么。)
我有一个连接到按钮的宏来隐藏“rHFilter”范围内不包含我想要的值的列和行(无论单元格“M2”的下拉菜单中的内容是什么)。为了获取下拉列表的值,我试图检查我的范围“rHFilter”中的所有值。 enter image description here
我的代码中有重复项 我的“strFilter”变量中有多个值的实例,但我不明白这个位在做什么,确切地说,它允许重复:
For Each c In Range("rHFilter").Cells
If Application.CountIf(Range(Cells(3, 2), c), c.Value) = 1 Then
strFilter = strFilter & "," & c.Value
End If
Next c
这似乎是从一个范围中获取唯一值以在我的宏中使用的最小方法 - 但如果我无法使其工作,我正在考虑尝试其他页面中的“集合”代码。谁能帮帮我?
顺便说一句,我也不明白这是在做什么:
'=========
'What is this statement supposed to do?
'If Application.CountIf(ThisWorkbook.Sheets(1).Columns(2), "-") _
= Range("rHFilter").Rows.Count Then Exit Sub
'=========
这里是更大的代码(任何感兴趣的人):
Sub SetrHFilterRange()
On Error Resume Next
Application.ScreenUpdating = False
strSN = ActiveSheet.name
Set ws = Sheets(strSN)
' Get the Last Cell of the Used Range
' Set lastCell = ThisWorkbook.Sheets(1).usedRange.SpecialCells(xlCellTypeLastCell)
Set lastCell = ws.Columns("B:G").Find("*", ws.[B3], xlValues, , xlByRows, xlPrevious)
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Set usedRange = Range("B3:G" & lastRow)
' Reset Range "rHFilter" from Cell C2 to last cell in Used Range
ThisWorkbook.Names.Add name:="rHFilter", RefersTo:=usedRange
' Set filtering cell value and formatting
With Cells(2, 13)
.Value = "-"
.FormatConditions.Delete
.FormatConditions.Add Type:=xlCellValue, Operator:=xlNotEqual, Formula1:="=""-"""
.FormatConditions(1).Interior.ColorIndex = 44
.Interior.ColorIndex = 17
End With
strFilter = "-"
For Each c In Range("rHFilter").Cells
If Application.CountIf(Range(Cells(3, 2), c), c.Value) = 1 Then
strFilter = strFilter & "," & c.Value
End If
Next c
With Cells(2, 13).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=strFilter & ",Blank Cells"
.InCellDropdown = True
End With
strFilter = ""
Application.ScreenUpdating = True
On Error GoTo 0
End Sub
Sub SetrHFilter()
strSN = ActiveSheet.name
Set ws = Sheets(strSN)
If lastCell Is Nothing Then
Set lastCell = ws.Columns("B:G").Find("*", ws.[B3], xlValues, , xlByRows, xlPrevious)
End If
On Error Resume Next
'=========
'What is this statement supposed to do?
'If Application.CountIf(ThisWorkbook.Sheets(1).Columns(2), "-") _
= Range("rHFilter").Rows.Count Then Exit Sub
'=========
' reset unhide in case the user didn't clear
ThisWorkbook.Sheets(1).Columns.Hidden = False
ThisWorkbook.Sheets(1).Rows.Hidden = False
eName = Cells(2, 13).Value
If eName = "-" Then Exit Sub
' Speed the code up changing the Application settings
With Application
lCalc = .Calculation
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
FilterRowsNCols:
' Hide columns if cells don't match the values in filter cell
If eName <> "Blank Cells" Then
For Each hFilterCol In Range("rHFilter").Columns
Set fName = hFilterCol.Find(what:=eName, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If fName Is Nothing Then 'not found
hFilterCol.EntireColumn.Hidden = True
End If
Next hFilterCol
Else
'Do something if the user selects blank - but what??
End If
If eName <> "Blank Cells" Then
For Each hFilterRow In Range("rHFilter").Rows
Set fName = hFilterRow.Find(what:=eName, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False)
If fName Is Nothing Then 'not found
hFilterRow.EntireRow.Hidden = True
End If
Next hFilterRow
Else
'Do something if the user selects blank - but what??
End If
Set lastCell = Nothing
If bFilter = False Then
bFilter = True
GoTo FilterRowsNCols
End If
' Change the Application settings back
With Application
.Calculation = lCalc
.EnableEvents = True
.ScreenUpdating = True
End With
On Error GoTo 0
End Sub
Sub ResetrHFilter()
On Error Resume Next
ThisWorkbook.Sheets(1).Columns.Hidden = False
ThisWorkbook.Sheets(1).Rows.Hidden = False
SetrHFilterRange
On Error GoTo 0
End Sub
===================================
编辑
在阅读和测试 Scott 的回答后添加了以下编辑:
我将代码更改为:
strFilter = "-"
For Each c In Range("rHFilter").Cells
If Application.CountIf(Range(Cells(3, 2), c), c.Value) = 1 Then
strFilter = strFilter & "," & c.Value
End If
Next c
With Cells(2, 13).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=strFilter & ",Blank Cells"
.InCellDropdown = True
End With
到这里:
strFilter = "-"
Set uniqCol = New Collection
For Each c In Range("rHFilter").Cells
If Not IsNumeric(c.Value) And Not IsDate(c.Value) Then
uniqCol.Add c.Value, CStr(c.Value)
End If
Next c
For Each itmVal In uniqCol
strFilter = strFilter & "," & itmVal
Next
With Cells(3, 34).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=strFilter & ",Blank Cells"
.InCellDropdown = True
End With
谢谢你,斯科特
【问题讨论】:
-
countifcounts 第二个参数在给定范围内的出现次数(第一个参数)。 -
编辑了“重复”(在第 3 段中)。我知道
countifcounts 的出现:我试图弄清楚为什么它不超过一个,因为它在列表中并得到了额外的 - 以及如何解决这个问题。 -
由于 for each 的方法,上面的代码不会发现唯一的。 for each 循环从左到右从上到下移动。因此,当它在第 3 行移动时,它正在做想要的事情,但是当它下降到下一行时,它比较的范围是 B3:B4 而不是 B3:G3 和 B4。因此它会给出重复。因此,如果您的计划是只获取唯一值,那么集合可能是最好的方法。
-
这是有道理的——我想知道是不是这样,但我无法解释。谢谢你。我会尝试通过一个系列来解决它 - 看起来它是如此接近和小,放弃它是一种耻辱。