Risultati da 1 a 6 di 6

Discussione: Application.EnableEvents = False/True



  1. #1

    L'avatar di alfrimpa
    Clicca e Apri
    Data Registrazione
    Dec 2015
    Località
    Napoli
    Età
    64
    Messaggi
    6797
    Versione Office
    2013
    Likes ricevuti
    719
    Likes dati
    164

    Application.EnableEvents = False/True

    Ciao a tutti

    Non so se qualcuno riesce a farmi un po' di chiarezza sull'istruzione che ho indicato in oggetto.

    Come saprete tale istruzione serve ad evitare il ricorsivo e "dannoso" ripetersi di eventi all'interno di una procedura evento.

    Per quanto abbia sperimentato i più comuni errori che si verificano in tali tipi di procedure (ma certamente non sono solo questi) è quando il Target.Rows.Count è maggiore di 1 oppure quando si cancella il valore del Target.

    In tali casi (ma non sempre e non sono in grado di dire quando) si può risolvere con istruzioni del tipo

    Codice: 
    If Target.Value = "" Then
    oppure

    Codice: 
    If Target.Rows.Count >1 Then
    Ho visto però spesso l'utilizzo di

    Codice: 
    Application.EnableEvents = False
    ....Codice....
    Application.EnableEvents = True
    C'è qualcuno che mi può spiegare come, dove e quando tali istruzioni possano essere utilmente adottate?

    Ricordo che posi tale domanda molto tempo fa su altro forum (allora non frequentavo ancora ForumExcel.it) e ricordo anche che mi dette risposta il "mitico" scossa e devo candidamente confessare che non riuscii, all'epoca, ad afferrare sino in fondo il senso dei suoi chiarimenti.

    Ringrazio sin d'ora.

    Alfredo

  2. #2
    L'avatar di GiuseppeMN
    Clicca e Apri
    Data Registrazione
    Oct 2015
    Località
    Mantova
    Messaggi
    864
    Versione Office
    2000 - 2013
    Likes ricevuti
    285
    Likes dati
    160
    Buona sera, Alfredo.

    @ alfrimpa , scrive:
    Ricordo che posi tale domanda molto tempo fa su altro forum (allora non frequentavo ancora ForumExcel.it) e ricordo anche che mi dette risposta il "mitico" scossa e devo candidamente confessare che non riuscii, all'epoca, ad afferrare sino in fondo il senso dei suoi chiarimenti.
    Non credo di essere il miglior interlocutore per spiegare adeguatamente la funzione di Application.EnableEvents; posso solo riportare un paio di esempi nei quali è stato indispensabile l'utilizzo di Application.EnableEvents.

    Codice: 
    Option Explicit
    
    Private Sub Worksheet_Change(ByVal Target As Range)
        Application.EnableEvents = False
            If Not Intersect(Target, Range("A1:A10")) Is Nothing Then
                Target = Target * 1000
            End If
        Application.EnableEvents = True
    End Sub
    Questo esempio disattiva gli eventi evitando di entrare in un Loop che genera Overflow.

    Codice: 
    Option Explicit
    
    Private Sub Worksheet_Activate()
        Application.EnableEvents = False
            Sort_ID
        Application.EnableEvents = True
    End Sub
    Dove Sort_ID è un Codice VBA inserito in un Modulo; esegue l'ordinamento di un RecordSet presente in un Foglio di lavoro diverso.
    Anche in questo caso, Application.EnableEvents = False/True si è reso indispensabile per evitare il ripetersi di:
    - Sort_ID
    La mia interpretazione di Application.EnableEvents = False è:
    - serve a fermare i gestori di eventi di Excel richiamati; è indispensabile per impedire un ciclo infinito.
    Questo in sintesi e in modo assolutamente "ruspante!"

    A disposizione.

    Buona serata e ... buon Campionato.

    Giuseppe
    Windows XP Excel 2000 - Windows 10 Excel 2013

  3. #3
    L'avatar di A.Maurizio
    Clicca e Apri
    Data Registrazione
    Aug 2015
    Località
    Torino
    Età
    56
    Messaggi
    383
    Versione Office
    2013
    Likes ricevuti
    44
    Likes dati
    0
    Ciao Afrimpa , per prima cosa Vorrei Salutare il mio Amico Giuseppe .
    E poi per rispondere alla Domanda il Costrutto (Application EnableEvents) si applica a tutte quelle situazioni :
    Nella maggior parte del codice VBA, è possibile utilizzare la proprietà Application.EnableEvents per impedire la chiamata di routine di evento di Excel. Questo spesso utilizzato nell'evento di modifica di un foglio di lavoro se l'evento di modifica si cambia il valore della cella. Senza EnableEvents è impostata su False, l'utente modifica una cella, che attiva l'evento Change, che cambia un valore che attiva l'evento di cambiamento, che cambia un cellule, che fa scattare l'evento di modifica, e così via ad nauseam fino a VBA decide di terminare il ciclo per evitare un errore di runtime "di spazio dello stack". EnableEvents è impostata su False impedirà questo ciclo.

    In otre io lo adottato quando avevo creato e non solo le mie prime figure in movimento come questa , che ti ho appena inviato .
    Spero di essere stato abbastanza delucidante , nel farti capire a cosa serve Ciao
    File Allegati File Allegati

  4. #4

    L'avatar di scossa
    Clicca e Apri
    Data Registrazione
    Jul 2015
    Località
    Verona Provincia
    Età
    57
    Messaggi
    1017
    Versione Office
    .
    Likes ricevuti
    366
    Likes dati
    0
    Citazione Originariamente Scritto da alfrimpa Visualizza Messaggio
    C'è qualcuno che mi può spiegare come, dove e quando tali istruzioni possano essere utilmente adottate?
    Ciao Alfredo, e ciao a tutti gli altri intervenuti,

    finalmente trovo due minuti per rispondere.

    Premessa: la proprietà Application.EnableEvents permette di abilitare o disabilitare il gestore degli eventi, e quindi di attivare o meno le varie routine di evento. Essendo una proprietà dell'aggetto Application la sua impostazione si riflette su tutte le cartelle di lavoro aperte in quella istanza di Excel.

    Quando disabilitare gli eventi (Application.EnableEvents = False)?

    Generalmente quando si sta scrivendo il codice di una routine di evento in cui utilizziamo un'istruzione che scatenerebbe l'evento stesso: ad esempio se nella routine di evento Worksheet_Change() utilizzassimo l'struzione
    Target.Value = Target.Value + 1
    Codice: 
    Private Sub Worksheet_Change(ByVal Target As Range)
      Target.Value = Target.Value + 1
    End Sub
    l'esecuzione di tale istruzione scatenerebbe a sua volta l'evento Worksheet_Change(), cioè richiamerebbe se stessa, entrando in un loop infinito (in realtà è "autolimitato" a meno di 100 iterazioni, infatti se provate il codice sopra vedrete che il valore della cella verrà incrementato di 95)

    Analogo discorso per l'evento Worksheet_SelectionChange():
    Codice: 
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
      Target.Offset(0, 1).Select
    End Sub
    Il codice sopra selezionerebbe ricorsivamente la cella a destra rispetto a quella selezionata fermandosi 100 celle a destra (A1 -> CW1)

    E' quindi evidente che non possiamo trascurare il problema della ricorsività e, pertanto, lo dobbiamo prevenire.

    Le vie percorribili sono sostanzialmente due: una più semplice (Application.EnableEvents = False), l'altra più articolata (variabile boolean statica) ma anche più "flessibile"; vediamole in dettaglio.


    • Application.EnableEvents = False

    Ricorrere alla disabilitazione degli eventi è la soluzione più semplice ed immediata ma anche più "rischiosa" e presenta delle limitazioni di cui è necessario essere coscienti: se per un qualsiasi errore il nostro codice dovesse interrompersi prima dell'istruzione che riabilita gli eventi, gli stessi resterebbero disabilitati a livello di applicazione (come spiegato in premessa) e "colpirebbe" tutte le routine di evento indiscriminatamente (infatti non è possibile disabilitare un singolo evento).
    E' quindi indispensabile che gli eventi siano disabilitati per un tempo il più limitato possibile, cioè che l'istruzione Application.EnableEvents = False sia immediatamente precedente all'istruzione che creerebbe ricorsività e che a detta istruzione segua immediatamente Application.EnableEvents = True
    Codice: 
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
     '...... codice vario, p.e. Intersect(Target .... ) ....
      Application.EnableEvents = False
      Target.Offset(0, 1).Select
      Application.EnableEvents = True
     ' ..... altro codice
    End Sub
    • variabile boolean statica

    Questa soluzione permette di aggirare il problema della ricorsività limitatamente al singolo evento senza disabilitare il gestore degli eventi, quindi è una soluzione molto meno problematica di Application.EnableEvents = False.
    Codice: 
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
      Static bInLoop As Boolean
      If Not bInLoop Then
        bInLoop = True
        Target.Offset(1, 0).Select
        bInLoop = False
      End If
    End Sub
    In sintesi, come spesso si verifica in Excel e a maggior ragione in VBA, non esiste un solo modo per "fare le cose"; sarà quindi responsabilità del programmatore valutare il problema e decidere quale sia la soluzione più adatta per quello specifico contesto.

    Spero di non aver confuso ancor di più le idee.
    Bye!
    scossa
    scossa's web site
    ___
    Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

  5. I seguenti utenti hanno dato un "Like"


  6. #5

    L'avatar di alfrimpa
    Clicca e Apri
    Data Registrazione
    Dec 2015
    Località
    Napoli
    Età
    64
    Messaggi
    6797
    Versione Office
    2013
    Likes ricevuti
    719
    Likes dati
    164
    Ciao Marco e grazie del tuo intervento che prometto di studiare con l'attenzione che merita e qualora dovessi avere ancora dubbi non esiterò a chiedere ulteriori delucidazioni.

    La mia confusione nasce dal fatto che tale tipo di istruzioni non viene sempre inserita nelle routine evento e spesso queste funzionano bene anche senza per cui mi chiedevo quando era il caso di utilizzarle.

    Mi rendo anche conto che, in questi casi, è difficile generalizzare (molto secondo me può dipendere dallo specifico) e dare delle regole valide per tutti.

    Nuovamente grazie.

    Alfredo

  7. #6

    L'avatar di scossa
    Clicca e Apri
    Data Registrazione
    Jul 2015
    Località
    Verona Provincia
    Età
    57
    Messaggi
    1017
    Versione Office
    .
    Likes ricevuti
    366
    Likes dati
    0
    Citazione Originariamente Scritto da alfrimpa Visualizza Messaggio
    La mia confusione nasce dal fatto che tale tipo di istruzioni non viene sempre inserita nelle routine evento e spesso queste funzionano bene anche senza per cui mi chiedevo quando era il caso di utilizzarle.
    Certo, come ho detto sopra, serve se utilizziamo un'istruzione che scatena a sua volta l'evento stesso: ad esempio nel codice dell'evento _Change cambiamo il valore di una cella ......
    Bye!
    scossa
    scossa's web site
    ___
    Se tu hai una mela, e io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

Discussioni Simili

  1. [Tutorial VBA] Application.FileDialog (Salva ed apri file e cartelle)
    Di dracoscrigno nel forum Imparando Excel & VBA - Tutorial di Excel-
    Risposte: 0
    Ultimo Messaggio: 09/02/17, 09:09
  2. lanciare tasto WinKey tramite comando Application.Sendkeys
    Di Gatt88 nel forum Domande su Excel VBA e MACRO
    Risposte: 0
    Ultimo Messaggio: 18/01/17, 22:32

Permessi di Scrittura

  • Tu non puoi inviare nuove discussioni
  • Tu non puoi inviare risposte
  • Tu non puoi inviare allegati
  • Tu non puoi modificare i tuoi messaggi
  •