Multiple Disjunctive Conditions for MS Access Subforms - ms-access

In configuring a MS Access subform, you can link master fields in the parent form to child fields in the child form. You can also have multiple links, but multiple links are conjunctive, e.g. having 2 links results in only rows that satisfy both link 1 and link 2.
I'm trying to have multiple disjunctive links (link 1 or link 2).
To provide more context, I have a table that expresses relationships between two objects so it includes two foreign keys referring to the same table. In the subform, I want to include rows in which the object's ID matches either foreign keys.

That is not possible.
Regard the Master/Child link fields as a filter or an inner join.

As others have mentioned, it is not possible to use MS Access' very basic linking system to do anything more than inner joins. However, I managed to figure out a simple workaround: using the parent form's Current event to update the subform's RecordSource.
This solution is a general one that can be used for subforms that have a more complex relationship with the parent form:
Private Sub Form_Current()
Dim sql as String
'This is the SQL statement for my situation, but you can write anything.
sql = "SELECT * FROM SourceTable WHERE fk1 = " & Me![ID] & " OR fk2 = " & Me![ID]
SubformName.Form.RecordSource = sql
End Sub

Related

Data entry form/subform in a Many-to-Many relationship

I have an Access database with a many-to-many relation. The origin table is called Property and the destination table is called Person. A property can have more than one owner, and a person can own more than one property. I created a join table to accommodate this M-M relationship.
Here is the relationship layout:
In order to fill these tables, I created a form for Property with a subform for the Person table. I followed several articles and posts to implement the needed functionality. They are here, here, here and here.
Here is the form:
The PersonName is a combo box with its row source set to the following SQL query:
SELECT Person.idPerson, Person.PersonName FROM Person;
The column count is set to 2 and the width is set to 0cm;1cm
The VBA code I used for the NoInList event of the combo box is:
Private Sub PersonName_NotInList(NewData As String, Response As Integer)
strSQL = "INSERT INTO Person([PersonName]) " & _
"VALUES ('" & NewData & "');"
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
MsgBox "The new person has been added to the list." _
, vbInformation, "Data Entry"
Response = acDataErrAdded
End Sub
Everything is working fine so far but I'm faced with the case where two persons have the same name. The form won't allow this as every time you type a name that is already in the table, predictably you get the existing values associated with this person. Creating a new entry in the Person table makes this entry visible in the form's combo box, but I don't want the data entry user to edit the tables.
How can I implement the functionality to create a new entry in the Person table from the form, while asking the user to confirm the new entry?
P.S. I know the question title doesn't specifically reflect the content, but I couldn't find a better wording for it.
Edit: To keep the question simple, I trimmed down the fields in the tables. There are additional attributes like date of birth that can possibly differentiate between two persons with the same name.
A recommended approach is to popup a form to add the new person to the person table. Your immediate problem of not being able to add the person is probably because you have the [PersonName] field either set as the primary key in the person table or you have that field set as an index duplicates not allowed.
I recommend that you consider looking up information on data normalization. This will help with understanding Primary and Foreign Keys.
I had a similar problem recently. I second the suggestion with the popup form. My problem seems to be similar to the problem you have. Access doesn't like adding things on the one side of a relationship when the many side already has entries.
To second what acr_scout has said: You can simply add a button on your form that opens another form.
Create a form that allows you to enter new persons to the persons table.
In design view of your original form, add a button. In Access 2016, this should just be the one just called "button" (there are other buttons) Access will then start a wizard, and there is an option to select the on-click procedure that opens a form of your choosing.
I just tried it out, it worked flawlessly and no VBA coding was necessary. You can also create a toggle button and add custom OnClick procedure yourself, if you so choose.
Another, less elegant approach might be to include a subform for the persons table in your original form.
EDIT: For what you are doing, no vba code should be ncessary, if I understood your problem correctly. Dr. Gerard Verschuuren has a great tutorial on YouTube, which helped me greatly when creating many-to-many forms.

How a user can pick up several records in a table

I apologize for probably silly question, but I've already dont know which words to use for searching what i need. I have the good programming experience but am pretty new to Access.
I have a form with the controls, also it has a subform with read-only list of people contacts. This list is populated by a dynamic query from multiple tables, so i don't know in design-time the count and names of all fields. The user wants to be able to manually pick up several contacts from the list to send them a single e-mail.
I used to a table control allows user to select multiple records (usually with ctrl). But it turned out that in Access datasheet the continuous selection is only allowed.
Then I thought of adding editable checkbox column to a readonly table, where the user would be able to mark the desired rows. But I have not found a way how to do this in Access. It seems that the method Append in Fields collection is available only for tables and indexes, but not for queries or recordsets.
I have also read advice to get rid of the subform, and display data in listbox with property multiselect = extended. But in this case, the user will lose the benefits of the table: he can't move and resize columns, sort and filter data.
I have a feeling that the decision should be very simple, I just do not know the conventional way of how to implement this functionality in Access. Help me please.
This is doable by utilizing the RecordsetClone property of the sub form. Here is an example:
Sub GetSelectedValue()
Dim rs as Recordset
Dim sContact as String
Set rs = Me.[SubFormName Goes Here].Form.RecordsetClone
rs.MoveFirst
rs.Move Me.[SubFormName Goes Here].Form.SelTop - 1
sContact = rs![Recordset Column Name Goes Here]
Set rs = Nothing
End Sub
You can put this on the main form via a button control that takes the active row contact and places that name into a listbox on your main form. Once the user has made all their choices, you can then run your e-mail program off the names within the listbox.
If you want a datasheet (for filter, sort, resize), then an editable checkbox is really your only option.
The column can be part of the original table, or create a join table with ID and check column, where you add the IDs from all records of your base table.
In the subform you can set all controls except the checkbox to Locked = True.

Access VBA - Help designing a Join form

I have a JoinTable, Table1 and Table2. Here is design (example):
JoinTable:
IDx
IDy
Table1:
IDx
Names
Surnames
Table2:
IDy
Address
City
Now, I will create a form, which will have a Recordsource of JoinTable. In this form I will have 2 combobox-es, from which I will select records from Table1 or Table2. Based on combobox selection (that's IDx or IDy), I want to see field values from related table....Example:
If I select from combobox IDx, I want to see in continuos form field values from Table2 under same record (which are joined in JoinTable).
I have managed to do this with subforms, but I have a lot of records that are joined in JoinTable under same ID's, so listing through subforms is not nice when there is a lot of matches, because subform's don't maximize when form is maximized (I tried this too with Iszoommed API, but It's still not good - screen flashes because of scrollbars appearing/dissapearing).
Does anybody have any idea on how I could navigate through records of both tables within same form, and without subforms so that I can maximize form and see all related records easily ?
You do this in Access using sub-forms.
As for design issues, you could maybe use other code (I found some nice ideas googling ms access subform auto resize), but the flashes would probably stay there: Access, as all Office applications, does not support multi-threading, OS will have to halt GUI process in order to allow other processes run, and user sees 'flashes'.
I have solved It. What you must do is a little hard to explain, but in general:
When you create a form that has recordsource from JoinTable - you have to build a recordsource query that contains both ID's from your JoinTable and then all other fields from related tables that you desire to have a look to.
On this form you add fields from those 2 tables that are linked in JoinTable. If desired you can hide/unhide those fields based on what search you would like to do (via combobox for each table or something else).
Then you have to VBA code It, my solution is like this - I have put 2 option buttons on form. When one of them is selected, a combobox is shown and fields from table that will be searched (other combobox and fields from other table are hidden at that time). Code goes something like this (for upper example):
Dim SQL As String
SQL = "SELECT JoinTable.IDx, JoinTable.IDy, Table1.Names, Table1.Surnames" & _
" FROM Table1 INNER JOIN JoinTable ON Table1.[IDx] = JoinTable.[IDx] " & _
" WHERE JoinTable.IDx=" & Me.MyCombo
If IsNull(MyCombo) = True Then
Me.RecordSource = ""
Else
Me.RecordSource = SQL
End If
Put this code in Combobox_After_Update and in Click_Event of Option buttons, and that's It. Now you can navigate through related (joined) records within one form with fields from related tables, using ID's of JoinTable and related tables and without subforms so you can maximize your form as you wish.

MS Access 2010: How Can I Avoid Uneditable Query Results?

I am working on my first Access 2010 database and have run into a problem editing the recordset returned from a query. This excellent blog entry details several scenarios which can result in uneditable query results. I believe my query results are not editable because my query has a Cartesian Join.
I'm not sure how to avoid this, however. The three tables involved are:
episodes
Individual television episodes
Primary key: "episode_id"
aridates
Individual airdates for a given episode
Primary key: "airdate_id"
Related to "episodes" by "airdate_episode_id"
startdates
Individual download start-dates for a given episode
i.e. when a given episode will be available to download
Primary key: "startdate_id"
Related to "episodes" by "startdate_episode_id"
So, there is no (and I think can be no) direct relationship between airdates and startdates. However, this makes the query:
SELECT episodes.episode_id, episodes.episode_number, episodes.episode_title, airdates.airdate_region_id, airdates.airdate_date
FROM (episodes LEFT JOIN airdates ON episodes.episode_id = airdates.airdate_episode_id) LEFT JOIN startdates ON episodes.episode_id = startdates.startdate_episode_id;
return a recordset which is not editable. I need to be able to see the episode name and number along with the airdate in order to enter a startdate (episodes can not be made available for download before they have aired). So essentially, in this view I only need to be able to edit "startdates.stardate_date".
Thanks in advance for any suggestions... a screenshot of the relationship in question can be seen here.
Create this query:
SELECT
episodes.episode_id,
episodes.episode_number,
episodes.episode_title,
airdates.airdate_region_id,
airdates.airdate_date
FROM
episodes LEFT JOIN airdates
ON episodes.episode_id = airdates.airdate_episode_id;
Use it as the recordsource for a new form. Then create another form which uses a query of only the startdates table as its record source.
Add the second form as a subform to the first form. On the property sheet for the subform control, make the link master field episode_id and the link child field startdate_episode_id.
If you are successful, the subform will display startdates rows where the startdate_episode_id matches the episode_id of the main form's current record. And if you add a new row in the subform, its startdate_episode_id will "inherit" the episode_id from the main form.
I emphasized control earlier because that point can be confusing. The subform control is a member of the main form's controls collection, and the subform control contains the subform. You must find the link master/child field properties on the subform control, not the actual subform itself.

Subforms integration not working seamlessly in Ms Access 2010

I have a form in MS Access 2010 with two sub forms in it. I've defined one-to-one relationship with the tables behind the forms. Both the sub-forms should be used to create a record in corresponding tables and then update the foreign key in the parent form. But when I fill the sub-form first, an entry is created in the corresponding table but the foreign key doesn't get updated. Shouldn't this happen automatically? Or should I add code for updating parent form's field?
Also when I start filling the main form first and then jump to any of the sub-form, I get the following error message:
"You must enter a value in the 'Activations.dbBoxID' field" (Activations is the main form here and dbBoxID is the foreign key field.)
Another issue is that I don't want sub-forms to update the corresponding tables until an entry in main table is also created (i.e. all required fields in main form are also filled).
I am new to MS Access. Any help would be really appreciated!
The concept you are missing here, and what's not being explained to you is that when you build a master to child relationship in access, you can model these relationships with forms and a sub form, but you base the forms on the actual tables and not queries that are an result of joining those tables together.
In other words, your master form should be based on the main or parent table. DO NOT join in the child table. I'm going to repeat this again: do not join in the child table.
So you can base the master or main form on a query, but when you do so, do not join in the child table in that query. In fact, in most cases there is really no advantage to using and basing a form on a query anyway. Simply create the form, and base it on the table.
The SAME ADVICE applies for the child form. You base the child form on the child table. You DO NOT use a query with a join.
The reason why you're getting error messages is because you have a query for the main form that is based on two tables. With an enforced relationship, when your focus switches from the main form to the child form, a record save of the main form occurs, and thus you're getting the error message.
So your error and problem is due to you basing a form on a query that is a join of two tables when it is not needed in this case.
A form with subforms works better if the data in the parent form are entered first. Then the subforms can be joined on the parent_key to foreign_key in each table without any code.
If you want to let users enter records in subforms first, don't update them until the parent form is completed/saved, you're going to need to do some coding. Not sure why you need/want to do that?
A client form with bills and payments subforms, for example you would enter enough client data to create a record. Then bills and/or payments can then be entered.