在 Excel 中,单元格通常是可选择和可编辑的。
我可以格式化一些要解锁的单元格,然后仅使用选择未受保护的单元格的选项来保护工作表。
这样,未解锁的锁定单元格就无法被用户选择或编辑,而未受保护的单元格仍然可以被选择和编辑。
我的问题是,我如何才能拥有可选择但不可编辑的单元格。只读状态,其中的信息可以查看、选择、复制,但不能修改。
如果我通过选择受保护的单元格的选项来保护工作表,我会得到我想要的内容,但我也不能有任何不可选择的单元格。
总而言之,我想要有不可选择(因此不可编辑)的单元格、可选的不可编辑单元格和可选的可编辑单元格。
优先考虑不需要使用 VBA 的解决方案,但如果不可能,那么最简单的越好。
我尝试的解决方案失败了:
保护工作表,锁定所需的不可选择的单元格,并解锁可选择的单元格,仅选中保护选项Select unlocked cells
。
为了使单元格(在本例中B2:C3
)看起来不可编辑,我在工作表中添加了 VBA 代码:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Const SelectableUneditableRangeAddress As String = "B2:C3"
If Not Excel.Intersect(Target.Worksheet.Range(SelectableUneditableRangeAddress), Target) Is Nothing Then
Excel.Application.EnableEvents = False
Excel.Application.Undo
Excel.Application.EnableEvents = True
End If
End Sub
这样,如果它影响任何可选择的不可编辑单元格,它会撤消任何更改(在应用之后)。
除了不理想之外,它还允许剪切和粘贴不可编辑的单元格。
答案1
我想到最好的解决方案是锁定除可选择的可编辑单元格之外的所有单元格,并使用Select locked cells
和Select unlocked cells
选中来保护工作表。
然后,为了让用户选择任何所需的不可选择的单元格时取消选择,我将以下 VBA 代码添加到工作表中:
Private PreviousSelection As Excel.Range
Private PreviousActiveCell As Excel.Range
Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
Const SelectableUneditableRangeAddress As String = "B2:C3"
Dim SelectableUneditableRange As Excel.Range
Dim UsedRange As Excel.Range
Dim Cell As Excel.Range
Dim SelectRange As Excel.Range
Dim ActivatedCell As Excel.Range
Set SelectableUneditableRange = Target.Worksheet.Range(SelectableUneditableRangeAddress)
Set UsedRange = Excel.Intersect(Target, Excel.Union(SelectableUneditableRange, Target.Worksheet.UsedRange))
For Each Cell In UsedRange
If Not Excel.Intersect(SelectableUneditableRange, Cell) Is Nothing Or Not Cell.Locked Then
If SelectRange Is Nothing Then
Set SelectRange = Cell
Else
Set SelectRange = Excel.Union(SelectRange, Cell)
End If
End If
Next Cell
Excel.Application.EnableEvents = False
If SelectRange Is Nothing Then
If PreviousSelection Is Nothing Then
Set PreviousSelection = Excel.Selection
End If
PreviousSelection.Select
If PreviousActiveCell Is Nothing Then
Set PreviousActiveCell = Excel.ActiveCell
End If
PreviousActiveCell.Activate
Set PreviousActiveCell = Excel.ActiveCell
Else
Set ActivatedCell = Excel.ActiveCell
SelectRange.Select
Set PreviousSelection = SelectRange
If Excel.Intersect(SelectableUneditableRange, ActivatedCell) Is Nothing And ActivatedCell.Locked Then
Set PreviousActiveCell = PreviousSelection.Cells(1, 1)
Else
ActivatedCell.Activate
Set PreviousActiveCell = ActivatedCell
End If
End If
Excel.Application.EnableEvents = True
End Sub