Excel中的保护和权限 一个奇奇怪怪的表单保护要求
一般来说,我对所有奇怪的问题是来者不拒的,只要真的是有这个需求,而且听起来还算是合理的话。
所以今天就有同事说到在Excel里面权限的设置的事。他的要求是这样的:
- 有一张表单,每个Sheet由不同的人负责里面数据的更新
- 每个人只能编辑自己负责的部分,要可以更改数据,插入行,删除行什么的
- 因为sheet还不少,所以最好不要用保护sheet然后输入密码的做法,因为这样每个sheet要一个密码,维护起来很麻烦。
我觉得他描述起来就够麻烦的了。Excel里面基础的权限保护有以下几个方法:
- 保护工作薄 (Protect Workbook)
- 保护工作表 (Protect Sheet)
- 设置可编辑区域 (Allow Users to Edit Ranges)

当然在这些之前还可以给整个文件设置一个打开密码。
保护工作表可以让单元格锁定并且不让其他人做类似更改格式之类的操作。
保护之针对锁定的单元格才生效,如何设置单元格是锁定或者非锁定的话是,看单元格的格式属性:

就是勾不勾Lock,勾选了的话protect了Sheet之后就会对这个格子起作用。
然后设置可编辑区域里面可以划选一个单元格区域,然后可以针对这个区域来设置谁有编辑的权限。
这样对每个Sheet都设置好区域,然后分配给不同的人,看起来就OK了。
实际用起来的时候出现一个问题,不能删行或者插入行。
想想也是,那个允许编辑区域只给了用户编辑的权限,是否可以插入或者删除行的话还是在保护工作表那里来设置:

但是这里即使是勾选上了删除/增加行,让所有人都有删除或者插入行的权限,插入行是OK了,删除行的时候还是会报错,告诉你不能删除有lock格子的行。

于是还是不行,后来同事说大致这样就可以啦,让他们要删的话就删数据吧,大不了每个月统一再整理一次数据,由他统一把空行都删掉。
不过还是觉得不服气,想想怎么可以绕过这个,还要不增加过多的权限(不能让操作者知道sheet的保护密码)
于是用VBA吧。其实只要做个简单的宏,解锁当前Sheet之后再删掉当前行,然后再锁定就好。
知道该怎么做之后就简单了
ActiveSheet.Unprotect "123"
Selection.Delete Shift:=xlUp
ActiveSheet.Protect Password:="123", AllowInsertingColumns:=True,AllowInsertingRows:=True
留了一个插入的权限,这样插入新的行就只要普通操作就好了。
但是这样随便是谁都能用这个宏来插入了,我们还是要做一点权限控制的。
这也简单,加个If检测一下用户就好
Sub DelRow()
If (UserName = "Randy" And ActiveSheet.Name = "Randy") Then
ActiveSheet.Unprotect "123"
Selection.Delete Shift:=xlUp
ActiveSheet.Protect Password:="123", AllowInsertingColumns:=True,AllowInsertingRows:=True
Else: MsgBox "You can't do this"
End If
End Sub
当然在这个之前要先拿一下username
先声明一下GetUserNameA
Option Explicit
' Access the GetUserNameA function in advapi32.dll and
' call the function GetUserName.
Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" _
(ByVal lpBuffer As String, nSize As Long) As Long
然后拿一下UserName:
Dim lpBuff As String * 25
Dim ret As Long, UserName As String
' Get the user name minus any trailing spaces found in the name.
ret = GetUserName(lpBuff, 25)
UserName = Left(lpBuff, InStr(lpBuff, Chr(0)) - 1)
这样一来就OK啦。Randy可以编辑Randy这一页,Ray可以编辑Ray这一页,如果Randy要删除一行的时候,用DelRow这个宏,然后excel会检测用户是不是Randy,Sheet是不是也是Randy,都是的话就删掉一行,不是的话就弹个窗,告诉你搞错啦。
然后把VBA也保护一下,不然打开就看到Sheet保护的密码了,等于上面这些全部白做了,最后把文件保存成.xlm,大功告成。
照例放上例子

