我有一个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
答案 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行(标题行)被删除时,运行剩下的代码" *
不完全。
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列中(不包括标题),因此实际上没有删除任何内容。要解决所有问题,我已使用更强大的版本(以及一些更漂亮的消息框)更新了代码:
vbOKCancel
备注:强>
vbYesNo
代替.Value2
,可以按 Esc 中止删除。Value
代替B
更快,并避免潜在问题,因为未执行隐式类型转换。<强>注意事项:强>
B
)列,因此如果用户在那里删除了一个单元格,则前一点适用。%USERPROFILE%\AppData\Roaming\npm
列中,并且只有第一个粘贴的值为空,则所有将删除那些预先存在的项目,而不是仅删除第一个* 来自已删除的评论