Несколько замечаний, ни одно из которых не является ответом на ваш вопрос, но может указать вам правильное направление:
Измените свои тесты для пустого набора записей / когда прекратить цикл.
Заменить этот код:
If Not rs.EOF Then
rs.MoveFirst
Do While Not rs.EOF And Not rs.BOF
[...]
rs.MoveNext
... с этим:
If rs.RecordCount<> 0
rs.MoveFirst
Do While Not rs.EOF
[...]
rs.MoveNext
Изменить способ использования второго набора записей.
Не открывайте его один раз для каждой строки, отфильтрованной для этой строки, но открывайте его без фильтрации и сортируйте по значению, по которому вы ранее фильтровали, и используйте FindFirst для навигации по нему:
Set rs = CurrentDb.OpenRecordset("SELECT * FROM DailySummaryMain")
Set rs2 = CurrentDb.OpenRecordset("SELECT dbo_StatusType.StatusTypeID, dbo_StatusType.Name FROM dbo_StatusType ORDER BY dbo_StatusType.StatusTypeID")
[...]
rs2.FindFirst "[StatusTypeID]=" & rs.Fields(3)
... Или сделать второй набор записей устаревшим.
Лучше, но, похоже, здесь есть одно совпадение значений, поскольку rs2 никогда не перемещается после первого совпадения, так почему бы не посмотреть, можно ли изменить сохраненный QueryDef "DailySummaryMain", чтобы присоединиться к dbo_StatusType, чтобы значение было прямо в одном наборе записей? Тогда вам вообще не понадобится rs2.
Обычно довольно неразумно ссылаться на поля по порядковому номеру.
Слишком легко полностью объединить вашу подпрограмму, добавив новое поле в исходную инструкцию SELECT в любом месте, кроме конца инструкции SELECT. Итак, измените порядковые номера на фактические имена полей, чтобы rs (0) стал rs («NameOfFirstField»).
Используйте SELECT CASE вместо цепочки If / Then / ElseIf / Else.
Изменить этот код:
If CInt(rs.Fields(2).Value) = 1 Then
row = row1
ElseIf CInt(rs.Fields(2).Value) = 2 Then
row = row2
ElseIf CInt(rs.Fields(2).Value) = 3 Then
row = row3
Else
row = row4
End If
... на это:
Select Case rs.Fields(2)
Case 1
row = row1
Case 2
row = row2
Case 3
row = row3
Case 4
row = row4
End Select
Или, поскольку все значения, кроме одного, могут быть построены из значения, выполните следующее:
If rs.Fields(2) = 4 Then
row = row4
Else
row = Eval("row" & rs.Fields(2))
End If
Контекст не совсем понятен (смысл элементов row и rowN неясен - являются ли они переменными какого-то рода?), Так что, возможно, последний не сработает (Eval () не всегда работать в том случае, если кажется, что так и должно), поэтому я бы, вероятно, пошел с SELECT CASE.
Excel может понадобиться. Значение, но Access нет.
Изменить это:
xlapp.Range("A" & i).Value = rs.Fields(0).Value
... на это:
xlapp.Range("A" & i).Value = rs.Fields(0)
Вам может и не понадобиться эта часть уравнения в Excel.