Problema con Query e Timer

di il
4 risposte

Problema con Query e Timer

Buongiorno
avrei bisogno di una dritta su un problema alquanto strano.
Mi spiego meglio.
Avrei bisogno di calcolare il tempo di esecuzione di una query un po' macchinosa
che calcola il numero dei test eseguiti in un anno per tutti i reparti.
La query racchiusa dentro una routine funziona bene,

il problema è che il cronometro non parte se non alla fine dell'esecuzione della query.

di seguito il codice della query :

Sub ContaTest()
Dim t As Long
Dim i As Integer
Dim z As Integer

Dim laTabella As String

If Option1.Value = True Then laTabella = "Archivio"
If Option2.Value = True Then laTabella = "Anagrafe"

  With MSFlexGrid1
  
    .Cols = nCol + 1
    For i = 1 To .Cols - 1
     
      For z = 1 To .Rows - 1
      
      sSQL = "SELECT COUNT(*) as t FROM " & laTabella & " WHERE Test='" & Apici(.TextMatrix(0, i)) & "'"
      sSQL = sSQL & " AND Reparto='" & Apici(.TextMatrix(z, 0)) & "'"
      sSQL = sSQL & " AND Data BETWEEN #" & Format(rtbPrima.Text, "mm/dd/yyyy") & "# AND #" & Format(rtbSeconda.Text, "mm/dd/yyyy") & "#"

      
      Set rs = New ADODB.Recordset
      rs.Open sSQL, cn, adOpenKeyset, adLockOptimistic
      
      If rs(0) > 0 Then
         .TextMatrix(z, i) = rs(0)
      Else
         .TextMatrix(z, i) = "0"
      End If
      
     Next z, i
 End With
rs.Close: Set rs = Nothing
End Sub


Codice del timer

Private Sub Timer1_Timer()
If Ms2.Caption = "9" Then
Ms2.Caption = "0"
Ms1.Caption = (Ms1.Caption + 1)
GoTo 11
Else
11
Ms2.Caption = (Ms2.Caption + 1)

If Ms1.Caption = "6" And Ms2.Caption = "0" Or Ms1.Caption = "6" Then
Ms1.Caption = "0"
SeC2.Caption = (SeC2.Caption + 1)
Else

If SeC2.Caption = "10" Then
SeC2.Caption = "0"
SeC1.Caption = (SeC1.Caption + 1)
Else

If SeC1.Caption = "6" And SeC2.Caption = "0" Or SeC1.Caption = "6" Then
SeC1.Caption = "0"
mIn2.Caption = (mIn2.Caption + 1)
Else

If mIn2.Caption = "10" Then
mIn2.Caption = "0"
mIn1.Caption = (mIn1.Caption + 1)
Else


End If
End If
End If
End If
End If
End Sub

Eseguo il tutto dal command

Timer1.Enabled = True
ContaTest

4 Risposte

  • Re: Problema con Query e Timer

    Intanto aggiungi delle righe

    DoEvents

    all'interno del ciclo interno della Sub ContaTest e all'interno della Timer1_Timer
  • Re: Problema con Query e Timer

    Perfetto! Grazie. E' bastato un solo DoEvents prima del ciclo.
    
      For i = 1 To .Cols - 1
          For z = 1 To .Rows - 1
          
          DoEvents
          
          sSQL = "SELECT COUNT(*) as t FROM " & laTabella & " WHERE Test='" & Apici(.TextMatrix(0, i)) & "'"
          sSQL = sSQL & " AND Reparto='" & Apici(.TextMatrix(z, 0)) & "'"
          sSQL = sSQL & " AND Data BETWEEN #" & Format(rtbPrima.Text, "mm/dd/yyyy") & "# AND #" & Format(rtbSeconda.Text, "mm/dd/yyyy") & "#"
    
    
  • Re: Problema con Query e Timer

    pierovb ha scritto:


    Perfetto! Grazie. E' bastato un solo DoEvents prima del ciclo.
    In realtà è "bastato" perché si tratta di un palliativo, ma il problema principale è che devi sapere come funziona il Timer o più in generale l'applicazione che stai realizzando con VB6.

    Il componente Timer si interfaccia con una API di Windows che fa inviare all'applicazione un messaggio periodicamente (WM_TIMER) che viene tradotto nell'esecuzione del codice che hai assegnato al timer.

    Quando arriva il messaggio, esso viene messo in una coda, assieme a tutti gli altri messaggi che arrivano all'applicazione, tra cui quelli di disegno, spostamento del mouse, clic, pressione di tasti, ecc.

    Nel tuo caso, se fai partire la query al clic su un pulsante, dietro le quinte la tua applicazione riceverà un messaggio opportuno ed eseguirà l'evento del click in risposta. Se la query dura 20 secondi, quel messaggio richiederà 20 secondi per poter essere gestito e questo vuol dire che la tua applicazione non potrà gestire fino ad allora tutti gli altri messaggi in arrivo sulla coda, compreso quello del timer che dovrebbe monitorare il tempo di esecuzione.

    Usare un DoEvents() significa dire all'applicazione di "scodare" i messaggi forzatamente: questo risolve (in parte) il tuo problema in quanto, durante il ciclo, se giunge un evento del timer questo può essere quindi gestito, a differenza della situazione precedente, ma assieme a quello vi sono potenzialmente anche altri eventi che potrebbero arrivare, ad esempio quello che rilancia la query o addirittura un evento di chiusura dell'applicazione, con effetti imprevedibili.

    In generale, la soluzione a queste problematiche la si trova nei thread, ma in VB6 non ci sono.

    Nel tuo caso comunque, è ancora più semplice: il Timer non è lo strumento adatto da utilizzare, poiché ti basta leggere la data/ora corrente prima di iniziare la query, e poi rileggerla nuovamente al termine, sottraendola a quella iniziale, per determinare in questo modo le ore, i minuti e i secondi trascorsi.

    Nello stato attuale, pur funzionando, le tempistiche di esecuzione sono pure inficiate dal DoEvents() e non è necessario istanziare un Timer per ottenere il dato che ti serve.

    Ciao!
  • Re: Problema con Query e Timer

    Alex
    Ho provato quanto suggerito in questo modo
    avvio la query
    
    Text2.Text = Format(Now, "dd/mm/yyyy hh:mm:ss")
    
    fine query
    
    Text3.Text = Format(Now, "dd/mm/yyyy hh:mm:ss")
    Text4.Text = DateDiff("s", Text2.Text, Text3.Text)
    
    Ed in effetti con il timer mi indica il tempo trascorso in 16 secondi
    mentre con un DateDiff è uguale a 37 secondi.
    Ho verificato, in modo un po' empirico, avviando contemporaneamente il cronometro
    del cellulare e devo dire che hai perfettamente ragione (non avevo alcun dubbio),
    l'esecuzione completa della query richiede 37 secondi.
Devi accedere o registrarti per scrivere nel forum
4 risposte