在Worksheet_Change处理程序中的多单元格条目上键入不匹配错误

时间:2018-03-23 23:19:51

标签: excel vba excel-vba

我有一个Worksheet_Calculate处理程序,一旦将一行添加到活动工作表上的表中,就会自动在另一个工作表上创建新记录。问题是,另一个用于记录删除的子句(Worksheet_Change处理程序)一直给我这个错误:

  

运行时错误' 13':类型不匹配

当我尝试将值粘贴到表格中的多个单元格中时,我只收到此错误。当我将值粘贴到单个单元格中时,没有问题。它甚至在粘贴到现有行时发生,只是覆盖预先存在的数据。

这个子甚至不应该运行。

当我转到调试器时,它表明问题出在这一行:

If Target.Column = 2 And Target.Row > 1 And Target.Value = "" Then

我希望表的行为类似于常规表,除非删除第1行下第2列中的数据。在所有其他实例中,它应该像任何其他表一样运行。

删除给我错误的记录的代码:

Public Sub Worksheet_Change(ByVal Target As Range) '_Change  creates the variable as a target, transferred as a value to "ProjectName"
    Dim ans As Integer 

    If Target.Column = 2 And Target.Row > 1 And Target.Value = "" Then

        ans = MsgBox("Are you sure you want to Delete......This cannot Be Undone !!!", vbYesNo)
            If ans = vbYes Then

                With Application
                    .EnableEvents = False ' freeze WorkSheetChange event since you're about to UNDO a change
                    .Undo ' undo the change
                    ProjectName = Target.Value ' assign the deleted-undone value in to YYY
                    Rows(ActiveCell.Row).EntireRow.Delete ' delete that row
                    .EnableEvents = True ' re-enable all events
                End With
                MsgBox ProjectName & " has been deleted."  ' now you have that value in ProjectName

            End If

    End If
DeleteRows (ProjectName) 'Gives sub-routine "DeleteRows" the company name
End Sub

1 个答案:

答案 0 :(得分:3)

在粘贴多个值时收到错误的原因是Target.Value如果Target多个单元格,则Target.Value返回一个数组,并且您无法将数组与字符串进行比较。这是"类型不匹配"手段。 ""的类型(数组)<> Target.Value = ""中的Target.Value字符串)的类型。

要解决此问题,可以尝试将Target.Cells(1).Value替换为Worksheet_Change(ByVal Target As Range),但您的代码仍然无法正常工作,因为有更多未解决的相关问题问题,以及其他不相关的问题:

  

这个子甚至不应该运行。

你误解了Target是什么。每当任何单元格已修改已删除时,它都会自动运行。 (从技术上讲,一个单元格可以被删除"或者删除"两者之间有细微差别。)

Target是已更改的单元格范围。它可以是一个细胞或多个细胞。您需要专门检查DeleteRows (ProjectName)是否与您感兴趣的单元格范围匹配,并排除所有其他单元格。要检查已删除(又名"已清除")单元格,您需要检查单元格内容是否为空白。检查真正的删除有点复杂。

  

我可以将_Change更改为_OnDelete或类似的东西吗? *

不,没有"删除"事件。如上所述,可以从"更改"事件。要查看可用事件列表,请选择"工作表"在代码窗口顶部的左下拉列表中,然后单击右侧下拉列表。

  

我以为我的代码在说," 当列B中的单元格大于第1行(标题行)被删除时,运行剩下的代码" *

不完全。

  1. 仅在删除<​​em>单个单元格时才能正常运行。多个删除的单元格将导致与上述相同的错误。
  2. IF位于ProjectName区块之外,因此只要任何单元格更改,始终即可运行。幸运的是Private Sub Worksheet_Change(ByVal Target As Range) ' Runs every time ANY cell in the sheet is modified , cleared or deleted 'v0.1.1 Dim rngClippedTarget As Range Set rngClippedTarget = Intersect(Target, Columns(2).Resize(Rows.Count - 1).Offset(1)) ' Extract the 2nd column, row 2 downwards, cells from Target (if any) If rngClippedTarget Is Nothing Then Exit Sub 'Ignore changes if there are none in column 2 (excluding header row) If rngClippedTarget.Cells(1).Value2 <> vbNullString Then Exit Sub ' Ignore changes if the first changed cell in column 2 has not been "emptied" With Application .EnableEvents = False ' Otherwise, the Worksheet_Change event is re-triggered by the .Undo .Undo ' Restore cleared values .EnableEvents = True End With Dim lngCellCount As Long lngCellCount = rngClippedTarget.Cells.Count Dim strConfirmMsg As String strConfirmMsg _ = rngClippedTarget.Cells(1).Value2 _ & IIf(lngCellCount = 1, "", " and " & lngCellCount - 1 & " other project" & IIf(lngCellCount = 2, "", "s")) _ & " will be deleted." & vbCrLf _ & "Are you sure? (This cannot be undone!)" If vbCancel = MsgBox(strConfirmMsg, vbCritical + vbOKCancel) Then Exit Sub 'Abort with all changes reverted Dim rngCell As Range For Each rngCell In rngClippedTarget DeleteRows rngCell.Value2 ' Delete the appropriate Database rows Next rngCell With Application .EnableEvents = False ' Otherwise, the Worksheet_Change event is re-triggered by the .Delete rngClippedTarget.EntireRow.Delete ' Delete all the changed rows in the sheet .EnableEvents = True End With MsgBox lngCellCount & " project" & IIf(lngCellCount = 1, " has", "s have") & " been deleted.", vbInformation End Sub 在每种情况下都是空白的,而不是在B列中(不包括标题),因此实际上没有删除任何内容。
  3. 要解决所有问题,我已使用更强大的版本(以及一些更漂亮的消息框)更新了代码:

    vbOKCancel

    备注:

    • 允许粘贴多个值,不会出错。
    • 允许一次删除多个项目。如果不需要,可以将其更改为提醒用户并改为中止。
    • 修复了取消删除并未还原已删除项目名称的问题。
    • 使用vbYesNo代替.Value2,可以按 Esc 中止删除。
    • 使用Value代替B更快,并避免潜在问题,因为未执行隐式类型转换。
    • 使用RVBA Naming Conventions

    <强>注意事项:

    • 如果用户实际删除工作表或表格行,则不起作用。删除工作表或表格行内容可以正常工作。 (代码可以更新以允许实际删除,但它有点复杂)
    • 如果已删除已空单元格,则会尝试删除名为&#34;&#34;的项目。
    • 不会忽略&#34;项目名称中的单元格&#34;表格下方的{B)列,因此如果用户在那里删除了一个单元格,则前一点适用。
    • 对于多个项目删除,它假定如果第一个项目名称为空,则其余项目也是如此。因此,如果用户将多个值粘贴到现有值的%USERPROFILE%\AppData\Roaming\npm 列中,并且只有第一个粘贴的值为空,则所有将删除那些预先存在的项目,而不是仅删除第一个

    * 来自已删除的评论