(Table Relationships)
I'm developing a travel agency database, and I've got a table for contacts (people), a table for trips, and a junction table, people_has_trips. "Trip" refers to a table whose identity is mostly many-to-many relationships with various optional travel elements such as hotel, flight, etc. (I have doubts about this structure, but that's an issue for another question).
Anyway, I'm in the early phases of designing the form for Trips, which will almost entirely consist of subforms linking to junction tables. The problem that's given me the most difficulty so far is that of how to add a contact to a trip. I'm fairly new to access, and thus far I've been populating such tables using autofilling comboboxes, but the contacts table contains over 100,000 records, and as such some sort of search function would be prudent.
Here's what I have so far. This subform is based on the people_has_trips table, and currently is limited to showing existing records. I disabled all fields as not to allow the editing of People records, but I'm somewhat stumped as to how to handle adding more people. In my limited Access knowledge, the most logical solution to me seemed to be having a button to open a form that would allow the searching of People and perhaps the addition of new people.
Now, I have a fully realized form for entering new People (shown below), but it doesn't have any real search functionality besides Access's built-in filters. So my subform currently opens People and... does nothing else. Quite frankly, I have no idea where to go from here. Do I develop a second form for searching people, or do I build in search functionality to the primary People form, something I should probably do anyway? If so, How? And after doing either of those things, how do I then populate people_has_trips? The only answer I can think of involves the user clicking the button to open People, finding the person they want to add, and then manually entering the primary key into the subform, which surely isn't optimal.
The aforementioned People entry form
The solution, I would wager, is VBA commands. I've recently taken the time to learn some VBA, and I'm a bit more comfortable with it, but I just don't know where to begin with this problem. I'm confident that I can adapt and apply other people's VBA ideas and code, but I can't find a thread on this particular issue from which to do that! I'm guessing the reason I can't find any help for this issue is that it's so blatantly obvious that nobody has asked the question yet, or my Google skills are lacking. Either way, I'd be quite happy to facepalm in realization of the solution. Thanks any and all for their help!
You need to be focused on your core problem and as far as I understood, you want to search and add "users/contacts" to your "People on this trip" form.
Yes combo-boxes can eat up time loading 100k rows and it's not really search friendly.
In your "People in this trip" form you can:
have a text box => for search
have a combo-box => showing search result
[Search] [Add] [Clear] buttons
In theory,
search button performs a search on your TContacts table and assigns the results to the combobox. something like SELECT PersonId, FirstName, LastName From Prople WHERE firstName like #keyword OR lastNAme like #keyword ... other fields
User selects a specific result form the combo-box.
Add button then performs SQL operation adding selected user to your junction table and refresh your junction table.
something like: INSERT INTO people_has_trips (people_personId, trips_tripId) values (#selectedPersonId, #tripId); followed by requery
This is just a theory, you need to try out something and narrow it down to a specific problem. Otherwise your question might be marked as too broad.
Related
I am attempting to recreate in MS Access a personal productivity database that I had in Notion (created based on this https://www.youtube.com/watch?v=32dLXdB4ozs). Basically I have a bunch of things (Projects, Meetings, People, Partners (which are orgs), tasks, etc.) and relationships between then. Each project has partners. Each meeting covers certain projects. People work on particular projects and for particular partner organizations, etc. Lots of these relationships are many-to-many.
I've set up most of the back-end stuff: I have a table for each "thing". I also have tables for each many-to-many relationship. So for example I have a People by Partners table to show which people work for which partners, a Projects by People table to show which people work on which projects. A Meetings by Projects table for which meetings are about which project...etc. etc. i have made each field in this a linked relationship to the other two forms. So for example, the projects by people table has a project field linked to the project page and a people field linked to the people table. I've set all of these relationships to have data integrity and to do cascading updates.
Now I'm creating the more interface-like part, which will be used both for viewing and entering data. So I'm starting with a project form. In the project form, I'm putting a sub-form that will list the partners on that project. I created that form based on this video (https://www.youtube.com/watch?v=N46mgIqLXbA&t=0s) which you probably can't see, but the basic idea is that it's a combo box with the record pulled from the partner table and then the update linked to the partner by project table. I have set this to pick from a list since there are a limited number of partners.
Ok, now here's where I'm running into a problem:
I want to set this so that if I enter a partner name not already on the partner list, it gives me the option to add it as new. I've set it up using this code: http://msaccessgurus.com/VBA/Code/Combo_NotInList.htm . T
he code works fine (* sort of, see next para) if I do it directly to update one of the original tables (e.g. Partners), but I need it to update the Partners by Projects table.. I need it to put in the new Partner name, link it to the currently-viewed project, and then from there update the Partners table (which I thought would happen with the cascading updates).
Instead if I enter info not on the list, it asks me if I want to add it and then when I say yes, nothing happens. It doesn't add. In the form field, it shows me the dropdown list of existing partners to pick from. It tells me there's a syntax error and the error seems to be somewhere in the error proc.
How do I get this set up so I can enter the names of new partners and it will appear correctly as added wherever it should appear? Obviously the partners/projects is just one case where I will need to do this, so i need to figure this out or the whole system can't work!
Thank you for any help. Please note: I am not a professional (or even particularly skilled) programmer. My job is something else entirely and I am a muddling amateur with a basic understanding of programming and database concepts and some minor experience with other programming languages, but absolutely nothing with vb.
I am currently working on a project for myself and I'm creating a database for an Institute that helps students prepare for grade 12. I have thought about this topic for quite a while and did not have any efficient solution. However, I think if I added a field like "Entered by" in each table, it's datatype will be Lookup wizard. I will take the list from an admin table.
Look here for image
However this does not seem to be efficient since other users might be able to infiltrate the tables and change data. My apologies for my English and any lack of basic knowledge in access. I'm still a student.
Well, I found an answer, you just need to do it in a form. Have the login form opened and connect its value to where you need. For example, if you need the name of the user in the open login from, you just create an "Entered by" field and make its default value equal to forms!login!username.
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.
currently Im working on a project that, at first glance, will require many tables in a database. Most of the tables are fairly straightforward however I do have an issue. One of the tables will be a list of members for the website, things like username, password, contact info, bio, education, etc will be included. This is a simple design, however, there is also a need for each member to have their availability entered and store in the database as well. Availability is defined as a date and time range. Like available on 4/5/2011 from 1pm to 6pm EST, or NOT available every friday after 8pm EST. For a single user, this could be a table on its own, but for many users, Im not sure how to go about organizing the data in a manageable fashion. First thought would be to have code to create a table for each user, but that could mean alot of tables in the database in addition to the few I have for other site functions. Logically i could use the username appended to Avail_ or something for the table name ie: Avail_UserBob and then query that as needed. But im curious if anyone can think of a better option than having the potential of hundreds of tables in a single database.
edit
So general agreement would be to have a table for members, unique key being ID for instance. Then have a second table for availability (date, start time, end time, boolean for available or not, and id of member this applies to). Django might sound nice and work well, but i dont have the time to spend learning another framework while working on this project. The 2 table method seems plausable but Im worried about the extra coding required for features that will utilize the availability times to A) build a calender like page to add, edit, or remove entered values, and B) match availabilities with entries from another table that lists games. While I might have more coding, I can live with that as long as the database is sound, functional, and not so messy. Thanks for the input guys.
Not to sound like a troll, but you should take a look into using a web framework to build most of this for you. I'd suggest taking a look at Django. With it you can define the type of fields you wish to store (and how they relate) and Django builds all the SQL statements to make it so. You get a nice admin interface for free so staff can login and add/edit/etc.
You also don't have to worry about building the login/auth/change password, etc. forms. all that session stuff is taken care of by Django. You get to focus on what makes your project/app unique.
And it allow you to build your project really, really fast.
djangoproject.org
I don't have any other framework suggestions that meet your needs. I do... but I think Django will fit the bill.
Create a table to store users. Use its primary key as foreign key in other tables.
The databases are written to hold many many rows in a table. There are not optimized for table creation. So it is not a good idea to create a new table for each user. Instead give each user an unique identifier and put the availability in a separate table. Provide an additional flag to make an entry valid or invalid.
Create a table of users; then create a table of availabilities per user. Don't try to cram availabilities into the user table: that will guarantee giant grief for you later on; and you'll find you have to create an availabilities table then.
Google database normalization to get an idea why.
Take it as truth from one who has suffered such self-inflicted grief :-)
I'm writing a CMS for various forms and such, and I find I'm creating a lot of drop-downs. I don't really feel like mucking up my database with tons of random key/string value tables for simple drop-downs with 2-4 options that change very infrequently. What do you do to manage this in a responsible way?
This is language-agnostic, but I'm working in Rails, if anyone has specific advice.
We put everything into a single LookUp table in the database, with a column that mapped to an enum that described which lookup it was for (title, country, etc.).
This enabled us to add the flexibility of an "Other, please specify" option in lookup dropdowns. We made a control that encapsulated this, with a property to turn this behaviour on or off on a case-by-case basis.
If the end user picked "Other, please specify", a textbox would appear for them to enter their own value. This would be added to the lookup table, but flagged as an ad hoc item.
The table contained a flag denoting the status of each lookup value: Active, Inactive, AdHoc. Only Active ones would appear in the dropdown; AdHoc ones were those created via the "Other, please specify" option.
An admin page showed the frequency of usage of the AdHoc values, allowing the administrators of the site to promote common popular values into general usage (i.e. changing their Status flag to Active).
This may well be overkill for your app, but it worked really well for ours: the app was basically almost entirely CRUD operations on very business-specific data. We had dozens of lookups throughout the site that the customer wanted to be able to maintain themselves. This gave them total flexibility with no intervention from us.
You cold have one single dropdown table with an extra column to say what the drop down is for... limit the results with a where clause...
At my current position, we implemented a LookupCode table that contains a CodeGroup,Code, and Meaning column, as well as some others (like active). That way you have a single table that contains all of your lookup values are in a single location and you can do some quick lookups to bind to your dropdown lists.