MS Access sub-sub forms - ms-access

I am using MS Access as a front end for a MySQL database. In it I have several tables, all based around the concept of a Household and People (one to many, respectively). From that there are several join tables (such as Ethnicity and Dietary Restrictions) which are many to many. I would like to be able to edit this from a single form in MS Access.
So far I have it set up so that I can edit the household information, view/edit all the people associated with it, and expand the person detail to view 1 (out of 3) of the join tables associated with that person record. I cannot figure out how to get all 3 tables to be visible, does anyone know how to do this?

I would built 3 grids using continues forms, or 3 forms in data sheet view.
You then create a 4 form, and drop in the above 3 forms.
In the master form (which is now a subform), in the on current event, you
place the following command to make the child forms follow this form.
me.Parent.Child1.Requery
me.Parent.Child2.Requery.
In the link child/master settings for child 1, you place:
linkChildFields main_id (whatever is the name of the field in
this sub-form that is used to relate back to the parent table)
LinkMasterFields [MasterForm].[form].[ID]
In the link child/master settings for child 2 form you place
linkChildFields main_id (whatever is the name of the field in
this sub-form that is used to relate back to the parent table)
LinkMasterFields [MasterForm].[form].[ID] ("masterForm" is the name of
the contorl you used to hold the master form).
The "many" to many screen looks like this:
The above is a classic accounting or funds distribution in which we take an amount like $50 and distribute the amount over many accounts.

Sounds like a structure problem, actually. Wouldn't it be more efficient to base your property accessory tables (dietary restrictions, occupations, etc) - properties that a single person might possess a number of - on your personal information table, perhaps keyed to a individual ID of some sort (employers often use SSNs, as they are unique - though in your case, you might just make them auto-generating). Items like Ethnicity, and position within a household are something an individual possesses one of, and would be something you could indeed place within your personal information table.
With proper structuring, and the right query work - you can have a form that allows you to edit all of these properties on a family while keeping referential integrity.

Related

Access changes table Relationships by itself

I am struggling with an issue in designing my Access database.
I am a caregiver, and part of my job is taking clients out into the community. I am attempting to build a catalog of outings to help the employees at our company come up with and store ideas for these. I want to store information for each of up to 5 types of events that clients can do at a location. That information includes the event type, when it runs and doesn't, and how much it'll cost, all of which would be user-selectable. (Separately in the same table, I want to include contact information and information that helps the user search for event locations, such as the ZIP code.) I have attempted to normalize the database by spreading event information across fields in the main table, linked to lookup tables. I am aware that Access has a limit of 32 relationships per table.
To help staff find event types, I am trying to set up a method for categorizing them. That requires setting up nested lookup tables, as shown in the first picture.
If I understand correctly, the additional "copies" of those lookup tables are aliases. When I save the setup for the relationships between those aliased lookup tables, close the Relationships window, and open it again, I find Access has changed them, as shown in the second picture. This happens whether I delete the lookup table information for each field in Datasheet View. I don't understand why it does this or how to fix it.
To answer your question:
In the object browser I see that you have only one table: t_OutingType. Therefore, the "tables" t_OutingType_2, t_OutingType_3 are just aliases; "pointers" to the same table (like a shortcut to a document). When you save the relationships and close the window, the relationship information is written to the metadata of the database. When you re-open the Relationships window Access re-builds the relationship diagram from the metadata, and it does not include the redundant aliases.
Additional advice:
Whenever you find yourself duplicating columns in a table, e.g., Event_1, Event_2, ... a little voice in your head should start shouting "Are you sure that's a good idea?" Imagine if you want to search the database for events that fall on a certain date. With the table layout described above you would need to ...
SELECT ... WHERE EventDate_1 = [theDate] OR EventDate_2 = [theDate] OR EventDate_3 = [theDate] ...
It's almost always better to split the Event information into a separate child table and maintain an association table between the child table and its parent.

Access: Entering multiple subform values with one entry in the form

I've been using Access to create simple databases for a while with great success, but have run into a problem I can't find an answer to.
We ship individualized serialized units to various end-users, and occasionally to resellers that stock them for end-users. I must keep track of which serial numbers end up with each end-users.
The first database I created to handle this recorded company information in one table using their account number as primary key, order information in a second table using the order number as the primary key and linked via the company name, and unit information in a third table with the serial number as the primary key and linked via the order number.
This worked very well until I had to account for these stock orders with a reseller. As it was structured, every unit was linked to one company via the sales order. The issue is that I may ship 20 units on one order to Company A, who then sells 5 to Company B and 3 to Company C.
I realized I needed to link the company name directly to the units, not the orders and have fixed that.
My issue now is simplicity in entering information in the form. My previous database involved the employee in our shipping department merely entering the sales order, selecting the customer name from a drop down menu, then scanning the serial numbers in a subform. This was to ensure simplicity and try to eliminate human error. He had only three things to input, and most of the input was done by scanning barcodes.
As it is currently structured now, the employees out in shipping would have to populate the company name for every record in the subform with the serial number and that complicates things in a way that is unacceptable. At the point of shipping, the company name will always be the same for every unit in the subform.
So.
How would I go about creating a form where the company name is entered once in the form, and automatically populates itself for every record in the subform? The caveat here is that I must also be able to go back occasionally and change the company name of individual units in an order without necessarily affecting the rest of the order. I suppose it starts out as a one-to-many relationship that then must be able to change.
I hope that makes sense.
I have looked for answers using various approaches with auto-fill and relationships and not preserving data integrity, but I feel the answer is just beyond my reach.
The only solution I can think of is to create another field in the unit table for the end-user, and perhaps write a formula that sets this default value as the company name from the order that shipped it. This seems unnecessarily complicated and redundant, there has to be a better way.

Display many to many relationship in continuous form

I can't figure out how to display a column that has many value for the same record in a continuous form
I got 3 tables
SalesCall
SalesCallId | etc..
Mill
MillId | name...
SalesCallMills <------ Junction table
Id | SalesCallId | MillID
the basic design for a many to many relationship.
When it's a simple form, I'm used to do a list and change the control source for the current ID with a SQL query.
What's the common practice to display this in a continuous form?
This was the form before when only 1 mill was possible.
I thought I could concat the mills, but it will be hard to read and it will be way to long.
So I thought about a list but I don't think it's possible to change the control source for each record.
Also, good to mention that this is read-only. It's not for adding or editing. The form to enter data is already made. And I think that one mill per record is not an option cause it would really confuse the user.
What's the proper way to display a multi value column with my database design?
This is a form with correlated subforms.
The two forms are synchronized via the link child and master fields:
Link Master Fields: Forms!Form7![SalesCall Subform].Form.SaleID
Link Child Fields: SalesCallId
And a little code in the Current Event of subform #1
Private Sub Form_Current()
Me.Parent.[SalesCallMills subform].Form.Requery
End Sub
Selecting a line in subform #1 displays the relevant detail lines in subform #2.
It should not be difficult to add suitable information on such things as mill name to the general outline.
The Junction Table will be the mainstay of your select, and you will hang the other tables from it.
You can use the Query Editor to view it visually, but the SQL statement would look like:
SELECT *
FROM (SalesCallMills
INNER JOIN SalesCall
ON SalesCallMills.ID=SalesCall.SalesCallID)
INNER JOIN Mill
ON SalesCallMills.ID=Mill.MillID;
(Access likes brackets around multi-table joins, so while they are not necessary for a pure SQL statement, Access will not work properly without them)
To view all the Mills against each SalesCall in a single line, you will have to leave the simple query behind, and write your own (vba) function
http://allenbrowne.com/func-concat.html has an example, and the code that will allow you to set the Mills field on your current form to something like =ConcatRelated("name", "Mill", "MillID= " & SalesCallMills.ID)
You could List the mills in a a text box by setting the format to rich text and then putting all the mills into the same field separated by the <br> tag like this.
Mill1<br> mill2<br>mill3
Considerations
1. This will mean that the text box has to be long enough.
2. You will have to concatenate the mills into a single field in you query which may not be feasible.
in a classic in traditional sense, there’s really not such a thing as a many to many relationship between two tables, however by cobbling together related tables one after another, you do at the end of the day due in effect get the same result of a many to many relationship, but technically that’s not what occurring between two tables. In effect you are always working your way down from a parent table to a child table. Those thinking in terms of junction tables are in fact thinking the wrong way.
If a person is allowed to have many favorite colors, then it in poor taste to call that table that simply links their many choices of color to the available colors as a "junction" table. It is far better to simply state that we need a table called:
My List Of Favorite colors table.
The fact the above table may then link to additional tables is moot. In fact it might have more than one column that are foreign keys, and then it not really a simple junction table, but at the day it is doing the same thing.
Anyway, in Access you can most certainly display two continues forms to display data modeled in this manner.
Let’s assume that each weekend we have to take in a bunch of donations from people. This means we have one main table with information about the date and time etc. of this donation event. Our next table would have people and their donation amount. The next table after that would be to take a donation amount, and split up their funds into different accounts. This is a classic accounting distribution problem that just about every accounting package from QuickBooks to whenever has to implement. As it turns out, this classic distribution problem can be solved with very little code when using access.
The trick to modeling these types of forms is to use several sub forms placed into one main form.
The following form shows this:
If you look at the top there’s a main record with information about this batch run and date and time. Now, on the left side is many people and a donation amount. And on the right side is that donation for the one person split out to many different accounts. So I’m displaying many people, and I’m also to display the many accounts that a donation may be split out to .
Keep in mind that access does not let you place a continuous subform inside of a continuous subform. However, you can certainly place two continuous of forms beside each other as the above screen shot shows to model the same affect that you desire.
There’s also surprisingly as mentioned very little code to manage this whole thing.
For the left side continuous form, because the link master and child settings are set to the main form record, then NO code is required for this form to be populated with data. However, for the right side continues form to follow and display the correct Accounting Data for each person in the leftr side continuous form, access will not automatically do this for you . However, a simple bit of code in the on-current event of the left side form will forced access to wake up and note the right side continues form has to be RE populated to display the donation accounts for that one particular person .
The one line of code placed in the left side on-current event will fix this:
me.Parent.Child2.Requery
The link master/child settings on the right side continuous form I use:
linkChildFields main_id (whatever is the name of the field in
this sub-form that is used to relate back to the parent table)
LinkMasterFields [MasterFormLeftSide].[form].[ID] ("masterFormleft" is the name of
the subform contorl you used to hold the continuous form on the left side ).
So, you’ll need a tiny little bit of code, but not a whole heck of a lot, and you now have a screen that displays many information related to many information.
I strongly disagree with "Those thinking in terms of junction tables are in fact thinking the wrong way." in #Albert D. Kallal's answer.
It is true that m:n relationships can't be implemented directly in a relational DB. That is why the one and only sane design of:
+----------+ +---------+
| Patients |--- m:n ---| Doctors |
+----------+ +---------+
... is:
+----------+ +-----------------+ +---------+
| Patients |--- 1:n ---| PatientsDoctors |--- n:1 ---| Doctors |
+----------+ +-----------------+ +---------+
Everything else might work in one way or another but is poor man's relational DB design. And with making compromises at the model design, at the very beginning of a project, the worse is very likely yet to come.

User interface for relational database: basic feature

This is a bit embarrassing but it's been a while.
When working with relational databases and linking to separate tables by primary:foreign keys, in 1-∞, such that, in a particular table, the table's foreign relationship returns an integer ID... how do you go about making this relationship intelligible to users?
For example:
You have a company table
CID
CompanyName
CompanyLocation
CompanyBusinessType
etc (not actual column names)
and an employee table
EID
firstName
surName
DOB
email
company
Employee company is related to CID. But some user putting in information about an employee would have to know the ID code for the particular company due to the nature of the relationship. You can run a query to return 'CompanyName's along with their associated 'CID's which can then be searched, but this cipher is hardly an ideal solution. I just cannot remember the theory of how one approaches this, even though I'm certain I've done it before. I need to implement it in both Microsoft Access 2010 and Microsoft SSMS (separate databases fwiw); but the execution should be relatively straightforward as soon as I remember how it's done!
Create a combo box with 2 columns. One column as the company name and the other as the company ID. You can set the width of the company ID to 0 if you don't want the user to see it.
This can be done with the Property Sheet on MS-Access Forms
Set the Row Source of the combo box to:
SELECT CompanyName, CompanyID FROM Company;
Set the Control Source of the combo box to:Employee.CompanyID
Also make sure the Row Source Type is set to Table/Query
If you need a many to many relationship (many employees belong to many companies) then you will need another table CompanyEmployees, something like this: -
If an employee only belongs to one company then this structure will do fine: -
In either case you will need to display the user with some form of drop down list when adding / editing a user to associate the users with one or more companies.

Why would a Microsoft Access form create records for one query but not another?

I have an Access database. Let's pretend it's for a pet store.
There's a table for animals.
Animals (animal_id, birth_date, price)
And then specific tables for the different types of animals we sell.
Dogs (animal_id, bark_volume)
Cats (animal_id, collar_size, shedding_rate)
Fish (animal_id)
Fish aren't interesting so they don't have any special fields. The Fish table just exists so you know which records in the Animals table are fish.
Now, I have a general purpose form for adding animals to the pet store. Before you get the form, you first have to say what kind of animal you're adding. Based on that, the form shows/hides fields, changes its recordsource, and binds the fields to the appropriate data columns. The form pulls its data from the queries DogInfo, CatInfo, and FishInfo.
Now, when you enter a dog or a cat, everything is fine. A record is added to both Animals and either Dogs or Cats.
However, when you enter a Fish, all you get is an Animal, no Fish.
What could be causing this? Is it somehow caused by the lack of other columns on the Fish table?
(Let's leave aside the fact that updating tables with a select query makes no sense at all. I didn't expect Access to let me do it at all in the first place, but Access's motto seems to be "Make the wrong thing easy to do and the right thing awkward to do." The database is relatively simple and infrequently used, though, and it's at least 100 times better than it was before I started working on it, so I'm not really too worried about this issue as long as I can make it work.)
"Is it somehow caused by the lack of other columns on the Fish table?"
Yes - when you enter data on child records (Dogs and Cats) Access will automatically fill in the parent ID (animal_id)
Since there is no data entry for the fish record it does not get created. You have to do that in code. Not sure how your form and data source is setup but you would do something like this on one of the form events:
Fish![animal_id] = Animal![animal_id]
Edit
In your FishInfo query you must give the Fish.[animal_id] an alias - you can't have two fields with the same name - call it Fish_animal_id
Then in the Form_BeforeUpdate event put this:
Me.Fish_animal_id = Me.animal_id
Have you thought about configuring relationships on the different tables? Given the design above, I would start by adding an identifying column to the specific-animal tables, and setting it as the primary key. E.g.:
Dogs(DOG_ID, animal_id, bark_volume)
Cats(CAT_ID, animal_id, collar_size, shedding_rate)
etc. In the relationships view, you'd then define a one-to-many (one-to-one?) relationship from Animals.ANIMAL_ID to Dogs.animal_id. You could then hook up the Animals table to a combo/listbox control on your form to select a record from that table. I think if you configure the control correctly, you can even create new records from that control (or you could use a subform).
Do you not have an separate IDs for the Dogs/Cats/Fish tables? Assuming the only difference is the number of columns, I'd be curious if that suddenly fixed it.
Bad design aside, did you set up a relationship between the various tables? And did you set the tables to enforce referential integrity?