|
Question : Sub-form Question
|
|
I have a very difficult sub-form question. My DB contains a contact form with two sub-form; one sub-form displays the contact's personal address while the second sub-form shows the phone number in a continuous format. The basic relational structure follows. OK!
tblCont trelContAddr tblAddr tblAddrCommPt tblCommPt ContID ContID FirstName AddrID AddrID AddrID LastName Addr2 Addr1 CommPtID CommPtID AddrTypeID CommPtTypeID PhonEmail
tblCont trelContCommPt tblCommPt ContID ContID FirstName CommPtID CommPtID CommPtTypeID PhonEmail
My database tracks contacts, companies, and projects. Each entity could have a common address or phone number. They could also exist without the other entity; in other words no table could link all entities at once.
My goal entails developing a form where one can edit and enter Contact Data. This task has been a chore and many problems have arisen. One problem stems from the complex relational structure that my DB necessitates.
A contact record could have a home phone number attached to the home address and a personal cellular. The home phone links to the AddrID while the cell phone links to the ContID. So one can not create a general-purpose updateable query for the phone sub-form. My possible choices follow.
1 -------------------------------------------------------------------------- ----------------------------- Create an additional Phone sub-form for a total of three sub-form. Base one on AddrID and the other on ContID. Thus each sub-form has its own query. This alternative may crowd the current Parent form and make the inputting data less intuitive (eg. Where do I enter what phone number?).
2 -------------------------------------------------------------------------- ------------------------------- Create an all-purpose relational table for both scenarios; then base the phone sub-from on a query with this new table.
telContAddrCommPt ContID AddrID Addr2 AddrTypeID CommPtID CommtTypeID
Whenever a contact record contains no address then one would choose NO ADDRESS, and vice verse for no phone (NO PHONE). This alternative does not seem logical, because one must remember to input this data instead of leave it blank. A VBA routine may solve this problem, yet tab order may still create additional problems.
Does anybody have any suggestions or advice for me?
|
|
Answer : Sub-form Question
|
|
Have you had any luck?
BTW, you should take a good look at Corel InfoCentral. Anyway, I can help you out. About a year and a half ago, I was facing the same type of issue. Essentially, you're looking for M-M (many to many) relationships. These are usually reserved for OODBMS or ORDBMS. So I also explored these avenues.
So let's simplify this problem to three tables (classes if you will): tblPerson tblAddress tblPhone
Here are some quick members:
tblPerson.ID {PK} - AutoNumber tblPerson.FirstName tblPerson.LastName
tblAddress.ID {PK} - AutoNumber tblAddress.Street tblAddress.City tblAddress.State
tblPhone.ID {PK} - AutoNumber tblPhone.Number tblPhone.Type
Okay...so the idea here is that you need to create 2 MANY-to-MANY relationships. Unfortunately, most RDBMSs don't support this mechanism directly. Instead, you have to create (as you already seem to understand) what are known as "junction" or "join" tables. It's these junction tables which allow an entity to either have no relationship or a many-to-many relationship or anything in between:
tblRELPersonAddress tblRELPersonPhone
Here are some members for you:
tblRELPersonAddress.PersonID {PK} & {FK:tblPerson.ID} tblRELPersonAddress.AddressID {PK} & {FK:tblAddress.ID}
tblRELPersonPhone.PersonID {PK} & {FK:tblPerson.ID} tblRELPersonPhone.PhoneID {PK} & {FK:tblPhone.ID}
Then two queries which will come in handy:
qryPersonAddress:
SELECT tblRELPersonAddress.PersonID, tblRELPersonAddress.AddressID, tblAddress.ID, tblAddress.Street, tblAddress.City, tblAddress.State, tblAddress.Zipcode FROM tblPerson INNER JOIN (tblAddress INNER JOIN tblRELPersonAddress ON tblAddress.ID = tblRELPersonAddress.AddressID) ON tblPerson.ID = tblRELPersonAddress.PersonID;
qryPersonPhone:
SELECT tblRELPersonPhone.PersonID, tblRELPersonPhone.PhoneID, tblPhone.ID, tblPhone.Number, tblPhone.Type FROM tblPhone INNER JOIN (tblPerson INNER JOIN tblRELPersonPhone ON tblPerson.ID = tblRELPersonPhone.PersonID) ON tblPhone.ID = tblRELPersonPhone.PhoneID;
Notice that the two junction tables are "center-joined" - in other words, they are always the "many" portion of a one-to-many relationship. The two queries above make this possible.
Let's assume that you were able to setup the example above. The next step would be to create your forms/subforms correct? Now, when you create your frmPerson form, just create a quick AutoForm:Column for tblPerson. Expand it so that you have some space for the subforms we're about to make. Instead of manually creating the subforms, let Access generate them for you. In other words, just drag your subform into the frmPerson form. It will prompt you on whether you'd like to use an existing form or table/query. Select table/query and then click next. Select qryPersonAddress from the list and then add ALL of its fields to the right listbox. It will then ask you how you want to relate the form to the query. Obviously, from the form you will choose Person.ID and from the query, you will choose qryPersonAddress.PersonID. Click finish and you're done. Repeat this step to create a "phones" subform for qryPersonPhone.
The end product, I believe, is closer to where you want to go. Although, reading back a bit, I also see that you want any two entities to maintain a relationship. If you want to explore this avenue with me, let me know - I've begun some work in this area also.
BTW, I can e-mail this DB to you - as I created it for a tutorial I was recently creating.
|
|
|
|