简体   繁体   English

Excel VBA:尽管有此工作簿,但ActiveX调整大小后,关闭时会提示保存。

[英]Excel VBA: On Close Save Prompt after ActiveX Resize Despite Thisworkbook.Saved=True

I've run into an interesting situation with Excel, and I was wondering if anyone of you knew an answer / solution. 我在使用Excel时遇到了一个有趣的情况,我想知道是否有人知道答案/解决方案。

Setup: I have an empty excel worksheet with a ActiveX ToggleButton on it. 设置:我有一个空的Excel工作表,上面有一个ActiveX ToggleButton。 In a VBA code, I change the width of the button to 0, and then change the width to 100. (Why I do that is a different question, its part of a larger project, however, this causes the problem). 在VBA代码中,我将按钮的宽度更改为0,然后将宽度更改为100。(为什么我这样做是一个不同的问题,它是较大项目的一部分,但是,这会引起问题)。

Then I set the save-status of the workbook to true, without actually saving the workbook. 然后,我将工作簿的保存状态设置为true,而没有实际保存工作簿。

Normally, if I now closed the workbook, it would just close, without asking me wether I want to save. 通常,如果我现在关闭工作簿,它将关闭,而不会询问我是否要保存。 Now, due to the resizing, and even though the .Saved-Status is True, it asks me if I want to save when I close the workbook, and by clicking onto the close Icon of excel, the .Saved-Status is set to "False" 现在,由于调整大小,即使.Saved-Status为True,它也会在关闭工作簿时询问我是否要保存,并通过单击excel的关闭图标将.Saved-Status设置为“假”

If you want to try for yourself, try the below steps. 如果您想自己尝试,请尝试以下步骤。 Alternatively, I uploaded for convenience the same file here: ( https://filebin.ca/3aLbbRxMTdUs/SavePromptUponResize.xlsm ) 另外,为方便起见,我在此处上传了相同的文件:( https://filebin.ca/3aLbbRxMTdUs/SavePromptUponResize.xlsm

1) create a new workbook and add a new ACTIVEX toggle button. 1)创建一个新的工作簿并添加一个新的ACTIVEX切换按钮。 2) in the VBA code of the workbook, add the below code 3) save the workbook, close it, and reopen it. 2)在工作簿的VBA代码中,添加以下代码3)保存工作簿,将其关闭,然后重新打开。 4) You should see a messagebox and after clicking, as second one 5) Now the status of the workbook is "saved" 6) Try to close the workbook -> you will be prompted if you want to save 7) If you check the .saved status now, it would say "false" 4)您应该看到一个消息框,单击后为第二个。5)现在,工作簿的状态为“已保存”。6)尝试关闭工作簿->如果要保存,系统将提示您7)如果选中现在处于.saved状态,它将显示为“ false”

Looking forward to your insights! 期待您的见解!

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

Please try the below: 请尝试以下方法:

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

The solution is as simple as this: 解决方案很简单:

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

This technique can be used anywhere in your code where you need to do something that 'dirties' the workbook. 这项技术可以在代码中需要执行使工作簿“肮脏”的事情的任何地方使用。 The beauty of it is that it preserves the save prompt if the user has modified the workbook. 它的妙处在于,它保留了保存提示,如果用户修改工作簿。

As to why it's happening, best guess is - a(nother) ActiveX bug in Excel. 至于为什么发生,最好的猜测是-Excel中的(另一个)ActiveX错误。

My experience has been that this Excel bug is triggered as a result of using VBA code to change the value of some properties of some ActiveX/OLE controls. 我的经验是,使用VBA代码更改某些ActiveX / OLE控件的某些属性的值会触发此Excel错误。 I don't have a complete list of such properties but here's a few: 我没有此类属性的完整列表,但有一些:

CommandButton: 命令按钮:

  • Enabled property 启用的属性

  • Height property 高度属性

TextBox: 文本框:

  • ForeColor property ForeColor属性

  • BackColor property BackColor属性

I use a generalized system (similar to Nikolaos Polygenis's solution), including extensive explanation due to this bug's subtlety, as follows: 我使用了一个通用系统(类似于Nikolaos Polygenis的解决方案),由于该错误的细微之处,包括了广泛的解释,如下所示:

  1. In a standard module, define a project-global variable to indicate the no-save-needed condition: '************************************************************************************************************* '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 '************************************************************************************************************* 在标准模块中,定义一个项目全局变量以指示不需要保存的条件: '************************************************************************************************************* '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. In the ThisWorkbook module, place the following Workbook_BeforeClose event handler, with full explanation: 在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. In any location in the code, in any module, whenever it's necessary to suppress Excel's user-inquiry about whether to save changes to the workbook before closing it, set SuppressWkBkSaveMsg to True: 在代码中的任何位置,任何模块中,每当有必要在关闭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 '************************************************************************************************************* ' '...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM