IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Помогите создать 2 экземпляра формы. (VBA,Access) (https://www.imho.ws/showthread.php?t=94761)

Raven B. 25.10.2005 15:30

Помогите создать 2 экземпляра формы. (VBA,Access)
 
Доброго времени суток.
Есть 2 формы. 1 вызывает 2 с неким параметром:

DoCmd.OpenForm "ph_f_search_res_form", , , , , , se_list.Column(1)

Все работает. Но если форма ph_f_search_res_form открыта, то нельзя вызвать еще один ее экземпляр. =(

Это возможно ? Если возможно, то подскажите как, пожалуста. :help:

LightImage 26.10.2005 09:41

При открытии формы проверяй, открыта ли она, и если да, то копируй форму, и эту копию уже и открывай. Вот код для создания копии формы:
Код:

Dim saveCount As Integer
Const frmname = "ph_f_search_res_form"
Dim newname As String
    If Not IsLoaded(frmname) Then
        DoCmd.OpenForm frmname, , , , , , se_list.Column(1)
    Else
On Error Resume Next
        saveCount = saveCount + 1
        newname = frmname & "-interm-" & saveCount
        DoCmd.DeleteObject acForm, newname
        DoCmd.CopyObject , newname, acForm, frmname
        DoCmd.OpenForm newname, , , , , , se_list.Column(1)
    Next

А вот функция, которая проверяет, открыта ли форма. Эта функция, если не ошибаюсь, есть в учебной базе Борей.
Код:

Function IsLoaded(ByVal strFormName As String) As Boolean
 ' Возвращает значения True, если форма открыта в режиме формы или таблицы.
    Const conObjStateClosed = 0
    Const conDesignView = 0
   
    If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> conObjStateClosed Then
        If Forms(strFormName).CurrentView <> conDesignView Then
            IsLoaded = True
        End If
    End If
End Function

А при завершении работы программы можешь подчищать лишние копии формы:
Код:

On Error Resume Next
Const frmname = "ph_f_search_res_form"
Dim newname As String
Dim i As Integer
    For i = 1 To saveCount - 1
        newname = frmname & "-interm-" & i
        DoCmd.DeleteObject acForm, newname
    Next

Переменную saveCount, понятно, желательно объявить глобальной в той форме, которая производит открывание других форм.

Raven B. 26.10.2005 20:40

Неработает =(
Говорит что не может найти свеже скопированый обьект.

Цитата:

Run-time error '7874'
Приложению 'Microsoft Office Access' не удается найти обьект 'ph_f_search_res_form-interm-1'
В чем может быть загвоздка ? :confused:

LightImage 27.10.2005 10:48

А вообще объект копируется? Отладчиком пройди, посмотри, создается копия вообще, и на какой строке ошибка, вдруг это при удалении возникает, если On Error Resume Next не сказал =)
Если при открытии копии ошибка, то м.б. надо закрытую форму копировать, хотя у меня в Access 2002 можно и открытую обрабатывать. Попробуй копировать нужную форму при открытии открывающей, а потом делать копию уже с этой копии.

Вообще то Access какой версии используешь?

Raven B. 27.10.2005 17:33

MS Office Access 2003.
Сейчас попробую выяснить...

Дико извиняюсь - бытавая, я прошу прощения, задолбаность. :idontnow:
Перепутал все что только можно. =)
Уже все работает. Проблема была с удалением еще не созданной формы. формы.
Еще раз извиняюсь за собственную невнимательность. :rolleyes:

Raven B. 27.10.2005 19:25

Вопрос по закрытию формы:
Нужно удалять копии когда закрывается эта самая копия. тоесть она дролжна инициировать свое удаление.

Написал:
Цитата:

Sub killform(ByVal str As String)
If IsLoaded(str) Then
DoCmd.Close acForm, str
End If
DoCmd.DeleteObject acForm, str
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim para, tmp As String
tmp = Form.OpenArgs
para = Split(tmp, "|") 'во втором элементе получившегося массива - номер копии

If Not para(1) = 0 Then 'тоесть если это не оригинал - удаляем
killform ("ph_f_search_res_form-interm-ph_f-" & para(1))
End If
End Sub
Однако при попытке выйти из формы получаю:
Цитата:

Run-time error '2501'
Прервано выполнение макрокоманды Close
Как с этим боротся ? Подскажите пожалуста.

SapeR 28.10.2005 01:21

Если я правильно помню - форма аксесса неразрывно связанна с неким дата-сорсом - таблицей или рекордсетом. (1) не факт что этот объект копируется при копировании формы - можето он эксклюзивный ? (2) в момент закрытия формы данный объект убивается, при попытке закрытия копии ... могет и заглючить. А поможет ли древнехалявный On Error Resume Next ?

Raven B. 28.10.2005 09:21

Цитата:

Если я правильно помню - форма аксесса неразрывно связанна с неким дата-сорсом - таблицей или рекордсетом.
Нет. Форма ни с чем не связана. Но связаны некоторые ее элементы. (listboxсы). Остальные данные формируются как реакция на действия пользователя.

Цитата:

(1) не факт что этот объект копируется при копировании формы - можето он эксклюзивный ?
Ну, таблицы никуда не копируются. Только формы.

Цитата:

(2) в момент закрытия формы данный объект убивается, при попытке закрытия копии ... могет и заглючить. А поможет ли древнехалявный On Error Resume Next
С On Error Resume Next не получается. Та же ошибка.
Насколько я понял, для того что бы обработка ошибки пропускалась ф-я должна выглядеть так ?
Цитата:

Sub killform(ByVal str As String)
On Error Resume Next

If IsLoaded(str) Then
DoCmd.Close acForm, str
End If
DoCmd.DeleteObject acForm, str

End Sub
Заглючить то оно заглючило. Только как эту проблему решить ? :help:

С уважением. Ворон.

LightImage 28.10.2005 09:33

Попробуй удалять в обработчике события "Закрытия":
Код:

Private Sub Form_Close()
Dim para, tmp As String
tmp = Form.OpenArgs
para = Split(tmp, "|") 'во втором элементе получившегося массива - номер копии

If Not para(1) = 0 Then 'тоесть если это не оригинал - удаляем
killform ("ph_f_search_res_form-interm-ph_f-" & para(1))
End If
End Sub

А вообще лучше при возможности удалять не в коде самой формы, а в коде, её открывающем. Нужно открыть копию модально, а следующей строкой после открытия удалить копию, т.е. примерно так:
Код:

DoCmd.OpenForm newname, , , , , acDialog, se_list.Column(1)
' Управление на следующую строку передается после закрытия
' формы newname
DoCmd.DeleteObject acForm, newname


Raven B. 28.10.2005 10:43

Как модальное окно я форму открывать не могу. :( Дело в том что содержимое форм пользователь хочет сравнивать, а если окно модально - работать с другими окнами не получится.

При событии Close результат тот же - прерывается на

DoCmd.Close acForm, str

С той же ошибкой.

LightImage 28.10.2005 11:58

Так DoCmd.Close в событии закрытия нельзя вызывать =)
Удалить форму из её же кода вряд ли удастся имхо.
Зачищай лишние экземпляры перед открытием нужной формы. В цикле по именам копий проверяй, открыта ли копия, если да, удаляй. А имена открытых копий можно хранить в динамическом массиве

Raven B. 30.10.2005 16:42

С защитой проблем нет.
И даже с удалением по закрытию вызывающей копии формы. Проблема в том что бы удалить копию сразу после ее закрытия. неужели это не возможно ?

LightImage 11.11.2005 11:28

Посмотри еще _http://www.sql.ru/forum/actualthread.aspx?bid=4&tid=47734


Часовой пояс GMT +4, время: 06:35.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.