Using one-to-one relationship

Anonymous
2011-02-07T01:32:55+00:00

For various reasons, I need to break up a large table into smaller tables.  I've set up the smaller tables with one-to-one relationships.

If I assign a form's record source using just one of the smaller tables (and its fields), the form opens correctly showing the first record.  And, I can move through all the records using the Access record controls.

If I add one or more of the smaller tables (which participate in the one-to-one relationship with the original table), the form opens but no records are available - i.e., it opens as if I asked it to display a new record, and it doesn't recognize that there are other records available.

The one-to-one relationships are correctly set, with each table's primary key being a single key.

I have form controls that need to be bound to several of the one-to-one tables, so several tables need to be the form's record source.

As an example:  Table A has an autonumber primary key field, AID, and another field, Aname.  Table B has a primary key field BID (numeric long integer type) joined to AID in a one-to-one relationship (with referential integrity), and another field, Baddress.

If Table A is a recordsource for a form, the value of field Aname appears on the form and I can move through all Table A records.  As soon as I add Table B (along with Table A) as a recordsource, the form opens with no records available (i.e., a blank form as if I told it to go to a new reocrd).

I realize I can resolve this through a single large table, but that's what I'm trying to avoid. 

Has anyone worked with one-to-one relationships enough to have run into this problem?  And come up with a solution?

Thanks for any help.

Mike

Microsoft 365 and Office | Access | For home | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments
Answer accepted by question author
ScottGem 68,840 Reputation points Volunteer Moderator
2011-02-10T19:13:03+00:00

Mike,

I'm going to agree with Roger yet again. Helping you has been a pleasure and we will be here to support you as your project continues.

The main difference between bound and unbound forms is that, with a bound form, Access handles all the I/O between the form and the table. With an unbound form, the user has to write code (VBA), to handle the I/O. The complexity of that code can vary widely depending on the usage and purpose of a form. For example, a form solely for entering new records is fairly easy to code. But a form for retrieving data and populating the unbound controls, can be very complex. The coding involved depends on the table structure and form layout. Personally, I'm lazy and tend to use bound forms wherever I can.

There is only ONE circumstance in Access where a child record can be created with an automatically populated FK. And that's when using a subform. When you correctly link a subform to the main (parent) form, then any records created in the subform have the FK automatically populated. This is one of the reasons I said that subforms are a very powerful feature. But this only works with bound forms. So, in every other circumstance, when you add a record to a child table, you have to make sure the FK is populated correctly.


Hope this helps, Scott<> P.S. Please post a response to let us know whether our answer helped or not. Microsoft Access MVP 2010 Blog: http://scottgem.wordpress.com Author: Microsoft Office Access 2007 VBA Technical Editor for: Special Edition Using Microsoft Access 2007 and Access 2007 Forms, Reports and Queries

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments
Answer accepted by question author
Anonymous
2011-02-10T18:15:24+00:00

Mike,

It's posts like this that makes the whole process of answering questions here worth while.  I think we've seen a lightbulb go off above your head <grin>

As you no doubt realize, there are two distinct knowledge sets necessary for database development: design and implementation.  The Design set is universal and can be applied to any DBMS implementation.  The Implementation set is specific to the DBMS.

For Design knowledge, I recommend Michael Hernandez' "Database Design for Mere Mortals".  I taught 12 years of college courses in db design from that book.  It was a revelation to me.

For Access Implementation knowledge, I recommend "Access Cookbook" by Ken Getz, Paul Litwin, and Andy Baron.  I learn best from examples and this book is a set of common problems and solutions in Access development.  It's not really a book that you read through.  It's best used to find how to solve a specific problem.

I created the samples on my website (www.rogersaccesslibrary.com) with the same idea in mind. 

Good luck!


-- Roger Carlson

MS Access MVP 2006-2010

www.rogersaccesslibrary.com

If you want a detailed answer, ask a detailed question!

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

44 additional answers

Sort by: Oldest
  1. Anonymous
    2011-02-14T13:27:33+00:00

    If the subform is to be restricted to the phase 1 milestones only then, yes, include a WHERE clause:

    WHERE MilestoneTypePhase = 1

    but I'd suggest also following this with an ORDER BY clause to sort the rows by date as and when the dates are entered.  If you want the entered dates last in the list in ascending date order, with the as yet unentered dates first:

    ORDER  BY ProjectMilestoneDate

    If you want dates in descending order, with the unentered dates last, you'd use:

    ORDER  ProjectMilestoneDate DESC

    If on the other hand you want the dates in ascending order, but with the unentered dates last you need to use a bit if trickery:

    ORDER  BY NZ(ProjectMilestoneDate,#2100-01-01#)

    or similarly if you want the dates in descending order, but with the unentered dates first:

    ORDER  BY NZ(ProjectMilestoneDate,#2100-01-01#) DESC

    The NZ function returns the end of century date in place of a Null, causing it to sort after (or before in descending order) the current dates.

    To force the subform to reorder the rows immediately after a date is entered put Me.Requery in the ProjectMilestoneDate control's AfterUpdate event procedure.

    You don't need to do anything to pair the milestone type and date; that's already inherent in the data structures.  The MilestoneTypeID which you've inserted via the SQL statement maps to the primary key of the tluMilestones table, so each row will map to a separate milestone type value in that table, and the date entered in the referencing row will be associated with that milestone type.

    As the subform is already populated with the relevant rows you can set its AllowAdditions property to False (No).  This will remove the unnecessary empty row at the bottom of the subform.


    Ken Sheridan, Stafford, England

    Was this answer helpful?

    0 comments No comments
  2. Anonymous
    2011-02-14T16:36:40+00:00

    Thanks for the replies.

    I admit that I'm getting a little frustrated with myself, mostly for not being able to ask the correct question.

    I do understand that "When you run the Append query, it adds 5 SEPARATE records to the table."  And, "You don't need to do anything to pair the milestone type and date; that's already inherent in the data structures."

    However, I do need to be able to pick out a specific record from one of the five records, to either display on a form or a report, rather than as a list of the five records and/or a continuous form.  The user data entry subform will be a tab control.  The dates will be spread across different tabs, not all in one tab.  The way to distinguish amongst them is through the MilestoneType field. 

    So, I guess what I'm asking is:  On a subform, set up as we've been discussing, where x new milestone records are added via the main form, each distinguished by a MilestoneType value ranging from 1 -> x (actually, the MilestoneTypeID), and ignoring the need to display the paired milestone description (which I don't need to do; I can use hard coded labels), how do I bind a single control to asingle milestone record by specifying the record's MilestoneType value?

    In other words, I want to be able to do what Ken suggested in the following, but on a record by record (individual control) basis:

    "If you don't want to be able to edit the MileStoneType, but merely enter the date then, as the subform's      RecordSource, return the MilestoneType column in the query rather than the MilestoneTypeID:

    SELECT ProjectMilestoneID, ProjectID, MilestoneType, ProjectMilestoneDate FROM tblProjectMilestones INNER JOIN tluMilestonesON tblProjectMilestones.MilestoneTypeID = tluMilestones.MilestoneTypeIDORDER BY MilestoneTypePhase;

    In this scenario add two text boxes to the form with MilestoneType and ProjectMilestoneDate as their ControlSource properties.  Set the Enabled property of the MilestoneType text box to False (No) and its Locked property to True (Ye) to make it read only.  Link the subform to the parent form on ProjectID as above,"

    Scott - you seem to be saying that I can't pick out or set the value of a single milestone record without using an unbound form.   Consequently, I'm going to have to get up to speed in understanding how to use unbound forms, else I can't implement the project as I need to.  I'm more than willing to put in the study time to accomplish this if you could cite some appropriate references for me.  There's certainly nothing like this in the standard Access reference books that I've consulted.  (For what its worth, I've ordered a copy of "Access Cookbook", which Roger suggested.  Perhaps there's some guidance in there?)

    I still don't know if my question is clear.  In my simplistic view, what I need to do is be able to bind a single subForm control to a single milestone record for display or data entry purposes, following the scheme that we've been discussing.

    Mike

    Was this answer helpful?

    0 comments No comments
  3. Anonymous
    2011-02-14T23:18:37+00:00

    At the risk of taking this further afield, I would have thought that I could use a query tied to a control in the subForm to pick out a single Milestone record.

    For instance, it would seem that something like this should work:

    SELECT tblProjectMilestones.ProjectMilestoneDate

    FROM Project INNER JOIN tblProjectMilestones ON Project.ProjectID = tblProjectMilestones.ProjectID

    WHERE (((tblProjectMilestones.MilestoneTypeID)=1) AND ((tblProjectMilestones.ProjectID)=[Project].[ProjectID]));

    By varying the value for tblProjectMilestones.MilestoneTypeID it should pick out each of the records in turn.

    I tried this on the subForm.  What I got was an error message saying:  "At most one record can be returned by this subquery."  Which, of course, is exactly what I want.  But when I acknowledge the error, the main form opens but not the subForm.

    Is this heading in the direction of using unbound forms?

    Mike

    Was this answer helpful?

    0 comments No comments