문제

Preface

I have a need to create multiple copies of a search form (in Access 2010) that returns a value to the calling (which is also the form that created the instance of the form).

As mentioned these forms could and will have multiple copies running at the same time for example a user could want to add a company to something so they:

  • Click "select company" and open an instance of the company search screen
  • Then open the company editor (leaving the original company search/selection screen open) as they notice the company has a parent company that hasn't been added yet.
  • They then click the "Select Parent Company" button that opens ANOTHER instance of the search and select screen
  • They find the parent company
  • Select it which closes the second search screen and the parent company is added to the first company.
  • The user then selects the modified company using the original search screen which again closes the original search screen and returns the selected company to what ever form they originally initialised the first search...

This all allows the users to update and correct data as and when they find error which reduces the likelihood of them forgetting and makes it much quicker!

MOST of this is fine now but I have had a lot of problems with instances of a form not being able to open as a "acDialog" thus stopping the calling code running until the search was done (see this question for more info) and the solution I have gone with is to simulate the pausing of the calling code by using a endless loop and checking if the search screen instant is still visible. Then when the user selects something on the search screen instant it puts the value in a hidden field in the search screen and hides it's self (not closed). The calling function then sees it's hidden grabs the value from the hidden field and unloads the instant.

Problem

I can check if the form is hidden using FormInstant.Visable but if the user closes the form this causes an error and the code I would normally use to check if the form exists requires a form name and as it's an instant of a form all the forms have the same name! I do have a reference to the form as it is stored in a local "form" object... The code I would normally use is:

CurrentProject.AllForms("FormName").IsLoaded

So how can I check for a instant of a form being loaded still?

도움이 되었습니까?

해결책

LOL I just realised while re-reading my msg that I can likely trap the error to work out if the form is open or not!

I have quickly written this and it seems to work fine:

Public Function IsFormLoaded(ByRef FormToTest As Form, _
                            Optional ByRef bIsVisable As Boolean = False) As Boolean
    Dim lErrorNum As Long
    bIsVisable = False
    On Error Resume Next
        bIsVisable = NewFormClone.Visible
        lErrorNum = Err.Number
    On Error GoTo 0

    If (lErrorNum = 0) Then
        IsFormLoaded = True
    Else
        IsFormLoaded = False
    End If
End Function

Guess it doesn't really mater who answers the question as long as it is answered and the next guy/gal can use it! :)

I will leave this open for a bit and if nobody finds a better answer I will mark this as it...

다른 팁

I like your answer. As for the loop/wait idea? A better way is to always include a reference in each form. I useally declare form module variable called frmPrevious.

Create instance of form
Instance.frmPrevious = me

So now we have the form "call" some code when the form is closed in place of some "visible" + looping code setting.

So in the close code of the form we have:

frmPrevious.FunctionCodeToRun

The above solves a good many issues, but one is you don't need dialog (which as you note cannot use) And you also dump the need for writing "loop + wait" code from the calling code.

This does however mean that your code continues in a new function in the calling form. I thus usually place that function right below the calling code in the calling form. I also tend to use a standard name for that function. I find this trade off worth it as opposed to loop/wait and continuing in the same code routine (I do agree this "continue" in code is often preferable, but then again having to write looping and wait code is not really that clean).

An old question but here's what experience taught me: If One, Two, ... instances of FormDefn opened then user closes One (Master which is the only one that can be designed), Forms(FormName) gives an error, Forms(Form) gives wrong object, but Forms(NumberIndex) does still exist with .Name = FormName!

OpenForm creates the Forms(FormName) object. Once closed Forms(FormName) gives an error. Any "Set xForm = New Form_xxx" creates forms in the forms collection that can only be accessed by the collection number index, and cant be designed.

So to later find a multi-instance form use something like:

Dim FormIdx     As Integer
Dim lForm       As Access.Form
For FormIdx = 0 To Application.Forms.Count - 1
    Set lForm = AccessFunc.Appl.Forms(FormIdx)
    If lForm.Name = pFormName Then
        IsFormOpened = True
        Set rForm = lForm
        GoTo IsFormOpened_Exit
    End If
Next

Try this also

Function IsLoaded(strFrmName As String) As Boolean

    '  Determines if a form is loaded.

    Const conFormDesign = 0
    Dim intX As Integer

    IsLoaded = False
    For intX = 0 To Forms.Count - 1
        If Forms(intX).FormName = strFrmName Then
            If Forms(intX).CurrentView <> conFormDesign Then
                IsLoaded = True
                Exit Function  ' Quit function once form has been found.
            End If
        End If
    Next

End Function

You can call the above function it in your project like so

If Not isLoaded("MyForm") Then
 MsgBox "MyForm is Not Loaded"
End If
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top