ProgressBar. (23/07/03 - Aggiornamento 10/02/04) Alcune richieste, anche passate, avevano come argomento, la realizzazione di una "barra di avanzamento" (ProgressBar) che avvisasse l'utente che una macro era in esecuzione. Infatti a volte si può lamentare una lentezza nell'esecuzione di procedure, tale da far pensare che il computer non stia lavorando, Una barra di avanzamento consentirebbe, con la sua progressione, di "visualizzare" che in effetti "qualcosa" sta succedendo. Premesso che alcune routine sono mal costruite, ed impiegano più tempo del dovuto a terminare, premesso che alcuni computer sono dotati di scarse risorse Hardware (poca RAM, dischi lenti, processori obsoleti) esistono tuttavia lentezze causate dalla gran quantità di dati che devono essere elaborati, da qui l'esigenza di avere un "segnale" che tutto sta procedendo. Bisogna capire come prima cosa, che qualsiasi ProgressBar per funzionare, deve poter essere collegata ad una variabile che sia un vettore del numero di iterazioni che si stanno eseguendo. Solo con questa impostazione sarà possibile verificare in tempo reale (o quasi ) l'avanzamento dell'esecuzione di una macro, e le istruzioni per l'avvio della ProgressBar, andranno posizionate opportunamente per evitare che lo scorrimento della barra di avanzamento non parta, o parta dopo, o addirittura interferisca con l'esecuzione stessa (della procedura) rallentandola ulteriormente. La ProgressBar più semplice e veloce da ottenere (ATTENZIONE: questa soluzione NON vale per la versione 97 di Excel), è quella di usare la "BARRA DI STATO". Vediamo come ottenerla: dal menù Visualizza, selezionare la voce "Barra di stato", vedi foto: e in fondo alla pagina, comparirà una barra in più, con all'estrema sinistra, la parola "Pronto" : Questa operazione può comunque essere evitata, perchè la "Barra di stato" può venire chiamata da un'istruzione che integreremo nella nostra macro, e che imposterà anche il testo che apparirà al posto di "Pronto", indicando peraltro il valore che indica lo "stato di avanzamento", ottenendo l'effetto di tranquillizzare chi aspetta che la macro termini. Nella foto sotto vediamo un'istantanea dei numeri che scorrono, indicando l'avanzamento: Vediamo quindi come sfruttare le istruzioni, presentando un esempio nel quale, riempiremo tutte le celle che vanno dalla cella A1 alla J500, con numeri casuali. Questa la macro, che potrete copiare e provare sul vostro computer :
se non si fosse utilizzata l'ultima istruzione (Application.StatusBar = False), ma questa: Application.StatusBar = "Procedura completata : " & Counter questo sarebbe ciò che vedremo nella barra di stato: il tutto crea un buon effetto di macro in esecuzione e termine. Bisogna fare attenzione al posizionamento delle istruzioni per l'avvio della StatusBar, si corre il rischio che per vedere una progressione di avanzamento, si rallenti in maniera notevole l'esecuzione della macro peggiorando il risultato finale in termini di tempo impiegato. Ognuno dovrà valutare le proprie necessità in funzione delle proprie istruzioni. Non chiedetemi aiuto in questo caso, ognuno dovrà capire come usare l'esempio proposto, e risolvere da solo. Un modo meno problematico e comunque di effetto, è quello di usare una UserForm con una Label, dove sfrutteremo la Caption della Label per gestire due messaggi: Inizio Procedura, e Fine Procedura. Se avviamo l'UserForm ad inizio macro, usando DoEvents, lasceremo la prosecuzione delle istruzioni fino alla fine, e indipendentemente dal tempo impiegato, otterremo di avvisare l'utente che la procedura è in esecuzione, e alla fine che è terminata, senza interferire con i tempi già lunghi richiesti dalle vostre procedure. Vediamo come lavorare:
Usiamo l'esempio dei numeri casuali usato sopra, ma con le istruzioni per inizializzare la UserForm:
L'efficacia è garantita, questa l'immagine iniziale all'avvio della macro: e questa l'immagine a fine procedura.
Un'altra ProgressBar molto più efficace come effetto visivo, che comporta un pò più di lavoro per ottenerla, la propongo nell'esempio sotto. Premetto che l'idea non è mia, ma trovata in Internet, e adattata da me per l'occasione. Viene sfruttata anche in questo caso una UserForm, ma l'effetto visivo dello stato di avanzamento simula il funzionamento di una reale ProgressBar. Anche questa procedura non è attuabile con la versione 97 di Excel o precedenti. Ma vediamo cosa serve:
Per poter usare questo esempio adattandola alle proprie necessità è utile evidenziare come lavora la sottoesposta macro: il nocciolo di tutto il lavoro è la selezione di ogni cella letta nei cicli For...Next e a questo provvede l'istruzione Cells(r, c).Select se non si fa la selezione lo scorrimento delle istruzioni sarà tanto veloce da vanificare l'effetto progressbar. Viceversa se usassimo un Ciclo For Each...Next e si selezionasse ogni cella letta le istruzioni si pianterebbero alla prima celle letta e per proseguire dovremmo annullare la procedura; se non selezioniamo una cella la procedura finisce senza l'effetto voluto, è quindi indispensabile usare un doppio ciclo For Next che ci consente di proseguire generando l'effetto dell'avanzamento; ovviamente manca un vettore numerico che serva da indice alla lunghezza della Label usata, e per questo usiamo una variabile contatore che si incrementa di una unità ad ogni cella letta, in questo caso la variabile Counter farà avanzare la lunghezza della Label. ed ora vediamo la routine presentata sopra per generare numeri casuali, modificata con le istruzioni necessarie:
Due immagini relative alla Sub TestBar
Chiaramente la velocità dell'avanzamento è proporzionale al tempo di esecuzione delle istruzioni.
Quando invece non sia possibile stabilire il numero di iterazioni legate all'esecuzione di una procedura, per cui risulta problematico determinare il vettore del valore di incremento di una ProgressBar, ma si voglia comunque avvisare l'utente che una procedura, a volte molto lunga, è in corso, possiamo usare una cella del foglio di lavoro (magari determinandola a priori, o meglio lasciando una cella libera per questo scopo), dove far apparire la scritta : "Procedura in esecuzione". Evitiamo in questo modo di "trafficare" con UserForm, e saremo comunque avvisati che il computer sta lavorando. L'idea, presentata dall'amico Falini Eliano ( falinieliano@virgilio.it ), è semplice, facilmente attuabile, e di sicura efficacia. Si pongono ad inizio e fine della procedura di cui vorremo avvisare, due semplici blocchi di istruzioni, il primo attiverà la cella che avremo destinato allo scopo, scrivendo una frase che ci avvisi, e magari evidenziamo di giallo la cella stessa, e ne evidenziamo i bordi; il secondo blocco invece ripristina la cella, eliminando la scritta, il colore e togliendo i bordi. Quando attiveremo la nostra procedura, verremo avvisati che la procedura è in esecuzione, e quando sarà terminata sparirà l'avviso e la formattazione della cella ritornerà normale. Simuliamo la Cella B1 come quella da noi destinata, e vediamo i due blocchi di istruzioni:
Ovviamente potrete decidere se usare il grassetto per la cella, ed eventualmete un colore per il font. Un grazie ad Eliano.
Buon lavoro. |