Excel仅当启用VBA时才可以保存文件,是否可能?
我有一个具有三级权限的文件。Excel仅当启用VBA时才可以保存文件,是否可能?,vba,excel,Vba,Excel,我有一个具有三级权限的文件。 系统会提示您在用户表单上输入密码,您可以获得管理员权限、读/写权限或只读权限。 这很好,除非你不启用宏 如果不启用宏提示,则不会显示userform,也不会设置权限,因此您具有完全访问权限 我看到您可以使用启动屏幕,但要使其正常工作,您需要保存工作簿(据我所知? 它们的基本概念是在关闭隐藏工作表和取消隐藏启动屏幕之前,先保存工作簿。 但是,如果用户犯了一个错误,那么在不保存的情况下关闭并稍后重新打开该怎么办?文件关闭时所有图纸都可见吗 所以我想也许我可以使用“资源管
系统会提示您在用户表单上输入密码,您可以获得管理员权限、读/写权限或只读权限。
这很好,除非你不启用宏 如果不启用宏提示,则不会显示userform,也不会设置权限,因此您具有完全访问权限 我看到您可以使用启动屏幕,但要使其正常工作,您需要保存工作簿(据我所知?
它们的基本概念是在关闭隐藏工作表和取消隐藏启动屏幕之前,先保存工作簿。 但是,如果用户犯了一个错误,那么在不保存的情况下关闭并稍后重新打开该怎么办?文件关闭时所有图纸都可见吗 所以我想也许我可以使用“资源管理器->右键单击->属性->只读”属性作为额外的保护层 我找到了这些函数
ActiveWorkbook.ChangeFileAccess Mode:=xlreadonly
ActiveWorkbook.ChangeFileAccess Mode:=xlreadwrite
但我尝试了只读行,它确实设置为只读,文件无法保存。然后我没有保存就关闭了工作簿,然后再次打开。但该属性似乎没有在文件的属性中设置,因为它没有勾选标记,当我打开文件时,我可以保存它 还有其他办法解决这个问题吗?
我想对用户“强制”使用VBA,或者确保如果在没有VBA的情况下打开文件,用户无法保存该文件。我找到了一个似乎有效的解决方案 您可以在
Workbook\u BeforeClose
中使用此行在文件属性中将文件设置为只读
SetAttr Application.ActiveWorkbook.FullName, vbReadonly
这将在属性中设置勾号,Excel将注意到该文件受写保护
然后在工作簿中\u Open()
(或在我的情况下,当权限已建立时)
第一行删除文件属性中的勾号,但Excel仍将文件“记住”为只读。第二行将告诉Excel使其读写,文件将再次正常工作。我找到了一个似乎有效的解决方案 您可以在
Workbook\u BeforeClose
中使用此行在文件属性中将文件设置为只读
SetAttr Application.ActiveWorkbook.FullName, vbReadonly
这将在属性中设置勾号,Excel将注意到该文件受写保护
然后在工作簿中\u Open()
(或在我的情况下,当权限已建立时)
第一行删除文件属性中的勾号,但Excel仍将文件“记住”为只读。第二行将告诉Excel使其可读写,文件将再次正常工作。这是一种比其他方法复杂得多的方法,但并不具有像那些精通技术的用户那样的风险,他们只需右键单击文件并弹出“属性”面板 创建2个新工作表。其中一个设置为
xlVeryHidden
——对于下面的示例,我将其称为hsheetstatus
。另一个是一个漂亮的大通知,告诉你不幸的仆从同事启用宏,它将改变可见性。我称之为hsEnableNotice
然后我有一个宏来显示hsEnableNotice
隐藏所有其他工作表(在hsSheetStatus
上存储它们的可见性和活动表),还有一个宏来执行相反的操作(从hsSheetStatus
恢复可见性/ActiveSheet),并将它们设置为在工作簿上运行,然后再保存,工作簿保存后
和工作簿打开后
:
Option Explicit
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
UnlockAndShow
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
LockAndHide
End Sub
Private Sub Workbook_Open()
UnlockAndShow
End Sub
Private Sub LockAndHide()
Dim lSheet As Long, ActiveName As String
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveName = ThisWorkbook.ActiveSheet.Name
hsEnableNotice.Visible = xlSheetVisible
hsEnableNotice.Activate
hsSheetStatus.Range(hsSheetStatus.Cells(1, 1), hsSheetStatus.Cells(hsSheetStatus.Rows.Count, 1)).EntireRow.Delete
For lSheet = 1 To ThisWorkbook.Sheets.Count 'By using Sheets instead of Worksheets, we include Charts etc
hsSheetStatus.Cells(lSheet, 1).Value = ThisWorkbook.Sheets(lSheet).Name
hsSheetStatus.Cells(lSheet, 2).Value = ThisWorkbook.Sheets(lSheet).Visible
If ThisWorkbook.Sheets(lSheet).Name = ActiveName Then hsSheetStatus.Cells(lSheet, 3).Value = 1
If ThisWorkbook.Sheets(lSheet).Name <> hsEnableNotice.Name Then ThisWorkbook.Sheets(lSheet).Visible = xlSheetVeryHidden
Next lSheet
ThisWorkbook.Protect Password:="ThisIsMyPassword.ThereAreManyLikeIt,ButThisOneIsMine.", Structure:=True, Windows:=False
Application.EnableEvents = True
End Sub
Private Sub UnlockAndShow()
Dim WasSaved As Boolean, lSheet As Long, lMax As Long
WasSaved = ThisWorkbook.Saved
Application.ScreenUpdating = False
Application.EnableEvents = False
lMax = hsSheetStatus.Cells(hsSheetStatus.Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Unprotect Password:="ThisIsMyPassword.ThereAreManyLikeIt,ButThisOneIsMine."
For lSheet = 1 To lMax
ThisWorkbook.Sheets(hsSheetStatus.Cells(lSheet, 1).Value).Visible = hsSheetStatus.Cells(lSheet, 2).Value
If hsSheetStatus.Cells(lSheet, 3).Value = 1 Then ThisWorkbook.Sheets(hsSheetStatus.Cells(lSheet, 1).Value).Activate
Next lSheet
hsSheetStatus.Visible = xlSheetVeryHidden
hsEnableNotice.Visible = xlSheetVeryHidden
Application.EnableEvents = True
Application.ScreenUpdating = True
ThisWorkbook.Saved = WasSaved
End Sub
选项显式
私有子工作簿_AfterSave(ByVal Success作为布尔值)
解锁显示
端接头
私有子工作簿\u在保存之前(ByVal SaveAsUI为布尔值,Cancel为布尔值)
锁皮
端接头
私有子工作簿_Open()
解锁显示
端接头
私有子锁和隐藏()
Dim lSheet为长,ActiveName为字符串
Application.ScreenUpdating=False
Application.EnableEvents=False
ActiveName=此工作簿.ActiveSheet.Name
hsEnableNotice.Visible=xlSheetVisible
激活
hsSheetStatus.Range(hsSheetStatus.Cells(1,1),hsSheetStatus.Cells(hsSheetStatus.Rows.Count,1)).EntireRow.Delete
对于lSheet=1到thiswook.Sheets.Count“通过使用工作表而不是工作表,我们包括图表等
hsSheetStatus.Cells(lSheet,1).Value=此工作簿.Sheets(lSheet).Name
hsSheetStatus.Cells(lSheet,2).Value=此工作簿.Sheets(lSheet).可见
如果ThisWorkbook.sheet(lSheet).Name=ActiveName,则hsSheetStatus.Cells(lSheet,3).Value=1
如果ThisWorkbook.Sheets(lSheet).Name hsEnableNotice.Name,则ThisWorkbook.Sheets(lSheet).Visible=xlSheetVeryHidden
下一页
ThisWorkbook.Protect Password:=“ThisIsMyPassword.TheAremanyKeit,ButThisOneIsMine.”,结构:=True,窗口:=False
Application.EnableEvents=True
端接头
私有子解锁和显示()
Dim保存为布尔值,lSheet保存为Long,lMax保存为Long
WasSaved=此工作簿。已保存
Application.ScreenUpdating=False
Application.EnableEvents=False
lMax=hsSheetStatus.Cells(hsSheetStatus.Rows.Count,1).结束(xlUp).行
ThisWorkbook.Unprotect Password:=“ThisIsMyPassword.There有多个yLikeit,但ThisOneIsMine。”
对于lSheet=1到lMax
ThisWorkbook.Sheets(hsSheetStatus.Cells(lSheet,1).Value).Visible=hsSheetStatus.Cells(lSheet,2).Value
如果hsSheetStatus.Cells(lSheet,3).Value=1,则此工作簿.Sheets(hsSheetStatus.Cells(lSheet,1).Value).激活
下一页
hsSheetStatus.Visible=xlSheetVeryHidden
hsEnableNotice.Visible=xlSheetVeryHidden
Application.EnableEvents=True
Application.ScreenUpdating=True
ThisWorkbook.Saved=已保存
端接头
这是一种比传统方法复杂得多的方法,但它的特点是,技术娴熟的用户只需右键单击文件并弹出“属性”面板,风险就不同了
创建2个新工作表。其中一个设置为xlVeryHidden
——对于下面的示例,我将其称为hsSheetStatus