[英]Why do I get the "type mismatch" error when running the macro?
這是我第一次做 VBA 宏,我很難理解這個問題。
我正在嘗試使用特定值過濾和着色單元格,但是當我嘗試運行代碼時,它顯示“類型不匹配”。
Dim count, i As Long
Dim ws As Worksheet
Dim count, i As Long
Dim ws As Worksheet
Set ws = Sheets("Sheet1")
count = ws.Cells(Rows.count, "E").End(xlUp).Row
i = 2
Do While i <= count
If Cells(i, 5).Value = "#N/A" _
Or Cells(i, 5).Value = "#Ref" _
Or Cells(i, 5).Value = "Null" _
Or Cells(i, 5).Value = "" _
Or Cells(i, 5).Value = "#DIV/0!" _
Or Cells(i, 5).Value = "" _
Or Cells(i, 5).Value Like "*-*" Then
Cells(i, 5).Interior.Color = RGB(38, 201, 218)
End If
i = i + 1
Loop
ws.Range("E1").AutoFilter Field:=5, Criteria1:=RGB(38, 201, 218), Operator:=xlFilterCellColor
當我單擊調試時,它會突出顯示 If 語句。 有沒有辦法解決這個問題,或者有沒有更好的方法來過濾這些值,同時在 VBA 中突出顯示它們?
不是真正的答案,更多的是擴展評論。
If IsError(Cells(i, 5)) Then
Cells(i, 5).Interior.Color = RGB(0, 0, 255)
ElseIf Cells(i, 5).Value = "" Then
Cells(i, 5).Interior.Color = RGB(0, 0, 255)
Else
Cells(i, 5).Interior.Color = xlNone
End If
此外,這是為了篩選錯誤https://docs.microsoft.com/en-us/office/vba/excel/concepts/cells-and-ranges/cell-error-values
第一個問題:如果您的單元格包含錯誤,它不包含字符串"#N/A"
或"#Ref"
,它包含一個特殊值。 您所看到的只是該錯誤的直觀表示。 如果要檢查 Excel 中的錯誤,應使用函數IsError
。 這將導致(等等,不要使用它! ):
If isError(Cells(i, 5).Value)
Or Cells(i, 5).Value = "Null" _
Or Cells(i, 5).Value = "" _
Or Cells(i, 5).Value Like "*-*" Then
第二個問題:在 VBA 中,條件語句沒有優化,VBA 將始終評估所有部分。 您的 If 語句包含多個條件,並與Or
結合使用。 雖然其他編程語言在一個條件使整個表達式為真時退出評估,但 VBA 將繼續評估所有條件。
現在,如果您在單元格中有錯誤並且您將使用上面的代碼,您仍然會收到類型不匹配錯誤:您無法將錯誤與字符串進行比較。 條件isError(Cells(i, 5).Value)
將得到 True,但 VBA 將繼續將單元格內容與字符串進行比較,這會導致不匹配。 您需要一種方法來拆分您的 If 語句。
更多評論:您正在將要使用的工作表分配給變量ws
,但您沒有使用它。 您將需要限定Cells
的每一次使用(寫入ws.Cells(i, 5)
,否則 VBA 將假定您正在使用活動工作表,並且可能是也可能不是 Sheet1。通常,這是通過With
-statement(注意所有前導點)。
您的聲明語句有缺陷(VBA 中的常見錯誤),您需要為每個變量指定類型。 在您的情況下, Count
將是Variant
類型,而不是Long
。 這里沒問題,但在其他情況下確實如此,因此請養成正確聲明所有變量的習慣。
您應該使用For
-Loop 而不是Do While
。
Dim count As Long, i As Long
With ws
count = .Cells(.Rows.count, "E").End(xlUp).Row
For i = 2 to count
Dim markCell as boolean
If isError(.Cells(i, 5).Value) Then
markCell = True
ElseIf .Cells(i, 5) = "Null" _
Or .Cells(i, 5).Value = "" _
Or .Cells(i, 5).Value Like "*-*" Then
markCell = True
Else
markCell = False
End If
If markCell Then
.Cells(i, 5).Interior.Color = RGB(38, 201, 218)
End If
Next i
End With
如果要檢查特定錯誤,首先需要檢查IsError
是否存在錯誤。 您無法在一種情況下檢查錯誤和值:
Do While i <= count
Dim Condition As Boolean
Condition = False ' initialize when in a loop!
If IsError(Cells(i, 5).Value) Then
If Cells(i, 5).Value = CVErr(xlErrNA) _
Or Cells(i, 5).Value = CVErr(xlErrRef) _
Or Cells(i, 5).Value = CVErr(xlErrNull) _
Or Cells(i, 5).Value = CVErr(xlErrDiv0) Then
Condition = True
End If
ElseIf Cells(i, 5).Value = "" Or Cells(i, 5).Value Like "*-*" Then
Condition = True
End If
If Condition = True Then
Cells(i, 5).Interior.Color = RGB(38, 201, 218)
End If
Loop
Sub FilterByColor()
Const wsName As String = "Sheet1"
Const Col As String = "E"
Dim FilterColor As Long: FilterColor = RGB(38, 201, 218)
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
If ws.FilterMode Then ws.ShowAllData ' remove any filters
Dim lRow As Long: lRow = ws.Cells(ws.Rows.count, Col).End(xlUp).Row
Dim rgData As Range ' data range; no header
Set rgData = ws.Range(ws.Cells(2, Col), ws.Cells(lRow, Col))
rgData.Interior.Color = xlNone ' remove all colors
Dim rgColor As Range ' the combined range to be colored
Dim DataCell As Range ' each cell of the data range
Dim cString As String
Dim DoColor As Boolean
For Each DataCell In rgData.Cells
If IsError(DataCell) Then ' error value
DoColor = True
Else
cString = CStr(DataCell.Value)
If Len(cString) = 0 Then ' blank
DoColor = True
Else
If InStr(1, cString, "-") > 0 Then ' contains a minus ('-')
DoColor = True
End If
End If
End If
If DoColor Then
If rgColor Is Nothing Then ' combine cells into a range
Set rgColor = DataCell
Else
Set rgColor = Union(rgColor, DataCell)
End If
DoColor = False ' don't forget to reset
End If
Next DataCell
If rgColor Is Nothing Then Exit Sub
rgColor.Interior.Color = FilterColor ' apply color in one go
Dim rgTable As Range ' table range; header included
Set rgTable = ws.Range(ws.Cells(1, Col), ws.Cells(lRow, Col))
rgTable.AutoFilter 1, FilterColor, xlFilterCellColor
' To delete the rows, you could continue with e.g.:
' rgData.SpecialCells(xlCellTypeVisible).EntireRow.Delete
' ws.AutoFilterMode = False ' remove 'AutoFilter'
End Sub
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.