quarta-feira, 20 de novembro de 2013

Site com boas informações de programação

Dica do amigo Victor Rubens!

http://wwww.codeproject.com

;-)

terça-feira, 15 de outubro de 2013

Mais material bom de VBA

No site da Microsoft.
Tomara que não saia do ar ou mude de lugar.

http://msdn.microsoft.com/en-us/library/bb726436(v=office.12).aspx

sábado, 12 de outubro de 2013

Comentário em células do Excel

Uma maneira interessante de orientar o usuário quanto ao preenchimento de determinadas colunas é colocar somente a mensagem na validação de dados.
Para isso, selecione a(s) célula(s), clique em Dados > Validação de Dados > Validação de dados > Mensagem de entrada e digite o alerta.

;-)


Importação de arquivo CSV no VBA

Outro dia me deparei com um problema muito estranho:
Utilizando o trivial "Open/Line Input/Close" para ler um arquivo CSV, ao fazer a leitura da primeira linha era carregado o arquivo inteiro (!) na variável string.
Provavelmente o arquivo não tinha o caracter de quebra de linha no final, mas o comportamento do VBA era muito estranho.
Pesquisando na net não vi nada sobre o assunto.

Ao experimentar com FileSystemObjects o mesmo se comportou da maneira como eu precisava, ou seja, a leitura seguiu de linha em linha e pude fazer a importação normalmente.

Ficam abaixo as 2 tentativas para consulta, sendo que o FileSystemObjects atendeu perfeitamente à necessidade da ocasião.
                              
;-)


Dim arquivo         As Variant
Dim fs              As New FileSystemObject  
Dim linha           As String
  
Set arquivo = fs.OpenTextFile(CurrentProject.Path & "\*.CSV", ForReading)   

linha = arquivo.ReadLine
Debug.Print linha
arquivo.Close



=====


    Dim arquivo     As String
    Dim linha       As String
   
    arquivo = Dir("C:\*.CSV")
    Open "C:\" & arquivo For Input As #1
    Line Input #1, linha
    Debug.Print linha
   
    Close #1

domingo, 22 de setembro de 2013

Aproveitando melhor o espaço em rede com arquivos XLS

Sabemos que no mundo corporativo, o espaço em rede geralmente é limitado e por isso nos vemos obrigados a compactar arquivos sempre que possível.
A dica de hoje é, utilize o formato de arquivo do Excel 2003 quando a planilha contiver somente dados sem formatação e sem os recursos avançados do Excel 2007 e superiores.
No comparativo abaixo, veja que uma arquivo XLS compactado com o WinRar ou WinZip é muito menor do que o mesmo arquivo no formato XLSX compactado.


ORIGINAL
WINRAR


ZIP

XSLX
2.414.174
2.307.292
95,6%

2.361.198
97,8%
XLS
4.868.608
1.312.301
27,0%

1.626.112
33,4%

;-)

sexta-feira, 6 de setembro de 2013

Espaço de armazenagem - onde estamos e para onde vamos...

Falar em Terabyte (1.000.000.000.000 de bytes) já não impressiona mais.
É comum ver HD's com 1, 2, 4 ou mais Terabytes de capacidade.
Em breve estaremos comprando HD's de Petabytes (1.000.000.000.000.000 de bytes), Exabytes (10 elevado a 18), Zettabyte (10 elevado a 21) e Yottabyte (10 elevado a 24) .
Ainda me lembro quando comprei meu HD de 1,7 Gb achando que nunca mais veria a mensagem Disk Full...


;-)


Preenchimento de contratos no Access

Tempos atrás eu vi um código que pretendia justificar um texto dentro de um TextBox num relatório e muita gente tentou adaptar o código para criar contratos e preenchê-los com dados de tabelas do Access.
A partir da versão 2007, o Office permitiu a criação de arquivos PDF o que deixou essa tarefa muito mais interessante, pois deixamos de depender de ferramentas de terceiros para gerar o contrato em PDF.
Eu mesmo usei durante muito tempo o PDF Creator, ferramenta muito boa e Open Source.
A dica para facilitar a tarefa é juntar recursos do pacote Office (que eu sempre digo que é uma suíte voltada a produtividade) e usar o melhor de cada um deles de forma integrada:
- Criar o contrato no Word utilizando todos os recursos de justificação de texto, tabelas para posicionar os campos e bookmarks (indicadores) para receber os campos da(s) tabela(s);
- A parte de programação pode ser feita tanto no Access quanto no Word.
Juntando tudo, basta preencher o contrato pelo VBA e gerar a saída no formato PDF.

Detalhes importantes que devem ser de conhecimento para utilizar esta técnica:
- Indicadores do Word;
- Modelos de documento (*.dot ou *.dotx);
- Criação de formulários no Word utilizando-se tabelas;
- Acesso à dados no Access (DAO ou ADO);
- Automação de aplicativos do Office (Access controlando o Word ou vice-versa) e
- Late Binding ou Early Binding.

Sobre este último item eu já devo ter escrito em algum post anterior, mas basicamente o Early Binding vai facilitar muito a programação porém exigirá que o programador saiba para qual versão do Office estará programando. O Late Binding não terá o problema da versão porém a programação será um pouco mais complexa.

;-)



Desfazer ações de macros e/ou VBA

Talvez seja redundante falar em macro e/ou VBA, mas faço essa colocação apenas para diferenciar a criação macro utilizando o gravador de macros do Excel e de códigos criados diretamente no ambiente do VBA (o que no fim das contas acaba sendo a mesma coisa).
Fato é que, qualquer que seja a ação executada pelo código, não há opção de desfazer, portanto é preciso muito cuidado ao testar algum programa em planilhas cujas informações são importantes.
A minha dica é trabalhar sempre numa cópia do arquivo e... testar, testar e testar até ter certeza de que está pronto para ser utilizado em produção.
Backup é sempre recomendável e normalmente a gente só lembra quando acontece uma tragédia...

;-)

sexta-feira, 30 de agosto de 2013

Indicação de livro para programadores VB/VBA iniciando em C#

Livro muito interessante para quem está iniciando no acesso a banco de dados com o C# e que já possuem algum conhecimento em VB/VBA.
O conteúdo é bem objetivo, sem entrar em detalhes da estrutura do C# vai direto ao assunto com exemplos bem didáticos e de fácil entendimento.
O preço gira em torno de R$ 35,00 (bem acessível) e na minha opinião vale o investimento.

Editora O'Reilly/Novatec.
Autor: Michael Schmalz
ISBN: 978-85-7522-315-4

;-)





Access: cuidados ao desabilitar avisos em macros e no VBA

As vezes quando damos manutenção em sistemas complexos e com sequências longas de comandos, é comum deixar passar um pequeno detalhe que pode ser crucial para localizar um possível erro aparentemente sem explicação.
Ao criarmos uma macro quase sempre iniciamos com o comando "Definir Avisos - Não" para que o Access não exiba mensagens de confirmação a cada consulta executada. O equivalente no VBA é o DoCmd.SetWarnings False.
O problema é que os comandos acima desabilitam também as mensagens de erro.
Imaginem uma tabela com um campo numérico onde a instrução é alterar o conteúdo para uma letra. Óbvio que será exibida uma mensagem de erro, mas veja que na sequência abaixo isso não ocorrerá pois os avisos foram desabilitados:

Sub teste_aviso()

    DoCmd.SetWarnings False
        DoCmd.RunSQL "UPDATE Tabela1 SET campo_numerico = 'A'"
    DoCmd.SetWarnings True    

    MsgBox "Consulta executada"

End Sub  


A dica portanto é, na hora de depurar a macro ou código VBA, executar consulta por consulta e acompanhar as mensagens de alerta do Access. Dá trabalho, demora, é necessário muita paciência e atenção.
Somente após ter certeza de que tudo está "ok", aí sim podemos desabilitar as mensagens seja por "Definir Avisos - Não" ou "DoCmd.SetWarnings False".

;-)

quarta-feira, 21 de agosto de 2013

Como a tecnologia evolue

Curiosidades... A primeira foto é de um HD de 4 Mb, um "monstro" para a época.
Mede pouco mais de um metro e meio de altura.
Na segunda foto, o meu HD portátil de 320Gb (que já é ultrapassado...).

VBA - Função de arredondamento com incremento personalizado

Outro dia precisei de uma função para transformar 1,1 em 2 e assim por diante (arredondar para cima sempre que a decimal for maior que zero) e com a ajuda do grande mestre Gib@ que conseguiu garimpar no suporte da Microsoft, deixo aqui para futuras consultas, pois os materiais da Microsoft costumam mudar de lugar ou simplesmente sumir. O link original: http://support.microsoft.com/kb/155696/pt-br

O exemplo a seguir cria um procedimento chamado RoundToNearest, que aceita três parâmetros:

   Parameter     Value

   ---------     ---------------------------------------------------------

   Amt           The numeric value you want to round

   RoundAmt      The increment to which Amt will be rounded

   Direction     Constant indicating which direction to round (up or down)

                                  

Por exemplo, RoundToNearest (3,33, 0,1, vb_roundup) retorna o valor 3.4.

1.       Crie um módulo e digite as seguintes linhas na seção declarações:

2.             Option Explicit

3.             Public Const vb_roundup = 1

      Public Const vb_rounddown = 0

Observação: Versões 1. x e 2.0, use a palavra "Global" em vez de "Público".

4.       Crie o procedimento a seguir.

Observação: No código de exemplo a seguir, um sublinhado (_) ao final de uma linha é usado como um caractere de 
continuação de linha. Remova o sublinhado do final da linha quando recriar esse código no Access Basic.

5.             Function RoundToNearest (Amt As Double, RoundAmt As Variant, _

6.                                      Direction As Integer) As Double

7.                On Error Resume Next

8.                Dim Temp As Double

9.                Temp = Amt / RoundAmt

10.            If Int(Temp) = Temp Then

11.               RoundToNearest = Amt

12.            Else

13.               If Direction = vb_rounddown Then

14.                  Temp = Int(Temp)

15.               Else

16.                  Temp = Int(Temp) + 1

17.               End If

18.               RoundToNearest = Temp * RoundAmt

19.            End If

20.         End Function

                                                 

21.   Para testar essa função, digite cada uma das linhas a seguir na janela Depurar 
(ou janela Verificação imediata no 1. x e 2.0) e, em seguida, pressione ENTER.

? RoundToNearest (0.25, vb_roundup, 1.36)

Observe que o procedimento retorna 1.5.

? RoundToNearest (1.36, 0.05, vb_rounddown)

Observe que o procedimento retorna 1.35.

? RoundToNearest (1.36, 0.75, vb_roundup)

Observe que o procedimento retorna 1.5, que é dois incrementos de 0,75.

Observação: Para usar a função acima na propriedade OrigemDoControle de um controle em um formulário, 
você precisará substituir as constantes vb_roundup e vb_rounddown com seus valores de número inteiro.

domingo, 28 de abril de 2013

Desanexando arquivos de uma pasta do Outlook

Escrevi este código para desanexar arquivos dos e-mails de uma pasta (que aqui vou chama-la de "Pasta a ser lida") com a condição de que o e-mail esteja marcado como "não lido". Utilizo o código para automação de um processo em que preciso processar vários arquivos do tipo texto (*.txt) em determinado horário da noite. ;-)
Option Compare Database
Option Explicit

Dim olapp           As New Outlook.Application
Dim pasta           As Outlook.Folder
Dim item            As Outlook.MailItem
Dim i               As Integer
Dim arq_anexo       As Outlook.Attachment
Dim repositorio     As String
    
    
Public Sub desanexa()

    'Define a pasta a ser lida
    Set pasta = olapp.GetNamespace("MAPI").Folders("Caixa de correio - Paulo K. Todoroki").Folders("Pasta a ser lida")
    
    For i = 1 To pasta.Items.Count
        DoEvents
        'Se a mensagem for do tipo E-MAIL  e marcada como NÃO LIDA
        If pasta.Items(i).Class = olMail And pasta.Items(i).UnRead = True Then
            'Para cada anexo da mensagem
            'Necessário o loop porque o primeiro anexo pode ser uma imagem com a assinatura
            For Each arq_anexo In pasta.Items(i).Attachments
                DoEvents
                arq_anexo.SaveAsFile "C:\Arquivos\" & arq_anexo.FileName
            Next arq_anexo
        End If
        
        'Marcar a mensagem como lida
        pasta.Items(i).UnRead = False
        
    Next
    
End Sub

Preenchendo textbox's em formulários desvinculados no Access

Iniciando pelas boas práticas de programação: nada mais lógico do que nomear um TextBox com o mesmo nome do campo da tabela obviamente respeitando os prefixos. Exemplo: no formulário o campo txt_nome recebe o valo do campo... nome! Tenho convivido com situações onde nem sempre isso ocorre. Campo como CNPJ tem variações e é carregado nos formulários em caixas de texto com nomes variados como txt_cnpj, txt_cpfcnpj, txt_cnpj_cli e por ai vai. Considerando que o boa prática foi respeitada, segue um código que preenche os campos de um formulário sem a necessidade de referenciá-los um a um. Escrevi o código para facilitar o dia a dia do desenvolvedor que sempre tem um pedido do tipo "é só acrescentar mais um campo...". Acrescentado o campo e o TextBox correspondente, nada é alterado no código. ;-)
Option Compare Database
Option Explicit

Private Sub Comando8_Click() 

    Dim nome_campo As String
    Dim nome_txt As String
    Dim campo_do_form As Control
    Dim formulario As Form

    ssql = "SELECT * FROM CLIENTES"
    Set rst = New ADODB.Recordset
    rst.Open ssql, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
    rst.MoveFirst

    Set formulario = Form_frm_teste      
    For Each campo_do_form In formulario
        nome_campo = Replace(campo_do_form.Name, "txt_", "")
        If Left(campo_do_form.Name, 3) = "txt" Then
            campo_do_form = rst.Fields(nome_campo).Value
        End If
    Next

    rst.Close
    Set rst = Nothing

End Sub

quarta-feira, 9 de janeiro de 2013

Bug

Até mesmo um simples jogo de paciência tem bug... estava com 9 cartas abertas e um espaço e olha só a mensagem! :-)

Pesquisar este blog

Arquivo do blog

Quem sou eu

Minha foto
Administrador de Empresas/Técnico em Processamento de Dados. Microsoft Office User Specialist - Excel Proficient. Pós-graduado em Business Intelligence.