Как я могу сделать новые записи каскадными по отношению один к одному в MS Access? - PullRequest
0 голосов
/ 02 февраля 2012

В настоящее время у меня есть отношение один к одному между двумя таблицами в MS Access, например:

Результаты студента

  • StudentResultsID (первичный ключ, автономный номер)
  • Различные поля, относящиеся к курсу.

Данные AVETMISS

  • StudentResultsID (первичный ключ, длинное целое)
  • Различные поля, относящиеся к конкретной бумажной форме, которую студент должен заполнять для каждого зачисления.

Когда пользователь добавляет новую запись в результаты для учащихся (это происходит каждый раз, когда студент зачисляется на курс), я хочу создать соответствующую запись в данных AVETMISS. Я думал, что это была функция создания отношений и обеспечения ссылочной целостности, однако даже при включенной опции я продолжаю получать несоответствия.

Если есть способ сделать это при настройке таблиц (или запросов) и отношений, которые были бы моим предпочтительным решением.

Если это невозможно, одно из решений, которое, как мне кажется, сработало бы, но гораздо менее идеально, - это настроить форму для AVETMISS Data для запуска некоторого кода или макроса при его открытии.

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

РЕДАКТИРОВАТЬ: Мне пришло в голову, что свойство «После вставки» в форме «Результаты для учащихся» может быть лучшим кандидатом для такого решения.

Если мне нужно прибегнуть к этому решению, я был бы очень признателен за это, поскольку почти ничего не знаю о Visual Basic и не хочу изучать его для трехстрочного фрагмента кода.

Пожалуйста, обратите внимание - во время моего исследования я обнаружил, что многие люди подвергают сомнению обоснованность использования отношений один к одному. Я прочитал аргументы против использования этих отношений, и я уверен, что это совершенно необходимо для моей ситуации.

Ответы [ 2 ]

3 голосов
/ 02 февраля 2012

Исходя из вашего описания, я думаю, что вы сможете решить эту проблему без кода.

Создайте форму, основанную на результатах учащихся, и вторую форму, основанную на данных AVETMISS. Затем добавьте эту вторую форму в элемент управления подчиненной формы в первой форме. Задайте для свойства master / child ссылки значение StudentResultsID.

В представлении формы подчиненная форма должна отображать строку данных AVETMISS, у которой StudentResultsID совпадает с текущей строкой, отображаемой в родительской форме.

Если для текущей родительской формы StudentResultsID не найдено ни одного соответствия подчиненной формы, его можно добавить, введя значение в любой другой доступный элемент управления данными, связанный с подчиненной формой (кроме StudentResultsID). При сохранении эта новая запись будет иметь такой же StudentResultsID, что и текущая строка родительской формы.

Свойство master / child ссылки гарантирует, что дочернее поле link (StudentResultsID) «наследует» значение мастер-поля.

1 голос
/ 02 февраля 2012

Создайте VUEW (называемый объектом запроса в пользовательском интерфейсе Access): INNER JOIN две таблицы в атрибуте StudentResultsID. Затем вставьте в VIEW вместо базовых таблиц. Сгенерированное значение автонумерации будет автоматически скопировано в ссылочную таблицу (хотя вам не нужен внешний ключ между таблицами, чтобы он работал, вы все равно должны иметь его).

Вот краткое «доказательство концепции» в VBA (но «решением» является чистый SQL): создается новый файл данных во временной папке с таблицами и примерами данных. Ссылки не требуются, просто скопируйте + вставьте в любой модуль VBA, например. использовать 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
...