如果陈述有多个条件,如何解决

时间:2019-03-29 18:38:46

标签: excel vba

我希望能够解析一个工作表并根据其中一个单元格中的“注销”条件删除某些行。诀窍是,它不可能是它的每个实例,而仅仅是下一行显示“状态”数组的一个参数的实例。工作表的大约大小为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行。

1 个答案:

答案 0 :(得分:1)

您的代码中有几个问题。

1)当您计划删除循环中的行时,请后退。

想象一下,您击中了3行,而您必须将其删除(firstRow = 3)。删除它,现在行4是行3,然后将firstRow迭代到4。本质上, WAS 4(现在是行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()的最后一个参数设置为1,以使其不区分大小写。 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