Если заявление с несколькими условиями, как исправить - PullRequest
0 голосов
/ 29 марта 2019

Я хочу иметь возможность анализировать рабочую таблицу и удалять определенные строки на основе критерия «Выйти из системы» в одной из ячеек. Хитрость заключается в том, что это не может быть каждый экземпляр этого, только те, где в следующей строке показан один из параметров массива 'status'. Примерный размер рабочего листа - 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 Ответ

1 голос
/ 29 марта 2019

В вашем коде есть несколько проблем.

1) Когда вы планируете удалять строки в цикле, работайте в обратном направлении.

Представьте, что вы нажали на строку3 и вы должны удалить его (firstRow = 3).Вы удаляете его, и теперь Row 4 - это Row 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"). Смещение (, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...