Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel仅当启用VBA时才可以保存文件,是否可能?_Vba_Excel - Fatal编程技术网

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