Mostrando postagens com marcador vba. Mostrar todas as postagens
Mostrando postagens com marcador vba. Mostrar todas as postagens

4/28/2008

Lendo arquivos de texto com VBA

Vou escrever uma função em VBA, bem "bobinha".

Sem problema, sem programa.


Primeiro, vamos "criar" um problema para resolver. Vamos supor que temos que ler um arquivo de texto e exibir cada linha lida, abaixo:

0200804131200
10011122233311
11044455566622
10077788899933
2200800039999


Note que a primeira linha e a última são diferentes das demais, elas se chamam HEADER e TRAILER respectivamente, elas identificam o início e op fim de um arquivo a ser lido (geralmente são opcionais). A primeira coluna identifica o tipo de dado do registro, neste caso 0 é o header, 1 são os dados e 2 o trailer. O header informa ainda a data e o horário do arquivo.
O objetivo desse código é apenas ler o arquivo, o header e o trailler serão usados em outro programa, mas isso fica para outro post.

Mãos a obra


Primeiro criamos uma sub LerArquivo:

Sub LerArquivo()

End Sub


Só para constar a diferença entre uma SUB e FUNCTION, é que a sub não nunca retorna valor, já uma fuction pode ou não retornar algum valor.

Vamos precisar de uma variável do tipo string para guardarmos as linhas coforma forem lidas.

Dim lin As String

Antes de ler de fato um arquivo é necessário abrir o arquivo, em VBA a função que faz isso é a Open, mas este comando não "anda" sozinho, é necessário informar o que será feito com esse arquivo, no nosso caso iremos apenas ler, portanto o devemos completar o comando com For Input As #N, onde N é um número que identifica os arquivos abertos.

Open "D:\Temp\Arquivo.txt" For Input As #1

Agora a leitura do arquivo propriamente dito, devemos usar um loop para fazer a leitura e exibir cada linha, enquanto o arquivo não chega ao fim.

Do While Not EOF(1)
Line Input #1, lin
Debug.Print lin
Loop


Não esqueça que depois de abrir e usar um arquivo é necessário fechá-lo:

Close #1

Veja o código completo como deve ficar:

Código completoSub LerArquivo()
Dim lin As String
Open "D:\Temp\Arquivo.txt" For Input As #1
Do While Not EOF(1)
Line Input #1, lin
Debug.Print lin
Loop
Close #1
Debug.Print "Fim =D"
End Sub


Até a próxima... se a terra não tremer de novo!

NMHO.

4/22/2008

Variáveis tipificadas dinamicamente em VBA

"Tipificar ou Não tipificar? Eis a questão!" -- Ok! Eu sei que essa paródia não tem graça, mas eu não resisti.


Apesar da piada, a dúvida é honesta. Das linguagens que eu conheço as duas que permitem são Visual Basic, Python e linguagens de script, e das as que não permitem, C# e Java. Depois de uma análise criteriosa, levando em consideração os paradigmas envolvidos chequei a conclusão que ... tanto faz (olha a piada boba ai de novo).

Na prática, não acho que esse seja um debate muito relevante (apesar de comum), porque no final, com variavel tipificada ou não, o programador sempre vai esquecer daquela vírgula, daquele ponto e algum lugar do código. Acho que o importante é conhecer e praticar sempre a sua linguagem preferida ou a que garante o leitinho das crianças. E por falar em leitinho das crianças, vou mostrar dar um exemplo em VBA.

Mãos a obra


Primeiro exemploSub StringNaoTipada_Soma_Integer()
Dim nt
Dim i As Integer
nt = "2"
i = 3
Debug.Print nt + i
End Sub


Neste primeiro exemplo a variável nt não teve o tipo de dados declarado (Variant/Empty), ao receber o número 2 entre aspas, o interpretador assume que a variável é uma Variant/String, quer ver? Na IDE do VBA, abra a janela "Variáveis locais" que está no menu Exibir e execute o código novamente, mas use o F8 para executar passo-à-passo, e observe a coluna "Tipo" dessa janela.

Segundo exemploSub IntegerNaoTipada_Soma_String()
Dim nt
Dim s As String
nt = 2
s = 3
Debug.Print nt + s
End Sub


Mais um exemplo mas com os tipos trocados dessa vez, o resultado é o mesmo.

Terceiro exemploSub StringNaoTipada_Soma_String()
Dim nt
Dim s As String
nt = "2"
s = 3
Debug.Print nt + s
End Sub



Enfim, é isso ai, pe-pes-soal.

4/16/2008

Diferença entre Option Compare Database e Option Explicit no VBA

Quando criamos um módulo e deixarmos o padrão Option Compare Database, o interpretador do VBA não vai exigir que as variáveis sejam declaradas e vai executar o códico do jeito que estiver, por exemplo:

código 1Option Compare Database
Sub contar()
i = 2
j = 3
Debug.Print i + j
End Sub


Como você pode ver, funciona, mas em um código muito grande pode ser difícil depurar os erros. Agora se declaramos que ele será Option Explicit, o interpretador só vai executar o código se todas as variáveis já estiverem explicitamente declaradas, por exemplo:

código 2Option Explicit
Sub contar()
Dim i
Dim j
i = 2
j = 3
Debug.Print i + j
End Sub


Até a próxima!

Atualização: "Dam You Copy and Cut!" Desculpe pessoal a primeira linha do segundo bloco de código estava errada.

NMHO.

1/20/2008

Excel e VBA com cobertura de TDD


Atualização:
O post original estava dando erro porque ele havia sido escrito no Google Texto & Planilhas e publicado diretamente de lá. O problema era que ao fazer alguma edição o blog todo ficava com o leiaute quebrado, por isso estou republicando este artigo.
Baseado em no trabalho Test Driven Development - using MS Excel and VBA de Clarke Ching (acessado em: outubro de 2007), resolvi fazer uma tradução/adaptação desse tutorial na forma de uma receita (quem sabe a Ana Maria Braga não me convida para o programa dela). Vamos lá.

Ingredientes
  • Microsoft Excel: o programa de planilha eletrônica escrita e produzida pela Microsoft.
  • VBA - Visual Basic for Applications: implementação do Visual Basic da Microsoft incorporada em todos os programas do Microsoft Office.
  • TDD - Test-Driven Development: técnica de escrever um pequeno teste que falhe, depois escrever um programa que faça o teste passar da maneira mais rápida e simples possível. Refatorar o código eliminando duplicação e código desnecessário incrementando o código e os testes de acordo com a necessidade.
Objetivo
Criar uma função que compara duas células e dependendo da combinação do conteúdo resultar em V (Verdadeiro), F (Falso) ou D (Duvidoso).

Preparando os ingredientes
Primeiro crie uma planilha em branco e verifique se está habilitada a execução de macros (menu Ferramentas, Macros, Segurança), eu recomendo deixar a segurança das macros no nível Médio (tá avisado). Em caso de dúvidas consulte o manual do Excel (sua cópia do Excel é original, não é?).

Na coluna A e B estarão as combinações possíveis para V, F ou D, na coluna RESULTADO colocaremos manualmente os valores esperados de acordo com a combinação das coluna A e B, na coluna FUNÇÃO a função =SALADA(A2;B2) e na coluna TESTE colocaremos a função =SE(C2=D2;“Passou”;“Falhou”) para comparar se a função SALADA está retornando o resultado esperado.



Agora pode colocar umas perfumarias como mudar fonte, colocar cor, borda, entre outras. Na realidade é tudo dispensável para este projeto, há apenas uma formatação que é necessária, mas eu mostro logo, logo. Agora é também a hora de preencher as células, inclusive colocando a função SALADA.

Como a função SALADA vai compara duas células ela será assim =SALADA(célula1;célula2), basta seguir o meu exemplo:



Ei, Deu erro!? ... Calma! Deu erro porque nós não criamos a tal função "salada" por isso deu o erro "#NOME?". Agora vamos trabalhar na coluna TESTE, coloque a =SE(C2=D2;“Passou”;“Falhou”). A célula vai resultar no mesmo erro da coluna D, o único jeito de resolver é colocando provisoriamente na coluna D a letra V na primeira e na segunda linha. Agora que a fórmula está funcionando coloque uma formatação condicional (menu Formatar e Formatação condicional...) e condicione que se o resultado forma “Passou” a célula deve ficar verde e se for “Falhou” que fique vermelha.



É importante ressaltar que a formatação condicional não é perfumaria, o destaque visual para o teste é algo que faz parte da metodologia TDD.

Colocando a mão na massa
Vamos começar a programar, antes que este artigo fique muito chato. Para acessar a IDE do Visual Basic for Applications basta teclar Alt + F11 ou pelo menu Ferramentas, clique em Macro e por fim Editor do Visual Basic. Você vai se deparar com esta interface:



O tempo vai fazer você vai perceber que a IDE do VBA é muito precária, principalmente se comparada com o Visual Basic ou outras IDE conhecidas, mas também deve notar que quanto mais você dominar a linguagem VBA, mais poderosas serão suas planilhas ou seus aplicativos criados no Access.

Vamos começar inserindo um novo módulo clicando no menu Inserir, seguido da opção Módulo. A IDE criar o arquivo do módulo e já deixe ele em uma pasta módulo, na propriedade (Name), logo abaixo, muda o nome para modSaladaMista.



Observação: Não vou explicar os detalhes da linguagem, o foco do artigo é demonstrar como usar TDD, o Excel e o VBA são apenas caodjuvantes, ferramentas usadas para explicar TDD.


Como comentado na primeira parte do artigo, a técnica TDD consiste em escrever um pequeno teste que falhe (já fizemos isso quando montamos a planilha), depois escrever um programa que faça o teste passar da maneira mais rápida e simples possível, portanto o primeiro teste da planilha espera que a função retorne V, então é isto que a primeira versão do nosso código deve fazer.

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
' Esta função faz a planilha atualizar
' seus resultados precionando-se F9
SALADA = "V"
' Para retornar um valor basta colocar
' o nome da funçao recebe o valor
End Function


É assim que deve ficar o nosso teste:



Quem tem alguma experiência em programação pode pensar que eu deveria programar de outra forma, afinal não parece muito inteligente uma função retornar diretamente um valor, sem tratamento nenhum, mas em TDD sempre devemos ter como preocupação primordial fazer o teste passar, depois refatoramos o código para melhorar. O próximo passo é fazer o segundo teste passar sem interferir no primeiro. Então vamos começar a colocar alguma lógica na nossa função mais:

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
If Parametro1 = "V" And Parametro2 = "F" Then
SALADA = "F"
Else
SALADA = "V"
End If
End Function


Agora temos dois testes estão passando:



Agora coloque a função de teste no restante das células. Reparem tudo que tem retorno "V" está com passou mas ainda não estamos tratando as células que possuem o valor "D", então vamos tratar de colocar algum tratamento para isso:

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
If Parametro1 = "V" And Parametro2 = "F" Then
SALADA = "F"
ElseIf Parametro1 = "V" And (Parametro2 = "V" Or Parametro2 = "D") = True Then
SALADA = "V"
End If
End Function


Olhem os testes agora...



...viu, não há retorno para os casos que não foram tratados, muito melhor não acham? Programar qualquer coisa usando a metodologia TDD é assim, basta tratar um teste após o outro e assim sucessivamente até que todos tenham passado. No próximo teste trata casos que possuem "F" e só de olhar podemos ver que todos resultam em "F", vamos tratar isso então:

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
If Parametro1 = "F" Or Parametro2 = "F" Then
SALADA = "F"
ElseIf Parametro1 = "V" And (Parametro2 = "V" Or Parametro2 = "D") = True Then
SALADA = "V"
End If
End Function


Incrível, não? Eu só mudei a primeira linha do IF e todas as alternativas que possuíam "F" passaram nos testes. Veja a próxima figura.



Agora só faltam dois testes para terminarmos esta função. Antes de continuar com o "D" eu percebi que a segunda linha do IF poderia ser mais simples, vamos refatorar um pouco este código. Eu deveria fazer isso só no final do programa mas como eu achei que estava tão tosco, resolvi acertar agora:

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
If Parametro1 = "F" Or Parametro2 = "F" Then
SALADA = "F"
ElseIf Parametro1 = "V" And Parametro2 <> "F" Then
SALADA = "V"
End If
End Function


Vamos trata dos "D" agora. Vamos inserir mais um teste no IF:

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
If Parametro1 = "F" Or Parametro2 = "F" Then
SALADA = "F"
ElseIf Parametro1 = "V" And Parametro2 <> "F" Then
SALADA = "V"
ElseIf Parametro1 = "D" Or Parametro2 = "D" Then
SALADA = "D"
End If
End Function


Ops! Um teste que não passou. Vamos voltar para o código, o erro estava no primeiro ElseIf, vejam a correção:

Public Function SALADA(Parametro1 As String, Parametro2 As String) As String
Application.Volatile
If Parametro1 = "F" Or Parametro2 = "F" Then
SALADA = "F"
ElseIf Parametro1 = "V" Or Parametro2 = "V" Then
SALADA = "V"
Else
SALADA = "D"
End If
End Function


Pronto, agora todos os teste passaram.



Show de bola não? Há um meio de fazer o mesmo no Access, mas eu ainda não dominei a ferramenta. Este é um exemplo bem simples para ilustrar como um "programa" orientado a testes é desenvolvido.

Esta obra está licenciada sob uma Licença Creative Commons.

Creative Commons License

Interessado em aprender mais sobre o Ubuntu em português?