从内存中强制卸载表单
我正在使用一些链接的数据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