Excel VBA:在ActiveX调整大小后关闭保存提示尽管Thisworkbook.Saved = True

时间:2017-09-14 09:37:04

标签: excel vba activex

我用Excel遇到了一个有趣的情况,我想知道你是否有人知道答案/解决方案。

设定: 我有一个空的excel工作表,上面有一个ActiveX ToggleButton。 在VBA代码中,我将按钮的宽度更改为0,然后将宽度更改为100.(为什么我这样做是一个不同的问题,它是较大项目的一部分,但是,这会导致问题)。

然后我将工作簿的保存状态设置为true,而不实际保存工作簿。

通常情况下,如果我现在关闭了工作簿,它就会关闭,而不会问我是否想要保存。 现在,由于调整大小,即使.Saved-Status为True,它会在我关闭工作簿时询问我是否要保存,并通过单击excel的关闭图标,将.Saved-Status设置为"假"

如果您想亲自尝试,请尝试以下步骤。 或者,为方便起见,我在此处上传了相同的文件:(https://filebin.ca/3aLbbRxMTdUs/SavePromptUponResize.xlsm

1)创建一个新工作簿并添加一个新的ACTIVEX切换按钮。 2)在工作簿的VBA代码中,添加以下代码 3)保存工作簿,关闭它,然后重新打开它。 4)您应该看到一个消息框,然后单击,作为第二个消息 5)现在工作簿的状态已经保存了#34; 6)尝试关闭工作簿 - >如果要保存,系统会提示您 7)如果你现在检查.saved状态,它会说" false"

期待您的见解!

Private Sub Workbook_Open()
MsgBox "Now a macro will run and resize twice the button you see." & vbCrLf & "Afterwards, the status of the workbook will be set to 'saved'." & vbCrLf & "However, upon closing, excel will still prompt to save."
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets(1)


ws.Shapes("ToggleButton1").Width = 0
ws.Shapes("ToggleButton1").Width = 100


wb.Saved = True
MsgBox "Macro finished, save status is: " & wb.Saved


End Sub



Private Sub CheckSaveStatus()
MsgBox "Save status is: " & ActiveWorkbook.Saved
End Sub

3 个答案:

答案 0 :(得分:1)

请尝试以下方法:

Option Explicit

Dim wb As Workbook
Dim ws As Worksheet
Dim i As Integer


Private Sub Workbook_BeforeClose(Cancel As Boolean)

If i = 1 Then

wb.Saved = False

Else

wb.Saved = True


End If

End Sub    


Private Sub Workbook_Open()


MsgBox "Now a macro will run and resize twice the button you see." & vbCrLf & "Afterwards, the status of the workbook will be set to 'saved'." & vbCrLf & "However, upon closing, excel will still prompt to save."

Set wb = ThisWorkbook
Set ws = wb.Sheets(1)


ws.Shapes("ToggleButton1").Width = 0
ws.Shapes("ToggleButton1").Width = 100

End Sub


Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
i = 1
End Sub

答案 1 :(得分:1)

解决方案就像这样简单:

Private Sub Workbook_Open()
  MsgBox "Now a macro will run and resize twice the button you see." & vbCrLf & "Afterwards, the status of the workbook will be set to 'saved'." & vbCrLf & "However, upon closing, excel will still prompt to save."
  Dim wb As Workbook: Set wb = ThisWorkbook
  Dim ws As Worksheet: Set ws = wb.Sheets(1)
  Dim boolSaved As Boolean

  boolSaved = wb.Saved
  ws.Shapes("ToggleButton1").Width = 0
  ws.Shapes("ToggleButton1").Width = 100
  If boolSaved Then wb.Save

  MsgBox "Macro finished, save status is: " & wb.Saved

End Sub

此技术可以在代码中的任何位置使用,您需要执行“弄脏”工作簿的操作。它的美妙之处在于,如果用户 修改了工作簿,它会保留保存提示。

至于它为什么会发生,最好的猜测是 - Excel中的一个(另一个)ActiveX错误。

答案 2 :(得分:0)

我的经验是,此Excel错误是由于使用VBA代码更改某些ActiveX / OLE控件的某些属性的值而触发的。我没有此类属性的完整列表,但有一些:

CommandButton:

  • 已启用属性

  • 高度属性

文本框:

  • ForeColor 属性

  • BackColor 属性

我使用通用系统(类似于Nikolaos Polygenis的解决方案),由于该错误的细微之处,包括了广泛的解释,如下所示:

  1. 在标准模块中,定义一个项目全局变量以指示不需要保存的条件: '************************************************************************************************************* 'EXCEL OLE/ACTIVE-X SAVE-BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND ' '(See the Workbook_BeforeClose event handler, in the ThisWorkbook module, for a complete explanation.) ' Public SuppressWkBkSaveMsg As Boolean ' 'END SAVE-BUG WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND '*************************************************************************************************************

  2. 在ThisWorkbook模块中,放置下面的Workbook_BeforeClose事件处理程序,并带有完整的说明:

    Private Sub Workbook_BeforeClose(Cancel As Boolean) '************************************************************************************************************* 'EXCEL OLE/ACTIVE-X SAVE-BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND ' 'Excel has a very subtle bug in which, if you change the value of some properties of some ActiveX/OLE 'controls, the parent workbook's Saved property will not function correctly until the next actual workbook 'save event. That is, you can subsequently set the workbook's Saved property to True but Excel will still 'prompt the user about whether to save the workbook when closing it. In fact, if you check the value of the 'Saved property in a Workbook_BeforeClose event handler, it will be defined as False even though no changes 'have been made to the workbook after explicitly setting it to True! ' 'The most effective workaround is to defer the override of the workbook's Saved property until the Close event 'has been actually initiated: declare the project-global SuppressWkBkSaveMsg variable in a standard module, 'add this Workbook_BeforeClose event handler to the ThisWorkbook module, and then set SuppressWkBkSaveMsg to 'True whenever it's necessary to suppress Excel's user-inquiry about whether to save changes to the workbook 'before closing it. ' If SuppressWkBkSaveMsg Then Me.Saved = True ' 'END SAVE-BUG WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND '************************************************************************************************************* End Sub

  3. 在代码中任何位置的任何模块中,每当有必要在关闭Excel之前禁止用户询问是否将更改保存到工作簿时,请将SuppressWkBkSaveMsg设置为True:

    'Do stuff that doesn't need to be saved, including modifications to OLE/ActiveX control-objects... ' '************************************************************************************************************* 'EXCEL OLE/ACTIVE-X SAVE-BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND ' '(See the Workbook_BeforeClose event handler, in the ThisWorkbook module, for a complete explanation.) ' SuppressWkBkSaveMsg = True ' 'END SAVE-BUG WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND '************************************************************************************************************* ' '...