Это происходит после замены DAO на ADO в проекте VB6, который использует базу данных Access 97.
Это происходит в строке с пометкой «Ошибка здесь» в следующем фрагменте:
If rset.BOF <> True Or rset.EOF <> True Then
rset.MoveLast
Do While rset.BOF <> True
rset.Delete
If rset.BOF <> True Or rset.EOF <> True Then
rset.MoveLast 'Error Here
End If
Loop
End If
Ошибка времени выполнения «3021» дает это объяснение:
"EOF или BOF - True, или
текущая запись была удалена.
запрашиваемая операция требует тока
запись. "
Похоже, что после удаления последней записи в наборе записей BOF +/- EOF все еще имеет значение false в версии кода ADO, в то время как обе версии имеют значение true в версии DAO.
Если я изменю код таким образом, он будет работать
РЕДАКТИРОВАТЬ: следующий код НЕ работает. Когда я попробовал это «решение» все записи
были уже удалены из таблицы, поэтому весь блок был обойден, и поэтому не было выдано никакой ошибки. Извините за плохую информацию.
If rset.BOF <> True Or rset.EOF <> True Then
rset.MoveLast
Do While rset.BOF <> True
rset.Delete
If rset.BOF <> True Or rset.EOF <> True Then
End If
If rset.BOF <> True Or rset.EOF <> True Then
rset.MoveLast
End If
Loop
End If
Может кто-нибудь объяснить это? (и в идеале предложить решение, которое не требует изменения кода!)
ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: насколько я могу судить, перепробовав множество способов, BOF и EOF бесполезны в ADO для тестирования пустого набора записей после удаления. Это потому, что вам нужно использовать один из методов перемещения для обновления BOF / EOF, и если набор записей пуст, вы получите ошибку. На наборе записей, который я использовал, свойство RecordCount обновлялось после удаления. Хотя я не собираюсь его использовать, этот код сделал работает:
If rset.BOF <> True Or rset.EOF <> True Then
Do While rset.RecordCount > 0
rset.MoveLast
rset.Delete
Loop
End If
Редактировать (1 месяц спустя)
Поэтому после переписывания целой кучи кода я наткнулся на цикл, содержащий удаление, которое не выдает ошибку. Единственное отличие заключалось в том, что этот цикл удалял первую запись в наборе записей каждый раз, а не последнюю, и поэтому после каждого удаления выполнялся
скорее, чем MOVELAST.
Поэтому я максимально сократил код, и следующий фрагмент отлично работает как на Postgresql, так и на Access - двух базах, которые я пробовал, с VB6 с использованием ADO.
Do While rset.EOF <> True
rset.Delete
rset.MoveFirst
Loop
После удаления окончательной записи EOF и BOF по-прежнему остаются ложными, но вы не получите ошибку при вызове метода MOVEFIRST. Вызов MOVEFIRST теперь устанавливает для EOF и BOF значение true, и цикл завершается.
Напротив, если метод MOVEFIRST заменен на MOVELAST, то ошибка (3021) возникает в обеих базах данных.
В своем ответе rskar процитировал это из MSDN
Используйте метод MoveNext для перемещения
текущая позиция записи одна запись
вперед (к нижней части
Recordset). Если последняя запись
текущая запись и вы называете
Метод MoveNext, ADO устанавливает текущий
запись на позицию после последней
запись в наборе записей (EOF - True).
Попытка двигаться вперед, когда
Свойство EOF уже True генерирует
ошибка.
Они упоминают, что MOVENEXT вызывает ошибку, и я полагаю, поскольку MOVELAST движется в том же направлении, это объясняет, почему оно также вызывает ошибку.
Хотелось бы, чтобы я не предполагал, что все методы перемещения приведут к подобным проблемам