2010-10-26 3 views
3

Я пишу решение в 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. Коллекция пользовательских форм? Дело в том, что если пользователь движется вперед, а затем назад, две копии формы появляются в памяти, а excel исключает исключения из двух модальных форм.

Приветствия, Ник

ответ

3

Ответ был (к сожалению) довольно прост и вдохновлен ответом bugtussle.

Подпрограмма передавала переменную curForm как объект MSForms.Userform, но форма хранится в памяти как собственный тип объекта. (Например, вы можете получить доступ к форме через Set form = new formName)

Итак, изменив тип paramor curForm на Variant, он передаст фактический объект, а не копию объекта. Разгрузка только выгружает копию, а не фактический объект.

Thanks 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

Я имею в виду, что выгрузка из объекта коллекции вместо переменной будет действительно избавиться от него. Попробуйте что-то вроде этого:

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 
+1

Это не работает, но вы вдохновили мое решение. Проблема заключалась в том, что я передавал форму в sub как тип MSForms.UserForm. Это предоставляет только подмножество свойств формы, поэтому не передает действительный объект формы, а копирует его. Свойство .name не существует для MSForms.Userform, поэтому ваше решение не сработало, но, изменив тип переменной на Variant, я мог бы правильно выгрузить форму. Поэтому спасибо за то, что вы на правильном пути. –