Buon Pomeriggio a tutti,
sono nuovo del Forum sebbene per anni mi abbia più volte risolto dei grattacapi.
Ho realizzato un DbAccess per tenere traccia della produzione e gestire gli ordini e le comande tra banco e laboratorio nel mio locale.
Il DB è diviso, FE sulle singole macchine e BE in un percorso di rete condiviso (connessione stabile Gbit LAN). I FE sono tutte copie dello stesso file ma abilitano o meno alcune funzioni a seconda della postazione e dell'utente.
Ciascun FE all'avvio lancia una Maschera "PannelloDiControllo" che rimane sempre visibile e contiene i pulsanti per aprire in modalità Dialog altre maschere sia collegate che scollegate al Db.
Su Form.Load di "PannelloDiControllo" via codice identifico la postazione(Banco, Laboratorio, Gelateria ecc) e l'utente loggato
recuperando le impostazioni che abilitano/disabilitano controlli e maschere. (Es. solo la postazione BANCO ha la possibilità di aprire la maschera "InserimentoOrdiniRapidi" mentre solo il laboratorio può aprire la maschera "ModificaRicetteProdotti".
Sull'evento OnTimer di "PannelloDiControllo" alcune postazioni accedono al DB ogni 10000 ms (10s) per verificare la presenza di nuovi ordini o (XOR) notificare messaggi.
Quello che mi sta facendo impazzire è la postazione Laboratorio. La Funzione "NuoviOrdini()" va ogni tanto in errore che non sempre viene intercettato dall'ErrorHandler su PannelloDiControllo.
La form visualizzata in quel momento si blocca (ogni click del mouse genera il caratteristico beep), a volte in secondo piano, invisibile, c'è il msgbox dell'ErrorHandler che basterebbe chiudere per risolvere; a volte l'unica cosa da fare è forzare la chiusura di Access da Gestione Risorse.
La cosa strana è che la funzione "ControllaOrdiniCompletati()", molto simile alla precedente, lanciata dalla postazione BANCO va che è un piacere ...
Il problema si verifica sia quando "PannelloDiControllo" è l'unica maschera visualizzata sia quando ne ho altre aperte in cascata in modalità Dialog
è la prima volta che uso l'ontimer di Access per accedere al db.
Apro il db con dbOpenSnapshot e non penso possa creare problemi di accesso concorrenziale ma mi dichiaro ignorante in materia
Ogni suggerimento è ben accetto.
Di seguito la parte del codice incriminata sulla form "PannelloDiControllo"
(I campi sui quali ci sono condizioni WHERE o sono ChiavePrimaria o Indicizzati)
Private Sub Form_Timer()
On Error GoTo ErrorHandler
If BolNotificaOrdiniNuovi And Not StopTimer And Me.TxtUtente <> "" Then 'solo per Laboratorio
Dim OrdiniInArrivo As Variant
Dim StrOrdine As String
Me.TxtErrore = "Controllo ordini in arrivo non attivo!"
OrdiniInArrivo = NuoviOrdini() 'DCount("ID", "Ordini-Header", "Stato = 0")
Select Case OrdiniInArrivo
Case 0
'Non Faccio Niente
Case 1
StrOrdine = " C'è un nuovo ordine"
Call SpeakIt(StrOrdine)
Case 9999
'Funzione NuoviOrdini non riuscita
'Genero un errore
Err.Raise 9999, , "La funzione NuoviOrdini() ha generato un errore"
Case Else
StrOrdine = " Ci Sono " & OrdiniInArrivo & " nuovi ordini."
Call SpeakIt(StrOrdine)
End Select
End If
If BolNotificaOrdiniCompletati And Not StopTimer And Me.TxtUtente <> "" Then 'solo per Banco
Dim OrdiniCompletati As String
Me.TxtErrore = "Controllo ordini completati non attivo!"
OrdiniCompletati = ControllaOrdiniCompletati() 'DCount("ID", "Ordini-Header", "Stato = 0")
Select Case OrdiniCompletati
Case ""
'Non Faccio Niente
Case "9999"
'"Funzione NuoviOrdini non riuscita"
'Genero un errore
Err.Raise 9999, , "La funzione ControllaOrdiniCompletati() ha generato un errore"
Case Else
DoCmd.OpenForm "Notifiche", acNormal, , , , acDialog, OrdiniCompletati
Call OrdineNotificato
End Select
End If
Me.TxtOrologio = Format(Now, "Dddd dd/mm/yyyy HH:mm")
Me.TxtErrore = ""
GoTo Fine
ErrorHandler:
Me.TxtErrore = "Controllo ordini in arrivo non attivo!"
StopTimer = True
MsgBox "Si è verificato un errore sulle operazioni temporizzate." & Chr(10) & Chr(10) & _
Err.Description & Chr(10) & Chr(10) & _
"Se il messaggio si ripresenta cliccare su 'ESCI' e riavviare il programma.", vbCritical
Err.Clear
StopTimer = False
Fine:
End Sub
Private Function NuoviOrdini() As Integer
Dim SQL As String, Rst As Recordset
On Error Resume Next
SQL = "SELECT ID FROM [Ordini-Header] WHERE [Stato] = 0 "
Set Rst = CurrentDb.OpenRecordset(SQL, dbOpenSnapshot, dbReadOnly)
If Not Rst.EOF Then
Rst.MoveLast
NuoviOrdini = Rst.RecordCount
Else
NuoviOrdini = 0
End If
Rst.Close
Set Rst = Nothing
If Err.Description <> "" Then
NuoviOrdini = 9999
Err.Clear
End If
End Function
Private Function ControllaOrdiniCompletati() As String
Dim SQL As String, Rst As Recordset
On Error Resume Next
SQL = "SELECT ID, Descrizione FROM [Ordini-Header] WHERE [Stato] = 4 AND [Notificato] = False"
Set Rst = CurrentDb.OpenRecordset(SQL, dbOpenSnapshot, dbReadOnly)
If Not Rst.EOF Then
Rst.MoveLast
If Rst.RecordCount > 1 Then
ControllaOrdiniCompletati = "Ci sono " & Rst.RecordCount & " completati."
Else
ControllaOrdiniCompletati = "L'ordine " & Rst.Fields("Descrizione").Value & " è pronto"
End If
Else
ControllaOrdiniCompletati = ""
End If
Rst.Close
Set Rst = Nothing
If Err.Description <> "" Then
ControllaOrdiniCompletati = "9999"
Err.Clear
End If
End Function