Quelle solution pour 1 tache de fond en VB6 ?

yan35 Messages postés 185 Date d'inscription dimanche 29 juin 2003 Statut Membre Dernière intervention 20 juin 2013 - 27 mars 2007 à 14:25
yan35 Messages postés 185 Date d'inscription dimanche 29 juin 2003 Statut Membre Dernière intervention 20 juin 2013 - 28 mars 2007 à 16:46
Bonjour,

Lorsqu'un utilisateur saisie des infos dans des controles d'une form, lors du Validate du 2° controle (le quantième importe peu), le source lance lance une requête SQL sur une base de données assez conséquente et présente sur un autre poste d'un réseau poste à poste, temps d'exécution de la requête est donc important et bloque la saisie des données dans les autres controles de la form, alors que son résultat n'est pas essentiel tant que tous les controles ne sont pas encore saisis.
Je souhaite donc lancer cette requête en tache de fond sans qu'elle pénalise la saisie sur la form.
Sachant que VB6 est fâché avec le multithread, je ne sais pas quelle meilleure piste choisir ?
- un timer : retarde le démarrage de la requête mais ne traite pas le problème car bloque la saisie quand la requête s'exécute,
- il faudrait donc lancer un serveur ? mais quel serait la meilleure liaison : DDE - OLE - Winsock ?
   (compte-tenu de l'organisation du réseau en poste à poste) et pourquoi ?
- Y a-t-il une autre solution, que celles évoquées ?

Par avance MERCI de m'orienter.

3 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
27 mars 2007 à 14:29
requete et base a optimiser ?
(fais voir le code SQL de la requete)

un Timer est une bonne idée, je me sert souvent de ce stratagème pour rendre la main tout de suite, et lancer des taches longues

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
yan35 Messages postés 185 Date d'inscription dimanche 29 juin 2003 Statut Membre Dernière intervention 20 juin 2013
27 mars 2007 à 14:59
Bonjour et Merci Renfield de cette réponse aussi rapide,

Voici mon code et les requêtes SQL qu'il réalise dans le timer :

Private Sub tmrFd_Timer()
'Calculs en tâche de fond : soit ML, soit Dm3 selon Tag de tmrFd
Dim RsReq As Recordset     ' crée 1 recordset qui servira à plusieures requêtes
Dim strR As String, arrDepSall() As String
If tmrFd.Tag = "ML" Then        'ML
    Dim RsCml As Recordset
    strR = "SELECT Sum(DOS) AS CumulDos From archives GROUP BY [POSITION]\1000, DEPOT, SALLE " & _
    "Having ((([position] \ 1000) = " & txtRayon & txtAlvéole & txtEtagère & ") And (DEPOT = " & Replace(lblDép.Caption, "n° ", "") & ") And (SALLE = " & Replace(lblSal.Caption, "n° ", "") & "))" & " UNION SELECT Sum(DOSCM) AS CumulDos From regroupts GROUP BY [POSITION]\1000, DEPOT, SALLE Having ((([position] \ 1000) = " & txtRayon & txtAlvéole & txtEtagère & ") And (DEPOT = " & Replace(lblDép.Caption, "n° ", "") & ") And (SALLE = " & Replace(lblSal.Caption, "n° ", "") & "))"
    Set RsCml = dbArchclts.OpenRecordset(strR, dbOpenDynaset)
    If RsCml.EOF Then
        Cml = 0
    Else
        For I = 1 To 2 'il y a toujours 2 enr : 1 pour archives, 1 pour regroupts (inutile de calculer le nbre)
            If Not IsNull(RsCml!cumuldos) Then Cml = Cml + RsCml!cumuldos
            RsCml.MoveNext
        Next
    End If
ElseIf tmrFd.Tag Like "Dm3*" Then        'Dm3
    arrDepSall = Split(tmrFd.Tag, ",")    strR "SELECT Sum((SELECT Avg(Dos.dm3) FROM Dos WHERE (((Dos.dm3) Is Not Null) and dos.doscm " & _
    "archives.dos) GROUP BY Dos.DosCm)) AS Cumul_Moydm3connus From Archives " & _    "Where Archives.DEPOT " & Val(arrDepSall(1)) & " And Archives.SALLE " & Val(arrDepSall(2)) & _
    " And Archives.NoReg = " & Replace(txtRegr, "R-", "") & " UNION " & _
    "SELECT Sum((SELECT  Avg(Dos.dm3) FROM Dos WHERE (((Dos.dm3) Is Not Null) and dos.doscm = " & _
    "regroupts.doscm) GROUP BY Dos.DosCm)) AS Cumul_Moydm3connus From Regroupts " & _    "Where Regroupts.Depot " & Val(arrDepSall(1)) & " And Regroupts.Salle " & Val(arrDepSall(2)) & _
    " And Regroupts.Reg2 = " & Replace(txtRegr, "R-", "")
    Set RsCml = dbArchclts.OpenRecordset(strR, dbOpenDynaset)
    If Not RsCml.EOF Then
        RsCml.MoveLast
        For I = RsCml.RecordCount To 1 Step -1
            If Not IsNull(RsCml!Cumul_Moydm3connus) Then Cdm3 = Cdm3 + RsCml!Cumul_Moydm3connus
            RsCml.MovePrevious
        Next
    End If
End If
tmrFd.Tag = ""
Set RsCml = Nothing
Set RsReq = Nothing
tmrFd.Enabled = False
End Sub

C'est sûr les requêtes sont lourdes : sous-requêtes, regroupement, union, en + sur du Access et sur 2 tables de 40000 enregistrements de + de 300 octets, chacune donc c'est long, c'est pourquoi je cherche à les exécuter en vrai tâche de fond.

Si tu as une piste, Merci.
0
yan35 Messages postés 185 Date d'inscription dimanche 29 juin 2003 Statut Membre Dernière intervention 20 juin 2013
28 mars 2007 à 16:46
Re,
Je crois avoir trouvé. J'ai testé un Exe activeX out of Process. En test ça marche, par contre je me demande ce que ça donnera dans la durée, une fois mon exe et mon exe activeX compilés ! ?  En effet je ne fais pas bien la différence avec du Multithread que je ne maîtrise pas mais j'ai vu sur ce site que VB6 est récalcitrant au Multithread.
Merci si quelqu'un peut m'éclairer à ce sujet.
0
Rejoignez-nous