簡體   English   中英

為什么運行宏時會出現“類型不匹配”錯誤?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM