Lavorare con gli Shapes.       (19/06/03)

Vedi anche articolo "Lavorare con gli "oggetti"" sito ennius.altervista

Gli Shapes (le Forme) sono un "territorio" abbastanza vasto dato il numero elevato di Forme disponibili su foglio di lavoro, ma in seguito ad una richiesta, visto poi che non è difficile capirne le basi, presento un esercizio che forse può interessare altri pellegrini.

Intanto cosa sono gli Shapes: sono "oggetti" (non "Oggetti" ActiveX) appartenenti al gruppo "Disegno", quali una Forma, una figura a mano libera, un rettangolo, un cerchio, una casella di testo, un oggetto OLE o un'immagine, e che si possono inserire sul foglio di lavoro semplicemente selezionando l'icona dell'oggetto posta nella finestra "Disegno", e poi, cliccando in un punto del foglio di lavoro, trascinare tenendo premuto il pulsante sinistro, per ottenere il dimensionamento voluto. Ogni oggetto Shape può essere inserito non solo manualmente, ma anche tramite codice vba: sconsiglio alle "reclute" l'inserimento tramite codice, visto che la creazione di uno Shape, che peraltro si ottiene con il metodo AddShape, comporta la definizione di un numero elevato di istruzioni (e a secondo il tipo di Shape scelto, di "nodi" ) che servono per il posizionamento dello Shape sul foglio di lavoro, oltre ai valori che ne determinano la dimensione e le caratteristiche, operazione complessa per chi vuol compilarlo da solo. Per verificare quanto appena detto, attivate il "registratore di macro", date un nome alla macro o lasciate il nome che propone Excel, e poi inserite uno Shape, posizionandolo e dimensionandolo, agendo sui circoletti che appaiono intorno al perimetro dello Shape, e dategli un colore; ad operazione ultimata, stoppate il registratore e recatevi nell'editor di visual basic, su un modulo troverete la macro che Excel ha compilato per voi, e vedrete tutte le istruzioni che servono a "creare" e impostare lo Shape. Qui sotto vi riporto un esempio per creare uno Shape rettangolo :

ActiveSheet.Shapes.AddShape(msoShapeRectangle, 108.75, 30#, 84.75, 30#).Select

Selection.ShapeRange.Fill.Visible = msoTrue
Selection.ShapeRange.Fill.Solid
Selection.ShapeRange.Fill.ForeColor.SchemeColor = 11
Selection.ShapeRange.Fill.Transparency = 0#
Selection.ShapeRange.Line.Weight = 0.75
Selection.ShapeRange.Line.DashStyle = msoLineSolid
Selection.ShapeRange.Line.Style = msoLineSingle
Selection.ShapeRange.Line.Transparency = 0#
Selection.ShapeRange.Line.Visible = msoTrue
Selection.ShapeRange.Line.ForeColor.SchemeColor = 64
Selection.ShapeRange.Line.BackColor.RGB = RGB(255, 255, 255)

Ogni Shape comunque inserito, viene identificato da un nome che identifica il "tipo" di oggetto, ed un numero progressivo (indice) per ogni  oggetto Shape inserito, indipendentemente dal "tipo". Ad esempio, se inseriamo un Rettangolo, nelle istruzioni andrà identificato con  Shapes("Rectangle 1"), se ne inseriamo un secondo, il suo identificativo sarà Shapes("Rectangle 2"), se inseriamo un  "ovale" il suo identificativo sarà Shapes("Oval 3") e così via.

Attenzione : se cancelliamo uno Shape e poi ne inseriamo uno nuovo, il numero assegnato al nuovo NON sostituisce il numero di quello cancellato, ma andrà in progressione; Excel memorizza infatti tutti gli oggetti Shape inseriti, anche quelli cancellati, ed assegna il numero successivo

Ma come caspita facciamo a conoscere con quale nome e numero Excel (il suo vba) identifica un oggetto, visto che quando lo si inserisce (con una routine come quella sopra) col metodo AddShape, il nome dell'oggetto viene assegnato usando una costante (tipo : msoShapeRectangle ) (vedi elenco costanti) e non con Shapes("Rectangle X") ?

Mi permetto di suggerire un metodo pratico e veloce: inseriamo manualmente il o i nostri Shapes, senza curarci di registrare niente; una volta inserito/i, attiviamo il registratore di macro indi clicchiamo sul o sugli Shapes; ora fermiamo la registrazione e nella macro creata da Excel, andiamo a leggere: troveremo il o i nomi con relativo numero indice e l'istruzione Select. Basterà ricordarsi con quale ordine abbiamo cliccato (selezionato) gli Shapes per trovare il relativo nome, un esempio:

ActiveSheet.Shapes("Rectangle 1").Select
ActiveSheet.Shapes("Rectangle 5").Select
ActiveSheet.Shapes("AutoShape 3").Select
ActiveSheet.Shapes("Freeform 2").Select
ActiveSheet.Shapes("AutoShape 4").Select
ActiveSheet.Shapes("Rectangle 6").Select

Aggiornamento:  Per chi invece voglia affidarsi a istruzioni Vba per reperire nome e id di ogni Shape inserito su in foglio, può usare questa routine che inizia contando il numero degli Shapes presenti, e tramite un ciclo For..Next, ci restituisce un messaggio con il nome e del numero id di ogni Shape trovato scorso dal ciclo. Sarà facile sapere quindi di un certo Shape Immagine (chiamato Picture), magari inserito e poi eliminato varie volte, quale numero id attuale possiede; questa la macro:

  • Sub DimmiNomeShape()
    Dim N As Integer
    x = ActiveSheet.Shapes.Count
    For N = 1 To x
    MsgBox ActiveSheet.Shapes(N).Name
    Next
    End Sub

  • fine aggiornamento

Un'altra possibilità di intervento sugli Shapes, ma questa la facciamo dal foglio di lavoro, è quella di richiamare, cliccando col destro del mouse sullo Shape, un menù contestuale, e da questo scegliere "Aggiungi testo" (e potremo inserire una parola o una frase) oppure scegliere "Formato Forme" che aprirà la relativa finestra dove saranno possibili tutta una serie di regolazioni, dalla scelta del font ed il suo colore, al centraggio del testo, al colore di fondo dello Shape, la sua trasparenza, la possibilità di impostare sfumature di colore, bloccarlo o meno, ecc. ecc. Tutte operazioni che comunque possiamo fare dopo aver attivato il registratore di macro, in modo da poter curiosare, ed apprendere, come il codice imposta tutti i passaggi che noi abbiamo fatto.

Ma veniamo all'esercizio: vogliamo "disegnare" sul foglio delle aree da usarsi come "mappe", cioè identificativi di zone, come se si fosse su una cartina topografica. Vogliamo che ad ogni click si attivino delle istruzioni, e che lo Shape cambi colore : ad ogni colore, vogliamo che vengano eseguite istruzioni diverse. Useremo lo Shape come se fosse un Commandbutton, al quale ad ogni click facciamo cambiare la Caption e quindi le istruzioni correlate.

Per prima cosa, useremo, per il disegno a mano libera, la Forma: "Figura a mano libera", reperibile dal menù Disegno/Forme/Linee/Figura a mano libera, così come nella sottostante immagine:

Realizzeremo un perimetro che chiuderemo ad anello con un doppio click di sinistro, e dopo aver impostato un colore, e regolata la trasparenza al 50%, otterremo una cosa del genere:

ora prepariamo una macro, dandogli un nome, nella quale inserire le nostre istruzioni. (quando la macro sarà compilata, tornando col destro sullo Shape, nel menù contestuale sceglieremo: "Associa macro" associandogli il nome della macro. Le istruzioni sono semplici, unica cosa che sottolineo è la necessità di selezionare lo Shape (per identificarlo) usando il metodo Select di cui Selection è una proprietà che utilizzeremo usando l'istruzione With :

Sub Dimmi()
ActiveSheet.Shapes("Freeform 1").Select
'si seleziona lo shape
With Selection 
'con la selezione attiva:

'sotto: Se il colore dello shape è ugualr a verde, allora
If .ShapeRange.Fill.ForeColor.SchemeColor = 13 Then

'mi cambi in suo colore in giallo
.ShapeRange.Fill.ForeColor.SchemeColor = 3

'ed esegui queste istruzioni (io ho messo una semplice messagebox, ma potranno essere 'eseguite qualsiasi tipo di istruzioni) :
MsgBox "Sono uno Shape"
Range("A1").Select 
'per deselezionare lo shape


Else
'altrimenti (cioè se il colore non è verde, e infatti sarà giallo dopo il primo click)

'esegue queste altre istruzioni (nell'esempio ancora un messaggio)
MsgBox "Buongiorno a tutti"

'ora colora di nuovo di verde, creando l'alternanza per la condizione If
.ShapeRange.Fill.ForeColor.SchemeColor = 13
Range("A1").Select   
'per deselezionare lo shape
End If
End With
End Sub

E questo, a parte il messaggio che non mostro, è l'effetto del cambio colore:

Come vedete non è difficile capire le istruzioni, l'unica cosa, non sono riuscito a trovare i codici colori usati da Fill.ForeColor.SchemeColor, consiglio i volenterosi, di selezionare sul foglio lo Shape, attivare il registratore di macro, e dalla finestra Formato Forme, cominciare a cambiare colore all'oggetto; in questo modo, a fine registrazione, avrete i codici colore scritti nella macro che il registratore avrà creato. Potrete segnarveli e poi cancellare la macro.

Se poi cerchiamo di conoscere

Buon lavoro

prelevato sul sito http://ennius.interfree.it