Excel VB错误Application.Undo&ActiveSheet.Protect

好奇,如果有人有这个解决scheme。 这是我的代码在下面,我认为这是完美的工作。 我们用了很长时间,有人指出我们一直在做什么,这会导致脚本错误。

这段代码的作用是防止某人一次更新多个单元格。 如果有人拷贝了大量的数据,在粘贴到Excel中的时候会占用多行或多列,比如应对电子邮件并将其粘贴到电子表格中,则会收到一个popup式警报,表示不要更改多个单元格在一次,然后它将撤消粘贴。 这部分工作很好。

什么人正在做,这是造成一个错误,他们会select一个单元格,并在单元格的右下angular,你可以点击并拖动填满或以上的方块,他们会select并填写。 如果只填充一个单元格,则不存在问题。 问题是当他们对两个或更多的单元执行此操作时,即发生错误时。 更具体地说,在说的Application.Undo的行。

所以这个问题真的不在Application.Undo这一行,实际上是在电子表格被locking的情况下。 如果我想删除说ActiveSheet.UnprotectActiveSheet.Protect的行,那么代码工作正常。 但是,我确实希望它被保护。 还有更多的代码,然后我在这里,但这只是它的一个片段,我确实有正确格式的单元格,所以正确的是locking的,其他人不是。 你应该能够把这些代码粘贴到一个新的电子表格中,并且能够工作,所以你可以看到我在说什么,但是,确保你先解锁一些单元格,然后才能进行编辑。 一旦你这样做,看到这个错误,去掉保护/不保护行再次尝试,代码将工作没有任何问题。

请让我知道如果有人有这个解决scheme,所以我仍然可以保持电子表格保护,并感谢您的帮助!

  Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False ActiveSheet.Unprotect Dim vClear As Variant Dim vData As Variant Dim lFirstRow As Long Dim lLastRow As Long 'This prevents more than one cell from being changed at once. 'If more than one cell is changed then validation checks will not work. If Target.Cells.Count > 1 Then vData = Target.Formula For Each vClear In vData If vClear <> "" Then 'If data is only deleted then more than one cell can be changed. MsgBox "Change only one cell at a time", , "Too Many Changes!" Application.Undo Exit For Else 'If data is deleted this will check to see what columns are being deleted. 'Deleting certain columns will also allow for the automatic deletion of other columns not selected. If vClear = "" Then 'If the target includes columns D, it will also clear columns M & N. If Not Intersect(Target, Columns("D")) Is Nothing Then 'Gets the first row in the target range. lFirstRow = Target.Rows(1).Row 'Gets the last row in the target range. lLastRow = lFirstRow + Target.Rows.Count - 1 'Clears the contents of corresponding rows in column M & N. ActiveSheet.Range(Cells(lFirstRow, 13), Cells(lLastRow, 13)).ClearContents ActiveSheet.Range(Cells(lFirstRow, 14), Cells(lLastRow, 14)).ClearContents End If 'If the target includes columns G, it will also clear columns I & K & N. If Not Intersect(Target, Columns("G")) Is Nothing Then 'Gets the first row in the target range. lFirstRow = Target.Rows(1).Row 'Gets the last row in the target range. lLastRow = lFirstRow + Target.Rows.Count - 1 'Clears the contents of corresponding rows in column I & K & N. ActiveSheet.Range(Cells(lFirstRow, 9), Cells(lLastRow, 9)).ClearContents ActiveSheet.Range(Cells(lFirstRow, 11), Cells(lLastRow, 11)).ClearContents ActiveSheet.Range(Cells(lFirstRow, 14), Cells(lLastRow, 14)).ClearContents End If 'If the target includes columns H, it will also clear columns I & K. If Not Intersect(Target, Columns("H")) Is Nothing Then 'Gets the first row in the target range. lFirstRow = Target.Rows(1).Row 'Gets the last row in the target range. lLastRow = lFirstRow + Target.Rows.Count - 1 'Clears the contents of corresponding rows in column I & K. ActiveSheet.Range(Cells(lFirstRow, 9), Cells(lLastRow, 9)).ClearContents ActiveSheet.Range(Cells(lFirstRow, 11), Cells(lLastRow, 11)).ClearContents End If 'If the target includes column J, it will also clear column K. If Not Intersect(Target, Columns("J")) Is Nothing Then 'Gets the first row in the target range. lFirstRow = Target.Rows(1).Row 'Gets the last row in the target range. lLastRow = lFirstRow + Target.Rows.Count - 1 'Clears the contents of corresponding rows in column K. ActiveSheet.Range(Cells(lFirstRow, 11), Cells(lLastRow, 11)).ClearContents End If End If End If Next End If ActiveSheet.Protect Application.EnableEvents = True End Sub Private Sub Worksheet_SelectionChange(ByVal Target As Range) Application.EnableEvents = False ActiveSheet.Unprotect Dim iFirstCol As Integer Dim iLastCol As Integer Dim iFirstRow As Integer Dim iLastRow As Integer Dim iColor As Integer '''Only adjust the below numbers to fit your desired results.''' iFirstCol = 1 'Change this number to the number of the first column that needs to be highlighted. Column A = 1. iLastCol = 15 'Change this number to the number of the last column that needs to be highlighted. Column A = 1. iFirstRow = 7 'Change this number to the number of the first row that needs to be highlighted. iLastRow = 500 'Change this number to the number of the last row that needs to be highlighted. iColor = 20 'Change this number to use a different highlight color. '''End of changes, do not change anything else.''' If Target.Count = 1 Then 'The row highlight will only be applied if the selected range is within this if statement criteria. If Target.Row > iFirstRow - 1 And Target.Row < iLastRow + 1 And Target.Column > iFirstCol - 1 And Target.Column < iLastCol + 1 Then 'Resets the color within the full range when cell selection changed. ActiveSheet.Range(ActiveSheet.Cells(iFirstRow, iFirstCol), ActiveSheet.Cells(iLastRow, iLastCol)).Interior.Color = xlNone 'Applies the colors to the row. For counter = iFirstCol To iLastCol With ActiveSheet.Cells(Target.Row, iFirstCol).Interior .ColorIndex = iColor .Pattern = xlSolid End With iFirstCol = iFirstCol + 1 Next counter End If End If ActiveSheet.Protect Application.EnableEvents = True End Sub 

好吧,我觉得现在有点愚蠢。 我想出了这个问题。 不敢相信花了这么长时间。 由于我的代码的最后一半,我的电子表格被保护,突出显示它的行。 我不得不将Target.Count部分移动到该子标题的顶部。 所以Private Sub Worksheet_SelectionChange(ByVal Target As Range)之前的所有内容都没有改变,但之后我不得不修改它在哪里检查select了多less单元格的位置,以防止电子表格被保护。 显然,当你拖下来时,就像是在同一时间单独地select单元格一样。 这就是为什么当我在电子表格中粘贴数据时,代码没有犯错,因为它只读取了一次SelectionChange类别,但是如果我拖下来,每次拖动时都会读取这个部分。 我以前不知道,但我想这一定是如何工作的。

所以我只是在SelectionChange部分修改了代码,现在就可以工作了。 也感谢所有对我留下评论和build议的人。

 Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Cells.CountLarge = 1 Then Application.EnableEvents = False ActiveSheet.Unprotect Dim iFirstCol As Integer Dim iLastCol As Integer Dim iFirstRow As Integer Dim iLastRow As Integer Dim iColor As Integer '''Only adjust the below numbers to fit your desired results.''' iFirstCol = 1 'Change this number to the number of the first column that needs to be highlighted. Column A = 1. iLastCol = 15 'Change this number to the number of the last column that needs to be highlighted. Column A = 1. iFirstRow = 7 'Change this number to the number of the first row that needs to be highlighted. iLastRow = 500 'Change this number to the number of the last row that needs to be highlighted. iColor = 20 'Change this number to use a different highlight color. '''End of changes, do not change anything else.''' 'The row highlight will only be applied if the selected range is within this if statement criteria. If Target.Row > iFirstRow - 1 And Target.Row < iLastRow + 1 And Target.Column > iFirstCol - 1 And Target.Column < iLastCol + 1 Then 'Resets the color within the full range when cell selection changed. ActiveSheet.Range(ActiveSheet.Cells(iFirstRow, iFirstCol), ActiveSheet.Cells(iLastRow, iLastCol)).Interior.Color = xlNone 'Applies the colors to the row. For counter = iFirstCol To iLastCol With ActiveSheet.Cells(Target.Row, iFirstCol).Interior .ColorIndex = iColor .Pattern = xlSolid End With iFirstCol = iFirstCol + 1 Next counter End If ActiveSheet.Protect Application.EnableEvents = True End If End Sub