Introdução
Uma necessidade muito comum em aplicativos é utilizar
critérios de tempo para execução de algumas rotinas. Esta é uma tarefa trivial
em várias linguagens, mas poucos pensam em utilizá-la no VBA por achar muito
complexo, tendo que envolver chamadas de API e outros recursos mais avançados da
linguagem
Porém, o VBA do Microsoft Excel disponibiliza um método que facilita esse tipo
de trabalho, o método OnTime().
O que é
O método OnTime programa um procedimento para ser executado em um momento
especificado no futuro (seja em uma determinada hora do dia ou após uma
quantidade específica de tempo decorrido).
A estrutura de chamada à função OnTime se faz da seguinte forma:
Application.OnTime([EarliestTime], [Procedure], [LatestTime],
[Schedule])
Argumentos da função:
EarliestTime
Variant necessário. Especifica quando você deseja que esse procedimento seja
executado.
Procedure
String necessário. O nome do procedimento a ser executado.
LatestTime
Variant opcional. Especifica até quando o procedimento pode ser executado. Por
exemplo, se LatestTime estiver definido como EarliestTime + 30 e o Microsoft Excel não estiver em modo
Pronto, Copiar, Recortar ou Localizar em EarliestTime devido a um outro procedimento estar sendo executado, o Microsoft Excel
esperará 30 segundos para que o primeiro procedimento termine. Se o Microsoft
Excel não estiver em modo Pronto dentro de 30 segundos, o procedimento não
será executado. Se esse argumento for omitido, o Microsoft Excel esperará até
que o procedimento possa ser executado.
Schedule
Variant opcional. True para programar um novo procedimento OnTime. False para limpar um
procedimento definido anteriormente. O valor padrão é True.
Exemplo
Para informar ao VBA um valor de data válido para execução do método OnTime,
usa-se a propriedade Now do VBA juntamente com a função TimeValue(). Somando as duas, é possível programar o procedimento para ser
executado quando uma quantidade de tempo específica (contando a partir de
agora) tiver decorrido.
Caso seja necessário informar uma hora específica, por exemplo, 3 da tarde (ou
15:00), usa-se TimeValue(time) onde time é um valor de hora
informado através de uma String.
Veja os exemplos de código abaixo:
1
2
3
4
5
6
7 |
Public Sub ExecutaOnTime()MsgBox “Opa!
Executou.”
End Sub
Public Sub TesteOnTime()
Call Application.OnTime(Now +
TimeValue(”00:00:10″), “ExecutaOnTime”)
End Sub |
Execute a função TesteOnTime, deixando o cursor do mouse sobre ele (linha 5 a
6) e clicando em F5. Se tudo der certo, em 10 segundos você deverá ver esta
mensagem:
Pronto! Conforme configuramos o OnTime para executar 10 segundos após a hora
atual (linha 6) pois, Now retorna a data e hora atual e TimeValue(”00:00:10″)
representa para o VBA 10 segundos, após executar a função TesteOnTime, ela
programa a função ExecutaOnTime (linha 1) para ser executada neste tempo.
Para efeitos de teste, configure outros valores de tempo, mas tome o cuidado
que sejam pequenos pois, se configurar para executar daqui a 24 horas
(”24:00:00″), vai ter que esperar um bom tempo.
Para fazer outro teste interessante do OnTime, mude o código para ficar desta
forma:
1
2
3
4
5
6
7 |
Public Sub ExecutaOnTime()
MsgBox “Opa!
Executou.”
End Sub
Public Sub TesteOnTime()
Call Application.OnTime(TimeValue(”13:00:00″),
“ExecutaOnTime”)
End Sub |
Da forma que está, o código irá configurar a função ExecutaOnTime (linha 1) para
ser executada às na próxima 13:00 do computador em que está sendo executada.
Como este é apenas um exemplo, configure uma hora que estiver mais próxima para
não esperar muito.
É possível também cancelar a execução de uma macro agendada com o OnTime. O
exemplo de código abaixo cancela a definição de OnTime do
exemplo anterior, ou seja, caso a execução da função ExecutaOnTime estiver
agendada, executar a função CancelaOnTime fará com que esta programação seja
cancelada. isso é feito passando o valor False para o parâmetro Schedule (linha
10):
1
2
3
4
5
6
7
8
9
10
11 |
Public Sub ExecutaOnTime()
MsgBox “Opa! Executou.”
End Sub
Public Sub TesteOnTime()
Call Application.OnTime(TimeValue(”13:00:00″),
“ExecutaOnTime”)
End Sub
Public Sub CancelaOnTime()
Call Application.OnTime(EarliestTime:=TimeValue(”13:00:00″),
Procedure:=”ExecutaOnTime”, Schedule:=False)
End Sub |
Conclusão
Com este recurso em mãos, é possível atender a algumas necessidades que no
contexto do Excel pareciam inviáveis. Um exemplo típico é uma tela de
aprensentação ou SplashScreen como é conhecida que apresenta o programa e fecha
em alguns segundos. Este é um bom teste para experimentar o uso do OnTime. Fica
aí um desafio.
O GridView, sem dúvida alguma, representa um grande avanço frente ao DataGrid do ASP.Net 1.1. Porém nossos clientes e usuários sempre necessitam de funcionalidades que vão além das fornecidas nativamente pelo GridView. Um exemplo frequente é a criação de totalizações e agrupamentos. No primeiro caso é relativamente fácil e rápido codificar o evento RowDataBound para obtenção de totais. A criação de grupos no GridView envolve um pouco mais de implementação e depuração. Há dezenas de artigos orientando tais implementações, porém eles induzem os desenvolvedores menos avisados à má prática da recodificação ao invés do reuso.
Mas é apenas quando precisamos combinar os dois recursos, grupos e sumarizações por grupo, que vemos o quanto é fácil se perder em código e depuração, caso não haja uma implementação consistente.
Com o objetivo de simplificar essas tarefas, o colega Agrinei desenvolveu uma biblioteca chamada GridViewHelper, que permite a utilização rápida e confiável de tais recursos.
A biblioteca é bem construída e simples de utilizar. A documentação é de fácil entendimento, mesmo assim, requer um bom conhecimento do controle GridView. Os resultados são bem agradáveis e torna simples algumas tarefas não tão triviais com o controle.
Alguns exemplos abaixo do que é possível obter com a biblioteca sem muito esforço, baseado nos dados do famoso banco de dados Northwind:
Sumarização
| ShipRegion |
ShipName |
OrderId |
ProductName |
Quantity |
UnitPrice |
ItemTotal |
| RJ |
Hanari Carnes |
10922 |
Alice Mutton |
15 |
R$ 39,00 |
R$ 585,00 |
| RJ |
Hanari Carnes |
10922 |
Guaraná Fantástica |
35 |
R$ 4,50 |
R$ 157,50 |
| RJ |
Hanari Carnes |
10925 |
Inlagd Sill |
25 |
R$ 19,00 |
R$ 475,00 |
| RJ |
Hanari Carnes |
10925 |
Filo Mix |
12 |
R$ 7,00 |
R$ 84,00 |
| SP |
Wellington Importadora |
10935 |
Chai |
21 |
R$ 18,00 |
R$ 378,00 |
| SP |
Wellington Importadora |
10935 |
Carnarvon Tigers |
4 |
R$ 62,50 |
R$ 250,00 |
| SP |
Wellington Importadora |
10935 |
Tunnbröd |
8 |
R$ 9,00 |
R$ 72,00 |
| SP |
Gourmet Lanchonetes |
10959 |
Rhönbräu Klosterbier |
20 |
R$ 7,75 |
R$ 155,00 |
| SP |
Queen Cozinha |
10961 |
Filo Mix |
6 |
R$ 7,00 |
R$ 42,00 |
| SP |
Queen Cozinha |
10961 |
Lakkalikööri |
60 |
R$ 18,00 |
R$ 1.080,00 |
| SP |
Comércio Mineiro |
10969 |
Spegesild |
9 |
R$ 12,00 |
R$ 108,00 |
| RJ |
Hanari Carnes |
10981 |
Côte de Blaye |
60 |
R$ 263,50 |
R$ 15.810,00 |
| RJ |
Que Delícia |
10989 |
Grandma’s Boysenberry Spread |
40 |
R$ 25,00 |
R$ 1.000,00 |
| RJ |
Que Delícia |
10989 |
Queso Cabrales |
15 |
R$ 21,00 |
R$ 315,00 |
| RJ |
Que Delícia |
10989 |
Jack’s New England Clam Chowder |
4 |
R$ 9,65 |
R$ 38,60 |
|
R$ 20.550,10 |
Agrupamento
| ShipName |
OrderId |
ProductName |
Quantity |
UnitPrice |
ItemTotal |
| RJ |
| Hanari Carnes |
10922 |
Alice Mutton |
15 |
R$ 39,00 |
R$ 585,00 |
| Hanari Carnes |
10922 |
Guaraná Fantástica |
35 |
R$ 4,50 |
R$ 157,50 |
| Hanari Carnes |
10925 |
Inlagd Sill |
25 |
R$ 19,00 |
R$ 475,00 |
| Hanari Carnes |
10925 |
Filo Mix |
12 |
R$ 7,00 |
R$ 84,00 |
| Hanari Carnes |
10981 |
Côte de Blaye |
60 |
R$ 263,50 |
R$ 15.810,00 |
| Que Delícia |
10989 |
Grandma’s Boysenberry Spread |
40 |
R$ 25,00 |
R$ 1.000,00 |
| Que Delícia |
10989 |
Queso Cabrales |
15 |
R$ 21,00 |
R$ 315,00 |
| Que Delícia |
10989 |
Jack’s New England Clam Chowder |
4 |
R$ 9,65 |
R$ 38,60 |
| SP |
| Wellington Importadora |
10935 |
Chai |
21 |
R$ 18,00 |
R$ 378,00 |
| Wellington Importadora |
10935 |
Carnarvon Tigers |
4 |
R$ 62,50 |
R$ 250,00 |
| Wellington Importadora |
10935 |
Tunnbröd |
8 |
R$ 9,00 |
R$ 72,00 |
| Gourmet Lanchonetes |
10959 |
Rhönbräu Klosterbier |
20 |
R$ 7,75 |
R$ 155,00 |
| Queen Cozinha |
10961 |
Filo Mix |
6 |
R$ 7,00 |
R$ 42,00 |
| Queen Cozinha |
10961 |
Lakkalikööri |
60 |
R$ 18,00 |
R$ 1.080,00 |
| Comércio Mineiro |
10969 |
Spegesild |
9 |
R$ 12,00 |
R$ 108,00 |
Agrupamento em 2 níveis
| OrderId |
ProductName |
Quantity |
UnitPrice |
ItemTotal |
| RJ |
| Hanari Carnes |
| 10922 |
Alice Mutton |
15 |
R$ 39,00 |
R$ 585,00 |
| 10922 |
Guaraná Fantástica |
35 |
R$ 4,50 |
R$ 157,50 |
| 10925 |
Inlagd Sill |
25 |
R$ 19,00 |
R$ 475,00 |
| 10925 |
Filo Mix |
12 |
R$ 7,00 |
R$ 84,00 |
| 10981 |
Côte de Blaye |
60 |
R$ 263,50 |
R$ 15.810,00 |
| Que Delícia |
| 10989 |
Grandma’s Boysenberry Spread |
40 |
R$ 25,00 |
R$ 1.000,00 |
| 10989 |
Queso Cabrales |
15 |
R$ 21,00 |
R$ 315,00 |
| 10989 |
Jack’s New England Clam Chowder |
4 |
R$ 9,65 |
R$ 38,60 |
| SP |
| Comércio Mineiro |
| 10969 |
Spegesild |
9 |
R$ 12,00 |
R$ 108,00 |
| Gourmet Lanchonetes |
| 10959 |
Rhönbräu Klosterbier |
20 |
R$ 7,75 |
R$ 155,00 |
| Queen Cozinha |
| 10961 |
Filo Mix |
6 |
R$ 7,00 |
R$ 42,00 |
| 10961 |
Lakkalikööri |
60 |
R$ 18,00 |
R$ 1.080,00 |
| Wellington Importadora |
| 10935 |
Chai |
21 |
R$ 18,00 |
R$ 378,00 |
| 10935 |
Carnarvon Tigers |
4 |
R$ 62,50 |
R$ 250,00 |
| 10935 |
Tunnbröd |
8 |
R$ 9,00 |
R$ 72,00 |
Existem exemplos mais avançados, mas mesmo com tanos recursos, o código para proporcionar a façanha é bem simples, a biblioteca dá conta de aplicar a formatação. Por exemplo, para fazer o agrupamento pela primeira coluna, o código a ser adicionado na sua página é:
protected void Page_Load(object sender, EventArgs e)
{
GridViewHelper helper = new GridViewHelper(this.GridView1);
helper.RegisterSummary(“ItemTotal”, SummaryOperation.Sum);
}
Bem simples e o resultado produzido é muito agradável.
Limitações
Nem tudo é perfeito, mas é preciso avaliar se é este mesmo o propósito. A biblioteca é poderosa, mas só funcionará bem quando o controle GridView trabalhar somente com BoundFields, principalmente na coluna que for agrupada. Ao tentar trabalhar com TemplateField, tive que fazer algumas modificações para que o agrupamento acontecesse. Mesmo assim, caso o controle dentro do TemplateField precisar utilizar propriedades como o CommandArgument, não funcionará pois aparentemente, após a formatação do GridView pela biblioteca, o DataBind é perdido. A razão é que, como linhas novas são adicionadas no GridView, ele se perde pois o RowIndex e outras propriedades tornam-se inválidas.
Valeu uma correção para quem tiver interesse. Afinal, a biblioteca é de código aberto.
Conclusão
Mesmo que o uso destas funcionalidades não seja tão comum, ou melhor, não façam parte das opções no seu cardápio de interfaces pois é complicado promovê-las, esta biblioteca torna-se obrigatória para quem faz uso intenso do controle GridView, principalmente para relatórios.
Site do Autor: http://www.agrinei.com/
Documentação e exemplos: http://www.agrinei.com/gridviewhelper/gridviewhelper_pt.htm
Download do código fonte: http://www.agrinei.com/gridviewhelper/gridviewhelpersample_pt.zip
![bathory-sitesplash3[1] bathory-sitesplash3[1]](http://www.tomasvasquez.com.br/blog/wp-content/uploads/2009/06/bathory-sitesplash31.jpg)
Ubuntu Satanic
Mais uma que valeu o dia.
Distribuição altamente customizada para quem curte um som mais “pesado”.
Direto da tumba de desenvolvedores malucos surgiu esse Ubuntu customizado. A edição satânica vem recheada com muito metal pesadão. As músicas, em sua maioria, têm a licença Creative Commons e estão disponíveis no site Jamendo.
No pacote do Ubuntu Satanic estão bandas como StabWounD, Auvernia, Frontside, Skaut, Taste of Hell, Scape.Goat e Holy Pain.
A sátira é tão pesada que o codinome da última versão, a Ubuntu SE 666.4, é Jesus Jugular. A distribuição já foi banida de alguns sites. Segundo o endereço oficial, até o Distro Watch, o famoso catalogador de distribuições Linux, retirou de sua lista o sistema das trevas.
O Ubuntu Satanic Edition vem com poucas aplicações. Entre elas estão:
• Firefox 3
• Rhythmbox Music Player, com plugin para o site Jamendo
• Pidgin IM
• Transmission BitTorrent Client
• Brasero Disc Burning
• Movie Player
Quem quiser arriscar, pode baixar o LiveCD.
Fonte: INFO
Introdução
O VBA possui dois tipos de estruturas para construção de algoritmos, Sub e Function.
A questão que surge é, quando usar uma ou outra na construção de nossos algoritmos em VBA no Excel? Na prática, Sub e Function trabalham da mesma forma com uma única diferença. A Sub são funções de processamento autônomo enquanto as Functions podem (e devem) retornar valores no final de sua execução.
Veja a estrutura de cada uma:
Sub
1
2
3 |
[modificador] Sub ExemploSub([parâmetros])
‘ corpo do código
End Sub |
Function
1
2
3
4
5 |
[modificador] Function ExemploFunction([parâmetros]) As [tipo]
‘ corpo do código
‘valor de retorno
ExemploFunction = [valor]
End Function |
onde:
[modificador] são palavras chave que definem o nível de acesso à estrutura de código.
[parâmetros] são variáveis que são passadas na chamada da função e utilizadas dentro. Podem existir vários ou mesmo nenhum parâmetro.
[tipo] é o que informa o tipo de dado a ser retornado pela Function. Pode ser qualquer tipo de dados válido do VBA.
[valor] uma valor que representa o retorno da função. Pode ser uma variável ou um valor constante.
Como saber qual utilizar? Isto depende do contexto da sua aplicação. Quando sua rotina precisar simplesmente executar uma processamento sem emitir qualquer tipo de informação, é aconselhável usar uma Sub. Já quando seu processamento necessitar devolver algum resultado, sem dúvida uma Function é necessária. Supondo uma situação em que você precisa criar funções que executassem operações aritméticas, elas precisariam depois de efetuar os cálculos, devolver o resultado para ser utilizado.
Veja este exemplo:
1
2
3 |
Public Function SomaSimplesF(x As Long, y As Long) As Long
SomaSimplesF = x + y
End Function |
O código efetua uma operação simples recendo duas variáveis do tipo Long como parâmetro e devolve também um Long (definido na construção da Function) através da chama SomaSimples na linha 2. Para testar as função, basta ir a uma célula da planilha e digitar =SomaSimplesF(1;3). É possível também testar a função através de código VBA, como no código abaixo:
1
2
3
4
5
6
7 |
Public Sub TestaSomaSimplesF()
Dim soma As Long
‘chama a função SomaSimplesF e atribui o resultado à variável soma
soma = SomaSimplesF(1, 2)
‘mostra o resultado em uma caixa de mensagem
MsgBox soma
End Sub |
Já se este exemplo fosse construído usando uma Sub, não seria possível diretamente retornar o valor como é feito na Function. A solução então seria mostrá-lo ao usuário, por exemplo em uma caixa de mensagem. Veja este exemplo:
1
2
3 |
Public Sub SomaSimplesS(x As Long, y As Long)
MsgBox = x + y
End Sub |
Para testar a função, é precisa criar outro bloco de código que faça a chamada a este. Crie a seguinte função para testar o SomaSimplesS:
1
2
3
4 |
Public Sub TestaSomaSimplesF()
‘Faz a chamada a Sub SomaSimplesF
Call SomaSimples(1, 2)
End Sub |
Veja que o Sub não tem sequer a opção de mencionar o tipo de dado que pode ser retornado.
No Microsoft Excel, as Functions possuem uma característica especial. Elas podem ser usadas para criação de funções de planilha. A exigência para que isso seja possível, é criá-las com o modificador Public, que é o padrão
caso seja omitido.
Dentro deste entendimento, uma Function sempre poderá assumir o papel de uma Sub, mas não o contrário. Também por isso, o Excel utiliza Functions para criação de funções de planilha personalizadas e Subs para gravação de Macros.
Para superar a limitação do retorno de um único valor ou mesmo conseguir retornar alguns valores em Subs, é necessária a utilização passagem de parâmetros por referência. Este assunto será discutido em outro texto.
Comentários
Alguns podem pensar que por segurança, é melhor sempre criar Functions ao
invés de Subs. Porém, para termos de organização de código e padronização
de suas rotinas em VBA, procure usar a estrutura correta para ter um bom
funcionamento de seu aplicativo.