The tabs should not make any difference.
If the other form is unbound, then it will not have any Dirty property,
so
the reference would generate an error. Perhaps use error handling for
this
case. Or just remove that If block if no editing is allowed in any
subforms.
Or test for the property, e.g.:
If HasProperty(sfm.Form, "Dirty")
after adding this function to the standard module as well:
Public Function HasProperty(obj As Object, strPropName As String) As
Boolean
'Purpose: Return true if the object has the property.
Dim varDummy As Variant
On Error Resume Next
varDummy = obj.Properties(strPropName)
HasProperty = (Err.Number = 0)
End Function
--
Allen Browne - Microsoft MVP. Perth, Western Australia.
Reply to group, rather than allenbrowne at mvps dot org.
Hi Allen,
I appreciate your help so far - hopefully I won't need to trouble you
again after this...
I tried using the
Call LoadOtherSubform(Forms!Main![SubForm], "JobSearch")
behind the command buttons, and it works great - with one exception.
One of the other subforms I have has three tabs. If I try to navigate
from that subform to another, I get an error message "Method 'Form' of
object '_SubForm' failed.
The debugger goes to the following line of code:
If sfm.Form.Dirty Then 'Save first.
I guess I need to modify the code so that it can deal with tabbed forms
as well as the others, but (surprise!) I'm not sure how...
If you can give me some pointers, I'll gladly try to write the code
myself.
Thanks,
Neil
Allen Browne wrote:
Hmm. I'm not sure I understand why you need the DoCmd.Close and
DoCmd.OpenForm hidden. Just setting the SourceObject should work.
You could also do it with:
Call LoadOtherSubform(Forms!Main![SubForm], "JobSearch")
if you wanted that function to take care of saving any edits in
progress
and
ensuring that Access does not mess up the LinkMasterFields and
LinkChildFields.
Cancel that last post! I have managed to get it to work by changing
the reference from Me.Parent! to Forms!Main!
One thing I would like to ask you is that my main form uses command
buttons to set the sourceobject for the subform. An example of the
code I'm using is:
DoCmd.Close acForm, "JobForm"
DoCmd.OpenForm "JobSearch", , , , , acHidden
Me.SubForm.SourceObject = "JobSearch"
(e-mail address removed) wrote:
Hi Allen,
Thanks for taking the time to reply. I have to admit that the code
you've posted is way beyond my current capabilities in access (but
I'm
keen to learn!).
I'm having trouble adapting the code - can you explain what "sfm"
refers to? I'm thinking it's the subform I'm trying to open, so
for
example I've changed the code from
sfm.LinkMasterFields = vbNullString
to Me.Parent!SubForm.LinkMasterFields = vbNullString
This throws an error to tell me that the object doesn't exist, so
I'm
either misunderstanding (highly likely) or my syntax is wrong
(equally
likely).
If it helps, my main form is "Main", my search form "JobSearch" and
my
details form "JobForm".
Allen Browne wrote:
Okay, there's a bunch of stuff happening here.
Firstly, you cannot use OpenForm to load a subform control. You
need
to
set
its SourceObject property. In doing so, you cannot pass a
WhereCondition, so
you will need to find the record, or appy a filter instead.
Another interesting aspect is that you are unloading the subform
while
its
module is still running, and replacing it with something else.
Access
will
probably let you get away with that, but it makes me a little
squeamish. I
would prefer to pass control to a generic function in a standard
module, so
there is no issue with fully unloading the subform's module.
This is just an aircode example of the kind of thing. I've
assumed
your
subform control is named Sub1. (Subform is a keyword.) Access can
assign the
wrong stuff to LinkMasterFields/LinkChildFields, so we make sure
those
are
clear.
Private Sub JobID_DblClick(Cancel As Integer)
Dim strWhere As String
If Not IsNull(Me.JobID) Then
strWhere = "JobID = " & Me.JobID
Call LoadOtherSubform(Me.Parent!Sub1, "JobForm",
strWhere)
End If
End Sub
Public Function LoadOtherSubform(sfm As Subform, _
strFormName as String, Optional strWhere As String)
Dim rs As DAO.Recordset
If sfm.Form.Dirty Then 'Save first.
sfm.Form.Dirty = False
End If
sfm.SourceObject = strFormName
sfm.LinkMasterFields = vbNullString
sfm.LinkChildFields = vbNullString
If strWhere <> vbNullString Then
Set rs = sfm.FormRecordsetClone
rs.FindFirst strWhere
If rs.NoMatch Then
MsgBox "Oops: the record disappered."
Else
sfm.Form.Bookmark = rs.Bookmark
End If
Set rs = Nothing
End If
End Function
I have an unbound main form with a single subform. The
sourceobject
for the subform is changed to various forms using command
buttons
on
the main form.
One of the subforms is a search, and another is a detailed view
of
the
record.
What I would like to do is double-click the row on the search
form,
and
display the detailed form in it's place, but with the relevant
record.
The code I have so far is:
Dim JobNo As Integer
JobNo = Me.JobID.Value
DoCmd.OpenForm "JobForm", , , "JobId = " & JobNo, , acHidden
Forms!Main.SubForm.SourceObject = "JobForm"
The DoCmd statement seems to work if the form is opened
normally
(i.e.
not hidden), but the code above opens the subform at the first
record.