domingo, 25 de dezembro de 2011

Outlook VBA - Desanexando todos arquivos

Outro dia me deparei com uma situação diferente: ter de desanexar aproximadamente 150 arquivos/e-mails.
Adaptando um código que peguei na internet, resolvi a parada movendo todos os e-mails para uma pasta temporária, criada apenas para esta finalidade e resolvi o problema na boa.
Abaixo o código.


Option Explicit

Public Sub salvar_anexos()
On Error GoTo erro

Dim objApp As Outlook.Application
Dim pasta_outlook As Outlook.MAPIFolder
Dim objItem As Object
Dim arq_anexo As Outlook.Attachment
Dim pasta As String

'Pasta onde serão gravados os arquivos anexos dos emails:
pasta = "C:\Teste"

Set objApp = Outlook.Application
Set pasta_outlook = objApp.ActiveExplorer.CurrentFolder

If MsgBox("Deseja desanexar todos os arquivos da pasta " & pasta_outlook.Name, vbYesNo) = vbNo Then Exit Sub

For Each objItem In pasta_outlook.Items
DoEvents
'Se o objeto é do tipo email, começa a desanexar os arquivos
If objItem.Class = olMail Then
For Each arq_anexo In objItem.Attachments
DoEvents
arq_anexo.SaveAsFile pasta & "\" & arq_anexo.FileName
Next arq_anexo
End If
Next objItem

MsgBox "Processo finalizado!", vbOKOnly

Exit Sub

erro:
MsgBox Err.Number & " - " & Err.Description, vbOKOnly
Exit Sub

End Sub

sábado, 26 de novembro de 2011

Office nas nuvens

Ainda não estou na nuvem, mas creio que se tornará inevitável...
Link do Office365 para quem quiser conhecer:



;-)

Coletando dados de pesquisas com o Outlook e Access

Outro dia estava procurando uma forma de fazer uma pesquisa de satisfação por e-mail e a primeira dificuldade foi justamente criar um texto que o usuário não pudesse modificar.
Apesar de não chegar no modelo que queria, acabei descobrindo um recurso do Access que facilitou muito.
O formulário final não é lá dos melhores em termos de estética, mas cumpre sua função.
Segue o link para quem quiser experimentar:

http://office.microsoft.com/pt-br/access-help/coleta-de-dados-por-meio-de-mensagens-de-email-HA010015427.aspx

;-)



sexta-feira, 21 de outubro de 2011

Mais um site legal sobre Outlook

http://www.outlookcode.com/default.aspx

O foco é programação, coisa meio rara em se tratando de Outlook.

;-)

quarta-feira, 12 de outubro de 2011

Site de VB com dicas interessantes

Tenho a impressão de que o site não é atualizado, mas as dicas que estão lá são bem interessantes.
Espero que não saia do ar...
http://www.codelines.com/

Indicado pelo grande amigo Gib@.

;-)

sábado, 8 de outubro de 2011

Conectando o SQL Server 2008 Express via VBA

Bem simples a conexão por ADO ao SQL Server Express 2008.
Uma vez conectado, nada muda no resto da programação.


Option Compare Database
Option Explicit
 
Sub teste_sql()
 
    Dim cnn As New ADODB.Connection
          
    cnn.Open "Provider=SQLNCLI10.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=base_teste;Data Source=pkazu\sql_express_2008"
   
    cnn.Execute "DELETE FROM TABELA1"
 
    cnn.Close
 
End Sub

domingo, 4 de setembro de 2011

Estupidez humana

Este espaço não era para este tipo de comentário, mas me revolta ver certas notícias pela internet.
Mais de 100 toneladas de tomate gastos em folia enquanto milhares morrem de fome é algo que não pode passar em branco.
Ok, ninguém sobrevive só comendo tomates, mas para quem não tem absolutamente nada, um tomate é o equivalente a esperança de viver um pouco mais.





segunda-feira, 22 de agosto de 2011

Copiando texto de arquivos PDF

Esta é para tirar poeira do blog, pois faz um bom tempo que não colocado dicas aqui...
Aliás, o blog que inicialmente era focado no Excel, agora praticamente virou blog de VBA.
Bem, pelo menos espero que mesmo assim continue sendo útil.

Vamos ao código de hoje.
O problema:
Precisava abrir muitos documentos PDF e selecionar apenas alguns campos para poder trabalhar com eles numa tabela do Access.
Após uma pesquisa pela internet, verifiquei que existe pouca coisa sobre automação do Adobe via VBA que pudesse me ajudar.
Automação com o Internet Explorer seria o óbvio, porém não existe "Select All" nem "Copy".
Parti para a solução que não considero a melhor, porém foi o que me quebrou o galho e espero que ajude aqueles que visitarem este blog.
Detalhe importante: os dados são copiados para um arquivo TXT e a parte de tratamento depende do documento que está sendo aberto e copiado, por isso não vou detalhar para não complicar.
Outro detalhe importante: marcar a referência Microsoft Forms 2.0 Object Library.
Se não estiver na lista das referências, procurar pelo arquivo FM20.dll que geralmente está em C:\Windows\System32\.

;-)


Option Compare Database
Option Explicit

Dim ie As Object
Dim temp_area As New DataObject
Dim arquivo As String

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Sub Pausa(ByVal segundos As Single)
Call Sleep(Int(segundos * 1000#))
End Sub

'Código teste para copia de texto de arquivo PDF

Sub IExplorer()

Open CurrentProject.Path & "\dados.txt" For Output As #1

Set ie = CreateObject("internetexplorer.application")
ie.Visible = True

arquivo = Dir(CurrentProject.Path & "\*.pdf")
Do While arquivo <> ""
ie.navigate CurrentProject.Path & "\" & arquivo
Do While ie.busy
DoEvents
Loop

Pausa 2
SendKeys "%E", True
SendKeys "{down}", True
SendKeys "{down}", True
SendKeys "{down}", True
Pausa 0.5
SendKeys "{ENTER}", True 'Selecionar tudo
SendKeys "%E", True
SendKeys "{down}", True
Pausa 0.5
SendKeys "{ENTER}", True 'Copiar

temp_area.GetFromClipboard
Print #1, temp_area.GetText
Print #1, "---------------------"

Debug.Print arquivo
arquivo = Dir

Loop

Close #1
ie.Quit
Set ie = Nothing

End Sub

terça-feira, 5 de julho de 2011

Carro personalizado


Este não podia ficar de fora do blog!!!

sábado, 2 de julho de 2011

Sobre o Custo Efetivo Total

Procurando a fórmula para o cálculo do C.E.T., achei no site do Banco Central do Brasil, a forma mais fácil de se chegar no valor.
O exemplo é extremamente simples, com a HP12C cheguei nos percentuais sem problemas.

http://www.bcb.gov.br/pre/bc_atende/port/custo.asp#3

;-)

quinta-feira, 14 de abril de 2011

Um lembrete quando utilizar late binding

Cuidado com algumas constantes...
Por exemplo, no Outlook VBA, o formato do texto do e-mail pode ser definido como olFormatHTML desde que a referência à versão corrente do Outlook esteja marcada!
No caso de late binding, lembre-se de que não há referência, portanto, neste exemplo o código retornará um erro.
Basta trocar o "olFormatHTML" por 2 que é a constante correspondente.
Ficaria assim:
email.BodyFormat = 2 (late binding) e
email.Bodyformat = olFormatHTML (early binding).
No Help dos VBA's do Office, pode encontrar todas as constantes necessárias para o dia a dia do programador.

;-)

sábado, 9 de abril de 2011

Compactando via VBA

Onde pretendo aplicar esta solução, o prompt do comando é bloqueado, portanto, o Shell não funciona.
De qualquer forma, fica aqui o código para quem quiser compactar usando o 7Zip ou WinRAR.
Para compactar um por um, basta fazer um loop e vir trocando o nome dos arquivos, idem para as senhas.
;-)

Sub teste()
Dim ret As Long
ret = Shell("C:\Arquivos de programas\WinRAR\rar a -pteste c:\base.rar c:\base.mdb")
End Sub

Sub teste7z()
Dim ret
ret = Shell("C:\Arquivos de programas\7-Zip\7z a -pteste c:\base.7z c:\base.mdb")
End Sub

Protegendo com senha os arquivos compactados pelo Windows





Poderia ser mais intuitivo, mas existe a possibilidade de proteger com senha quando se compacta um arquivo pelo próprio Windows, sem utilizar um compactador de terceiros.
Clique com o botão direito sobre o arquivo a ser compactado, selecione Enviar para > Pasta compactada (zipada).
No arquivo zipado que se criou, clique com o botão direito do mouse e clique em Explorar.
No menu arquivo, aparece então a opção de adicionar senha.

;-)


Compactando com senha todos os arquivos de uma pasta


Estou tentando fazer essa tarefa via VBA, mas enquanto não encontro solução... segue a dica de um compactador que faz esse trabalho, o PeaZip.
Trabalha com vários formatos (*.7Z, *.rar, *.zip e outros), e tem versão "Portable" que funciona a partir do pendrive.
Ainda não testei, mas aparentemente muito bom e simples de usar.
Já ia esquecendo... os arquivos são individuais, ou seja, trata-se de criar um zip para cada cada arquivo e não um zip contendo todos os arquivos!

http://www.peazip.org

;-)

terça-feira, 29 de março de 2011

Mais um código para obter via VBA o IP do seu computador

Com os devidos créditos nos comentários.


Option Explicit

Global num_ip As String

' VBA MODULE: Get all IP Addresses of your machine
' (c) 2005 Wayne Phillips (http://www.everythingaccess.com)
' Written 18/05/2005
'
' REQUIREMENTS: Windows 98 or above, Access 97 and above
'
' Please read the full tutorial here:
' http://www.everythingaccess.com/tutorials.asp?ID=Get-all-IP-Addresses-of-your-machine
'
' Please leave the copyright notices in place.
' Thank you.
'
'Option Compare Database

'A couple of API functions we need in order to query the IP addresses in this machine
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function GetIpAddrTable Lib "Iphlpapi" (pIPAdrTable As Byte, pdwSize As Long, ByVal Sort As Long) As Long

'The structures returned by the API call GetIpAddrTable...
Type IPINFO
dwAddr As Long ' IP address
dwIndex As Long ' interface index
dwMask As Long ' subnet mask
dwBCastAddr As Long ' broadcast address
dwReasmSize As Long ' assembly size
Reserved1 As Integer
Reserved2 As Integer
End Type

Public Function ConvertIPAddressToString(longAddr As Long) As String

Dim IPBytes(3) As Byte
Dim lngCount As Long

'Converts a long IP Address to a string formatted 255.255.255.255
'Note: Could use inet_ntoa instead

CopyMemory IPBytes(0), longAddr, 4 ' IP Address is stored in four bytes (255.255.255.255)

'Convert the 4 byte values to a formatted string
While lngCount < 4

ConvertIPAddressToString = ConvertIPAddressToString + _
CStr(IPBytes(lngCount)) + _
IIf(lngCount < 3, ".", "")

lngCount = lngCount + 1

Wend

End Function

Public Sub GetIPAddresses(Optional blnFilterLocalhost As Boolean = False)

Dim Ret As Long, Tel As Long
Dim bytBuffer() As Byte
Dim IPTableRow As IPINFO
Dim lngCount As Long
Dim lngBufferRequired As Long
Dim lngStructSize As Long
Dim lngNumIPAddresses As Long
Dim strIPAddress As String

On Error GoTo ErrorHandler:

Call GetIpAddrTable(ByVal 0&, lngBufferRequired, 1)

If lngBufferRequired > 0 Then

ReDim bytBuffer(0 To lngBufferRequired - 1) As Byte

If GetIpAddrTable(bytBuffer(0), lngBufferRequired, 1) = 0 Then

'We've successfully obtained the IP Address details...

'How big is each structure row?...
lngStructSize = LenB(IPTableRow)

'First 4 bytes is a long indicating the number of entries in the table
CopyMemory lngNumIPAddresses, bytBuffer(0), 4

While lngCount < lngNumIPAddresses

'bytBuffer contains the IPINFO structures (after initial 4 byte long)
CopyMemory IPTableRow, _
bytBuffer(4 + (lngCount * lngStructSize)), _
lngStructSize

strIPAddress = ConvertIPAddressToString(IPTableRow.dwAddr)

If Not ((strIPAddress = "127.0.0.1") _
And blnFilterLocalhost) Then

'Replace this with whatever you want to do with the IP Address...
num_ip = strIPAddress

End If

lngCount = lngCount + 1

Wend

End If

End If

Exit Sub

ErrorHandler:
MsgBox "An error has occured in GetIPAddresses():" & vbCrLf & vbCrLf & _
Err.Description & " (" & CStr(Err.Number) & ")"

End Sub

Criando arquivos MDE no Access 2007 - Parte III

Apesar de ter escrito em outros lugares que não ia baixar o hotfix (achei uma falta de respeito com o consumidor não corrigir esse erro banal até o SP2), mudei de idéia e fui buscar o arquivo.
Para minha surpresa, foi necessário cadastrar meu e-mail para receber as instruções!
Bem, feito isso, olha só o que veio no e-mail demonstrando o pouco caso com o problema.

:-(


INFORMAÇÕES IMPORTANTES

Para sua conveniência, colocamos o hotfix solicitado em um site HTTP. Você pode baixar o hotfix desse site e com isso evitamos ocupar a sua caixa de entrada de emails.

AVISO Esse hotfix não foi submetido a um teste completo. Portanto, destina-se somente a sistemas ou computadores enfrentando o mesmo problema descrito em um ou mais artigos da Base de Dados de Conhecimento Microsoft listados no campo "Números do artigo da base de dados" da tabela que se encontra no final desta mensagem de email. Se você não tiver certeza de que algum problema específico de compatibilidade ou instalação esteja associado a esse hotfix, será recomendável aguardar pela próxima versão do service pack. O service pack incluirá uma versão totalmente testada dessa correção. Sabemos que pode ser difícil determinar se algum problema de compatibilidade ou instalação está associado a um hotfix. Assim, se desejar confirmar se o hotfix corrige o seu problema específico, ou se algum problema de compatibilidade ou instalação está a ele associado, os analistas de suporte dos Serviços de Atendimento ao Cliente poderão ajudá-lo. Para obter mais informações sobre como contatar o suporte, copie o link a seguir e cole-o no seu navegador da Web:

http://support.microsoft.com/contactus/

Para obter opções adicionais de suporte, copie o link a seguir e cole-o no seu navegador da Web:

http://support.microsoft.com/

Antes de instalar o hotfix
------------------------------

Se você decidir instalar esse hotfix, observe os itens a seguir:

Não implante um hotfix em um ambiente de produção sem antes testá-lo.

Faça backup do sistema ou computador que receberá o hotfix antes de instalá-lo.

Criando arquivos MDE no Access 2007 - Parte II

Achei muito bom a opção de criar um arquivo MDE em vez do ACCDE no Access 2007, porém encontrei problemas...
Um MDE criado no 2007 simplesmente não abre em outro computador!
Gastando meu precioso tempo numa pesquisa na net, descobri que o problema é de conhecimento da Microsoft e até disponibilizou um hotfix para sanar o inconveniente.
Inadmissível um problema tão tosco e básico, lamentável mesmo.

link para o hotfix:
http://support.microsoft.com/kb/943249

;-)

terça-feira, 22 de março de 2011

Cadê os comandos do Office 2010?

Segue link com o "de -> para" dos comandos do Office 2010 em relação ao 2003.
Não sei quanto tempo o link estará no ar.
É necessário ter o Silverlight instalado.
Estranhamente o tutorial não roda no Chrome.

http://office2010.microsoft.com/en-us/word-help/learn-where-menu-and-toolbar-commands-are-in-office-2010-HA101794130.aspx#_Toc268688374

Se não estiver enganado, acho que já vi algo parecido para o Office 2007...

;-)

Criando arquivos MDE no Access 2007

Estava preocupado em trabalhar com o Access 2007, pois sempre criava MDE's para proteger meus códigos VBA e nesta versão, vi somente a opção de criação de ACCDE's, o equivalente do primeiro caso.
Questionando no fórum ExpertAccess, nosso colega JPaulo indicou um texto interessante que reproduzo parte dele mais abaixo, onde descreve-se a funcionalidade de criar MDE a partir de banco de dados MDB da versão 2003 no Access 2007.
Façam um teste.
Criem um mdb no formato 2003 e na faixa de opções "Ferramentas de banco de dados" aparecerá o botão "criar MDE".
Usando o formato ACCDB, na faixa de opções aparece "Criar ACCDE".
Muito bom, tomara que na versão 2010, o recurso seja mantido.

;-)

Obs.: costumo colocar o link + o texto, pois frequentemente os sites são atualizados e por vezes, o link torna-se inválido. Procuro dessa forma, preservar o texto original para futuras consultas aqui.

link do texto:
http://office.microsoft.com/en-us/access-help/6-key-considerations-when-creating-access-2007-databases-HA010219005.aspx


trecho do texto:
TIP In previous versions of Access this was called a Microsoft Database Executable (MDE) file. The functionality and creation process are the same. If you open an older (Access 2002 or Access 2003) MDB file in Access 2007, a Make MDE command appears in the Database Tools group on the Database Tools tab in place of the Make ACCDE command that appears when you're working in an Access 2007 database.

quinta-feira, 10 de março de 2011

Mais um site sobre Outlook...

... com muitas informações!!!
http://www.outlookcode.com/

;-)

segunda-feira, 7 de março de 2011

Agenda no Office

Tenho visto muita gente desenvolvendo uma agenda no Accesss, mas creio que "reinventar a roda" é perda de tempo.
Segue minha opinião:
A maioria dos computadores (para não dizer todos) que têm o Access instalado, invariavelmente têm o MS Outlook também.
Então para que criar uma agenda no Access, se você tem no MS Outlook uma excelente agenda, totalmente funcional e completa?
Via VBA é possível fazer os dois aplicativos interagirem entre si, obtendo assim a produtividade esperada do pacote Office.
Falar em produtividade aqui no blog já é "chover no molhado", mas insisto no assunto para que os colegas programadores gastem menos tempo com soluções mirabolantes em VBA e entendam que a integração entre os aplicativos Office é o caminho para a produtividade.
Quem já vem acompanhando o blog, sabe que tenho a mesma opinião quanto a criação de controle de estoque em Excel: funciona quando a quantidade de itens é pequena (eu diria que até uns 50 itens no estoque e com pouca movimentação de entradas e saídas).
É o aplicativo inadequado para a tarefa.
Dúvidas? Vejam o famoso Northwind que é o banco de dados exemplo que vem no Office (não sei se na versão 2010 ainda vem).
Onde encontrar muita coisa de programação VBA no Outlook: http://www.rsoutlook.com


;-)

Zipando via VBA com o 7Zip

Segue uma adaptação de um código que eu peguei na internet.
Não é de minha autoria, mas vou deixar aqui para futuras consultas.
É bom ressaltar que o 7Zip é um compactador free e até o último comparativo que fiz, tinha uma taxa de compressão melhor que a do WinRAR.


Option Explicit

Dim nome_zip As Variant
Dim pasta_a_zipar As Variant
Dim strDate As String
Dim Pasta_destino As String
Dim oApp As Object


Sub Zipar_tudo_com_7Zip()

'Pasta onde estará o arquivo zipado
Pasta_destino = "C:\Users\todorok\Desktop\"

'Pasta que contém os arquivos a serem zipados
pasta_a_zipar = "C:\Users\todorok\Desktop\Kaizen\"

'Arquivo zip que contém os arquivos compactados
nome_zip = Pasta_destino & "backup" & ".zip"

'Criar um arquivo zip vazio
Call Novo_zip_vazio(nome_zip)

Set oApp = CreateObject("Shell.Application")
'Copiar os arquivos para dentro do arquivo zip vazio
oApp.NameSpace(nome_zip).CopyHere oApp.NameSpace(pasta_a_zipar).Items

'Aguardar o término da compactação
On Error Resume Next
Do Until oApp.NameSpace(nome_zip).Items.Count = oApp.NameSpace(pasta_a_zipar).Items.Count
Application.Wait (Now + TimeValue("0:00:01"))
Loop
On Error GoTo 0

MsgBox "Fim!"
End Sub

Sub Novo_zip_vazio(sPath)
'Se já existir um arquivo zip, apagá-lo e criar um novo
If Len(Dir(sPath)) > 0 Then Kill sPath
Open sPath For Output As #1
Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
Close #1
End Sub

domingo, 23 de janeiro de 2011

Linguagem de programação dirigida a iniciantes

Chegou o Small Basic, uma linguagem de programação que, segundo a Microsoft, destina-se a crianças ou pessoas que desejam aprender a programar de forma simples e intuitiva.
Ainda não instalei, mas logo farei um teste.
Para pessoas que já têm alguma experiência, em princípio não vejo muita coisa interessante, mas o que me chamou a atenção é que o Small Basic é orientado à objetos e imagino eu que, pela sua simplicidade, deve ajudar a quem vive no mundo da orientação à eventos, aprender os novos conceitos.

Links:
Download do Small Basic:
http://blogs.msdn.com/b/smallbasic/archive/2010/06/11/small-basic-v0-9-is-here.aspx

FAQ:
http://msdn.microsoft.com/en-us/beginner/ff384239.aspx

Manuais:
http://msdn.microsoft.com/en-us/ff423682
Obs.: infelizmente o português BR não estava disponível no momento em que escrevia este post, mas o link para o português PT está ativo.

Home do Small Basic:
http://msdn.microsoft.com/en-us/beginner/ff384126.aspx

;-)

Verificando a versão do Excel via VBA

Esta questão foi postada num dos grupos de discussões que participo.
A resposta é bem simples, basta usar o Application.Version que será mostrada a versão do Excel que está sendo executada.
Abra o VBA (ALT + F11), tecle CTRL + G para abrir a janela de verificação imediata e digite Debug.Print Application.Version

O resultado será:
Versão 8 para o Excel 97
Versão 9 para o Excel 2000
Versão 10 para o Excel 2002
Versão 11 para o Excel 2003
Versão 12 para o Excel 2007
Versão 14 para o Excel 2010

A pergunta mais óbvia: cadê a versão 13?
Se alguém souber, me mande por e-mail, apenas por curiosidade.
Certamente, a necessidade de verificar a versão deve-se a alguma incompatibilidade de comandos entre a versão onde foi desenvolvido e a versão onde será executado o programa.
Nestes casos, minha recomendação também é simples:
Se você sabe que tem mais de uma versão do Excel instalado na sua empresa, desenvolva sempre para a versão mais antiga e use sempre que possível, late binding para evitar problemas com referências aos outros aplicativos do MS Office.
A pequena perda de performance no late binding é praticamente imperceptível, visto que os PC's atuais são bem rápidos e raramente aplicações desenvolvidas no Excel têm a performance como foco principal.


;-)

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.