【问题标题】:VBA Hide User form but retain data entered into itVBA隐藏用户表单但保留输入的数据
【发布时间】:2018-07-01 20:30:59
【问题描述】:

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

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

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

Sub NonACATMemo()

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

...然后在用户窗体本身中关闭它...

Private Sub UserForm_Terminate()
MemoReasons.Hide
End Sub

我还从表单上的命令按钮调用此子程序。我遇到的问题是,当我使用此方法时,出现错误“运行时错误'402':必须首先关闭或隐藏最顶层的模态表单。”如果我使用 unload me,当我尝试从表单中获取数据时,它会被清除,并且会出现“服务器不可用”错误或类似情况。

那么,关于隐藏用户表单但保留其中数据的任何想法?

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

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

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

【问题讨论】:

  • 你说只有一个用户表单,但是,UserInput = 1 个表单,MemoReasons = 2 个表单?
  • 我以前没有见过这种方法。为什么不直接做 MemoReasons.Show ?另外,我认为问题在于您试图从其Terminate 事件中隐藏表单。我会发布一个建议。
  • @user2140261 我的印象是我必须调暗并为此设置一个类的实例,但看来我错了。看起来我可以按照我最初充电的方式执行它,但我必须将 UserInput 声明为全局变量,然后在用户表单上使用“UserInput.Hide”来获得我正在寻找的功能。事实上,删除声明和设置,我可以使用 MemoReasons.Show 和 MemoReasons.EmailFlag 等。
  • @DavidZemens 我把它放在终止事件中,因为我的印象是这样做,无论用户是否使用右上角的 X 控件关闭表单,表单中的信息都会保留,或我放在上面的“完成”命令按钮。我发现它不是那样工作的,而且我似乎没有正确理解终止事件。

标签: class vba user-controls automation


【解决方案1】:

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

您可以执行以下操作:

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 事件中放置一个调试器断点来检查结果,它应该只在第一次显示用户窗体时触发,从而授予用户窗体状态保留。

【讨论】:

  • 谢谢你!我以为我知道表格是如何工作的,直到今晚
  • @Eric 谢谢先生!
【解决方案2】:

我以前从未见过这种方法。通常,我会通过以下方式实例化表单:

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

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

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

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

【讨论】:

  • 啊,我现在看到我正在寻找的是 queryclose 事件。我想我现在要放弃那部分,我必须满足于在命令按钮单击事件中使用“MemoReasons.Hide”。只要您不使模块中的类实例变暗,这种方法就可以工作。我在上面评论了如何让它发挥作用,但感觉很笨拙和草率。
  • @user2761919 请参阅上面的修订版,我认为可以为您澄清:)
猜你喜欢
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
相关资源
最近更新 更多