ado execute acync?

Ёжик`
Дата: 21.02.2008 22:45:33
MSA2003, ADP, MSSQL2005
Требуется запускать хранимки или батчи в асинхронном режиме, с произвольным таймаутом, ловить ошибки, сообщения и окончание выполнения.
Таймаут задавать умею, в асинхроне вроде запустил, но с последним требованием - облом.
Public Function SpRun2(Str As String)
Dim cnn As New ADODB.Connection
cnn.ConnectionString = CurrentProject.AccessConnection
cnn.CommandTimeout = 900
cnn.Open
'cnn.Execute Str
cnn.Execute Str, , adAsyncExecute 
cnn.Close
Set cnn = Nothing
End Function
бухой бык
Дата: 22.02.2008 10:55:15
Что именно явлеиццо последним? Ловить ошибки, ловить сообщения или окончание выполнения?
Может смотреть в сторону АДОИветс (willEvent) ?
Ёжик`
Дата: 22.02.2008 11:02:10
бухой бык
Что именно явлеиццо последним? Ловить ошибки, ловить сообщения или окончание выполнения?
Может смотреть в сторону АДОИветс (willEvent) ?

Ловить и ошибки, сообщения, окончание выполнения

Примеры АДОИветс есть?
Ёжик`
Дата: 22.02.2008 11:03:58
Поймать окончание удалось:
Public Function SpRun3(Str As String)
On Error GoTo er

Dim cnn As New ADODB.Connection, mNow As Date

mNow = Now()

cnn.ConnectionString = CurrentProject.AccessConnection
cnn.CommandTimeout = 900
cnn.Open
cnn.Execute Str, , adAsyncExecute

Do Until cnn.State = 1
    DoEvents
Loop

cnn.Close
Set cnn = Nothing

Debug.Print Format(Now() - mNow, "d дней, hh часов, nn минут, ss секунд") & " заняло выполнение операции."

ex: Exit Function
er: mes.ErrorLog
End Function
Latuk
Дата: 22.02.2008 11:07:22
Private WithEvents mcnn As ADODB.Connection

Private Sub mcnn_ExecuteComplete(ByVal RecordsAffected As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
'здесь че надо при завершении выполнения
End Sub


Set mcnn = New ADODB.Connection
mcnn.Open CurrentProject.AccessConnection
mcnn.CommandTimeout = 900

mcnn.Execute "супер пупер SQL команд", , adAsyncExecute
Ёжик`
Дата: 22.02.2008 11:22:54
Сенкс.
Пока что сделал в форме так:
Private WithEvents cnn As ADODB.Connection

Private Sub cnn_ExecuteComplete(ByVal RecordsAffected As Long _
    , ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum _
    , ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset _
    , ByVal pConnection As ADODB.Connection)
DoCmd.Hourglass False
MsgBox "Выполнение асинхронного задание закончено", vbInformation
End Sub

Private Sub CmdRun_Click()
DoCmd.Hourglass True
cnn.Execute Me.QueryVal, , adAsyncExecute
End Sub

Private Sub Form_Close()
cnn.Close
Set cnn = Nothing
End Sub

Private Sub Form_Open(Cancel As Integer)
Set cnn = New ADODB.Connection
cnn.Open CurrentProject.AccessConnection
cnn.CommandTimeout = 900
End Sub
бухой бык
Дата: 22.02.2008 11:49:10
ой, прастите, вопроса не увидел... сидел банкноты нумирувал... ну да ладно, вижу и без моих примеров разобралися.
Latuk
Дата: 22.02.2008 12:15:10
учти
при закрытии формы подключение будет закрыто и выполнение команды прервется.
если кнопку нажать несколько раз,то команда попадет в очередь
и будет последовательно выполнятся в контексте конекта.(т.е. сначала закончится выполнение перво потом запустится вторая)

Что можно сделать на основе формы чтобы получить асинхронного исполнителя...
создавать экземпляры формы чтобы выполнять сразу несколько команд
форма может держать сама себя ("Мюнхаузен")
и сама контролировать свое закрытие при завершении команды

В модуле формы
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                                    ( _
                                     ByVal hwnd As Long, _
                                     ByVal wMsg As Long, _
                                     ByVal wParam As Long, _
                                     lParam As Any _
                                     )  As Long

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Dim frm As Form 'ссылка на саму себя "Мюнхаузен"
Private WithEvents cnn As ADODB.Connection


Private Sub Form_Open(Cancel As Integer)
'подвешиваем Мюнхаузена
Set frm = Me
End Sub

Private Sub Form_Close()
cnn.Close
Set cnn = Nothing
'Топим "Мюнхаузена"
Set frm = Nothing
End Sub

Private Sub Form_Unload(Cancel As Integer)
'Упс нашу форму выгружают закрывая акс надо чето делать 
'ато команда прервется недовыполнившись
'например сештаки подождать но это черевато если команда к примеру в дедлоке 
'ну вылетит по таймауту...
Do Until cnn.State = 1
    Sleep 333 ' цикл с дуевентом без передышки вешает проц ну вот и передышка :)
    DoEvents
Loop

End Sub

'публичное свойство для передачи команды в форму
Public Property Let RunStr(RStr As String)
'здесь запускаем нашу команду
Set cnn = New ADODB.Connection
cnn.Open CurrentProject.AccessConnection
cnn.CommandTimeout = 900
cnn.Execute RStr, , adAsyncExecute 
End Property


Private Sub cnn_ExecuteComplete(ByVal RecordsAffected As Long _
    , ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum _
    , ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset _
    , ByVal pConnection As ADODB.Connection)

'Мавр сделал свое дело мавр может уходить...
'заставляем наш экземпляр формы закрытся
SendMessage Me.hwnd, WM_CLOSE, 0&, 0&

End Sub



Фукция обертка в модуле
Public Sub SpRun(Str As String)

Dim frm As Form
Set frm = New Form_AsyncExecfrm

frm.RunStr=Str 

'уничтожаем ссылку но форма уже сама себя держит
Set frm = Nothing

End Sub

PS Вместо формы можно сделать абычный класс но это немного сложнее
Ёжик`
Дата: 22.02.2008 12:23:50
Спасибо за предложения, замечания и Sleep
Класс я уже сделал (в форме производил тестирование)
Ёжик`
Дата: 22.02.2008 12:50:52
Пока что готов такой класс, нужно обработчики ошибок навесить, ловушку для сообщений,
и сваять прогрессбар (пусть квадратики бегают, без попытки оценки оставщегося времения выполнения) с выводом сообщений.
'в любом модуле
dim a as new mSql
a.ExeWait "exec чё то там" & VbNewLine & "exec чё то там еще"
set a = nothing
'class name: mSql
Option Compare Database
Option Explicit

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private WithEvents cnn As ADODB.Connection
Private IsRunningStatus As Boolean

Private Sub cnn_ExecuteComplete(ByVal RecordsAffected As Long _
    , ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum _
    , ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset _
    , ByVal pConnection As ADODB.Connection)

IsRunningStatus = False
DoCmd.Hourglass False
End Sub

Private Sub Class_Initialize()
Set cnn = New ADODB.Connection
cnn.Open CurrentProject.AccessConnection
cnn.CommandTimeout = 0
End Sub

Private Sub Class_Terminate()
cnn.Close
Set cnn = Nothing
End Sub

Public Sub ExeWait(QueryStr As String)
DoCmd.Hourglass True
IsRunningStatus = True
cnn.Execute QueryStr, , adAsyncExecute
Do Until Not IsRunningStatus
    Sleep 333
    DoEvents
Loop
End Sub