
У меня почти получилось. Думаю, мне просто нужна еще одна пара глаз на это. Думаю, моя проблема — это просто проблема структуры программирования. Либо слишком много циклов, либо открытие/закрытие наборов записей в неправильном порядке.
Я пытаюсь скопировать все файлы вложений, содержащиеся в записях из одного набора записей dao, в соответствующие записи в другом наборе записей dao. Оба набора записей извлекают данные из одной и той же таблицы. Первый набор записей (rstOld) содержит записи со значением даты за прошлый год, и эти записи могут содержать любое количество вложений. Второй набор записей (rstNew) содержит записи со значением даты за этот год, и эти записи не содержат никаких вложений.
Для этого я запускаю цикл по каждой записи в rstNew. Для каждой записи в rstNew я соберу значение поля Name и затем запущу второй цикл. Второй цикл найдет запись в rstOld с соответствующим полем Name. Оттуда мне просто нужно скопировать все вложения из записи в rstOld в запись в rstNew.
Странно то, что это будет работать правильно на первой первой записи в rstNew, в которой оно найдет совпадение. После этого это больше не будет работать для любых последующих записей.
Вот мой код на данный момент:
Dim db As Database
Dim strOldSQL As String
Dim rstOld As DAO.Recordset2
Dim strNewSQL As String
Dim rstNew As DAO.Recordset2
Dim rstOldAttachments As DAO.Recordset2
Dim rstNewAttachments As DAO.Recordset2
Dim strCurrentSiteName As String
Dim strOldSiteName As String
Set db = CurrentDb()
'First let's open a recordset that contains all of the records from this year.
strNewSQL = "SELECT tblAuditForms.SiteName, tblAuditForms.Attachments, tblAuditForms.AuditYear FROM tblAuditForms WHERE AuditYear = #" & Format(cboMyDate, "mm/dd/yyyy") & "# ORDER By tblAuditForms.SiteName;"
Set rstNew = db.OpenRecordset(strNewSQL)
rstNew.MoveFirst
rstNew.Edit
Do While Not rstNew.EOF 'Now we need to loop through these records.
strCurrentSiteName = rstNew.Fields("SiteName").Value 'Get the name of the site for the current record that we're on. We'll use this to compare with the sites in the previous audit.
'Now let's open a recordset that contains all records from the previous audit.
strOldSQL = "SELECT tblAuditForms.SiteName, tblAuditForms.Attachments, Year([AuditYear]) FROM tblAuditForms WHERE Year([AuditYear]) = " & Me.cboPreviousDate & " ORDER BY tblAuditForms.SiteName;"
Set rstOld = db.OpenRecordset(strOldSQL)
rstOld.MoveFirst
Do While Not rstOld.EOF 'Loop through each of the records from the previous audit until we find a record that matches the current site name.
strOldSiteName = rstOld.Fields("SiteName").Value
If strCurrentSiteName = strOldSiteName Then 'If this is true, then we've found a record from the previous audit that matches the one from our current audit.
'Now it's just a matter of copying the attachments from the old record into the new one. Working with attachments is annoying though.
'This next block should loop through the attachments (if any) in the old record and copy them into the new record.
Set rstOldAttachments = rstOld.Fields("Attachments").Value
rstOldAttachments.MoveFirst
Set rstNewAttachments = rstNew.Fields("Attachments").Value
Do While Not rstOldAttachments.EOF
rstNewAttachments.AddNew
rstNewAttachments.Fields("FileData").Value = rstOldAttachments.Fields("FileData").Value
rstNewAttachments.Fields("FileName").Value = rstOldAttachments.Fields("FileName").Value
rstNewAttachments.Fields("FileType").Value = rstOldAttachments.Fields("FileType").Value
rstNewAttachments.Update
rstOldAttachments.MoveNext
Loop
'Now that we've found the site from the previous audit and copied its attachments into the new record we can close the old recordset and move onto the next site in the current audit.
rstOldAttachments.Close
rstNewAttachments.Close
Exit Do
End If
rstOld.MoveNext
Loop
rstOld.Close
rstNew.Update
rstNew.MoveNext
Loop
'If we've gotten this far then we've looped through all of the new records that we just created from the weekly staffing workbook.
rstNew.Close
Как я уже говорил, этот код будет работать в первом цикле через rstNew recordset, но не будет работать в последующих циклах. Я выхожу из цикла слишком рано? или закрываю recordset слишком рано?
решение1
Я понял это! Я знал, что я был близко. Я узнал, что после выполнения оператора recordset.update (или в моем случае rstNew.update) свойство editmode набора записей возвращается к 0. Это объясняет, почему он успешно копировал вложения в первом цикле, но не копировал в последующих циклах. Поэтому все, что мне нужно было сделать, это переместить оператор "rstNew.Edit" прямо над строкой "Set rstNewAttachments = rstNew.Fields("Attachments").Value".
Вот как выглядит новый код:
Dim db As Database
Dim strOldSQL As String
Dim rstOld As DAO.Recordset2
Dim strNewSQL As String
Dim rstNew As DAO.Recordset2
Dim rstOldAttachments As DAO.Recordset2
Dim rstNewAttachments As DAO.Recordset2
Dim strCurrentSiteName As String
Dim strOldSiteName As String
Set db = CurrentDb()
'First let's open a recordset that contains all of the records from this year.
strNewSQL = "SELECT tblAuditForms.SiteName, tblAuditForms.Attachments, tblAuditForms.AuditYear FROM tblAuditForms WHERE AuditYear = #" & Format(cboMyDate, "mm/dd/yyyy") & "# ORDER By tblAuditForms.SiteName;"
Set rstNew = db.OpenRecordset(strNewSQL)
rstNew.MoveFirst
Do While Not rstNew.EOF 'Now we need to loop through these records.
strCurrentSiteName = rstNew.Fields("SiteName").Value 'Get the name of the site for the current record that we're on. We'll use this to compare with the sites in the previous audit.
'Now let's open a recordset that contains all records from the previous audit.
strOldSQL = "SELECT tblAuditForms.SiteName, tblAuditForms.Attachments, Year([AuditYear]) FROM tblAuditForms WHERE Year([AuditYear]) = " & Me.cboPreviousDate & " ORDER BY tblAuditForms.SiteName;"
Set rstOld = db.OpenRecordset(strOldSQL)
rstOld.MoveFirst
Do While Not rstOld.EOF 'Loop through each of the records from the previous audit until we find a record that matches the current site name.
strOldSiteName = rstOld.Fields("SiteName").Value
If strCurrentSiteName = strOldSiteName Then 'If this is true, then we've found a record from the previous audit that matches the one from our current audit.
'Now it's just a matter of copying the attachments from the old record into the new one. Working with attachments is annoying though.
'This next block should loop through the attachments (if any) in the old record and copy them into the new record.
Set rstOldAttachments = rstOld.Fields("Attachments").Value
rstOldAttachments.MoveFirst
rstNew.Edit
Set rstNewAttachments = rstNew.Fields("Attachments").Value
Do While Not rstOldAttachments.EOF
rstNewAttachments.AddNew
rstNewAttachments.Fields("FileData").Value = rstOldAttachments.Fields("FileData").Value
rstNewAttachments.Fields("FileName").Value = rstOldAttachments.Fields("FileName").Value
rstNewAttachments.Fields("FileType").Value = rstOldAttachments.Fields("FileType").Value
rstNewAttachments.Update
rstOldAttachments.MoveNext
Loop
'Now that we've found the site from the previous audit and copied its attachments into the new record we can close the old recordset and move onto the next site in the current audit.
rstOldAttachments.Close
rstNewAttachments.Close
Exit Do
End If
rstOld.MoveNext
Loop
rstOld.Close
rstNew.Update
rstNew.MoveNext
Loop
'If we've gotten this far then we've looped through all of the new records that we just created from the weekly staffing workbook.
rstNew.Close