1

我正在尝试使用veryhidden 来强制用户启用宏来维护我的工作簿的安全性。

这很好用,只是用户抱怨缺少一个对话框来询问他们是否希望保存或不关闭。

我以 msgbox 的形式添加了保存/不保存功能,但是这打开了一个违反安全性的特定情况:

也就是说,如果用户打开文件,启用宏,通过启动屏幕,使用保存功能保存工作簿,然后关闭而不保存,那么下次打开工作簿时,它不会强制用户启用宏。

我试图通过设置在保存时运行的以下代码来解决这个问题(我在保存之前没有运气,因为它在代码运行后再次保存,这破坏了代码的要点)但是这段代码似乎生成由保存触发的无限循环。我尝试在开始时进行检查以检查状态是否已保存,但由于宏在保存后运行,因此对于宏而言始终是真实状态。

同样,我尝试在底部添加检查以查看其是否已保存,如果已保存,则退出子例程,但是代码永远不会走这么远,因为它会在保存时再次触发。

有人有想法么?(下面的代码)

Private Sub Workbook_AfterSave(ByVal Success As Boolean)

If Success = True Then
    'Step 1: Define WS variable
        Dim ws As Worksheet
    'Step 2: Unhide the Starting Sheet
        Sheets("START").Visible = xlSheetVisible
    'Step 3: Start looping through all worksheets
        For Each ws In ThisWorkbook.Worksheets
    'Step 4: Check each worksheet name
        If ws.Name <> "Start" Then
    'Step 5: Hide the sheet
        ws.Visible = xlVeryHidden
        End If
    'Step 6: Loop to next worksheet
        Next ws
    'Step 7: Save the workbook
        ActiveWorkbook.Save
    'Step 8: Start looping through all worksheets
        For Each ws In ThisWorkbook.Worksheets
    'Step 9: Re-Unhide All Worksheets
        ws.Visible = xlSheetVisible
    'Step 10: Loop to next worksheet
        Next ws
    'Step 11: Re-Hide the Start Sheet
        Sheets("START").Visible = xlVeryHidden
    'Step 12: Exit loop
        If ThisWorkbook.Saved = True Then
        Exit Sub
        End If
End If
End Sub
4

2 回答 2

1

避免无休止的触发循环:

    'Step 7: Save the workbook
        Application.EnableEvents = False
        ActiveWorkbook.Save
        Application.EnableEvents = True
于 2018-11-28T09:00:53.253 回答
0

稍微不同的策略:

  1. Workbook_BeforeSave取消隐藏 START 工作表并隐藏所有其他将触发的工作表
  2. Workbook_AfterSave隐藏 START 并取消隐藏所有其他工作表和
  3. Workbook_Open隐藏 START 并取消隐藏所有其他工作表。

编码:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    Dim ws As Worksheet

    Application.ScreenUpdating = False 'stops flicker and improves speed
    Sheets("START").Visible = xlSheetVisible
    For Each ws In ThisWorkbook.Worksheets
        If ws.Name <> "Start" Then
            ws.Visible = xlVeryHidden
        End If
    Next ws
    Application.ScreenUpdating = True
End Sub

Private Sub Workbook_AfterSave(ByVal Success As Boolean)
    Dim ws As Worksheet

    Application.ScreenUpdating = False 'stops flicker and improves speed
    For Each ws In ThisWorkbook.Worksheets
        ws.Visible = xlSheetVisible
    Next ws
    Sheets("START").Visible = xlVeryHidden
    Application.ScreenUpdating = True
End Sub

Private Sub Workbook_Open()
    Dim ws As Worksheet

    Application.ScreenUpdating = False 'stops flicker and improves speed
    For Each ws In ThisWorkbook.Worksheets
        ws.Visible = xlSheetVisible
    Next ws
    Sheets("START").Visible = xlVeryHidden
    Application.ScreenUpdating = True
End Sub
于 2018-11-28T12:15:11.697 回答