Visual Basic em Português

Página pessoal de Jorge Paulino sobre o Visual Basic (VB.NET, ASP.NET, VB6, VBA) e algumas noticias de tecnologia

Revista PROGRAMAR - 33ª Edição Fevereiro de 2012

Revista PROGRAMAR
 Edição 33 - Fevereiro de 2012

(clica para download)


Nesta edição continuaremos também a premiar os autores dos três melhores artigos, dado o sucesso nas edições anteriores. E os leitores devem dar a sua opinião para que possamos premiar correctamente. Para isso vote em http://tiny.cc/ProgramarED33_V

Assim nesta edição trazemos até si, como artigo de capa, um artigo sobre Kinect Hack para conhecer melhor algumas técnicas de programação para este novo dispositivo. Nesta 33ª edição pode ainda encontrar os seguintes artigos:

  • Geração de Números Aleatórios - Parte 3 - O terceiro de 4 artigos do mesmo autor da excelente série “Programação em Lua”, desta vez sobre geração de números aleatórios.
  • Herança com JavaScript - Saiba como usar a funcionalidade herança do paradigma da programação orientada por objetos na linguagem de programação JavaScript
  • Programação Orientada aos Objectos em Pascal - Pensa que o Pascal é uma linguagem apenas de aprendizagem e que parou no tempo? Então mude de ideias e veja como pode tirar partido do paradigma da programação orientada aos objetos nesta linguagem
  • VISUAL (NOT) BASIC -Iterators - Saiba como pode utilizar iteradores na próxima versão da linguagem de programação Visual Basic (neste momento disponível em Developer Preview).
  • CORE DUMP - Ambientes Produtivos - Será que os ambientes produtivos disponibilizados pela gestão aos trabalhadores são os melhores? Conheça a opinião deste autor
  • Enigmas de C#: Disposable Structs - Mais um enigma da linguagem de programação C#, desta vez envolvendo Disposable Structs
E ainda em colaboração com as comunidades NetPonto, AzurePT e SharepointPT, respectivamente: 
  • BizTalk Server - Como funcionam os mapas - Continuação do artigo sobre princípios básicos dos mapas publicado na edição anterior
  • SQL Azure Federations na prática - Aprenda a implementar o padrão Sharding, que permite aumentar a escalabilidade de bases de dados de grandes dimensões.
  • Desenvolvimento em SharePoint 2010 - Parte 2 - Continuação do artigo anterior, desta vez saiba como desenvolver um sistema básico de logging
Mais informação

Excel: Dicas de VBA - vLookupValues() uma Variante do Vlookup()

A função VLOOKUP (PROCV em Português) é uma função muito interessante e muito utilizada pois permite procurar por um valor numa tabela/matriz e devolver o valor que está na coluna ou na coluna à direita, indicando-se para isso o índice. Existe também a função HLOOKUP (PROCH em Português) para pesquisas na horizontal.

Para quem nunca utilizou, este é o sintaxe da função:

=VLOOKUP(valor procurar; tabela; coluna a devolver; resultado aproximado)

Mas vejamos um exemplo simples para mostrar como funciona a função VLOOKUP.

Como podem ver na imagem anterior temos uma tabela com duas colunas. Na coluna A temos a selecção, utilizando um ‘x’ (podíamos procurar por número, ID, etc.) e na coluna B temos nomes de B2 a B9. Se quisermos procurar o nome que está selecionado podíamos usar a seguinte função:

=VLOOKUP("x";A2:B9;2;FALSE)

O resultado na célula onde colocássemos a função seria “Paulo”

Breve descrição dos argumentos:

  • O primeiro argumento (x) indica o valor a procurar;
  • O segundo argumento (A2:B9) indica a matriz, sendo a coluna da esquerda a coluna onde vamos procurar os valores (neste caso a coluna A);
  • O terceiro argumento (2) indica a coluna de onde será devolvido o valor. Neste caso vamos devolver o valor que está na coluna B (2ª coluna), e por isso indicamos o valor 2, mas se tivéssemos mais colunas, por exemplo números de telefone na coluna C, poderíamos indicar como valor 3 e modificar o segundo argumento de A2:B9 para A2:C9.
  • O quarto argumento (FALSE) indica que não queremos resultados aproximados mas sim exactos

Mas por muito interessante e útil que a função seja só nos devolve um resultado, ou seja, se selecionar dois ou três nomes, apenas irá devolver o primeiro que encontrar.

Usando VBA podemos resolver esta “limitação” e devolver múltiplos resultados de acordo com as selecção. Para isso podemos criar um novo módulo e utilizar o seguinte código:

Public Function VLookupValues(lookupValue As String, _
            lookupRange As Range, _
            columnIndex As Integer, _
            Optional distinct As Boolean = False) _
            As String
           
Dim x As Long
Dim result As String
 
On Error GoTo errVLookupValues
 
    ' Ciclo em todas as linhas do range
    For x = 1 To lookupRange.Rows.Count
   
        Dim r As Range
        Set r = lookupRange.Cells(x, 1)
   
        ' Verifica se o valor é igual ao indicado
        If r.Value = lookupValue Then
       
            Dim str As String
           
            ' Utiliza o Offset para ir buscar a coluna indicada
            str = r.Offset(, columnIndex - 1).Value & ";"
           
            ' Caso se pretenda apenas os valores diferentes e 
            ' já  esteja já na lista não faz a concatenação
            If distinct And InStr(1, result, str, vbTextCompare) = 0 _
                        Or Not distinct Then
                result = result & str
            End If
           
        End If
    Next
   
    ' Se não encontrar nada coloca uma mensagem genérica
    If Len(result) > 0 Then
 
        ' Remove o último ";"
        VLookupValues = Left(result, Len(result) - 1)
    Else
        VLookupValues = "Não Encontrado"
    End If
   
Exit Function
errVLookupValues:
    VLookupValues = ""
   
End Function

Para tornar a função mais versátil foi adicionado um argumento opcional que permite indicar se queremos resultados únicos ou não. O sintaxe para utilizar esta função é o seguinte:

=vLookupValues(valor procurar; tabela; coluna a devolver; resultados únicos)

E utilizando a mesma tabela agora com várias selecções:

Se utilizarmos a função =VLookupValues("x";A2:B9;2;FALSE), em qualquer célula, obtemos o resultado: Rui;Ana;Paulo;Paula

Podemos ainda indicar no último argumento se queremos ou não resultado únicos.

Podem descarregar um exemplo para testar!


Revista PROGRAMAR - 32ª Edição Dezembro 2011

Já está disponível a edição 32 de Dezembro de 2011, da revista PROGRAMAR, da comunidade Portugal-a-Programar. Segue o anúncio oficial do lançamento:



(clica para download)

Com o Natal por perto, a equipa de Revista PROGRAMAR traz-lhe um presente de Natal, a edição de Dezembro recheada de óptimos artigos.

Nesta edição continuaremos também a premiar os autores dos três melhores artigos, dado o sucesso nas edições anteriores. E os leitores devem dar a sua opinião para que possamos premiar correctamente. Para isso vote em http://tiny.cc/ProgramarED32_V


Assim nesta edição trazemos até si, como artigo de capa, um artigo sobre iOS, Cocoa Touch & MVC para conhecer melhor algumas técnicas de programação para dispositivos móveis da Apple. Nesta 32ª edição pode ainda encontrar os seguintes artigos:

  • Geração de Números Aleatórios - Parte 2
    • O segundo de 4 artigos do mesmo autor da excelente série “Programação em Lua”, desta vez sobre geração de números aleatórios.
  • Automatização de tarefas usando atributos
    • Continuação do artigo sobre atributos em C# da edição número 30. Neste artigo, conheça melhor o funcionamento do conceito de contextos nesta linguagem.
  • SQL Azure Fedarations
    • Introdução às SQL Azure Federations.
  • Enigmas de C#: Arrays
    • Saiba porque motivo, um array pode invocar uma System.ArrayTypeMismatchException.
  • VISUAL (NOT) BASIC - Um pouco mais de Windows Phone 7
    • Saiba como pode tirar partido de algumas funcionalidades e características no desenvolvimento de aplicações para esta plataforma.
  • CORE DUMP - Free as in Beer
    • Atualmente, as empresas usam software open source, não por ser livre, mas por ser grátis. Conheça a opinião do autor sobre este tema.
E ainda em colaboração com as comunidades AzurePt e NetPonto, respectivamente: 
  • Como suportar múltiplas identidades no seu WebSite com Windows Azure AppFabric ACS
    • Saiba como resolver o problema das identidades em demasia através do Azure.
  • BizTalk Server - Princípios Básicos dos Mapas
    • Explore através deste artigo, o editor de mapas do BizTalk Server.
Mais informação

Excel: Dicas de VBA - Personalizar o Friso II

No primeiro artigo sobre a personalização do friso (ribbon) foi mostrado como criar um novo separador e um novo grupo com dois controlos, neste caso, dois botões.

Mas podemos utilizar inúmeros controlos de modo a tornar as opções mais simples para o utilizador. Como referido também no artigo anterior, este é o esquema base para construção do friso:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="customTab1" label="Extra Options">

<!-- Grupos, Controlos, etc -->

</tab>
</tabs>
</ribbon>
</customUI>

O próximo código XML apresentado irá ser colocado dentro da tab com o ID “customTab1”

Vamos ver então alguns controlos, alguns eventos, designados por callbacks, e algumas opções mais avançadas!

image

Para criar um grupo com caixas de selecção (checkboxes), no primeiro grupo (myCheckBox Group), podemos o fazer da seguinte forma:

<group id="Group1" label="myCheckBox Group">
<checkBox id="cb1" label="Opção A" onAction="cbGetDescription" />
<checkBox id="cb2" label="Opção B" onAction="cbGetDescription" />
<checkBox id="cb3" label="Opção C" onAction="cbGetDescription" />
<checkBox id="cb4" label="Opção D" onAction="cbGetDescription" />
<checkBox id="cb5" label="Opção E" enabled="false" />
<checkBox id="cb6" label="Opção F" enabled="false" />
</group>


clip_image003

Neste caso estamos a criar um grupo, onde vamos ter várias checkboxes (6). As primeiras quatro estão a chamar o callback cbGetDescription, onde irmos depois verificar qual a opção selecionada, e as duas últimas estão desabilitadas para efeitos de demonstração.

No callback (evento) cbGetDescription podemos usar o seguinte código:

Sub cbGetDescription(control As IRibbonControl, pressed As Boolean)
Select Case control.id
Case "cb1"
MsgBox "Opção A - Seleccionada: " & pressed
Case "cb2"
MsgBox "Opção B - Seleccionada: " & pressed
Case "cb3"
MsgBox "Opção C - Seleccionada: " & pressed
Case "cb4"
MsgBox "Opção D - Seleccionada: " & pressed
End Select

End Sub


No segundo grupo (MyDrops Group) estão dois controlos de selecção: Combobox e DropDown. A diferença entre ambos é que na Combobox é possível alterar o texto enquanto na DropDown não. Neste exemplo, e para mostrar diferentes formas de carregamento de dados, na Combobox estão já definidos alguns itens e a DropDown será preenchida dinamicamente com dados de um Array definido no código.

O XML para a sua criação será então o seguinte:

<group id="Group2" label="myDrops Group">

<comboBox id="cboItems" label="ComboBox:" onChange="cboOnChange">
<item id="item1" label="Item 1" />
<item id="item2" label="Item 2" />
<item id="item3" label="Item 3" />
</comboBox>

<dropDown id="dropDynamic" label="Dropdown:"
onAction="ddOnAction"
getItemLabel="ddGetItemLabel"
getItemCount ="ddGetItemCount" >
</dropDown>

</group>
clip_image005

Como código para a Combobox podemos definir então:

Sub cboOnChange(control As IRibbonControl, text As String) 
MsgBox "Texto seleccionado: " & text
End Sub

Isto irá mostrar uma mensagem com o texto seleccionado ou inserido.

Para a DropDown o código é ligeiramente mais complexo!

Para começar vamos adicionar na primeira linha do XML o atributo onLoad definindo desta forma que quando o friso é iniciado iremos executar determinado código (poderia ser feito também no evento Workbook_Open).

<customUI xmlns=http://schemas.microsoft.com/office/2009/07/customui
onLoad="RibbonLoad">


Desta forma vamos executar o callback RibbonLoad() na inicialização do friso, onde iremos carregar alguns valores no array. Estes valores vão ser utilizados pelos métodos GetItemLabel() e GetItemCount() como é possível ver no seguinte código/comentários.

Private paises(4) As String
Private x As Integer

Sub RibbonLoad(ribbon As IRibbonUI)
paises(0) = "Portugal"
paises(1) = "Espanha"
paises(2) = "França"
paises(3) = "Alemanha"
paises(4) = "Inglaterra"
End Sub

' Mostra a determinada posição do array de acordo com o índex recebido
Sub ddOnAction(control As IRibbonControl, id As String, index As Integer)
MsgBox paises(index), vbInformation
End Sub

' Este evento é chamado uma vez por cada posição na lista, definido no
' evento ddGetItemCount(). Desta forma, quando o evento é executado, colocamos
' um valor de cada posição do array e incrementamos o contador de posição
Sub ddGetItemLabel(control As IRibbonControl, index As Integer, ByRef returnedVal)
returnedVal = paises(x)
x = x + 1
End Sub

' Define o número de itens a aparecer na lista
Sub ddGetItemCount(control As IRibbonControl, ByRef returnedVal)
returnedVal = UBound(paises) + 1
End Sub


O terceiro e último grupo (myMisc Group) tem diferentes controlos para mostrar mais algumas das possibilidades disponíveis (não todas, obviamente). O XML é um pouco extenso mas será explicado de seguida:

<group id="Group3" label="myMisc Group">

<gallery id="MonthGallery" label="Escolher mês usando uma Gallery:"
columns="3" rows="4" onAction="SetMonth" >
<item id="m01" label="Janeiro"/>
<item id="m02" label="Fevereiro"/>
<item id="m03" label="Março"/>
<item id="m04" label="Abril"/>
<item id="m05" label="Maio"/>
<item id="m06" label="Junho"/>
<item id="m07" label="Julho"/>
<item id="m08" label="Agosto"/>
<item id="m09" label="Setembro"/>
<item id="m10" label="Outubro"/>
<item id="m11" label="Novembro"/>
<item id="m12" label="Dezembro"/>

<button id="mActual" imageMso="CalendarToolSelectDate"
label="Mês Actual" onAction="SetCurrentMonth" />
</gallery>

<editBox id="EditBox1" label="Texto a pesquisar:" onChange="EditBoxOnChange"
imageMso="FindAllDownloadedDocuments" />

<separator id="separator1"/>

<toggleButton id="toggleActivar" label="Activar/Desactivar"
imageMso="AcceptTask" getPressed="toggleGetPressed"
onAction="toggleOnAction" />

<menu id="Menu1" label="Menu Opções Sistema" itemSize="normal">
<button idMso="Cut"/>
<button idMso="Copy"/>
<button idMso="Paste"/>


<menuSeparator id="menuSeparator1" title="Mais opções ..."/>
<menu id="SubMenu1" label="Ficheiro">
<button idMso="FileSave"/>
<button idMso="FileSaveAs"/>
<button idMso="FileOpen"/>
<button idMso="FileClose"/>
</menu>
<menu id="SubMenu2" label="Diversos">
<button idMso="FileExit"/>
</menu>
</menu>

<dialogBoxLauncher>
<button id="Launcher1" screentip="My Launcher"
onAction="ThisWorkbook.LauncherCode" />
</dialogBoxLauncher>

</group>


Para começar uma galeria (Gallery) onde estamos a definir os diferentes meses do ano. Aqui podemos indicar quantas linhas e colunas queremos, assim como utilizar outros controlos. No código XML está definido no final um botão que irá escolher o mês actual.

image

O código associado é muito simples:

' Mostra o mês de acordo com o index recebido
Sub SetMonth(control As IRibbonControl, id As String, index As Integer)
MsgBox MonthName(index + 1)
End Sub

' Mostra o mês por extenso do mês actual
Sub SetCurrentMonth(control As IRibbonControl)
MsgBox MonthName(Month(Now))
End Sub

De seguida temos uma EditBox que permite o utilizador escrever algum texto. No código basta simplesmente mostrar o resultado no callback EditBoxOnChange():

Sub EditBoxOnChange(control As IRibbonControl, text As String)
MsgBox "O texto indicado foi: " & text, vbInformation
End Sub

Depois um separador e um botão retentivo (toggle button), ou seja, quando pressionado fica seleccionado e quando pressionado novamente perde a selecção.

image

No código do toggle button mostramos apenas o estado no callback onAction() e definimos também, no callback getPressed(), o estado inicial quando o friso é inicializado.

' Quando o botão (toggle) é pressionado mostra o estado
Sub toggleOnAction(control As IRibbonControl, pressed As Boolean)
MsgBox "Controlo: " & control.id & " - Pressionado: " & pressed
End Sub

' Define o estado inicial do botão
Sub toggleGetPressed(control As IRibbonControl, ByRef returnedVal)
returnedVal = True
End Sub


Depois, no próximo controlo utilizado, não existe qualquer código associado pois estamos a definir funções de sistema através da atribuição de um idMso. Isto significa que cada opção que colocarmos no menu, que poderá ser colocado em outro controlo, irá executar a função que o sistema está preparado para o fazer (save, save as, copy, cut, etc).

Desta forma, podemos colocar no nosso friso algumas opções já existentes no Excel e que podem ser úteis. A lista dos ID’s (idMso) que podemos utilizar pode ser descarregada aqui:

O último controlo, embora meio escondido e disponível no canto inferior direito do grupo, é um DialogBox Launcher que permite simplesmente lançar uma janela com opções relaccionadas com o respectivo grupo.

image

O código pode então mostrar uma mensagem, chamar um userform, etc. Neste exemplo irá mostrar apenas uma mensagem, mas tem uma particularidade, que se aplica a todos os controlos. No XML está definido para o callback onAction() o método ThisWorkbook.LauncherCode. Isto significa que o seguinte código tem de estar localizado no ThisWorkbook para funcionar, pois está a ser apontado para tal.

Sub LauncherCode(control As IRibbonControl)
MsgBox "Mais opções ..."
End Sub


Podemos apontar para módulos específicos, worksheets, etc.

NOTA IMPORTANTE: Caso o XML não esta correcto (tags inválidas, tags não fechadas, etc) o separador não ficará visível.

 

E são alguns exemplos que mostram como personalizar o friso e como utilizar o código para cada controlo. Existem muito mais opções para cada controlo e muito mais controlos. Para complementar estes dois pequenos artigos podem ver os seguintes links, que além de um PDF que podem descarregar gratuitamente, podem consultar online:

Podem ainda descarregar o ficheiro de exemplo utilizado neste artigo: download


Formação Ciclo

Formações em Destaque:

Introdução à Programação em VBA - Microsoft Excel Programação Avançada em VBA para Microsoft Excel Introdução ao .NET Framework 4.0 com VB .NET

Mensagens Recentes

Twitter Updates

Microsoft Office Especialist

Membro da Comunidade
Experts-Exchange


Administ. da Comunidade
Portugal-a-Programar

Twitter
Artigos no CodeProject
Artigos no CodeProject

Seguidores

Subscrever Novidades

Endereço de Email:

Delivered by FeedBurner

Histórico