Consiglio ottimizzazione codice

di il
5 risposte

Consiglio ottimizzazione codice

Buongiorno a tutti,

vorrei chiedere un consiglio alla community in merito al codice che sto per postare.

Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal count As Long)
On Error GoTo ErrorHandler
   
    If Not Me.Dirty Then
       If (count < 0) And (Me.CurrentRecord > 1) Then
           DoCmd.GoToRecord , , acPrevious
       ElseIf (count > 0) And (Me.CurrentRecord <= Me.Recordset.RecordCount) Then
           DoCmd.GoToRecord , , acNext
       End If
    Else
        MsgBox "I dati sono stati modificati!" & vbNewLine & "Salvare o annullare le modifiche prima di passare ad un altro record.", vbOKOnly, "Avviso!"
    End If

ErrorHandler:
   Call ErrHandler(Err.Number)
End Sub

Con questo codice in pratica permetto di girare tra i record, se non sono stati editati/modificati e fin qui va bene, il problema sorge che dopo il messaggio e facendo esclusivamente salva

    DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

è come se andasse in loop e ripropone sempre lo stesso messaggio “bloccandosi”

su un'altra maschera ho invece risolto/ovviato in un altro modo, dovendo anche dover inserire dei controlli in più, con questo codice:

Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal count As Long)
On Error GoTo ErrorHandler
   Dim Risp As Integer
   
   With CodeContextObject
       If Not .Dirty Then
           If (count < 0) And (Me.CurrentRecord > 1) Then
               DoCmd.GoToRecord , , acPrevious
           ElseIf (count > 0) And (Me.CurrentRecord <= Me.Recordset.RecordCount) Then
               DoCmd.GoToRecord , , acNext
           End If
       Else
           Risp = MsgBox("I dati sono stati modificati! Salvare o annullare" & vbNewLine & "le modifiche prima di passare ad un altro record." _
                  & vbNewLine & vbNewLine & "Si vuole salvare ora?", vbQuestion + vbYesNo + vbDefaultButton1, "Avviso!")
           If Risp = 6 Then
               If .C = 0 Then
                   If .F = 0 Then
                       If .R = 0 Then
                           MsgBox "Non è stato specificato" & vbNewLine & "il tipo di anagrafica" & vbNewLine & "Cliente/Fornitore/Rappresentante" _
                           & vbNewLine & "Si prega di specificare per poter salvare"
                           .C.SetFocus
                           Exit Sub
                       Else
                           GoTo SaveAndGo
                       End If
                   Else
                       GoTo SaveAndGo
                   End If
               Else
                   GoTo SaveAndGo
               End If
           Else
               Exit Sub
           End If
       End If
   End With
   
SaveAndGo:
   DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
   If (count < 0) And (Me.CurrentRecord > 1) Then
       DoCmd.GoToRecord , , acPrevious
   ElseIf (count > 0) And (Me.CurrentRecord <= Me.Recordset.RecordCount) Then
       DoCmd.GoToRecord , , acNext
   End If
   
ErrorHandler:
   Call ErrHandler(Err.Number)
End Sub

Ora vorrei chiedere un Vs parere sul perchè mi riporta quell'errore ridondante con il primo codice “semplice” e se c'è un modo per snellire di più il secondo visto che vorrei inserire questi controlli ad ogni spostamento tra record ed eventualmente anche in altre maschere

grazie mille per le risposte

5 Risposte

  • Re: Consiglio ottimizzazione codice

    Hai verificato se dopo il SAVE la proprietà Dirty è False…? (temo sia rimasta a True)
    Nel caso oltre al Save, subito dopo forza Dirty=False

    Per il resto… non mi addentro… risulta poco comprensibile come ragionamento da fuori…!

    Esempio:

    If Risp = 6 Then
    	If .C = 0 Then
    		If .F = 0 Then
    			If .R = 0 Then

    Non poteva essere messo un OR…?

    Dim AllTrue As Boolean
    
    AllTrue = Risp = 6 AND .C = 0 AND .F = 0 AND .R = 0
    IF AllTrue Then
    	MsgBox "Non è stato specificato" & vbNewLine & "il tipo di anagrafica" & vbNewLine & "Cliente/Fornitore/Rappresentante" _
                               & vbNewLine & "Si prega di specificare per poter salvare"
       .C.SetFocus
    ElseIf Risp = 6 OR .C = 0 OR .F = 0 OR .R = 0 Then 
    	DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
    	....
    	....
    End IF
  • Re: Consiglio ottimizzazione codice

    05/02/2024 - @Alex ha scritto:


    Hai verificato se dopo il SAVE la proprietà Dirty è False…? (temo sia rimasta a True)
    Nel caso oltre al Save, subito dopo forza Dirty=False

    ecco, questo non l'avevo verificato, ed infatti inserendolo adesso non mi da più errore

    Per il resto… non mi addentro… risulta poco comprensibile come ragionamento da fuori…!

    Esempio:

    If Risp = 6 Then
    	If .C = 0 Then
    		If .F = 0 Then
    			If .R = 0 Then

    Non poteva essere messo un OR…?

    If Risp = 6 OR .C = 0 OR .F = 0 OR .R = 0 Then 
    	DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
    	....
    	....
    End IF

    adesso mi spiego per quella parte, se hai modificato i dati e vuoi salvare allora verifico se almeno una delle caselle di controllo C/F/R (che stanno per cliente fornitore rappresentante) sia spuntata, se risulta spuntata procede altrimenti ti blocca.

    Questo dovrebbe essere il senso, quindi il risp = 6 then lo devo lasciare, poi per il secondo, se inserissi l' OR mi controllerebbe se uno di quei controlli è uguale a 0 e quindi mi risulterebbe sempre in true in quanto un anagrafica può essere una delle tre come tutte e tre le funzioni, ma non deve poter essere “nessuna” delle 3, forse se scrivessi con AND verifico se tutte e tre sono 0 ed in quel caso do l'errore, altrimenti va bene e procedo, quindi così

    If Risp = 6 Then
        If .C = 0 AND .F = 0 AND .R = 0 Then 
    	DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
    	....
    	....
    End IF

    e potrei snellirlo di più in tal modo

  • Re: Consiglio ottimizzazione codice

    Hai un po di confusione… 

    Secondo te che differenza passa a scrivere queste 2 cose:

    If Risp = 6 Then
        If .C = 0 AND .F = 0 AND .R = 0 Then 
    AllTrue = Risp = 6 AND .C = 0 AND .F = 0 AND .R = 0
    IF AllTrue Then

    Nessuna solo che la 2°, quella che ti ho suggerito è debuggabile… la tua no, ma a livello LOGICO sono la stessa cosa, anche se hai omesso un END IF, vedi tu riflettici meglio.

  • Re: Consiglio ottimizzazione codice

    Riflettendoci hai ragione, anche se ho ritenuto opportuno fare una modifica ancora

                AllTrue = Risp = 6 And .C = 0 And .F = 0 And .R = 0
               If AllTrue Then
                   MsgBox "Non è stato specificato" & vbNewLine & "il tipo di anagrafica" & vbNewLine & "Cliente/Fornitore/Rappresentante" _
                           & vbNewLine & "Si prega di specificare per poter salvare"
                   .C.SetFocus
                   Exit Sub
               ElseIf Risp = 7 Then
                   .Undo
               Else
                   GoTo SaveAndGo
               End If

    perchè con l'alltrue si verifica che abbiano risposto si e se tutte e tre le caselle di controllo sono 0, così facendo voglio salvare ma c'è “un errore” quindi compare il msgbox, ferma il salvataggio e lo spostamento tra i record però nel caso in cui la risposta sia no, anche se c/f/r siano 0 andava sempre sull'else e quindi salvava sempre anche rispondendo no, quindi ho inserito un elseif per controllare se la risposta è no ed in quel caso annulla le modifiche, altrimenti procede normalmente…

    credo così dovrebbe andar bene, alleggerito di molto e funzionale

  • Re: Consiglio ottimizzazione codice

    05/02/2024 - @Alex ha scritto:


    If Risp = 6 Then If .C = 0 Then If .F = 0 Then If .R = 0 Then

    Così a pelle:

    If (c=o and f=0 and r=0) then …

    Mi sembra di capire che devono essere tutte a zero.

    Se usi or basta che una sia <>0 che procede e non va bene.

    Ottimizzare? Bèh controlla se il dataset va in edit mode e metti un flag a true.

    Se flag=true then messaggio(salvare? Si, no)

    Se si post se no cancel.

    Purtroppo inyerpretare i nomi che hai dato (tipo c, f, r) senza capire di cosa hai bisogno è difficile rispondere.

    Se ho capito bene e vuoi controllare se la tabella è andata in editmode basta il flag. Al controllo lanci la funzione di controllo dei campi e stoppi con messaggio di errore o salvi o annulli.

    Sicuramente nidificare if non ha senso.

    Valuta l'ipotesi di usare case.

    Puoi anche evitare l'edit accidentale e portare la tabella da readonlily afalse con il doppio click (sempre da lanciare la funz in casi di postrecord).

    Si, si può ottimizzare sia il codice che la logica.

Devi accedere o registrarti per scrivere nel forum
5 risposte