Il blog di Gianni Giaccaglini

Blog su VBA e VSTO
Gianni Giaccaglini

My Links

News

NB - V. anche gli ARTICOLI (in fondo a questa barra)
Solo quesiti validi a: giannigiac@tin.it
Il mio Best seller su VBA
(v. www.hoepli.it)


Il mio ultimo libro su Open XML
(v. www.FAG.it):



La mia nipotina ELISA

Foto con dedica a ME di
Bill Gates giovanissimo
nei mitici anni 80!

Categorie Post

Categorie Articoli

Archivio

Immagini

Blog Stats

Prime novità di Office 2007: CommandBar e nuova proprietà Range di oggetti vari

Prime novità di Office 2007: CommandBar e nuova proprietà Range di oggetti vari

Non ho qui intenzione esaurire il tema delle nuove funzionalità di Office 2007. La medicina va presa a piccole dosi, con qualche prudente sguardo alle novità delle macro, peraltro non proprio sconvolgenti, almeno a prima vista.

Barre strumenti personali: addio?

Da più di un visitatore è pervenuto un grido di dolore, più o meno del tenore seguente: Che fine hanno fatto le mie belle barre personalizzate, coi loro bravi pulsanti e controlli che scatenano le mie macro in qualunque punto del foglio o del documento?

Risposta: non sono sparite, il timore che qualcuno potrebbe nutrire viene presto fugato. Di che timore parlo? Del fatto che ora tutte le barre strumenti non personali sono assorbite dal nuovo Ribbon, (mal) tradotto in Barra multifunzione  nell’edizione italiana (ma, ohibò,  non andava benone Nastro?). Anticipo che anche questo si può personalizzare anche a fondo, mediante opportuni file XML (v. http://blog.shareoffice.it/giannigiaccaglini/articles/8979.aspx )

La cosa curiosa è che le vecchie barre non sono state “uccise”, anzi si possono ancora trattare in VBA. Eccone subito alcuni esempi, relativi alle CommandBar File e Task Pane, che poi – chi non lo sapesse – corrispondono al menu File e al riquadro delle attività.

Application.CommandBars("File").Visible = True 'oppure = False

Application.CommandBars("Task Pane").Visible = True 'oppure = False

Application.CommandBars("File").Enabled = False 'Disabilita il menu File?

‘sì in Word o Excel 2003, niente affatto in Word o Excel 2007

Application.CommandBars("Task Pane").Enabled = False 'idem c.s.

Office 2007 accetta senza fare una piega tali comandi, che però purtroppo non hanno nessun effetto e si continua a vedere l’intero Ribbon, di cui le vecchie barre (o, forse più esattamente, i loro comandi e controlli) dovrebbero pur continuare a far parte. Si scopre inoltre che i valori default della proprietà Visible sono False, mentre gli Enabled sono True, ma la modifica a False lascia le cose immutate. Verrà così delusa qualche anima spericolata, avvezza a disabilitare comandi o interi menu, per inibirne l’uso all’utente finale, così impara ad essere, anzi a non essere, così cattivo…

Le barre personali fanno eccezione (in parte)

Il timore dell’angosciante domanda in apertura viene fugato, come anticipato. Infatti presto si scopre che esse vanno, automaticamente, a far parte della zona Componenti aggiuntivi del Ribbon. Meno male, però si evidenzia pure un limite di questa faccenda (che così risulta consolatoria solo parzialmente):

  • Se si clicca su una diversa sezione (Tab) del Ribbon scompare, così funziona il Ribbon, quella dei Componenti aggiuntivi e, con essa, pure le barre personali;
  • Legata a questa c’è la pratica impossibilità di farle fluttuare sul foglio o documento.

La cosa ha un risvolto anche in VBA:

Application.CommandBars("MiaBellaBarra").Floating = msoFloating

La precedente istruzione non viene rifiutata, ma non ha effetto. Idem con le altre opzioni della proprietà Floating, come msoTop, msoBottom, msoLeft ecc, che, lungi dal porre la barra in cima, in fondo o altrove, la lasciano custodita nel girone dei, stavo per dire dannati, Componenti aggiuntivi. Insomma, dobbiamo continuamente cliccare lì per vederla e usarla.

Sempre alle barre personali si applicano e funzionano invece le proprietà Visible ed Enabled

Nota – Questi discorsi, nel bene e nel male, valgono anche per le barre e controlli che certi programmi, come Adobe, hanno aggiunto in precedenza a Word o Excel 2003. Sono regolarmente ereditati dai corrispondenti membri della famiglia 2007.

Dimenticavo di dire che, come d’altronde anticipato nel titolo di questo paragrafo:

  • Creare manualmente nuove barre personali come avveniva nel mondo 2003 è impossibile; inutile fare clic destro sul Ribbon, non si vedono né si possono modificare barre di sorta né tantomeno crearne di nuove; il clic destro apre solo due opzioni relative alla barra di accesso rapida;
  • in tale nuova barra, che diamo per nota, si possono solo inserire comandi standard (quelli d’uso più comune per ciascuno) ed è vano ogni tentativo di incorporarvi icone o pulsanti cui associare macro, anzi non sembra proprio che non faccia in nessun modo parte delle combriccola delle CommandBar, ergo escluderei che si possa programmare in VBA (se qualcuno mi può smentire si faccia vivo)
  • lo si può però fare mediante codice VBA e anche in questo caso la neonata barra personale si colloca nel calderone dei Componenti aggiuntivi.

Ed ecco del codice (senza commenti) atto a creare una barra personale formata da tre generici menu e ad aggiungervi altrettanto generiche voci, associando con OnAction - per brevità alla sola seconda voce - tre ridicole macro.

Sub CreaMenu(PBarra, VettMenu)

  'Crea una barra personale temporanea di nome PBarra,

  'formata da menu attinti da un array VettMenu

  Dim i As Integer

  Set Bar = CommandBars.Add(Name:=PBarra, temporary:=True)

    Bar.Visible = True

    For i = 0 To UBound(VettMenu)

      Bar.Controls.Add Type:=msoControlPopup

      With Bar.Controls(i + 1)

        .Caption = VettMenu(i)

      End With

    Next

End Sub

 

Sub ProvaCreaMenu()

  'Crea tre generici menu in una "MiaBarra" 

  CreaMenu PBarra:="MiaBarra", _

  VettMenu:=Array("Menu1", "Menu2", "Menu3")

End Sub

 

Sub AggiungiVoci(PBarra, NumContr, VettVoci, VettMacro)

  'Aggiungi al menu NumContr di una barra personale PBarra,

  'comandi attinti da un array VettVoci, associando a

  'ciascun commando una macro attinta da un VettMacro

 Dim i As Integer

  With CommandBars(PBarra).Controls(NumContr)

    For i = 0 To UBound(VettVoci)

      With .Controls

        .Add

        .Item(i + 1).Caption = VettVoci(i)

        .Item(i + 1).OnAction = VettMacro(i)

      End With

    Next

  End With

End Sub

 

Sub ProvaAggiungiVoci()

  'Aggiungi voci e relative macro al secondo menu

  'della “MiaBarra”

   AggiungiVoci PBarra:="MiaBarra", NumContr:=2, _

   VettVoci:=Array("Voce1", "Voce2", "Voce3"), _

   VettMacro:=Array("Mac1", "Mac2", "Mac3")

End Sub

 

'Seguono tre macro-del-cavolo evocate dalle

'predette Voce1, Voce2  e Voce3...

 

Sub Mac1

  MsgBox "Ciao, sono la macro 1"

End Sub

Sub Mac1

  MsgBox "Ciao, sono la macro 2"

End Sub

Sub Mac1

  MsgBox "Ciao, sono la macro 3"

End Sub

Programmabilità del Ribbon? Sì e multiforme, ma tramite XML

I tradizionalisti incalliti si accorgeranno che, benché la nuova barra multifunzione rassomigli vagamente a una barra menu non si comporta allo stesso modo per un aspetto: la seconda, una volta selezionato un menu, permette di spostarsi da un menu all’altro trascinando il cursore del mouse o semplicemente le fredde destra e sinistra, mentre il Ribbon esige dei clic per passare da una Tab all’altra. Pazienza, ci faremo il callo.

Quel che invece è bene sottolineare fin d’ora è che la barra multifunzione non si può programmare almeno direttamente in VBA.

La pratica non applicabilità di codice VBA alle vecchie barre strumenti ne è un indizio, cui se ne possono aggiungere altri due:

  • Se si prova ad accendere il Registratore delle macro, sull’operazione manuale della selezione di una sezione del Ribbon non si ottiene nulla;
  • Idem se si cerca nella Guida un qualche oggetto Ribbon, con specifiche proprietà e metodi.

Che cosa è successo? Navigando con pazienza nella Guida si scopre che il Ribbon è un oggetto interamente XML! Pertanto lo si può modificare adattandolo a tutte le esigenze modificando lo schema XML o creando un proprio schema del genere. E il bello è che si possono anche inserire nuovi tipi di controlli ai quali sono associabili macro On Action (in modo, si direbbe, concettualmente simile a quanto avviene già coi controlli delle vecchie barre personali.

L’argomento apre nuovi orizzonti su cui ci proponiamo di dare qualche lume appena possibile, dicendo fin d’ora che documentazione adeguata è reperibile sul sito MSDN di Microsoft, mentre la Guida VBA comprende l’argomento anche con esempi vari, ma… non brilla per chiarezza, almeno per chi inizia. Vedremo.

La proprietà Range applicabile a nuovi oggetti

Concludiamo con questa semplice ma utile novità di Excel 2007, che consiste nella possibilità di applicare la proprietà Range a una varietà di oggetti, restituendone l’intervallo associato. Per entrare in medias res, forniamo due esempi relativi all’oggetto Autofilter, ovvero all’elenco del foglio cui è applicato il Filtro automatico (altrimenti si ha errore…):

Sub SegnalaZonaFiltroAutom()

  With ActiveSheet.AutoFilter.Range

    MsgBox .Address

    If MsgBox("Seleziono l'intervallo del Filtro?", vbYesNo) = _

    vbYes Then .Select

  End With

End Sub

Sub SpostaFiltroAutom()

 'Sposta l’elenco filtrate in F4

  ActiveSheet.AutoFilter.Range.Cut Range("F4")

End Sub

Nel primo caso vengono segnalati i riferimenti dell’elenco, poi questo viene selezionato se l’utente accetta la proposta. Già questo fa capire che l’oggetto Range restituito non è read-only (se qualcuno lo temeva) ma può essere ulteriormente manipolato, come mostra la seconda più “audace” routine.

Per finire due esempi relativi all’oggetto Hyperlink, che anch’esso ora gode della proprietà Range.

Sub ProvaHypRange()

  Set hr = ActiveSheet.Hyperlinks(1).Range

  ActiveWindow.ScrollRow = hr.Row

  ActiveWindow.ScrollColumn = hr.Column

  If MsgBox("Torno all'ovile?", vbYesNo) = vbYes Then

    ActiveCell.Select

  End If

End Sub

In questo caso il primo legame ipertestuale del foglio viene visualizzato nell’angolo in alto a sinistra della finestra portandone lo scroll orizzontale e quello verticale a livello della riga e colonna del link, senza, si badi bene, che cambi la cella corrente. Pertanto forzando la selezione di questa la si fa tornare in primo piano.

La Sub seguente va testata dopo aver sparso qua e là nel foglio di versi legami ipertestuali locali (diciamo che puntano a celle di altri fogli).

Sub EsploraLink()

  Dim Lnk As Hyperlink, hr As Range, AttW As Window

  'Dim Ovile As Range

  Set AttW = ActiveWindow

  Set Ovile = ActiveCell

  For Each Lnk In ActiveSheet.Hyperlinks

    Set hr = Lnk.Range

    AttW.ScrollRow = hr.Row

    AttW.ScrollColumn = hr.Column

    If MsgBox("Lancio l'hyperlink?", vbYesNo) = vbYes Then

      ActiveCell.Select

      Lnk.Follow

      Exit For

    End If

  Next

  ActiveCell.Select

End Sub

Anche in questo caso ogni link spazzolato dal ciclo For Each Lnk  ... Next viene messo in evidenza ponendo all’utente la richiesta di lanciarlo o meno, cosa che viene fatta in caso affermativo con lnk.Follow.

?>

?>

posted on venerdì 23 marzo 2007 19.21