Neste breve artigo discutirei a criação de um menu dinâmico na nova interface de usuário do Excel 2007. Este artigo é um excerto do material de treinamento sobre programação do RibbonX o qual pode ser adquirido na loja do site em: http://shop.linhadecodigo.com.br/treinamento.asp?id=2778. No Treinamento, o leitor aprenderá todo o processo de programação e implementação das soluções desenvolvidas.
Para aqueles que se acostumaram com o antigo método de personalização das barras de ferramentas o novo método pode parecer horrível. Não obstante a nova complexidade introduzida no RibbonX, a flexibilidade e novas possibilidades de personalização vão muito além do que é possível fazer no antigo sistema. Por exemplo:
- Você alguma vez precisou desabilitar um comando no Excel (digamos, o comando “Imprimir”)? Se sim, o leitor recordará das implicações disso. Na nova interface, podemos fazê-lo globalmente evitando brechas na impressão;
- Precisou remover o menu principal pelo seu? Lembra da implicação disso para outras sessões do Excel?
- Alguma vez precisou adicionar imagens em grupos? Agora, podemos fazê-lo rapidamente como mostra a figura:

Figura 1: Criando galerias de imagens
Ao passo que é verdadeiro que requererá um pouco mais de tempo nosso no XML, é muito mais verdadeiro que as possibilidades mais do que compensam tal trabalho. Além do que para os que desenvolvem em VS.NET o trabalho é facilitado pelos “schemas” XML que adicionam “Intellisense” durante a criação.
Portanto, vamos supor o seguinte cenário: existe uma determinada interface que deve somente ser mostrada quando algo é clicado (como as guias sensíveis ao contexto). Em situações como estas, nós queremos criar o conteúdo dinâmicamente para que o mesmo seja mostrado somente nas situações determinadas.
Obtemos tal resultado utilizando o atributo getContent. O valor do atributo é, na verdade, um callback (um procedimento VBA) que deve ser executado para determinar o conteúdo.
Vejamos um exemplo simples de como isso pode ser feito. A figura abaixo mostra a nossa guia com um menu sem conteúdo:

Figura 2: Menu de conteúdo dinâmmico
O conteúdo do menu deve ser mostrado quando a célula A1 da primeira planilha for diferente de vazio. Aqui, teremos dois trabalhos distintos envolvendo XML (os quais podem ser feitos no CustomUI Editor ou outro editor de XML qualquer):
· Criar o XML para definir a guia conforme mostrado acima;
· Criar o XML para ser inserido dinamicamente no VBA o qual será retornado pelo callback especificado no atributo getContent.
Vamos iniciar pelo XML que criará a guia, grupo e botão conforme a figura anterior:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="setRib">
<ribbon startFromScratch="false">
<tabs>
<tab
id="idGuia"
insertBeforeMso="TabHome"
label="Minha Guia">
<group
id="ifGrp"
label="Meu Grupo">
<dynamicMenu id="idDMnu"
getContent="conteudoDin"
imageMso="Spelling"
label="Meu Menu Dinâmico"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Note o atributo getContent do menu dinâmico no XML acima. É este callback que será utilizado para escrever o conteúdo dinamicamente.
Note também o atributo onLoad. Aqui, utilizamos tal atributo para podermos invalidar a Faixa de Opções e forçar a chamada do callback conteudoDin.
O próximo passo requer a criação do conteúdo dinâmico. Neste caso, o ideal é criar um novo arquivo Excel e criar toda a interface e testá-la. Uma vez que tal interface esteja pronta, nós precisamos transformá-la em uma string que será utilizado no VBA.
Este processo requererá um pouco de paciência e cuidado. Lembre-se que usamos as aspas (“”) para abrir e fechar uma string. Não obstante, o código XML já conterá aspas que envelopam os valores dos atributos (por exemplo, getContent="conteudoDin").
Neste caso, precisamos duplicar as aspas para que não haja erro na string durante o callback.
Vejamos então uma string contendo o código XML:
xml = "<menu xmlns=""http://schemas.microsoft.com/office/2006/01/customui"">" & _
"<button id=""btn1"" imageMso=""FileOpen"" label=""Abrir doc"" onAction=""callbackDin"" />" & _
"<button id=""btn2"" imageMso=""ChartTypeAllInsertDialog"" label=""Criar gráfico"" onAction=""callbackDin"" />" & _
"<button id=""btn3"" imageMso=""XmlDataRefresh"" label=""Atualizar Dados XML"" onAction=""callbackDin"" />" & _
"</menu>"
Finalmente, precisamos gerar os callbacks e exportá-los para o VBA onde escreveremos o miolo. Iniciaremos pelo VBE da pasta de trabalho onde inseriremos o código a seguir:
Option Explicit
Private Sub Workbook_Open()
' Ao abrir, determina se a célula A1 possui
' algo escrito
If Sheet1.Range("A1") <> "" Then
' Variável global declarada no módulo
' como sendo pública
blnConteudo = True
End If
End Sub
Agora, inseriremos o código no VBE da planilha 1 (sheet1) para checar se o valor em A1 é diferente de vazio. A checagem ocorrerá sempre que algo for modificado na planilha:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' O valor booleano para determinar se o conteúdo
' é ou nao mostrado é definido de início como "False" (falso)
blnConteudo = False
' Checar para saber se há algo na célula A1
If Sheet1.Range("A1") <> "" Then
' Se sim, modificar o valor booleano para "True"
blnConteudo = True
End If
' Chamar a rotina que invalida o RibbonX
Call invalidarRib
End Sub
Finalmente, adicione um módulo onde inseriremos os callbacks como segue:
Option Explicit
'Variável booleana pública para determinar
'Se o conteúdo é ou nao mostrado
Public blnConteudo As Boolean
'Variável global representando o nosso RibbonX
Dim mRib As IRibbonUI
'Rotina a ser chamada para invalidar o RibbonX
Sub invalidarRib()
mRib.Invalidate
End Sub
'Callback executado quando o ribbon é carregado
'(refere-se ao atributo onLoad)
Sub setRib(ribbon As IRibbonUI)
' Instancia a variável global como sendo o ribbon
Set mRib = ribbon
' Invalida o Ribbon forçando a reexecução dos callbacks
mRib.Invalidate
End Sub
'Callback para gerar o conteúdo dinâmica
Sub conteudoDin(control As IRibbonControl, ByRef returnedVal)
' Variável do tipo string para armazenar o código xml
Dim xml As String
' Código xml do conteúdo dinâmico. Note que podemos definir
' callbacks dentro deste conteúdo xml. Porém, não esqueça de
' adicionar tais callbacks ao seu conteúdo VBA.
xml = "<menu xmlns=""http://schemas.microsoft.com/office/2006/01/customui"">" & _
"<button id=""btn1"" imageMso=""HappyFace"" label=""Smile"" onAction=""callbackDin"" />" & _
"<button id=""btn2"" imageMso=""FormatPainter"" label=""Paint"" onAction=""callbackDin"" />" & _
"<button id=""btn3"" imageMso=""AutoFilter"" label=""Filter"" onAction=""callbackDin"" />" & _
"</menu>"
' Checar o valor booleano e determinar o que deve ser mostrado
If blnConteudo = True Then
' Se verdadeiro, mostrar conteúdo dinâmico
returnedVal = xml
Else:
' Caso contrário, mostrar nada.
returnedVal = False
End If
End Sub
Sub callbackDin(control As IRibbonControl)
MsgBox "Você clicou no botão de id: " & control.ID, vbInformation
End Sub
Salve, feche o arquivo e abra-o novamente. A interface dinâmica está pronta para uso, bastando apenas modificar o valor contido na célula A1 da planilha 1:

Figura 3: Resultado do conteúdo criado dinamicamente
Conclusão
Neste curto artigo mostro como modificar a nova interface de usuário do Excel utilizando conteúdo dinâmico.
Este artigo é excerto do material de Treinamento encontrado em http://shop.linhadecodigo.com.br/treinamento.asp?id=2778 o qual trata exclusivamente da programação e personalização da interface do RibbonX. No Treinamento, o leitor aprenderá todo o processo de programação e implementação das soluções desenvolvidas.
O material é desenvolvido sobre o Excel 2007 português e não é compatível com a versão Beta 2 do Excel. Os interessados podem obter um cópia do Office 2007 Trial em http://us1.trymicrosoftoffice.com/ para acompanhar o Treinamento.
Robert Friedrick Martim, Expert da Comunidade Excel
Robert Martim é Economista, Formado e Pós-Graduado em Finanças pela Universidade de Londres, Microsoft MVP Excel.
Conheça alguns dos e-books do autor sobre Excel e Access: