Crearsi uno SlideShow con un controllo Image (ActiveX). - dal 04/09/04 pagina vista: volte

Un esercizio semplice che potrà interessare per diletto o per lavoro. Sappiamo che è possibile inserire nei fogli di lavoro delle immagini, sia come sfondo dei fogli di lavoro (dal menù Formato/Foglio/Sfondo...) sia come "Forma" (dal menù Inserisci/Immagine scegliendo poi la provenienza: clipart, file, scanner, ecc).

E' possibile inserire immagini usando un "controllo ActiveX" (preso quindi da "Strumenti di controllo" ex "Casella degli strumenti") : il controllo "Immagine" (in inglese Image), che essendo stato creato per questo scopo, non solo possiede delle "proprietà" su cui intervenire per regolazioni, ma è possibile intervenire via codice vba sul controllo stesso, e quindi risulta "programmabile".

Questo "controllo" lo abbiamo già visto nell'articolo "ComboBox, Listbox e Image" sull'altro sito, a cui rimando per leggersi le caratteristiche delle  "proprietà" del "Controllo Image".

In quell'articolo il controllo Image veniva usato su una UserForm, mentre qui lo useremo direttamente sul foglio di lavoro. Possiamo decidere diversi modi per associare questo controllo alle immagini, qui lo useremo come contenitore di immagini correlate a nomi di un elenco (nomi di piante, di persone, di articoli di magazzino, di città, di disegni tecnici, di logo, ecc. ecc.), e sceglieremo tre modi diversi per cambiare le immagini. Condizione comune a tutti e tre i modi sarà quella di chiamare le immagini usando una numerazione progressiva: 1.jpg, 2.jpg, 3.jpg, ecc.; potremmo tranquillamente usare anche dei nomi classici, tipo marina.jpg, roma.jpg, sandra.jpg, ecc., ma usando numeri al posto di nomi facilita l'identificazione delle immagini soprattutto quando useremo i cicli.

  • in manuale - una volta disposto il nostro elenco di nomi, useremo una "Casella Combinata" presa da "Moduli". Sappiamo che questa "Casella Combinata", che funziona come riepilogo per selezionare un nome dell'elenco, restituisce, nella cella collegata, non il nome selezionato, ma il "numero dell'indice riga" relativo al nome selezionato nella casella stessa. Questo "numero indice" sarà il numero letto dalle istruzioni che vedremo e che servirà a riconoscere l'immagine corrispondente. Quindi se selezioneremo il sesto nome nella casella combinata, il numero che vedremo nella cella collegata sarà 6, chiaro fino a qui?

  • per attivare le istruzioni che provvedano al cambio con l'immagine richiesta, useremo una macro che chiameremo con un nome che simula un "evento", l'evento Cambia, la macro quindi la chiameremo :

  • Private Sub Adiscesa1_Cambia() - vediamo di capire questo nome: quando inseriamo qualcosa da Moduli, questo"qualcosa" in realtà appartiene all'insieme delle "Forme", e come tale gli viene assegnato da excel un nome ed un indice numerico: La Casella Combinata viene identificata come "Adiscesa" e come indice gli viene assegnato il numero 1 in quanto prima "Forma" inserita sul foglio di lavoro. Il nome della macro prende il nome quindi dal nome/indice della Forma e dall'azione che su questa eserciteremo, cioè un cambio di nome dell'elenco. (Ricordo che gli strumenti (improprio perchè Forme) presi da Moduli, NON possiedono "eventi", ecco perchè ho usato la parola "simula"). Ovviamente come "intervallo di input" per la casella a discesa useremo la colonna con i nomi che ci interessa collegare alle immagini.

Ma vediamo l'esempio di una possibile situazione: una tabella con nomi di piante, che formano l'input per la casella combinata (da B3 in poi), e la cella B1 come cella collegata: vediamo anche nella casella combinata la voce "ANGELICA", che è la sesta nell'elenco, selezionata e in B1 vediamo appunto il numero 6, a destra il controllo Image con la foto della pianta selezionata:

Selezionando un altro nome cambieremo anche l'immagine, e questa la semplice istruzione inserita in un modulo standard:

  • Private Sub Adiscesa1_Cambia()
    x = ActiveSheet.[B1].Value
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" & x & ".jpg")
    End Sub

Cosa dice l'istruzione: con la variabile "x" prendiamo il numero che è in B1, la seconda riga imposta l'istruzione necessaria a caricare l'immagine corrispondente. La sintassi deve essere uguale: identifichiamo il controllo Image1 sul foglio attivo, e impostiamo la sua proprietà "Picture" dicendogli con l'istruzione LoadPicture il percorso dove risiede l'immagine da caricare. Ognuno chiaramente scriverà il percorso dove saranno le immagini da caricare, sul proprio computer.

Un'altra routine, sempre attivabile manualmente, è la seguente dove sfrutteremo la colonna A, dove abbiamo scritto un numero progressivo a lato di ogni nome di pianta, con  l'evento Worksheet_SelectionChange del foglio di lavoro. Infatti o selezionando manualmente un numero o spostandoci con freccia su, freccia giù, attiviamo un cambio di selezione e le istruzioni all'evento associate. Inseriamo anche un controllo sfruttando Intersect in modo che la routine si attivi solo nel Range (colonna A) voluto:

  • Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Intersect(Target, Range("A3:A13")) Is Nothing Then
    Exit Sub
    Else
    x = ActiveCell.Value
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" & x & ".jpg")
    End If
    End Sub

 

  • in automatico - per ottenere il vero e proprio SlideShow avremo bisogno di un ciclo che legga i numeri della colonna A, collegando il numero nella cella in quel momento letta, col numero identificativo dell'immagine. In questo modo otterremo insieme allo scorrimento delle celle colonna A, anche lo scorrimento delle immagini. Solo che ci troviamo di fronte un problemino : lo scorrimento delle celle avviene talmente veloce da parte del codice, che le immagini non fanno in tempo ad essere caricate, e vedremmo solo l'immagine iniziale e la finale. Abbiamo bisogno quindi di "temporizzare" lo scorrimento delle immagini, per dare tempo a noi di goderci l'immagine, e per il controllo Image ad effettuare la sostituzione delle immagini. Il tempo di "visione" potremo deciderlo usando una cella dove scrivere il numero di secondi di temporizzazione, oppure di inserire detto valore direttamente nel codice, o ancora usare una InputBox con la quale reperire il numero di secondi (ricordiamoci Val(nomevariabile) per rendere come numero il valore preso con la inputbox). Vediamo la routine e relativi commenti in verde:

Sub ciclus()
Dim CEL As Range 'con Cel identifichiamo la cella

'sotto: impostiamo con "zona" l'area che vorremo spazzolare con il ciclo For Each
Set zona = ActiveSheet.Range([A3], [A3].End(xlDown))
For Each CEL In zona
 'inizio ciclo: per ogni cella nell'area "zona"
x = CEL.Value
'con la variabile "x" prendiamo il numero nella cella letta dal ciclo, e quindi 'carichiamo il controllo Image fornendo il percorso dove sono le foto
ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" & x & ".jpg")

'sotto: iniziamo il temporizzatore: è con PauseTime che stabiliamo quanti secondi fermare le 'istruzioni
Dim PauseTime, Start
PauseTime = 3
' si imposta la durata in secondi
Start = Timer
' Start sarà uguale a Timer e impostiamo il momento di inizio. Con la Funzione 'Timer otteniamo un valore Single che rappresenta il numero di secondi trascorsi dalla mezzanotte.

'--------------------
'sotto: inizia un ciclo While..Loop che confronta il Timer del momento con il valore rappresentato 'da Start + il numero di secondi di pausa, e fino a che Timer sarà inferiore di Start + PauseTime si 'continua il ciclo, dopodichè si esce e si proseguono le istruzioni (Next)
Do While Timer < Start + PauseTime
DoEvents
' durante l'esecuzione del ciclo, per non restare bloccati, si passa il controllo ad altri 'eventuali processi con DoEvents
Loop
Next
'con Next si corrono tutte le celle e all'ultima si esce, avvisiamo con un messaggio che siamo 'all'ultima immagine
MsgBox "Lo SlideShow è finito, torno alla prima"

'e si chiama la macro, che se nessuno aveva usato la casella combinata, è impostata sulla prima 'immagine e la visualiziamo
Adiscesa1_Cambia
End Sub

STAMPA.Questa routine è valida anche per ottenere stampe del foglio o comunque di ogni immagine che scorre, inserendo prima dell'istruzione Next, l'istruzione: Activesheet.PrintOut Copies:=1, Collate:=True (oppure Selection al posto di ActiveSheet ,se avrete selezionato un area da mandare in stampa), in questo caso PauseTime sarà sufficiente impostarlo a 1 secondo. Infatti la velocità di scorrimento di un ciclo è maggiore della capacità di aggiornamento del controllo Image, e se non si interpone una pausa tra un ciclo e il successivo, si stamperebbe solo la prima immagine caricata.

Un altro modo di usare cicli per ottenere uno SlideShow sarà quello di usare un ciclo For..Next, indicando come numero iniziale e numero finale i numeri che rappresentano i due limiti estremi dei nomi delle immagini, senza necessità di scorrere le celle come nel precedente ciclo For Each..Next, esempio:

  • For N = 1 To 10  'inizio ciclo che si ripeterà per 10 volte, tante quante saranno le immagini
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" & N & ".jpg")

  • seguono le istruzioni per temporizzare

  • Next

Nota: per evitare errori se l'immagine da caricare non esiste o non è esatto il nome-numero, consiglio di usare la gestione degli errori.

Un suggerimento per usare per il nome delle immagini non solo un numero, che può essere poco descrittivo o a noi poco riconoscibile, ma anche un nome più necessariamente un numero, sul tipo di Amalfi1.jpg, Amalfi2.jpg, ecc.ecc., può essere letta questa istruzione sotto, dove concateniamo un nome alla variabile assegnata al ciclo:

  • x = CEL.Value 'x corrisponde al numero letto dal ciclo For Each
    y = "Amalfi" & x & ".jpg"
    'con y otteniamo la concatenazione del nome Amalfi + il numero x + l'estensione
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" + y)

Se invece avremo scelto il ciclo For Next, dove è N la variabile che porta il numero, l'esempio sarebbe:

  • For N = 1 To 10  'inizio ciclo che si ripeterà per 10 volte, tante quante saranno le immagini
    y = "Amalfi" & N & ".jpg"
    'con y otteniamo la concatenazione del nome Amalfi + il numero N + l'estensione
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" + y)

Ma esistono ancora altre possibilità, una potrebbe essere quella di destinare una cella come contenitore di un nome, che quindi diventerebbe modificabile, ed assegnare la cella alla variabile y, per esempio in A1 scriviamo Amalfi:

  • For N = 1 To 10  'inizio ciclo che si ripeterà per 10 volte, tante quante saranno le immagini
    y = [A1].Value & N & ".jpg"
    'con y otteniamo la concatenazione del nome n A1 + il numero N + l'estensione
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" + y)

o ancora, supponendo che le immagini l'avessimo chiamate col  SOLO nome della pianta (vedi prima immagine sopra), potremmo usare il ciclo For Each Next scorrendo le celle della colonna B, in questo caso la variabile x porterebbe già il nome della foto, così:

  • Set zona = ActiveSheet.Range([B3], [B3].End(xlDown)) 'si cambia la colonna
    For Each CEL In zona
     'inizio ciclo: per ogni cella nell'area "zona"
    x = CEL.Value
    'con la variabile "x" prendiamo il NOME nella cella letta dal ciclo
    y = x & ".jpg" 'con y otteniamo la concatenazione del nome x + l'estensione
    ActiveSheet.Image1.Picture = LoadPicture("C:\Immagini\" + y)

Insomma, ce n'è per tutti i gusti, fate le vostre prove, ci sono altre possibilità, scopritele, e buon divertimento.

Buon lavoro.

prelevato sul sito www.ennius.altervista.org