Raf*_*pov 0 excel vba excel-vba
我想传递列O中某个范围内的所有单元格,并删除所有不包含值的行:OI和SI.
我的代码显示错误:
If Selection.Value <> "SI" Or "OI" Then
Run Code Online (Sandbox Code Playgroud)
作为一种类型不匹配
Sub CHECK()
Dim MFG_wb As Workbook
Dim Dep As Integer
Dim I As Integer
Set MFG_wb = Workbooks.Open _
("C:\Users\rosipov\Desktop\eliran\MFG - GSS\MFG Daily\Fast Daily " & Format(Now(), "ddmmyy") & ".xlsx", _
UpdateLinks:=False, IgnoreReadOnlyRecommended:=True)
MFG_wb.Sheets("Aleris").Activate
Dep = MFG_wb.Sheets("Aleris").Range("O2", Range("O2").End(xlDown)).Count
Range("O2").Select
For I = 1 To Dep
If Selection.Value <> "SI" Or "OI" Then
EntireRow.Delete
Else
Selection.Offset(1, 0).Select
End If
Next I
End Sub
Run Code Online (Sandbox Code Playgroud)
尝试使用此代码来解决您的问题.它不仅修复了有问题的界限,而且避免了其他一些陷阱,从长远来看也不可避免地会引发问题.
Sub CHECK()
Dim ManufacturingFile As Workbook
Set ManufacturingFile = Workbooks.Open _
("C:\Users\rosipov\Desktop\eliran\MFG - GSS\MFG Daily\Fast Daily " & Format(Now(), "ddmmyy") & ".xlsx", _
UpdateLinks:=False, IgnoreReadOnlyRecommended:=True)
Dim Aleris As Worksheet
Set Aleris = ManufacturingFile.Worksheets("Aleris")
Dim TotalRows As Long
TotalRows = Aleris.Range("O2", Aleris.Range("O2").End(xlDown)).Count
' Avoid Select at all costs
' Range("O2").Select
Dim i As Long
For i = TotalRows To 1 Step -1
If Aleris.Range("O" & i).Value <> "SI" And Aleris.Range("O" & i).Value <> "OI" Then
Aleris.Rows(i).Delete
End If
Next i
End Sub
Run Code Online (Sandbox Code Playgroud)
首先,您的问题是由于If Selection.Value <> "SI" Or "OI" Then因为"OI"无法作为Boolean声明进行评估而引起的.在幕后,翻译试图转换"OI"为True或False无法转换.结果,您收到错误.修复很简单:
If Selection.Value <> "SI" or Selection.Value <> "OI" Then.现在我们有两个Boolean语句,都检查是否相等.口译员对此感到满意,并且运行得很好.
除此之外,我修复了你不合格的范围参考,以及你的Activate和Select.尽管其他人提出了一些建议,但这些都是非常糟糕的习惯.你的代码会破坏,而且会花费你.不相信我?阅读几乎任何其他职位约Activate和Select,你会看到同样的事情.
为什么这是一个坏主意?您完全无法控制ActiveSheet运行时的内容.当然你可以Activate,但会有一些东西进来并将焦点转移到另一张纸上,然后你会遇到问题.如果你不小心的话,这个bug可以花费数小时的工作量.
修复很简单.只需声明一个变量(就像你几乎拥有的那样),并使用该变量.瞧!不再担心错误的表格.
最后,Excel当您使用索引来引用工作表的某些部分时,非常擅长理解您的意思.你没必要Selection.Offset(1, 0).Select然后Selection.EntireRow.Delete因为所有这些真正意味着ActiveSheet.Rows(Selection.Row + 1).Delete我们可以进一步重构以使用工作表和索引Foo.Rows(i + 1).Delete.看到这里的模式?逐步变得更抽象,直到您的代码变得稳固.
我改变的最后一件事是你的变量名.使用描述性名称,它使您的代码更易于维护.此外,在您理解之前,永远不要在名称中使用下划线"_" Interfaces.下划线对翻译有特殊意义.
最后,查看Rubberduck项目:rubberduckvba.com.它是一个免费的插件,致力于改善VBA编码体验.最好的部分?大部分反馈都作为检查内置于RD中.它为您完成了工作,您可以在此过程中学习.
祝你好运!