Как обновить несколько записей подчиненной формы линейным образом из основной формы? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть текстовое поле даты в основной форме, которое выводит 6 последовательных дат (интервалы 2 недели) в подчиненной форме. Подформа заполняется этими датами как часть события AfterInsert() основной формы.

Private Sub Form_AfterInsert()
    Dim strSQL As String
    Dim i As Integer
    For i = 2 To 12 Step 2
        strSQL = "INSERT INTO tbl_Date (DateDescriptionID, TestDate) "
        strSQL = strSQL & "SELECT " & Me.tbDescriptionID & ", (DateAdd('ww', " & i & ", #" & Me.tbStartDate & "#));"
        CurrentDb.Execute strSQL, dbFailOnError
    Next i
End Sub

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

Private Sub tbStartDate_AfterUpdate()
    Dim strSQL As String
    strSQL = "UPDATE tbl_Date "
    strSQL = strSQL & "SET [TestDate] = NULL "
    strSQL = strSQL & "WHERE [DateDescriptionID] = " & Me.DescriptionID & ";"
    CurrentDb.Execute strSQL, dbFailOnError
End Sub

Пользователь вводит 05/01/2018

Date           Data
05/15/2018     Apple
05/29/2018     Banana
06/12/2018     Orange
06/26/2018     Strawberry
07/10/2018     Pineapple
07/24/2018     Peach

Пользователь изменяет запись на 06/30/2018

Date           Data
07/14/2018     Apple
07/28/2018     Banana
08/11/2018     Orange
08/25/2018     Strawberry
09/08/2018     Pineapple
09/22/2018     Peach

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

Пропустить все компоненты SQL и использовать DAO и recordsetclone - намного чище, быстрее и с автоматическим обновлением:

Private Sub Form_AfterInsert()

    Dim rs As DAO.Recordset
    Dim i As Integer

    Set rs = Me!NameOfYourSubformCONTROL.Form.RecordsetClone
    For i = 2 To 12 Step 2
        rs.AddNew
            rs!DateDescriptionID.Value = Me!tbDescriptionID.Value
            rs!TestDate.Value = DateAdd("ww", i, Me!tbStartDate.Value)
        rs.Update
    Next i
    rs.Close

End Sub

и

Private Sub tbStartDate_AfterUpdate()

    Dim rs As DAO.Recordset
    Dim i As Integer

    Set rs = Me!NameOfYourSubformCONTROL.Form.RecordsetClone

    rs.MoveFirst
    While Not rs.EOF
        i = i + 2
        rs.Edit
           rs!TestDate.Value = DateAdd("ww", i, Me!tbStartDate.Value)
        rs.Update
        rs.MoveNext
    Wend        
    rs.Close

End Sub
0 голосов
/ 31 августа 2018

Я иду за SQL:

Я предполагаю таблицу с именем tblData с полями ID (PK, Autoincrement), Data (Text) и Sort (Long)

ID     Data        Sort
1     Apple          3
2     Banana         5
3     Orange         2
4     Strawberry     1
5     Pineapple      4
6     Peach          6

Запрос:

SELECT Data, DateAdd("ww", 2 * Sort, Forms!ParentForm!txtDate) as ComputedDate FROM tblData Order By Sort;

Используйте это как источник записей для подчиненной формы. Если txtDate хранится в таблице, вы можете присоединиться или посмотреть. Только одна Дата хранится всегда в актуальном состоянии.

0 голосов
/ 30 августа 2018

Рассмотрите возможность использования коррелированного подзапроса, но поскольку MS Access допускает только обновляемые запросы для операторов UPDATE, используйте совокупность доменов DCount. Кроме того, рассмотрим параметризацию , чтобы четко отделить код SQL от значений данных VBA.

В частности, DCount создает порядок ранга в столбце TestDate , а затем умножает каждое на 14, желаемую длительность интервала дней (например, 1 * 14, 2 * 14, 3 * 14) , Для этого решения петли не нужны.

SQL (сохранить как сохраненный запрос доступа)

PARAMETERS [DescIDParam] Long;
UPDATE tbl_Date t
SET t.[TestDate] = DCount("*", "tbl_Date", "TestDate <= #" & t.[TestDate] & "#") * 14, t.[TestDate])
WHERE t.[DateDescriptionID] = [DescIDParam]

1020 * VBA *

Private Sub tbStartDate_AfterUpdate()
    Dim qdef As QueryDef

    Set qdef = CurrentDb.QueryDefs("mySavedUpdateQuery")

    ' BIND VALUE TO PARAMETER
    qdef![DescIDParam] = Me.tbDescriptionID

    ' EXECUTE ACTION
    qdef.Execute dbFailOnError

    Set qdef = Nothing
End Sub
...