用数组替换'If Activecell.value = X'的长列表?

时间:2014-02-06 15:29:22

标签: excel vba excel-vba

我编写了一个宏来搜索一列文本,并删除与下面宏中的文本匹配的值(当文本匹配整个行被删除时)。要删除的值列表大约有140个唯一编号,我在下面列出了5个作为示例。

编写这部分代码的简化方法是什么,而不是写'Activecell.Value = XXXX或_'140次?

我正在研究如何使用数组来存储我想要删除的所有值,但是我无法正确实现它。

感谢您的帮助!

Sub DeleteClosedStores()

Range("F7").Select

While ActiveCell.Value <> ""
    If ActiveCell.Value = 25401 Or _
        ActiveCell.Value = 8587 Or _
        ActiveCell.Value = 8275 Or _
        ActiveCell.Value = 8518 Or _
        ActiveCell.Value = 8522 Or Then

        Selection.EntireRow.Delete
    Else
        ActiveCell.Offset(1, 0).Select
   End If
Wend

5 个答案:

答案 0 :(得分:1)

像这样写你的宏:

Sub DeleteClosedStores()
Range("F7").Select
Dim KillArray
KillArray = Array(25401, 8587, 8275,8518,8522)
Dim f As Variant
While ActiveCell.value <> ""
    f = Filter(KillArray, ActiveCell.value)
    If UBound(f) <> -1 Then
        Selection.EntireRow.Delete
    Else
        ActiveCell.Offset(1, 0).Select
   End If
Wend
End Sub

当然@sarvesh是对的。你需要在某处输入你的价值观。

答案 1 :(得分:0)

将所有这些值存储在VB整数数组中,并使用For...Next循环比较所有值。 但是你仍然必须至少输入所有这140个值来存储在一个数组中。

答案 2 :(得分:0)

我至少会使用工作表的Cells属性。此方法迭代单元格,而不是移动ActiveCell。它比移动活动单元要快得多。

Private Sub deleteRows()
    Dim i As Integer
    i = 7
    While Cells(i, "F").value <> ""
        If checkCondition(Cells(i, "F").value) Then
            Cells(i, "F").EntireRow.Delete
        End If
        i = i + 1
    Wend
End Sub

Private Function checkCondition(value As String) As Boolean
    ' assuming everything is a number
    num = CLng(value)
    checkconditionmet = IIf(num = 25401 Or _
                            num = 8587 Or _
                            num = 8275 Or _
                            num = 8518 Or _
                            num = 8522, True, False)
End Function

这是O(n),但是如果你想将单元格预加载到变量中,那么迭代该变量,也就是O(n)(O(n)+ O(n)) 。但你不想迭代两次。

答案 3 :(得分:0)

尝试使用此代码(顺便说一句,请避免使用SelectActiveSth语句。这会使您的代码变慢):

Sub DeleteClosedStores()
    Dim str1 As String
    Dim rng As Range

    str1 = "|25401|8587|8275|8518|8522|"

    Set rng = Range("F7")
    While rng.Value <> ""
        Set rng = rng.Offset(1)
        If InStr(1, str1, "|" & rng.Offset(-1) & "|") > 0 Then
            rng.Offset(-1).EntireRow.Delete
        End If
    Wend
End Sub

主要想法是使用例如分割您的值。 “|”像这样:str1 = "|25401|8587|8275|8518|8522|",然后将rng.Value夹在“|”中像这样"|" & rng.Offset(-1) & "|"(例如,如果rng.Offset(-1)的值是8587,则代码将尝试在|8587|中找到|25401|8587|8275|8518|8522|

答案 4 :(得分:0)

非循环答案会更快

这个使用带有测试的工作列来删除匹配的行AutoFilter(第1行除了标题)

Sub KillEm()
    Dim rng1 As Range, rng2 As Range, rng3 As Range
    Set rng1 = Cells.Find("*", , xlValues, , xlByColumns, xlPrevious)
    Set rng2 = Cells.Find("*", , xlValues, , xlByRows, xlPrevious)
    Set rng3 = Range(Cells(rng2.Row, rng1.Column), Cells(1, rng1.Column))
    Application.ScreenUpdating = False
    With rng3.Offset(0, 1)
        .FormulaR1C1 = "=SUM(COUNTIF(RC1,{25401,8587,8275,8518,8522}))=1"
        .AutoFilter Field:=1, Criteria1:="TRUE"
        .Offset(1, 0).Resize(rng3.Rows.Count - 1, 1).EntireRow.Delete            
        .EntireColumn.Delete           
    End With
    Application.ScreenUpdating = True
End Sub
相关问题