Патрик Кафф предложил эту функцию:
Function RowsChanged(updateQuery As String) As Long
Dim qry As QueryDef
Set qry = CurrentDb.QueryDefs(updateQuery)
qry.Execute
RowsChanged = qry.RecordsAffected
End Function
Я не понимаю, почему возникнет проблема с назначением переменной QueryDef для выполнения запроса, когда это можно сделать непосредственно CurrentDB.Execute без инициализации (или очистки) каких-либо объектных переменных.
Очевидно, что при запросе параметров необходимо использовать подход QueryDef, поскольку вы должны назначить значения параметрам перед его выполнением. Но без параметров нет причин делать это более сложным, чем необходимо. Такая общая функция, которая не настроена на обработку запросов параметров, кажется неправильно спроектированной.
И, конечно, следует также использовать dbFailOnError, чтобы вы не получили неожиданных результатов (dbFailOnError работает с QueryDef.Execute, так же, как и с CurrentDB.Execute). В этом случае действительно должен быть обработчик ошибок.
Вместо того, чтобы писать обработчик ошибок каждый раз, когда вы выполняете SQL, вы можете сделать это вместо этого. Следующая функция возвращает RecordsActed и будет корректно восстанавливаться после ошибок:
Public Function SQLRun(strSQL As String) As Long
On Error GoTo errHandler
Static db As DAO.Database
If db Is Nothing Then
Set db = CurrentDB
End If
db.Execute strSQL, dbFailOnError
SQLRun = db.RecordsAffected
exitRoutine:
Exit Function
errHandler:
MsgBox Err.Number & ": " & Err.Description, vbExclamation, "Error in SQLRun()"
Resume exitRoutine
End Function
Его также можно использовать для замены DoCmd.RunSQL (вы просто вызываете его и игнорируете возвращаемое значение). Фактически эта функция была полностью разработана для использования в качестве глобальной замены DoCmd.RunSQL.