强制从内存中卸载表单

时间:2010-10-26 06:31:24

标签: excel vba excel-vba

我正在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会抛出有关打开的两个模态表单的异常。

干杯, 尼克

2 个答案:

答案 0 :(得分:3)

答案是(遗憾的)非常简单,并受到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

答案 1 :(得分:1)

我认为从集合对象而不是变量中卸载将真正摆脱它。尝试这样的事情:

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