Archive Page 2
É uma necessidade básica para quem está começando a programar em VBA.
Depois da criação das primeiras macros e formulários, é preciso alguma forma de executá-los sem precisar ir direto ao VBA ou simplesmente acionando o menu de macros.
Os caminhos mais tradicionais são:
- Associar a execução de uma macro a um botão de comando ou outro componente qualquer
- Colocar a execução de determinada macro na abertura do arquivo
Vamos tratar aqui da segundo item.
Usando o Auto_Open
Existe uma forma geral de executar esta tarefa no VBA, idenpendente de qual seja o aplicativo hospedeiro. Basta dar ao nome da macro, ou seja, o cabeçalho da função como Auto_Open.
Suponha a macro abaixo:
Public Sub MostraMensagem()
MsgBox "Seja bem vindo"
End Sub
Clicar em F5 para testar o código. O resultado deve ser uma caixa de mensagem com a mensagem “Seja bem vindo”. Para mostrar esta macro na abrir um arquivo, bastaria que esta fosse renomeada para Auto_Open ao invés do nome original. Para não estragar o código, poderíamos criar uma macro de nome Auto_Open que chama a nossa macro, por exemplo:
Public Sub Auto_Open()
Call MostraMensagem
End Sub
O único requisito para o funcionamento desta macro é que ela não tenha parâmetros, podendo ser um Function ou Sub e ser chamada após esta execução.
Mapeando o evento de abertura do arquivo
Este é outro método também largamente utilizado. Praticamente todos os aplicativos dotados do VBA possuem um evento que representa a abertura de um arquivo. Abaixo segue alguns exemplos do Microsoft Office:
| Aplicativo |
Evento |
| Excel |
Workbook_Open |
| Word |
Document_Open |
Alguns aplicativos são excessão, como o PowerPoint que suporta somente eventos em nível de Aplicativo, assunto não abordado aqui.
Como exemplo, usarei o Excel para mapear o evento Workbook_Open.
- Abra o Excel
- Acione o VBA em Ferramentas->Macro->VBA ou simplesmente Alt+F11
- Na janela de projeto, procure o item EstaPasta_de_trabalho
- Clique duas vezes para abrir a tela de código
- Na caixa de listagem à esquerda superior da tela de código, selecione o item Workbook
- Caso nada aconteça, selecio a caixa de listagem à direto superior da tela de código e selecione o item Opem
- Isso fará com que o evento Workbook_Open seja criado automaticamente
O código gerado é parecido com este:
Public Sub Workbook_Open()
End Sub
Qualquer código colocado dentro deste procedimento será executado na abertura da pasta de trabalho.
Conclusão
Como no VBA não existe um contexto de aplicativo, onde existe um método principal de início de execução, estas rotinas auxiliam bastante quando profissionalizamos programas feitos nesta linguagem.
Bom proveito!
Tags: No Tags .
A algum tempo a série “Tube”, que no final das contas séra XpressMusic da Nokia vem fazendo algum barulho, como já foi informado neste blog.
Nesta semana surgiram boatos que dia 02 de outubro ocorreria o lançamento do Nokia 5800 XpressMusic.

Nokia 5800 XpressMusic
Especificações (ainda não confirmadas): Symbian S60 (”Taco 5 OS”), 3G (2.100 MHz) e quad-band GSM, Wi-Fi, tela de 640 x 360 (3,2 polegadas), câmera de 3,2 megapixels com flash, Bluetooth com suporte a A2DP, A-GPS, saída para TV e fone de ouvido 3,5 mm, mede 111 x 52 x 15,5 mm e pesa 109 gramas, além de aceitar um cartão microSD.
Um site dos EUA diz ter o telefone já em pré-venda, desbloqueado, por US$ 499.
Mais informações:
http://www.gsmarena.com/nokia_5800_xpressmusic_previewed_and_pictured_seems_cool-news-603.php
http://zumo.uol.com.br/2008/10/01/nokia-tube-5800-touch-agora-vai/
Mais uma vez são rumores. Os sites oficiais não confirmam nenhuma informação. Só nos resta esperar.
Tags: No Tags .
A situação
Uma rotina tradicional, principalmente para quem trabalham com coleções. E para quem não sabe, trabalhar com DataTables e DataSets não o livra de usá-las pois estes objetos não passam de coleções, sejam de DataColumns, DataRows ou mesmo DataTables.
Pois bem, você executa um código “normal”, por exemplo, para remover linhas de um DataTable “varrendo” sua coleção de linhas. O código seria algo parecido com isto:
public void RemoveProducts(int ID)
{
DataTable productData = new DataTable();
productData = GetProducts(ProductID, false, true);
foreach ( dr in productData.Rows) {
if ((dr("ID") != ID.Value)) {
productData.Rows.Remove(dr);
}
}
}
Sem muitos segredos, o método preenche um DataTable e através de um laço foreach, remove as linhas que obedeçam a um determinado critério.
O problema
Qualquer código que trate coleções desta forma será muito “bem” recebido com a seguinte mensagem:
A descrição da Exception é bem genérica, mas para este caso a explicação é que, uma vez que um laço como o foreach analisa uma coleção para promover o laço, ela cria um Enumerador na primeira execução para promover um MoveNext, que fará avançar para próximo item. Se a coleção for modificada, seja por adição ou remoção de itens, o Enumerador se tornará inválido e o aplicativo retornará a Exception acima.
Abaixo segue a explicação da Microsoft para o fato:
After an enumerator is created or after the
Reset method is called, an enumerator is positioned before the first element of the collection, and the first call to the
MoveNext method moves the enumerator over the first element of the collection.
If MoveNext passes the end of the collection, the enumerator is positioned after the last element in the collection and MoveNext returns false. When the enumerator is at this position, subsequent calls to MoveNext also return false until Reset is called.
An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and the next call to MoveNext or Reset throws an InvalidOperationException.
Portanto, nada de mexer na coleção durante a execução de um laço foreach OK.
A solução
Se for realmente necessário construir uma rotina que altere a coleção durante a execução do laço, será preciso recorrer ao laço for tracional ao while. De qualquer forma, mesmo no for tradicional, será necessário fazer o laço de forma reversa, já que você não sabe se o último item estará lá durante a execução do laço.
Por isso a melhor forma de contruir o código sem ter problemas é varrer a coleção de trás para frente. No caso do código apresentado acima, uma possível solução seria esta:
for (int i = productData.Rows.Count - 1; i >= 0; i += -1) {
DataRow dr = productData.Rows(i);
if ((dr("ID") != ID.Value)) {
productData.Rows.RemoveAt(i);
}
}
Como dito, o laço é feito da última linha para a primeira, tomando o cuidado de sempre referenciar o índice com o valor -1.
Referências
http://msdn.microsoft.com/en-us/library/system.invalidoperationexception.aspx
http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext.aspx
Abraços
Tomás
Tags: No Tags .
Não tem jeito. Apesar da imensa blibloteca que o .NET Framework possui, ainda não há (pelo menos até onde consegui pesquisar) um método nativo para comparação de Arrays ou Coleções.
Como esta foi uma necessidade que tive mais de uma vez em sistemas dos quais participei na construção, publicarei um método genérico para comparação de Arrays simples em C#.
/// <summary>
/// Compara dois arrays de string
/// </summary>
/// <param name="arrayA">Array 1</param>
/// <param name="arrayB">Array 2</param>
/// <returns>True se os arrays forem iguais,
/// False do contrário</returns>
public static bool ArrayCompare(string[] arrayA, string[] arrayB)
{
if (arrayA.Length != arrayB.Length)
{
return false;
}
for (int i = 0; i < arrayA.Length; i++)
{
if (arrayA[i] != arrayB[i])
{
return false;
}
}
return true;
}
O código abaixo completo mostra a utilização da função:
using System;
public class testCompareArrays
{
public static void Main(string[] args)
{
string[] array1 = new string[] {"a", "b", "c", "d", "e"};
string[] array2 = new string[] {"a", "b", "c", "d", "e"};
if(ArrayCompare(array1, array2))
{
Console.WriteLine("Os arrays são iguais");
}
else
{
Console.WriteLine("Os arrays são diferentes");
}
}
/// <summary>
/// Compara dois arrays de string
/// </summary>
/// <param name="arrayA">Array 1</param>
/// <param name="arrayB">Array 2</param>
/// <returns>True se os arrays forem iguais,
/// False do contrário</returns>
public static bool ArrayCompare(string[] arrayA, string[] arrayB)
{
if (arrayA.Length != arrayB.Length)
{
return false;
}
for (int i = 0; i < arrayA.Length; i++)
{
if (arrayA[i] != arrayB[i])
{
return false;
}
}
return true;
}
}
O exemplos faz uso de um array de strings, porém é simples alterá-lo para qualquer outro tipo, desde que seja nativo ou que sobrecarregue o operado ==.
Bom proveito!
Tomás
Tags: No Tags .
O velho paradigma: Para que criar se é possível reaproveitar?
Puristas gostam de fazer do seu próprio jeito, mas se cada um quisesse inventar a sua própria roda, onde estaríamos hoje?
Bom, baseado nesse conceito é que existem uma série de exemplos já criados que podem ser reaproveitados (neste site inclusive ;-)). Quando estes exemplos vem de uma fonte confiável, melhor ainda!
A Microsoft através de seu portal publica exemplos atrás de exemplos dos mais variados tipos e melhor, condensa os melhores em uma página de soluções focadas para o dia a dia das empresas. São arquivos criados por editores de alto nível, geralmente empresas parceiras.
A lista destes exemplos pode ser vista em seguida:
 |
Controle de estoque, folha de pagamento, fluxo de caixa e muito mais. |
 |
Ata de Reunião
Criada para facilitar a elaboração de atas de reunião, para posterior distribuição entre os participantes.
|
 |
Calendário de Atividades
Para facilitar a elaboração e emissão de um calendário de atividades do escritório, casa ou escola.
|
 |
Capa de Fax
Para ser usado na criação de folhas de rosto, para envio de mensagens via fax, integrando o MS-Word e o MS-Outlook.
|
 |
Controle de Energia
Sua função é auxiliar no controle de energia dos principais eletrodomésticos, e calcular a média de gastos mensais.
|
 |
Controle de Estoque
Sua função é auxiliar no controle do estoque dos produtos de consumo interno de pequenas empresas.
|
 |
Controle de Horas
Tem a finalidade de facilitar o controle das horas trabalhadas.
|
 |
Custo de Funcionário
Para somatórias de salário, benefícios e tributação envolvida na contratação de funcionários.
|
 |
Fluxo de Caixa
A função desta solução é auxiliar no controle de movimentação de contas efetuando lançamentos de despesas
|
 |
Folha de Pagamento
Para facilitar a elaboração e emissão de uma folha de pagamento.
|
 |
Gerenciamento de Clientes
Este modelo tem como objetivo facilitar o controle sobre as operações de compra e venda de uma empresa.
|
 |
Históricos Financeiros
O objetivo desta aplicação é apresentar aos usuários uma forma simples e rápida de organizar uma aplicação utilizando os recursos interativos do Microsoft Excel.
|
 |
Lançamentos Financeiros
Esta solução a forma que podemos acessar uma base de dados em MS-SQL Server 7.0 e gerar relatórios através de uma Tabela Dinâmica, em uma interface customizada e amigável.
|
 |
Lista de Ramais
Um recurso simples, porém muito utilizado pelas empresas é uma lista de ramais internos. Esta aplicação desenvolvida em MS-Excel apresenta uma serie de funcionalidades, como pesquisa por nome/apelido, nome completo e alias. Permite a impressão da lista e a pesquisa por aniversariantes do dia, da semana ou mês.
|
 |
Prestação de Contas
Com esta solução, você poderá simplificar a atividade de prestar contas de viagens, sendo possível, visualizar as despesas realizadas de acordo com as suas diferentes categorias e tipos. A Solução permite que você efetue análises gráficas da distribuição das despesas.
|
 |
Simulador de Vendas
Esta solução permite que você faça simulações do volumes de vendas da sua Empresa. Tomando como partidor os valores de previsão de vendas (previsto ou budget) para o ano e dos valores realizados até a presente data, com o simulador você poderá definir quanto falta para você vender, por produto, para atingir a meta estabelecida no plano anual de vendas ou buscar uma nova meta para melhorar a sua bonificação/remuneração.
|
O link original é:
http://www.microsoft.com/brasil/pequenasempresas/office/solucoes.mspx
Bom proveito!
Tags: No Tags .