从内存中强制卸载表单

我正在使用一些链接的数据input表单在Excel中编写一个解决scheme。 要在表格序列之间移动,用户可以点击“上一个”或“下一个”button,当前表单被卸载,新的表单被加载并打开。

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会抛出关于两个正在打开的模式表单的exception。

干杯,尼克

答案(可惜)很简单,并受到bugtussle的回答的启发。

该子例程是作为一个MSForms.Userform对象传递curFormvariables,但窗体作为其自己的对象types保存在内存中。 (例如,您可以通过Set form = new formName访问表单)

因此,通过将curForm参数types更改为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 

我在想,从集合对象而不是variables卸载将真正摆脱它。 尝试这样的事情:

 For i = VBA.UserForms.Count - 1 To 0 Step -1 if VBA.UserForms(i).Name = curForm.name Unload VBA.UserForms(i) end if Next i