首页 > 解决方案 > if语句有多个条件,如何解决

问题描述

我希望能够解析工作表并根据其中一个单元格中的“注销”标准删除某些行。诀窍是,它不能是它的每个实例,只是下一行显示“状态”数组的一个参数的那些实例。工作表的大致大小为 4 列和大约 10000~ 行。

Dim firstRow As Long
Dim nextRow As Long
Dim currentDate(1 To 5) As String
Dim totalDelete As Long
Dim p As Integer
Dim i As Integer
Dim status(1 To 5) As String

status(1) = "Available"
status(2) = "Email"
status(3) = "Available, No ACD"
status(4) = "Aux, Technical Issues"
status(5) = "Aux, Client Callback"

currentDate(1) = Sheets("Cover").Range("E12")
currentDate(2) = Sheets("Cover").Range("F12")
currentDate(3) = Sheets("Cover").Range("G12")
currentDate(4) = Sheets("Cover").Range("H12")
currentDate(5) = Sheets("Cover").Range("I12")

firstRow = 2
nextRow = 3
totalDelete = 0

For i = 1 To 5
    For p = 1 To 5

        Do While firstRow <= 10000
            If Cells(firstRow, "C") = "Logged Off" And Cells(nextRow, "C") = status(p) And Cells(nextRow, "B") = currentDate(i) Then
                Rows(firstRow).Delete
                totalDelete = totalDelete + 1

            Else
                firstRow = firstRow + 1
                nextRow = nextRow + 1
            End If

        Loop
        Debug.Print currentDate(p)
        Debug.Print status(p)

    Next p

Next i

Debug.Print totalDelete

现在我期望它循环大约 10000 行并检查我上面描述的内容。它通过几个循环来检查我拥有的两个数组中所有可能的日期和状态。代码中的调试只是我检查状态和 currentDate 是否正确输出,它们是。这让我相信我的 IF 语句可能有问题。但是,我不是最擅长这个,所以我只是看不到我哪里出错了。

   A    |  B        |  C          |  D 

1 data  | 3/25/2019 | Logged Off  | data

2 data  | 3/25/2019 | Logged Off  | data

3 data  | 3/25/2019 | email       | data

4 data  | 3/25/2019 | email       | data

所以在运行代码之后,我希望它至少会删除第 2 行。

标签: excelvba

解决方案


您的代码中有几个问题。

1)当您计划在循环中删除行时,向后工作。

想象一下,您点击了 row3并且您必须删除它 ( firstRow = 3)。你删除它,现在 Row4是 Row3并且你迭代firstRow4. 基本上WAS4(现在是 Row 3)的行被跳过并且不被检查。

反而

 FirstRow = 10000
 Do While firstRow >= 2 

firstrow并在每个循环中递减:

firstRow = firstRow - 1 

以确保您不会从自己身下拉出地毯。这可能会或可能不会解决您看到的问题,但这是您代码中的一个明确错误。

2)你的循环内循环

那是5 x 5 x 10000循环或250000循环。这是相当激进的。相反,只需循环 10000 次并进行如下测试:

If Cells(firstRow, "C") = "Logged Off" And inStr(1, Join(status, "|"), Cells(firstRow+ 1, "C").value, 1) And InStr(1, Join(currentDate, "|"), Cells(firstRow + 1, "B"), 1) Then

您可以仅使用该Join()函数将数组转换为由|每个元素之间分隔的单个字符串。Instr()然后测试您的单元格值是否在该字符串中。我们将最后一个参数设置为Instr()to1使其不区分大小写。10000 个循环会快得多。

3)你不需要这个nextRow变量(虽然这只是挑剔,所以如果你嫁给了那个东西,你可以忽略。)

而是使用 Cells(firstRow + 1, "C") 或 Cells(firstRow, "C").Offset(,1) 进行检查。以这种方式增加和跟踪的变量更少。

这是重写:

Dim firstRow As Long
Dim currentDate(1 To 5) As String
Dim totalDelete As Long
Dim status(1 To 5) As String

status(1) = "Available"
status(2) = "Email"
status(3) = "Available, No ACD"
status(4) = "Aux, Technical Issues"
status(5) = "Aux, Client Callback"

currentDate(1) = Sheets("Cover").Range("E12")
currentDate(2) = Sheets("Cover").Range("F12")
currentDate(3) = Sheets("Cover").Range("G12")
currentDate(4) = Sheets("Cover").Range("H12")
currentDate(5) = Sheets("Cover").Range("I12")

firstRow = 10000
totalDelete = 0


Do While firstRow >= 2
    If Cells(firstRow, "C") = "Logged Off" And inStr(1, Join(status, "|"), Cells(firstRow+ 1, "C").value, 1) And InStr(1, Join(currentDate, "|"), Cells(firstRow + 1, "B"), 1) Then
        Rows(firstRow).Delete
        totalDelete = totalDelete + 1                    
    End If
    firstRow = firstRow - 1  
Loop

Debug.Print totalDelete

推荐阅读