VBA Excel使用ListObjects在工作表中运行带有IF AND THEN语句宏

eagi6jfj  于 2022-11-26  发布在  其他
关注(0)|答案(2)|浏览(252)

我试图在带有ListObjects的工作表中运行带有IF AND THEN语句的宏。

在工作表“CommissionVoice”中,宏必须检查列“L”是否包含文本值“No Pay”或“Below Target”。如果它包含这些字符串,则列K(整数)需要与列E(百分比)一起计算。
到目前为止,我只能用一个简单的IF语句创建下一个(测试)代码,但这并不起作用:

Sub Test()

    Dim tbl As ListObject
    Dim rng As Range
    Dim cel As Range
    Set tbl = ActiveSheet.ListObjects("CommissionVoice")
    Set rng = tbl.ListColumns(12).DataBodyRange
    
    For Each cel In rng
    If InStr(1, cel.Value, "No pay") > 0 Then
        cel.Offset(0, -1).Value = "OK"
    End If
Next cel

End Sub

有人能帮我吗?

czq61nw1

czq61nw11#

类型不匹配错误可能有不同的原因,例如,您无法将字符串赋给数字或将数字赋给对象。通常,使用调试器很容易找到此错误。请检查引发错误的语句的所有相关值/变量。
在这个特定的例子中,命令InStr(1, cel.Value, "No pay")引发了错误。唯一可能是错误类型的值是cel.Value,它表示实际单元格的值。现在,单元格只能包含数值、字符串值、布尔值或错误。错误不是字符串,它们是一种单独的数据类型。当您看到#N/A时,这不是字符串"#N/A"。这些错误值不能用作任何其他数据类型,也不能转换为任何其他数据类型,因此会出现类型不匹配错误。
您可以使用函数IsError检查VBA中的错误。因此,您可以认为该语句只需更改为

If Not IsError(cel.Value) And InStr(1, cel.Value, "No pay") > 0 Then

但是,这并不能解决问题- VBA将始终检查条件的所有部分,因此无论如何都会执行InStr-命令。
2次尝试(还有其他)

' 2 separate If-statements
If Not IsError(cel.Value) Then
    If InStr(1, cel.Value, "No pay") > 0 Then
        (...)
    End If
End If

' Store the value into an intermediate variable and change an error to blank
Dim cellValue as Variant
cellValue = cel.Value
If IsError(cellValue) Then cellValue = ""
If InStr(1, cellValue, "No pay") > 0 Then
    (...)
End If

但正如评论中已经指出的,很可能用公式来解决这个问题会更好。

yiytaume

yiytaume2#

在Excel表格中(ListObject

Sub Test()

    ' Reference the objects.
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1") ' adjust!
    Dim lo As ListObject: Set lo = ws.ListObjects("CommissionVoice")
    
    With lo
        
        ' Get the column indexes.
        Dim colAdj As Long: colAdj = lo.ListColumns("Adjustments").Index
        Dim colNps As Long: colNps = lo.ListColumns("NPS").Index
        Dim colPer As Long: colPer = lo.ListColumns("NPS Performance").Index
        
        With .DataBodyRange ' excluding headers
            
            ' Write the values from the data columns to arrays.
            Dim adjData() As Variant: adjData = .Columns(colAdj).Value
            Dim npsData() As Variant: npsData = .Columns(colNps).Value
            Dim perData() As Variant: perData = .Columns(colPer).Value
            
            Dim r As Long
            
            ' Loop over the rows and modify the values in the arrays.
            For r = 1 To .Rows.Count
                Select Case CStr(perData(r, 1))
                    Case "No pay", "Below Target"
                        ' Maybe some rounding 'nps = Round(nps*(1-adj),2)' ?
                        npsData(r, 1) = npsData(r, 1) * (1 - adjData(r, 1))
                        perData(r, 1) = "OK"
                    'Case Else ' do nothing
                End Select
            Next
            
            ' Write the arrays back to their data columns.
            .Columns(colNps).Value = npsData
            .Columns(colPer).Value = perData
        
        End With
    
    End With

    ' Inform (don't know the jargon).
    MsgBox "Negative commissions applied.", vbInformation

End Sub

相关问题