Открытие пользовательских форм из пользовательской формы снова и снова - вызывает проблемы с объектами

В настоящее время я создал инструмент в Excel 2003, который отображает ряд форм ввода данных. Клиент запросил, чтобы на формах были кнопки «Предыдущая форма» и «Следующая форма».

Код, используемый для перемещения между формами, выглядит следующим образом.

Sub NextForm(strFormName As String)
    Dim intCurPos As Integer
    Dim strNewForm As String

    'Find out which form we are currently on from a list in a range
    intCurPos = WorksheetFunction.Match(strFormName, Range("SYS.formlist"), 0)
    If intCurPos = WorksheetFunction.CountA(Range("SYS.formlist")) Then
        'We want to use the first one
        intCurPos = 0
    End If

    'Get the name of the form to open
    strNewForm = WorksheetFunction.Index(Range("SYS.formlist"), intCurPos + 1)
    'Load the form into the Userforms Collection
    Set newForm = VBA.UserForms.Add(strNewForm)
    'Show the form
    newForm.Show
End Sub

У меня проблема в том, что после того, как вы сделаете это 25 раз (да, я знаю), система выйдет из строя. Я понимаю, что это потому, что каждый раз, когда вы переходите к строке newForm.Show выше, код не завершается и поэтому остается в памяти.

Немодальные формы решили бы эту проблему, но тогда пользователь мог бы загружать другие формы и делать другие вещи, которые вызывали бы серьезные проблемы.

Есть ли у кого-нибудь предложения, чтобы помочь с этим? Как-то заставить выполнение кода, но не остановить модальную способность формы?

Длинный выстрел, но ценю любую помощь.


person Nick Perkins    schedule 09.12.2010    source источник
comment
Обязательно ли открывать все 25 форм? Вы пытались выгрузить форму, а затем открыть следующую?   -  person CaBieberach    schedule 09.12.2010
comment
Рассматривали ли вы использование элемента управления MultiPage в своей пользовательской форме, т.е. загрузите одну пользовательскую форму и используйте «Далее» и «Назад» для циклического переключения вкладок на многостраничном...   -  person Alex P    schedule 09.12.2010
comment
@CaBieberach: каждая форма выгружается до открытия следующей. Однако кодовая точка, в которой обработка остановилась для формы 1, остается в памяти, и так далее для остальных 24. Только когда окончательная форма закрыта, Excel возвращается к запуску кода (который в данном случае является просто Exit Sub) .   -  person Nick Perkins    schedule 10.12.2010
comment
@Remnant: мы использовали это. Мы собирались иметь две формы (есть два набора отдельных данных), но для Excel было слишком много элементов управления, чтобы загружать формы. Одна форма должна была иметь 161 поле x 10 элементов управления. Другой был контроль 95 x 10. У Excel был плевок, поэтому мы разделились на пять форм. На самом деле мы используем многостраничный элемент управления для каждой из этих форм. Всего в пяти формах 32 страницы.   -  person Nick Perkins    schedule 10.12.2010


Ответы (1)


Возможно, вам следует изменить свой подход.

Я бы предложил следующее:

В основном модуле используйте цикл для циклического открытия формы и цикла каждый раз, когда пользователь нажимает кнопку «Следующая форма».

'This sub in your main Module
sub ShowAndCyleForms
   Dim FormName As String
   Dim MyForm as Object
   Dim CloseForm as Boolean

   FormName = "frmMyForm"         

   do while CloseForm=False
      set MyForm = VBA.UserForms.Add(FormName)           
      MyForm.Show
      CloseForm=MyForm.CloseStatus
      FormName=MyForm.strNewForm
      Unload MyForm
      Set MyForm = Nothing
   loop 

end sub

В каждой форме объявляйте:

Public CloseStatus as Boolean
Public strNewForm as String

В каждой кнопке «Следующая форма» введите что-то вроде:

Private Sub btnNextForm_Click()
   CloseStatus=False
   strNewForm= NextForm(Me.Name)
   Me.Hide
End Sub

Измените свою подпрограмму, чтобы она была функцией, которая обеспечивает следующее имя формы.

Sub NextForm(strFormName As String)
   Dim intCurPos As Integer

   'Find out which form we are currently on from a list in a range
   intCurPos = WorksheetFunction.Match(strFormName, Range("SYS.formlist"), 0)
   If intCurPos = WorksheetFunction.CountA(Range("SYS.formlist")) Then
       'We want to use the first one
       intCurPos = 0
   End If

   'Get the name of the form to open
   NewForm = WorksheetFunction.Index(Range("SYS.formlist"), intCurPos + 1)
   '
End Sub

Вам также нужно будет изменить свой O.K. чтобы просто скрыть форму вместо ее выгрузки и установить для параметра CloseStatus значение true.

Идея состоит в том, чтобы контролировать загрузку/выгрузку всех ваших форм извне в одной процедуре.

Надеюсь, это достаточно ясно.

person CaBieberach    schedule 13.12.2010
comment
это выглядит как отличное решение - вы тестировали его, чтобы увидеть, сохраняется ли память и есть ли верхний предел для процесса зацикливания, прежде чем он выйдет из строя? - person SpyJournal; 14.12.2010
comment
Спасибо. Это выглядит как отличное начало. Я собираюсь сделать тестовый пример, чтобы посмотреть, как это работает, но я не вижу проблемы с первого взгляда. - person Nick Perkins; 15.12.2010
comment
Во-первых, еще раз спасибо за это. Я поместил это в тестовый пример, и он работает так, как должен. Блестящий. Примечание для тех, кто придет к этому позже - в btnNextForm_Click CloseStatus=True должно быть CloseStatus=False. Вы хотите установить CloseStatus=True только тогда, когда больше не хотите отображать какие-либо формы. Ваше здоровье :) - person Nick Perkins; 16.12.2010
comment
Приятно слышать, что это помогло. Я отредактировал свой пост, чтобы отразить CloseStatus=False. Спасибо за ответ - person CaBieberach; 21.12.2010