如何在Excel VBA中检测单元格是否具有受保护的格式



我有一些VBA代码,我想设置给定工作簿中符合某些条件的所有单元格的格式(前景((本质上是为了自动标记特定UDF的使用(。如果用户的工作簿中有受保护的工作表,他们可能(明智地(以允许格式化的方式对其进行了保护。如何检查(从表示单元格的VBA Range对象(任何给定工作表上的单元格是否适合进行格式编辑?

我知道这个问题的第一个答案是一个错误处理程序来尝试并处理失败的情况,但由于它必须在每个工作表的UsedRange中的每个单元格上运行,我希望它能很快。我也意识到这是VBA,所以可能没有更快或更优雅的方法,但这里有很多收集的智慧,因此我提出了这个问题!

我认为错误处理仍然是一条路要走。但据我所知,如果工作表中的一个单元格的格式化失败,则所有其他单元格的格式化也将失败,即使这些单元格已解锁

尝试以下策略:其想法是,如果任何单元格的格式设置失败,则停止尝试格式化当前工作表,然后转到下一个工作表。

Sub MyProcedure()
Dim sht As Worksheet
Dim cl As Range

For Each sht In ThisWorkbook.Sheets

For Each cl In sht.UsedRange

On Error Resume Next

' Format the cell in a DIFFERENT procedure so that
' if an error occurs the rest of formatting lines are
' are not attempted (this is the key idea)
ApplyFormat cl

If Err.Description = "Application-defined or object-defined error" Then
Err.Clear
Exit For
End If

Next cl

'* Either reset your error handling here if you have more code for each sheet
On Error GoTo 0

' ...more code

Next sht
'* Or eset you error handling here
On Error GoTo 0

' ...more code

End Sub
Sub ApplyFormat(cl As Range)
' apply your formatting here
End Sub

您需要首先检查工作表是否受到保护,如果没有,请执行所需操作。

如果"受保护",则应仅检查尝试更改的范围(如果已锁定(,是否已锁定单元格(如果未锁定(,并且仅在解锁时执行作业。您无法检查单元格是否具有保护的格式。。。下一个代码将向您展示(我认为(在这种情况下要做什么:

Sub testSheetProtectedLockedCells()
Dim sh As Worksheet, rng As Range
Set sh = ActiveSheet: Set rng = sh.Range("A2:C4")
'Just for testing: _________________________________________
rng.Locked = Not rng.Locked 'lock - unlock the range...
rng.cells(1, 1).Locked = Not rng.cells(1, 1).Locked ' lock-unlock one cell of the range
'___________________________________________________________
If Not sh.ProtectionMode Then
DoIt rng
Else
If rng.Locked = False Then
DoIt rng
ElseIf IsNull(rng.Locked) Then
MsgBox "Cell(s) of the range """ & rng.address & """ are locked." & vbCrLf & _
"Please, unlock all the range and run the code again!", vbInformation, _
"Locked cells in the range to be processed..."
Else
MsgBox "The range """ & rng.address & """ is locked." & vbCrLf & _
"Please, unlock it and run the code again!", vbInformation, _
"Locked range to be processed..."
End If
End If
End Sub
Sub DoIt(rng As Range) 'do here the job you need...
Debug.Print rng.address, rng.Locked
End Sub

最新更新