虽然答案比您预期的要复杂,但可以做到这一点。 Jon van der Heyden 曾经在他的网站 (exceldesignsolutions.com) 上有一篇关于此的好文章,但我认为他已将其删除。我采用了他的一些代码,允许您将行添加到受保护工作表上的列表对象。这样做的好处是它强制用户只在列表对象正下方的行中输入数据,从而确保列表对象“增长”以包含新数据。
简而言之,使用的方法是创建一个自定义类,该类将包含一个 listobject 和一个事件处理程序,该处理程序侦听对包含它的工作表的更改。如果更改位于列表对象正下方的行中,则撤消更改,取消保护工作表,重做更改并重新保护工作表。另外解锁列表对象正下方的行。
这里是做什么:
在包含列表对象的工作簿中,创建一个自定义类模块并将其命名为 cProtectedLO。粘贴以下代码:
Option Explicit
Private m_loTable As ListObject
Private m_strPassWord As String
Private WithEvents m_appExcel As Excel.Application
Public Property Set Table(ByVal loTable As ListObject)
Set m_loTable = loTable
End Property
Public Property Let Password(ByVal strPassword As String)
m_strPassWord = strPassword
End Property
Private Sub Class_Initialize()
Set m_appExcel = Excel.Application
End Sub
Private Sub m_appExcel_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim rngTable As Excel.Range
Dim varValue As Variant
Set rngTable = m_loTable.Range
If Sh Is rngTable.Parent Then
If Not Intersect(Target.Offset(-1), rngTable) Is Nothing Then
If Intersect(Target, rngTable) Is Nothing Then
varValue = Target.Value
Sh.Unprotect Password:=IIf(Len(m_strPassWord), m_strPassWord, Null)
With Application
.EnableEvents = False
.Undo
Target.Value = varValue
Sh.Cells.Locked = True
m_loTable.DataBodyRange.Locked = False
m_loTable.Range(m_loTable.Range.Rows.Count, 1).Offset(1, 0).Resize(1, m_loTable.ListColumns.Count).Locked = False
.EnableEvents = True
End With
Sh.Protect Password:=IIf(Len(m_strPassWord), m_strPassWord, Null)
Target.Offset(1).Select
End If
End If
End If
End Sub
Private Sub Class_Terminate()
Set m_loTable = Nothing
Set m_appExcel = Nothing
End Sub
添加一个普通代码模块并将此代码粘贴到其中:
Option Explicit
Public m_colProtectedLO As Collection
Public Sub EnableProtectedTables(Optional ByVal pw As Variant)
Dim clsProtectedLO As cProtectedLO
Dim wks As Worksheet, lo As ListObject
Set m_colProtectedLO = New Collection
For Each wks In ThisWorkbook.Worksheets
For Each lo In wks.ListObjects
Set clsProtectedLO = New cProtectedLO
With clsProtectedLO
Set .Table = lo
If Not IsMissing(pw) Then
.Password = pw
End If
End With
wks.Unprotect Password:=pw
lo.DataBodyRange.Locked = False
lo.Range(lo.Range.Rows.Count, 1).Offset(1, 0).Resize(1, lo.ListColumns.Count).Locked = False
wks.Protect Password:=pw
m_colProtectedLO.Add Item:=clsProtectedLO
Next lo
Next wks
End Sub
在 ThisWorkbook 模块中,粘贴以下内容:
Option Explicit
Private Sub Workbook_Open()
EnableProtectedTables
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Set m_colProtectedLO = Nothing
End Sub
请注意,工作表受密码保护,您必须将其作为“pw”参数的值包含在对 EnableProtectedTables 的调用中,如下所示:
EnableProtectedTables pw:="YourPasswordHere"
保存工作簿,将其关闭并再次打开,您应该已准备就绪。