使用多个条件循环遍历列和行
Looping through columns and rows with multiple criteria
在我下面的样本数据中,每个客户至少有两个任务。
如果客户的第一个任务被取消,我想删除行。
(第一个任务需要根据创建日期来确定)
我的数据:
No. CLIENT TASK Created
123 Aaaa Done 14/12/2018
123 Aaaa Done 20/12/2018
123 Bbbb Cancelled 26/02/2020
123 Bbbb Done 03/03/2020
123 Cccc Done 20/02/2020
123 Cccc Cancelled 01/03/2020
应删除的数据:
(26/02创建的第一个任务已取消)
123 Bbbb Cancelled 26/02/2020
123 Bbbb Done 03/03/2020
我开始编写代码,但我需要一些指导,因为我不知道如何继续:
With ActiveSheet.AutoFilter.Range
Set rFiltered = .Resize(.Rows.Count - 1).Offset(1).Columns(2).SpecialCells(xlCellTypeVisible)
End With
FirstRow = rFiltered.Cells(1, 1).End(xlToLeft).Row
LastRow = Sheet1.Range("A" & Sheet1.Rows.Count).End(xlUp).Row
Set Frgn = Range(Cells(FirstRow, 2), Cells(LastRow, 2))
For i = FirstRow To LastRow
For j = 2 To 2
If Sheet1.Cells(i, j).Value = Sheet1.Cells(i, j) And _
Sheet1.Cells(i, j) = "Done" Then
For k = 3 To 3
If Sheet1.Cells(i, j).Value = Sheet1.Cells(i, j) And _
Sheet1.Cells(i, k) = "Cancelled" Then
Sheet1.Cells(i, k).Delete
End If
Next k
End If
Next j
Next i
我不知道你是否看到我的第一个 post 但它不正确,我没有足够仔细地阅读你的请求(抱歉)。这应该更适合你。请参阅内联评论。
希望对您有所帮助。
Sub DeleteCancelledClients()
'this "With" block will identify your auto-filtered table and detect the range of your non-header rows
Dim dataRows As Range
With ActiveSheet.AutoFilter.Range
Set dataRows = .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible)
End With
'sort your table, the loop is easier to manage if your data is in a useful order
With ActiveSheet.AutoFilter.Sort
.SortFields.Clear
.SortFields.Add2 Key:=dataRows.Columns(1)
.SortFields.Add2 Key:=dataRows.Columns(2)
.SortFields.Add2 Key:=dataRows.Columns(4)
.Apply
End With
'iterate over the rows in your data
For i = 1 To dataRows.Count
'If this is a cancelled record, check to see if it's the first row for that client and number. (We sorted client - number groups by date, so this is easier)
If dataRows.Cells(i, 3) = "Cancelled" _
And (dataRows.Cells(i, 2) <> dataRows.Cells(i, 2).Offset(-1, 0) _
Or dataRows.Cells(i, 1) <> dataRows.Cells(i, 1).Offset(-1, 0)) Then
'our client-number's first row is a cancelled task. read through for all the other rows for this client-number (They're in a block, so this is easier)
j = 0
While dataRows.Cells(i, 2) = dataRows.Cells(i, 2).Offset(j + 1, 0) _
And dataRows.Cells(i, 1) = dataRows.Cells(i, 1).Offset(j + 1, 0)
j = j + 1
Wend
'delete this client-number all at once
Rows(dataRows.Cells(i, 2).Row & ":" & dataRows.Cells(i, 2).Row + j).Delete
'roll back our counter by one. Our current row actually contains a new client thanks to the delete operation so we have to process this again
i = i - 1
End If
Next i
End Sub
下面的场景呢?如果 NUMBER 不同,则应单独处理。
在下面的例子中,只有编号为 456 的行应该被删除。但是宏也会删除 123。如何修改代码使其也包含数字条件?
Number Client Status Date
123 Aaa Done 20/02/2020
123 Aaa Done 05/03/2020
456 Aaa Cancelled 05/03/2020
456 Aaa Done 03/03/2020
在我下面的样本数据中,每个客户至少有两个任务。 如果客户的第一个任务被取消,我想删除行。 (第一个任务需要根据创建日期来确定)
我的数据:
No. CLIENT TASK Created
123 Aaaa Done 14/12/2018
123 Aaaa Done 20/12/2018
123 Bbbb Cancelled 26/02/2020
123 Bbbb Done 03/03/2020
123 Cccc Done 20/02/2020
123 Cccc Cancelled 01/03/2020
应删除的数据: (26/02创建的第一个任务已取消)
123 Bbbb Cancelled 26/02/2020
123 Bbbb Done 03/03/2020
我开始编写代码,但我需要一些指导,因为我不知道如何继续:
With ActiveSheet.AutoFilter.Range
Set rFiltered = .Resize(.Rows.Count - 1).Offset(1).Columns(2).SpecialCells(xlCellTypeVisible)
End With
FirstRow = rFiltered.Cells(1, 1).End(xlToLeft).Row
LastRow = Sheet1.Range("A" & Sheet1.Rows.Count).End(xlUp).Row
Set Frgn = Range(Cells(FirstRow, 2), Cells(LastRow, 2))
For i = FirstRow To LastRow
For j = 2 To 2
If Sheet1.Cells(i, j).Value = Sheet1.Cells(i, j) And _
Sheet1.Cells(i, j) = "Done" Then
For k = 3 To 3
If Sheet1.Cells(i, j).Value = Sheet1.Cells(i, j) And _
Sheet1.Cells(i, k) = "Cancelled" Then
Sheet1.Cells(i, k).Delete
End If
Next k
End If
Next j
Next i
我不知道你是否看到我的第一个 post 但它不正确,我没有足够仔细地阅读你的请求(抱歉)。这应该更适合你。请参阅内联评论。
希望对您有所帮助。
Sub DeleteCancelledClients()
'this "With" block will identify your auto-filtered table and detect the range of your non-header rows
Dim dataRows As Range
With ActiveSheet.AutoFilter.Range
Set dataRows = .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible)
End With
'sort your table, the loop is easier to manage if your data is in a useful order
With ActiveSheet.AutoFilter.Sort
.SortFields.Clear
.SortFields.Add2 Key:=dataRows.Columns(1)
.SortFields.Add2 Key:=dataRows.Columns(2)
.SortFields.Add2 Key:=dataRows.Columns(4)
.Apply
End With
'iterate over the rows in your data
For i = 1 To dataRows.Count
'If this is a cancelled record, check to see if it's the first row for that client and number. (We sorted client - number groups by date, so this is easier)
If dataRows.Cells(i, 3) = "Cancelled" _
And (dataRows.Cells(i, 2) <> dataRows.Cells(i, 2).Offset(-1, 0) _
Or dataRows.Cells(i, 1) <> dataRows.Cells(i, 1).Offset(-1, 0)) Then
'our client-number's first row is a cancelled task. read through for all the other rows for this client-number (They're in a block, so this is easier)
j = 0
While dataRows.Cells(i, 2) = dataRows.Cells(i, 2).Offset(j + 1, 0) _
And dataRows.Cells(i, 1) = dataRows.Cells(i, 1).Offset(j + 1, 0)
j = j + 1
Wend
'delete this client-number all at once
Rows(dataRows.Cells(i, 2).Row & ":" & dataRows.Cells(i, 2).Row + j).Delete
'roll back our counter by one. Our current row actually contains a new client thanks to the delete operation so we have to process this again
i = i - 1
End If
Next i
End Sub
下面的场景呢?如果 NUMBER 不同,则应单独处理。 在下面的例子中,只有编号为 456 的行应该被删除。但是宏也会删除 123。如何修改代码使其也包含数字条件?
Number Client Status Date
123 Aaa Done 20/02/2020
123 Aaa Done 05/03/2020
456 Aaa Cancelled 05/03/2020
456 Aaa Done 03/03/2020