我通过Worksheet_Change事件运行一段代码,我让它在事件开始时调用unprotect子,并在事件结束时调用一个protect子。这可以按预期工作。
我尝试将保护设置为userinterfaceonly:=在工作簿打开事件中为true,以消除每次更改事件触发时取消保护和重新保护的需要(更多只是为了探索功能而不是其他任何事情) 。问题是,如果工作表受到保护(即使使用UserInterfaceOnly = True),更改锁定范围上的条件格式的代码也会发生错误,尽管它可以正常工作并且如果工作表不受保护,无论是手动还是通过VBA在该行之前取消保护工作表在那条线之后重新保护。
我已经玩了一下,似乎在更改锁定单元格上的条件格式化方面有任何错误。我想知道在UserInterfaceOnly范围内是否允许在保护工作表时更改锁定范围的条件格式?如果有人知道这是否是一个限制,如果这个论点有任何其他限制,那么很高兴知道。
在我的本练习册中#39;模块我:
Private Sub Workbook_open()
ActiveSheet.Protect userinterfaceOnly:=True
End Sub
在我的工作表模块中,我有以下内容 - FormatConditions.Delete行错误,运行时错误1004:当Case解析为true时应用程序或对象定义错误。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$D$6" Then
Application.ScreenUpdating = False
Select Case Range("D6")
Case "Select Function"
Range("F6").Value = ("")
Range("H4:I4").Select
Selection.FormatConditions.Delete <<<<<<THIS LINE ERRORS
Selection.ClearContents
Call DeleteButtons
Call HideAll
Range("D6").Select
Case "Goods In & Redelivery"
Range("F6").Value = ("EXPLANATORY TEXT")
Call DeleteButtons
Range("D10:F10").ClearContents
Call UnHideAll
Call HideCollection
Call FillDelivery
Call GIRButtons
Range("D10").Select
Case "Collection & Redelivery"
Range("F6").Value = ("EXPLANATORY TEXT")
Call DeleteButtons
Call UnHideAll
Call HideGoodsIn
Call ClearDelivery
Call CRButtons
Range("H4").Select
Case "Delivery Only"
Range("F6").Value = ("EXPLANATORY TEXT")
Call DeleteButtons
Call UnHideAll
Call HideGoodsInCollection
Call ClearDelivery
Call DelButtons
Range("H4").Select
End Select
Application.ScreenUpdating = True
End If
End Sub
答案 0 :(得分:1)
与.Protect UserInterfaceOnly:=True
一起使用AllowFormattingCells:=True
。这允许条件格式化修改受保护的单元格。
答案 1 :(得分:1)
我绝对认为这是一个Excel错误,因为UserInterfaceOnly选项旨在允许vba代码更改工作表而不必一直取消保护和保护工作表,这有很多缺点(Some reasons why not to do this in this link)。
虽然Anthony的答案可以作为一种解决方法,但它可以让用户更改工作表单元格格式,即使它受到保护,在我的情况下也是不可接受的。
我一直在努力,直到找到一个可以接受的解决方案。它仍然是一种解决方法,但是可以接受。
解决方法:
解决方法包括在电子表格的另一个区域中创建一组具有所需格式(包括条件格式)的单元格“模板”(可以在工作表的设计阶段之后隐藏或驻留在另一个工作表中) )并且只要您希望在电子表格的可见区域中应用其格式(可以在您的vba逻辑中定义要复制的模板的特定部分),请使用Range.Copy
和Range.PasteSpecial
。当然,像往常一样,Excel会很好地将条件格式化公式调整到复制目标(除非您使用$ $ $ 1锚定地址,这在特定情况下可能很有用)。 (请阅读下面的副作用以规避它们)
OBS: Range.Copy <Another range as a parameter>
不同工作表也违反了工作表保护,无论使用的是UserInterfaceOnly选项(在同一工作表中,这都可以正常工作)。如果要在具有保护的不同工作表之间进行复制,请将操作拆分为两个:首先使用Range.Copy
然后使用Range.PasteSpecial xl<whatever>
(是的,另一个excel工作表保护错误)
附带利益
这种方法的另一个好处是,您可以使用Excel的界面来设计模板,而不必使用Range.FormatConditions.<whatever>
进行编码。这在处理模式,颜色等方面非常有用,也有助于减少VBA代码的数量。
OBS:请注意,为了简化代码,我甚至在模板单元格中使用命名范围,以便Range.Copy调用在代码中变得更加优雅,例如Range("ATemplateNamedRange").Copy
。
副作用
根据您使用的Office版本及其应用的修补程序,Excel可能会使包含条件格式的单元格的C&amp; P变得非常混乱,从而导致规则的累积和重复。由于上述错误,在粘贴之前使用Range.ConditionalFormatting.Delete
会违反表单保护,因此唯一可行的解决方法是在粘贴之前使用目标中的Range.ClearFormatting
(正确地尊重UserInterfaceOnly选项)。是的,这将擦除所有格式,但您可以从模板中恢复它(并巧妙地使用Application.ScreenUpdating = <true/false>
)
有关条件格式的其他奇怪效果
同样取决于Office版本,删除单元格(不清除,但实际上是删除)会混淆条件格式规则范围(这甚至不取决于要删除的区域,这与具有条件的单元格完全无关格式)。 Excel试图变得聪明并且不必要地分割/合并范围(使得它们的维护变得非常不可能)。在设计过程中巧妙地使用C&amp; P而不是删除/插入是避免这种情况的解决方法。