Call a modal Access form

  • Thread starter Thread starter David
  • Start date Start date
D

David

I know these are pretty basic questions - I guess so
basic that no-one thinks it warrants an explanation. I
have three books + the help file and none covers it
explicitly so far as I can see.

1. From VBA, how do I display a new modal Access form?
Does it have to be done by DoCmd.OpenForm("MyForm")? Does
this create a new instance of the form or does it just
activate a form that has already been created?

2. From within the form's events, how can the form be
closed and control returned to the calling routine? Is
the form destroyed or simply hidden? (ie do results have
to be returned via global variables or are the form's own
public variables accessible once closed?).

3. Does anything need to be done once control has
returned (eg DoCmd.Close acForm, "MyForm") so that it can
be re-opened. Would it then be re-opened in the same way
as 1?

4. Another topic: Does form.ReQuery commit all data on a
bound form before re-executing the query? Does
form.Refresh? I need a method of committing the data
without moving to another record eg so that a report can
be run on the (changed) underlying data.

Any help will be appreciated.

Regards, David
 
1. From VBA, how do I display a new modal Access form?
Does it have to be done by DoCmd.OpenForm("MyForm")?

Yes. Look at the WindowMode argument (acDialog is the value to specify).
Does
this create a new instance of the form or does it just
activate a form that has already been created?

Depends. If the form is already open, modal or non-modal view, then the
code will reuse the same instance without changing the modality. If the
form is closed, then a new instance will be created.
2. From within the form's events, how can the form be
closed and control returned to the calling routine?

If the form is opened in modal view, the calling routine will stop
processing code (any code after docmd.openform) until the form is closed.
Is
the form destroyed or simply hidden? (ie do results have
to be returned via global variables or are the form's own
public variables accessible once closed?).

The form will be destroyed if the 'close' action is performed. Typically,
you would put 'me.visible=false' type of code behind a 'Close' button and
take away the control box from the user. This way, once the form is
hidden, code execution in the the calling routine will resume and the
form instance will still be available to you. It will be the
responsibility of the calling routine to close the form once all values
are read-off of it.

DoCmd.OpenForm "form1", , , , , acDialog
MsgBox Forms.Count
DoCmd.Close acForm, "form1"
MsgBox Forms.Count
3. Does anything need to be done once control has
returned (eg DoCmd.Close acForm, "MyForm") so that it can
be re-opened. Would it then be re-opened in the same way
as 1?

See above.

4. Another topic: Does form.ReQuery commit all data on a
bound form before re-executing the query? Does
form.Refresh? I need a method of committing the data
without moving to another record eg so that a report can
be run on the (changed) underlying data.

Don't bother with either option. Issue a 'Save Record'.
docmd.RunCommand acCmdSaveRecord

-- Dev
 
none covers it explicitly so far as I can see.

Access help is notorious: but I am surprised that a good Access VBA book
does not describe this use well, because you are right that it's a standard
method.
1. From VBA, how do I display a new modal Access form?
Does it have to be done by DoCmd.OpenForm("MyForm")?

Yes: use the acDialog argument.
Does
this create a new instance of the form or does it just
activate a form that has already been created?

If there is an instance of the form loaded, it will be reactivated. You can
create and display a new instance of a form with

Set frm = New frm_MyCustomForm

but (a) it will disappear as soon as the variable goes out of scope and (b)
I don't know any way of making it modal.
2. From within the form's events, how can the form be
closed and control returned to the calling routine?

docmd.unload acForm, me.Name

unloads the form, or

Me.Visible = False

hides it and returns to calling code so that its controls and properties
are still available.
(ie do results have
to be returned via global variables or are the form's own
public variables accessible once closed?).

I do this kind of thing:

docmd.openform "MyForm",,,,,acDialog,"Jack"

' the form opens and does something with Jack...
' then the user clicks OK (hides it) or Cancel (unloads it)

' you have to check if the form has been unloaded because
' referring to its controls or properties will load it back
' into memory, which is not what you want.
If IsLoaded( "MyForm" ) then
' it's still loaded
MyNewValue = Forms("MyForm").Controls("txtInput").Value
DoCmd.Unload acForm, "MyForm"

Else
'user cancelled
MsgBox "Bye Bye"
MyNewValue = Null

End If
3. Does anything need to be done once control has
returned (eg DoCmd.Close acForm, "MyForm") so that it can
be re-opened. Would it then be re-opened in the same way
as 1?

Once it has been unloaded, it will be reset to its design values. If you
want to keep its controls you need to (a) store them - ugh! - or (b) keep
it loaded but hidden.
4. I need a method of committing the data
without moving to another record eg so that a report can
be run on the (changed) underlying data.

Me.Dirty = False

(believe it or not) saves the data in the current record...

Hope that helps


Tim F
 
(answers inline)
David said:
I know these are pretty basic questions - I guess so
basic that no-one thinks it warrants an explanation. I
have three books + the help file and none covers it
explicitly so far as I can see.

1. From VBA, how do I display a new modal Access form?
Does it have to be done by DoCmd.OpenForm("MyForm")? Does
this create a new instance of the form or does it just
activate a form that has already been created?

I'm not sure what you mean by "create" in this context. I *think*
you're talking about creating a new *instance* of a form that has
already been "created"; i.e., designed and saved in the database.
Also, "modal" can mean a variety of things, but I think from your later
questions that you want to open the form in dialog mode. That is, you
want the code that opens it to pause while the form is open, then resume
when the form is closed or hidden.

If my interpretation is correct, then you must open the form using the
DoCmd.OpenForm method, and specify the WindowMode:=acDialog argument.
For example:

DoCmd.OpenForm "MyForm", WindowMode:=acDialog

However, if the form is already open, this won't work -- it will neither
open a second instance of the form, nor will it put the open instance
into dialog mode. Although you can open multiple (non-default)
instances of forms that have class modules, I don't believe there's any
way to open such instances in dialog mode.
2. From within the form's events, how can the form be
closed and control returned to the calling routine? Is
the form destroyed or simply hidden? (ie do results have
to be returned via global variables or are the form's own
public variables accessible once closed?).

When you close a form, the contents of its class module are destroyed.
If you want the calling routine to be able to retrieve data from the
dialog form after it is "closed", don't close it at all, but merely hide
it by setting its Visible property to False. Only close it when the
calling routine doesn't need any information from it; for example, when
an operation is being cancelled. For example:

Private Sub cmdOK_Click()

' Hide this form so the caller can retrieve data from it.
Me.Visible = False

End Sub

Private Sub cmdCancel_Click()

' Close this form. The calling routine will interpret this
' as a "Cancel".
DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Then the calling code can check for whether the form is still open, and
act accordingly. For example:

' Open dialog form.
DoCmd.OpenForm "frmDialog", WindowMode:=acDialog

' When control returns, the form is either closed or hidden.
If CurrentProject.AllForms("frmDialog").IsLoaded Then

' The user clicked the "OK" Button.

' Get data from the form.
With Forms!frmDialog
varSomeVariable = .SomePublicVariable
varOtherVariable = !SomeControl
End With

' Close the form.
DoCmd.Close acForm, "frmDialog", acSaveNo

' ... continue with other code ...

Else
' The user clicked the "Cancel" Button, or
' closed without clicking OK.

' ... do something else, or Exit Sub, or whatever
' may be appropriate ...

End If
3. Does anything need to be done once control has
returned (eg DoCmd.Close acForm, "MyForm") so that it can
be re-opened. Would it then be re-opened in the same way
as 1?

I'm not sure what you mean here. If the form was hidden, you can make
it visible again in dialog mode by issuing another

DoCmd.OpenForm "frmDialog", WindowMode:=acDialog

You can't just say

Forms!frmDialog.Visible = True

as the form won't be in dialog mode when it is made visible?
4. Another topic: Does form.ReQuery commit all data on a
bound form before re-executing the query?
Yes.


Yes.

I need a method of committing the data
without moving to another record eg so that a report can
be run on the (changed) underlying data.

Both of the above are overkill for that. All you need to do is

If Me.Dirty Then RunCommand acCmdSaveRecord

or even

If Me.Dirty Then Me.Dirty = False
 
Back
Top