我正在 Excel 中编写一个解决方案,该解决方案使用多个链接的数据输入表单。要在表单序列之间移动,用户可以单击“上一个”或“下一个”按钮。当前表单将被卸载,新表单将被加载并打开。
Sub NextForm(curForm As MSForms.UserForm, strFormName As String)
Dim intCurPos As Integer
Dim strNewForm As String
Dim newForm As Object
intCurPos = WorksheetFunction.Match(strFormName, Range("SYS.formlist"), 0)
If intCurPos = WorksheetFunction.CountA(Range("SYS.formlist")) Then
Debug.Print "No"
Else
Unload curForm
strNewForm = WorksheetFunction.Index(Range("SYS.formlist"), intCurPos + 1)
Set newForm = VBA.UserForms.Add(strNewForm)
newForm.Show
End Sub
原样的代码允许通过编辑“SYS.formlist”范围随时将新表单添加到序列中。
我注意到的一个问题是,即使当前表单卸载后,它仍然保留在 VBA.Userforms 集合中。我认为这是因为该代码是从该用户表单调用的。
有没有办法强制从 VBA.Userforms 集合中删除该表单?发生的情况是,如果用户向前移动然后向后移动,内存中会出现表单的两个副本,并且 excel 会抛出有关打开的两个模式表单的异常。
干杯, 尼克
最佳答案
答案(遗憾的是)非常简单,并且受到 bugtussle 答案的启发。
子例程将 curForm 变量作为 MSForms.Userform 对象传递,但表单作为其自己的对象类型保存在内存中。 (例如,您可以通过 Set form = new formName 访问表单)
因此,通过将 curForm 参数类型更改为 Variant,它将传递实际对象而不是对象的副本。卸载只是卸载副本,而不是实际对象。
谢谢bugtussle!
因此,更正后的代码是:
Sub NextForm(curForm As Variant, strFormName As String)
Dim intCurPos As Integer
Dim strNewForm As String
Dim newForm As Object
intCurPos = WorksheetFunction.Match(strFormName, Range("SYS.formlist"), 0)
If intCurPos = WorksheetFunction.CountA(Range("SYS.formlist")) Then
Debug.Print "No"
Else
Unload curForm
strNewForm = WorksheetFunction.Index(Range("SYS.formlist"), intCurPos + 1)
Set newForm = VBA.UserForms.Add(strNewForm)
newForm.Show
End Sub
关于vba - 强制从内存中卸载表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4021227/