问题
I currently have a one to one relationship between two tables in MS Access like so:
Student Results
- StudentResultsID (primary key, autonumber)
- Various fields relating to the course.
AVETMISS Data
- StudentResultsID (primary key, long integer)
- Various fields relating to a specific, paper form that must be filled out by the student for each enrolment.
When the user adds a new record to Student Results (this occurs everytime a student is enrolled into a course) I want to create a matching record in AVETMISS Data. I thought this was a function of creating the relationship and enforcing referential integrity, however even with this option turned on I keep getting inconsistencies.
If there is a way to make this happen in the setup of the tables (or queries) and the relationship that would be my preferred solution.
If this is not possible, one solution that I think would work, but is much less ideal, is to rig the form for AVETMISS Data to run some code or macro when it is opened.
Something like this in the On Load property:
Does this StudentResultsID exist in AVETMISS Data?
Yes - Do nothing
No - Create new record with this StudentResultsID
EDIT: It's occured to me that the 'After Insert' property in the Student Results form may be a better candidate for this kind of solution.
If I must resort to this solution I would really appreciate some guidance in this as I know next to nothing about Visual Basic and don't want to learn it for a 3-line snippet of code.
Please note - During my research I found a lot of people questioning the reasoning behind using a one to one relationship. I have read the arguments against using these relationships and I am certain that it is completely necessary for my situation.
回答1:
Based on your description, I think you may be able to solve this with no code.
Create a form based on Student Results and a second form based on AVETMISS Data. Then add that second form to a subform control on the first form. Set the link master/child property to StudentResultsID.
When in form view, the subform should display the AVETMISS Data row whose StudentResultsID matches the current row displayed in the parent form.
If no subform match exists for the current parent form StudentResultsID, you can add one by typing a value into any other the available subform bound data controls (other than StudentResultsID). When saved, that new record will have the same StudentResultsID as the parent form current row.
The link master/child property ensures the child link field (StudentResultsID) "inherits" the master field value.
回答2:
Create a VUEW
(called a 'query' object in the Access UI): INNER JOIN
the two tables on the StudentResultsID
attribute. Then insert into the VIEW
rather than the base tables. The generated autonumber value will be automatically copied to the referencing table (although you don't need a foreign key between the tables for this to work, you should have one anyhow).
Here's a quick 'proof of concept' in VBA (but the 'solution' is pure SQL): creates a new data file in temp folder, with tables and sample data. No references required, simply copy+paste into any VBA module e.g. use Excel:
Sub TargetTheView()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = _
"CREATE TABLE StudentResults (" & _
"StudentResultsID INTEGER IDENTITY NOT NULL PRIMARY KEY, " & _
"StudentResultsData VARCHAR(30) WITH COMPRESSION NOT NULL);"
.Execute Sql
Sql = _
"CREATE TABLE AVETMISS (" & _
"StudentResultsID INTEGER NOT NULL PRIMARY KEY " & _
" REFERENCES StudentResults, " & _
"AVETMISSData DECIMAL(6, 3) NOT NULL);"
.Execute Sql
Sql = _
"CREATE VIEW v_AVETMISSStudentResults AS " & _
"SELECT S.StudentResultsID, S.StudentResultsData, " & _
" A.StudentResultsID AS StudentResultsID_A, " & _
" A.AVETMISSData " & _
" FROM StudentResults AS S " & _
" INNER JOIN AVETMISS AS A " & _
" ON S.StudentResultsID = A.StudentResultsID;"
.Execute Sql
Sql = _
"INSERT INTO v_AVETMISSStudentResults " & _
" (StudentResultsData, AVETMISSData) " & _
" VALUES ('One point one', 1.1); "
.Execute Sql
Sql = _
"INSERT INTO v_AVETMISSStudentResults " & _
" (StudentResultsData, AVETMISSData) " & _
" VALUES ('two point two', 2.2); "
.Execute Sql
Sql = _
"INSERT INTO v_AVETMISSStudentResults " & _
" (StudentResultsData, AVETMISSData) " & _
" VALUES ('three point three', 3.3); "
.Execute Sql
Sql = "SELECT * FROM v_AVETMISSStudentResults;"
Dim rs
Set rs = .Execute(Sql)
MsgBox rs.GetString
End With
Set .ActiveConnection = Nothing
End With
End Sub
来源:https://stackoverflow.com/questions/9106974/how-can-i-make-new-records-cascade-across-a-one-to-one-relationship-in-ms-access