How can I make new records cascade across a one to one relationship in MS Access?

夙愿已清 提交于 2020-01-07 06:42:39

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!