所以昨天我发布了我的第一个SO问题,结果像一吨砖一样下降。但是我已经振作起来,尘土飞扬,希望这个问题会更容易接受... :-)
我正在尝试从必须监视的“健康调查问卷”列表中删除重复数据,但是我一直在努力的棘手的一点是在一列中找到重复数据,然后检查相邻三列中同一行的数据也是重复的。存储搜索到的“重复的行”是让我失望的地方。
这是我从其他功能类似的脚本中整理的一些代码。我现在处于 Debug模式,并不断抛出错误……我对VBA没有太多的经验,所以我已经没有足够的选择了。
我目前收到变量g
和firstAddress
的类型不匹配错误。为什么这些会引起问题???
我可以叫firstAddress.Row
还是我叫错了树?
这是代码段:
g = .Find(Range("G" & i).Text, LookIn:=xlValues)
If Not g Is Nothing Then
firstAddress = g.Address
dupRow = firstAddress.Row
这是下面的整个代码。任何帮助将非常感激!
Sub FindCpy()
Dim lw As Long
Dim i As Integer
Dim sh As Worksheet
Dim dupRow As Integer
Dim g As Integer
Dim firstAddress As Integer
'Used for the new worksheet we are pasting into
Dim objNewSheet As Worksheet
Dim rngNextAvailbleRow As Range
'Used to narrow down the logical operators for duplicates
Dim rngFirst As Range
'Set the ranges
rngFirst = Range("G" & 1, "G" & lw)
Set sh = Sheets("Completed")
lw = Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lw 'Find duplicates from the list.
If Application.CountIf(Range("A" & i & ":A" & lw), Range("A" & i).Text) = "Complete" Then
'if COMPLETE, check the rest of the sheet for any 'in progress' duplicates...
With Worksheets("Still In Progress").rngFirst
g = .Find(Range("G" & i).Text, LookIn:=xlValues)
If Not g Is Nothing Then
firstAddress = g.Address
dupRow = firstAddress.Row
If Range("H" & dupRow).Text = Range("H" & i).Text _
And Range("I" & dupRow).Text = Range("I" & i).Text _
And Range("J" & dupRow).Text = Range("J" & i).Text Then
'select the entire row
Range.EntireRow.Select
'copy the selection
Selection.Cut
'Now identify and select the new sheet to paste into
Set objNewSheet = ThisWorkbook.Worksheets("Completed")
objNewSheet.Select
'Looking at your initial question, I believe you are trying to find the next available row
Set rngNextAvailbleRow = objNewSheet.Range("A1:A" & objNewSheet.Cells(Rows.Count, "A").End(xlUp).Row)
Range("A" & rngNextAvailbleRow.Rows.Count + 1).Select
ActiveSheet.Paste
'delete the initial row
rngCell.EntireRow.Delete
Set g = .FindNext(g)
Loop While Not g Is Nothing And g.Address <> firstAddress
End If
End With
Next i
End Sub
最佳答案
我仔细检查了您的代码。有很多问题。我想我能够解决其中的一些问题-有一个我猜到了您打算做什么,但是其中一个我只是将其标记出来。您需要说明要执行的操作,因为您要删除从未定义的范围...
第一个问题是该行:
If Application.CountIf(Range("A" & i & ":A" & lw), Range("A" & i).Text) = "Complete" Then
CountIf
函数返回一个数字;您正在将该数字与字符串“Complete”进行比较。我认为您永远都不会越过这一行,因此其余代码(无论正确与否)将不会执行。由于我不确定何时将行标记为“完成”,因此无法完全清楚您在此行中要执行的操作-但如果A & i
中的单元格具有字符串,则假定您有兴趣执行其余代码在其中“完成”,那么您可能想做If Range("A" & i).Text = "Complete" Then
有许多
If - Then
,With
和Loop
结构没有用匹配的End
正确终止。我已尝试纠正此问题-确保我做对了。请注意,使用适当的缩进确实有助于发现这样的问题。空格键是您的 friend ...由于
Find
方法返回一个对象,因此使用该函数的正确方法是Set g = .Find(Range("G" & i).Text, LookIn:=xlValues)
除此之外-在代码的顶部使用
Option Explicit
,并定义具有最大限制(正确)类型的变量。当我这样做时,我发现了无法纠正的错误-既未声明也未设置的rngCell
变量……它显示出它可以提供的帮助。同样适合捕捉错别字-VBA会很乐意让您编写诸如myVar = 1
MsgBox myVra + 1
由于输入错误,消息将是
1
而不是2
。Explicit
甚至应该是一个选项,这是VBA团队做出的许多莫名其妙的设计决定之一。这是您的代码“大多数错误已修复”。至少这样会编译-但是您必须弄清楚如何处理剩余的错误(而且我不确定我猜对了您想对标记为“完成”的单元格进行的处理是正确的)。
欢迎发表评论。
Option Explicit
Sub FindCpy()
Dim lw As Long
Dim i As Integer
Dim sh As Worksheet
Dim dupRow As Integer
Dim g As Range
Dim firstAddress As Range
'Used for the new worksheet we are pasting into
Dim objNewSheet As Worksheet
Dim rngNextAvailbleRow As Range
'Used to narrow down the logical operators for duplicates
Dim rngFirst As Range
'Set the ranges
rngFirst = Range("G" & 1, "G" & lw)
Set sh = Sheets("Completed")
lw = Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lw 'Find duplicates from the list.
' If Application.CountIf(Range("A" & i & ":A" & lw), Range("A" & i).Text) = "Complete" Then
If Range("A" & i).Text = "Complete" Then
'if COMPLETE, check the rest of the sheet for any 'in progress' duplicates...
With Worksheets("Still In Progress").rngFirst
Set g = .Find(Range("G" & i).Text, LookIn:=xlValues)
If Not g Is Nothing Then
firstAddress = g.Address
dupRow = firstAddress.Row
If Range("H" & dupRow).Text = Range("H" & i).Text _
And Range("I" & dupRow).Text = Range("I" & i).Text _
And Range("J" & dupRow).Text = Range("J" & i).Text Then
'select the entire row
g.EntireRow.Select
'copy the selection
Selection.Cut
'Now identify and select the new sheet to paste into
Set objNewSheet = ThisWorkbook.Worksheets("Completed")
objNewSheet.Select
'Looking at your initial question, I believe you are trying to find the next available row
Set rngNextAvailbleRow = objNewSheet.Range("A1:A" & objNewSheet.Cells(Rows.Count, "A").End(xlUp).Row)
Range("A" & rngNextAvailbleRow.Rows.Count + 1).Select
ActiveSheet.Paste
'delete the initial row
rngCell.EntireRow.Delete ' <<<<<< the variable rngCell was never defined. Cannot guess what you wanted to do here!
Do
Set g = .FindNext(g)
Loop While Not g Is Nothing And g.Address <> firstAddress
End If ' entire row matched
End If ' Not g Is Nothing
End With ' With Worksheets("Still in Progress")
End If ' CountIf = "Complete"
Next i
End Sub
另一个方便的技巧:当您像使用
Range("A" & rngNextAvailbleRow.Rows.Count + 1).Select
一样“粘贴到下一个可用行”时,通常可以方便地执行以下操作:Dim destination As Range
Set destination = Worksheets("Sheetname").Range("A1")
当您需要粘贴一些东西时:
destination.Select
ActiveSheet.Paste
Set destination = destination.Offset(1,0)
这样,
destination
始终指向“我可以粘贴的下一个位置”。我发现它很有帮助,而且更清洁。
关于vba - Excel VBA : Compiler Errors,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18204496/