我现在有两列数据,第a列是编号,第x列是等级。第a列中有12个编号,其中每个编号出现的次数大于等于1,对应在第x列的等级分为A,B C三级,同一个编号对应的等级可能不同也可能相同。现在,用vba实现以下功能:选出那些出现次数大于1的编号(也就是对应等级可能不止一种或者一种等级有多行的编号),查看其在x列对应的等级;若对应的多个等级中包含A,则对于这个编号只留一个包含A的行,该编号的其余行均删除;若对应等级不包含A,则判断多个对应的等级中是否包含B,是则只留一个包含B的行,该编号的其余行均删除;若不含B,也就是只含C,则只留一个包含C的行,该编号的其余行删除
以下是GPT给出的代码:
Sub DeleteRows()
Dim i As Long
Dim lastRow As Long
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
' 获取最后一行的行号
lastRow = Cells(Rows.Count, "a").End(xlUp).Row
' 遍历编号列,将编号和对应的行号存入字典中
For i = 1 To lastRow
If Not dict.Exists(Cells(i, "a").Value) Then
dict.Add Cells(i, "a").Value, i
Else
dict.Item(Cells(i, "a").Value) = dict.Item(Cells(i, "a").Value) & "," & i
End If
Next i
' 遍历字典,对于出现次数大于1的编号进行处理
For Each key In dict.Keys
If UBound(Split(dict.Item(key), ",")) > 0 Then
Dim rows() As String
rows = Split(dict.Item(key), ",")
Dim foundA As Boolean, foundB As Boolean, foundC As Boolean
foundA = False: foundB = False: foundC = False
' 遍历该编号对应的所有行,查找是否包含A、B、C等级
For i = LBound(rows) To UBound(rows)
If Not foundA And Cells(rows(i), "x").Value = "A" Then
foundA = True
ElseIf Not foundB And Cells(rows(i), "x").Value = "B" Then
foundB = True
ElseIf Not foundC And Cells(rows(i), "x").Value = "C" Then
foundC = True
End If
' 如果找到了A、B、C等级,则删除该行并退出循环
If foundA Or foundB Or foundC Then
Rows(rows(i)).Delete
Exit For
End If
Next i
' 如果没有找到A、B、C等级,则删除该编号对应的所有行(除第一行)
If Not (foundA Or foundB Or foundC) Then
For i = UBound(rows) To LBound(rows) + 1 Step -1
Rows(rows(i)).Delete
Next i
End If
End If
Next key
End Sub
报错:rows as string那里声明重复了,要如何解决
【以下回答由 GPT 生成】
首先,上述代码中的dict.Item(Cells(i, "a").Value) = dict.Item(Cells(i, "a").Value)
这一行是错误的,应该将其改为dict.Item(Cells(i, "a").Value) = dict.Item(Cells(i, "a").Value) & "," & i
,将重复的行号用逗号连接起来。
为了实现所描述的功能,我们可以对这段代码进行优化,具体步骤如下:
dict2
字典用于存储每个编号对应的等级信息。dict
中。dict2
中。dict2
字典,筛选出出现次数大于1的编号,并根据优先级情况删除多余的行。下面是优化后的代码示例:
Sub DeleteRows()
Dim i As Long
Dim lastRow As Long
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim dict2 As Object
Set dict2 = CreateObject("Scripting.Dictionary")
' 获取最后一行的行号
lastRow = Cells(Rows.Count, "a").End(xlUp).Row
' 遍历编号列,将编号和对应的行号存入字典中
For i = 1 To lastRow
If Not dict.Exists(Cells(i, "a").Value) Then
dict.Add Cells(i, "a").Value, i
Else
dict2.Item(Cells(i, "a").Value) = dict2.Item(Cells(i, "a").Value) & "," & i
End If
Next i
' 遍历dict2字典,删除多余的行
Dim key As Variant
Dim rowsToDelete As String
For Each key In dict2.keys
Dim levels As String
levels = dict2.Item(key)
If Len(levels) > 0 Then
Dim arrLevels() As String
arrLevels = Split(levels, ",")
Dim aFound As Boolean
Dim bFound As Boolean
Dim cFound As Boolean
aFound = False
bFound = False
cFound = False
Dim j As Long
For j = 0 To UBound(arrLevels)
Dim level As String
level = Cells(arrLevels(j), "b").Value
If level = "A" Then
aFound = True
bFound = False
cFound = False
rowsToDelete = rowsToDelete & "," & arrLevels(j)
ElseIf level = "B" Then
If Not aFound Then
aFound = False
bFound = True
cFound = False
rowsToDelete = rowsToDelete & "," & arrLevels(j)
End If
ElseIf level = "C" Then
If Not aFound And Not bFound Then
aFound = False
bFound = False
cFound = True
rowsToDelete = rowsToDelete & "," & arrLevels(j)
End If
End If
Next j
End If
Next key
' 删除多余的行
rowsToDelete = Mid(rowsToDelete, 2) ' 去掉开头的 ","
Dim arrRows() As String
arrRows = Split(rowsToDelete, ",")
Dim k As Long
For k = UBound(arrRows) To LBound(arrRows) Step -1
Rows(arrRows(k)).Delete
Next k
End Sub
请注意,上述代码假设编号列为"A"列,等级列为"B"列。如果实际情况不符,需要根据实际情况进行修改。
希望这个解决方案对您有帮助!如果还有其他问题,请随时提问。
【相关推荐】