VBA隐藏用户表单但保留输入的数据

时间:2013-09-19 14:42:47

标签: class vba user-controls automation

我又回来了,我希望这是一个相当简单的问题。

我正在尝试在VBA中创建用户表单。用户将在表单中输入某些信息,然后关闭表单。我希望用户表单保留用户关闭后输入的数据。我将它视为一个类模块,因为它本身就是技术,或者至少我理解它。这是我正在使用的代码:

在显示用户表单的主要子组件中:

Sub NonACATMemo()

Dim UserInput As MemoReasons
Set UserInput = New MemoReasons
UserInput.Show

...然后在用户表单中关闭它......

Private Sub UserForm_Terminate()
MemoReasons.Hide
End Sub

我也从表单上的命令按钮调用此子。我遇到的问题是,当我使用这种方法时,我得到一个错误“运行时错误'402':必须首先关闭或隐藏最顶层的模态形式。”如果我使用卸载我,当我尝试从表单中获取数据时,它被清除,我得到“服务器不可用”错误或其他相应的事情。

那么,有关隐藏用户表单但保留数据的想法吗?

最后几个笔记:这是项目中唯一的用户表单,下面是我如何使用Public Property Get方法从中获取数据的示例:

Debug.Print UserInput.EmailFlag
Debug.Print UserInput.ContraFirm
Debug.Print UserInput.MemoReason

好吧,如果有人有任何建议,我会全力以赴。

2 个答案:

答案 0 :(得分:5)

我之前没见过这种做法。通常,我只是通过以下方式实例化表单:

MemoReasons.Show

确实_Terminate()事件正在消除表单中保存的数据。因此解决方案是从按钮单击调用_Terminate()事件。相反,只需隐藏表单,例如:

Sub ShowMemoReasons()
'In a normal code module, this calls the form
' could be run from the macros menu or attached to
' a shape/button/etc on the worksheet.

MemoReasons.Show

End Sub

将它们放在MemoReasons代码模块中:

Private Sub CommandButton1_Click()  '<-- Rename to handle your button's click event

    MemoReasons.Hide  '## Hides the form but does not release it from memory

End Sub
Private Sub UserForm_Terminate()
'Any events pertaining to the termination of the form object
' otherwise, all form control data will be wiped out when
' this object releases from memory

End Sub

执行这些操作后,如果您使用按钮隐藏表单,则可以调用ShowMemoReasons()并重新显示表单,同时保留以前输入的数据在表格中。

如果您使用红色的“X”按钮或某个其他事件触发Terminate事件,您将丢失表单数据。有必要进行验证并使用QueryClose事件阻止此操作。

更新

我认为您不需要Dim用户表单的实例(如果您可能同时显示多个表单,则会出现例外情况)。否则,将UserInput声明为公共变量是多余且令人困惑的。

无意中,这就是您收到错误的原因:Must close or hide topmost modal form first。如果您必须以这种方式实施,则应使用MemoReasons.hide

,而不是Me.Hide。{/ 1}

只要您只显示表单的一个实例,就可以始终引用MemoReasons.property,因为MemoReasons是公共对象,就像ThisWorkbookActiveWorksheet一样等等。

相反,您应该能够在任何子例程中引用此对象(MemoReasons是一个对象),例如创建另一个未从前一个子节点调用的对象。运行sub以显示表单,输入一些数据,然后隐藏表单。隐藏表单,然后运行此子例程,您应该从表单中看到结果数据。

Sub Test2()
    Debug.Print MemoReasons.EmailFlag
End Sub

答案 1 :(得分:4)

这是一个古老的话题......希望有人需要帮助。

您可以执行以下操作:

1 - 放置一个关闭/取消按钮(您可以将取消属性设置为True)

2 - 将以下代码附加到点击事件

Private Sub btnClose_Click()
    'Do some stuff if necessary
    Me.Hide
End Sub

3 - 将此代码附加到 QueryClose 事件

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  If CloseMode = 0 Then 'vbFormControlMenu = 0 ([X] button on top right), see MSDN
     Cancel = True 'Don't fire Terminate event...
     btnClose_Click '...instead, call my close event handler
   End If
End Sub

您可以通过在 UserForm_Initialize 事件中放置一个调试器断点来检查结果,它应该仅在第一次显示UserForm时触发,从而授予UserForm状态保留。