Olá pessoas Excelentes.
Antes de iniciarem a leitura deste artigo, leiam a primeira parte da matéria, pois os conceitos iniciais foram explicados lá, ok.
Dando prosseguimento ao tutorial para enviar emails diretamente da sua planilha no Excel com o uso da biblioteca Microsoft CDO (cdosys.dll), hoje, vou explicar como anexar arquivos à mensagem de email e como enviar múltiplos emails de uma listagem contida em sua planilha.
Vou focar este artigo nos procedimentos de envio de email, caso você queira saber como gerar arquivos dinamicamente para anexar em suas mensagens, sugiro que leia estes artigos:
Criar um novo arquivo automaticamente
Enviar planilha por email diretamente do Excel
Salvar planilha como arquivo de texto (.txt)
Anexando arquivos
Para anexarmos arquivos na mensagem, vamos utilizar a propriedade setEmailAnexo da nossa classe clsEmail que criamos no artigo anterior.
Essa propriedade irá anexar, um a um, todos os arquivos que nós carregarmos no array vAnexos, que em nosso exemplo, será populado através da caixa Anexar Arquivos que inicializaremos pelo comando GetOpenFilename.
Vejamos o código para que você possa entender mais claramente.
Sub EnviarEmailComAnexo()
Dim objEmail As clsEmail
Dim vAnexos As Variant
Dim sh As Worksheet
Dim vNomeTemp As Variant
On Error GoTo Erro_Sub
Set objEmail = New clsEmail 'Inicializa a classe clsEmail
Set sh = Sheets("PlanEmailComAnexo") 'Define a planilha
'Fazendo uma validação simples. Se o email do destinatário foi informado
If Len(Trim(sh.Range("C8"))) = 0 Then
MsgBox "Informe o email do destinatário.", vbInformation
Exit Sub
End If
If Len(Trim(sh.Range("C6"))) = 0 Then
vNomeTemp = Split(sh.Range("C8"), "@")
sh.Range("C6").value = vNomeTemp(0)
End If
With objEmail
.setConfEmailServidor = "smtp.seuservidor.com.br" 'Servidor de saída de emails. Ex: smtp.uol.com.br
.setConfEmailPorta = "25" 'Porta. Padrão é a porta 25
.setConfEmailSSL = false 'Se necessita conexão segura SSL
.setConfEmailFrom = "seu-email@seuservidor.com.br" 'Seu email: O remetente do email. Ex: seunome@uol.com.br
.setConfEmailSenha = "sua-senha" 'Sua senha: A senha que você usa para acessar seus emails
.setConfEmailFromNome = "Seu Nome" 'Seu nome: O nome que será exibido no campo De:
.Configurar 'Executa a configuração
.setEmailTo = sh.Range("C8") 'Email do Destinatário
.setEmailToNome = sh.Range("C6") 'Nome do Destinatário
.setEmailTitulo = "Aprendendo a enviar emails diretamente do Excel - Com Anexo" 'Título da mensagem
'Aqui, você deve digitar o conteúdo. Pode utilizar formatação HTML.
.setEmailConteudo = "Olá, <strong>" & .getEmailToNome & "</strong>.<br><br>Estou aprendendo muito aqui no site <a href=""https://www.exceldoseujeito.com.br"">Excel do Seu Jeito</a>." _
& "<br><br>Acesse <a href=""https://www.exceldoseujeito.com.br"">https://www.exceldoseujeito.com.br</a> e fique expert no Excel."
vAnexos = Application.GetOpenFilename(Title:="Anexar arquivos", MultiSelect:=True)
If IsArray(vAnexos) Then
.setEmailAnexo = vAnexos
End If
.EnviarEmail 'Executa o envio do Email
End With
Set objEmail = Nothing
MsgBox "Email enviado com sucesso!", vbInformation
Exit Sub
Erro_Sub:
MsgBox Err.Description, vbExclamation
Exit Sub
End Sub
Não esqueça de fazer as alterações necessárias com suas credenciais de acesso de email SMTP, do título da mensagem e conteúdo. Nada impede que você modifique o código para buscar estas informações na sua própria planilha, onde você pode definir estes dados de smtp, título e conteúdo da mensagem em células da mesma forma que o nome e email do destinatário.
Crie uma planilha nomeada “PlanEmailComAnexo” como a da figura a seguir.
Atribua a macro que acabamos de criar ao botão Enviar, assim:
Pronto. Agora insira o nome e o email do destinatário. Ao clicar em Enviar, será solicitado que você informe os anexos. Selecione os arquivos que deseja enviar e clique em Abrir.
Enviando vários Emails a partir de uma lista de contatos
Outra necessidade que muitos leitores costumam comentar é a possibilidade de enviar múltiplos emails. Ou seja, a partir de uma tabela contendo várias pessoas para receber determinada mensagem, seja um relatório de vendas para cada gerente, seja uma tabela de preços para cada vendedor de acordo com o departamento em que atua, enfim, diversas situações que podem ser programadas especificamente para cada caso.
Neste exemplo, vou mostrar como percorrer uma listagem de contatos e enviar um email personalizado para cada destinatário. Digo personalizado porque cada mensagem vai com o nome da pessoa no conteúdo da mensagem – e poderia ser qualquer informação específica, como as citadas acima.
O processo é bem parecido com os anteriores, a diferença é a inclusão de um laço de repetição da rotina para cada item da lista. O comando de repetição irá fazer quantos envios forem necessários de acordo com a quantidade de emails na lista.
Apenas tenha cuidado quanto aos limites de seu servidor de emails, porque existem algumas regras para evitar a prática de SPAM. Verifique o seu caso e implemente soluções para evitar um possível bloqueio. Você pode utilizar comandos de controle de tempo como o Wait para controlar a frequência de envios.
Vejamos o código.
Sub EnviarVariosEmails()
Dim objEmail As clsEmail
Dim sh As Worksheet
Dim vNomeTemp As Variant
Dim sNomeTo As String
Dim sEmailTo As String
Dim sStatus As String
Dim iLinhaInicial As Long
Dim iLinhaFinal As Long
Dim i As Long
On Error GoTo Erro_Sub
Set objEmail = New clsEmail 'Inicializa a classe clsEmail
Set sh = Sheets("PlanListaDeEmails") 'Define a planilha
With objEmail
.setConfEmailServidor = "smtp.seuservidor.com.br" 'Servidor de saída de emails. Ex: smtp.uol.com.br
.setConfEmailPorta = "25" 'Porta. Padrão é a porta 25
.setConfEmailSSL = false 'Se necessita conexão segura SSL
.setConfEmailFrom = "seu-email@seuservidor.com.br" 'Seu email: O remetente do email. Ex: seunome@uol.com.br
.setConfEmailSenha = "sua-senha" 'Sua senha: A senha que você usa para acessar seus emails
.setConfEmailFromNome = "Seu Nome" 'Seu nome: O nome que será exibido no campo De:
.Configurar 'Executa a configuração
'Percorre a listagem de emails para enviar
iLinhaInicial = 8 'Informe a linha que começa a lista de emails
iLinhaFinal = sh.Range("A1").SpecialCells(xlCellTypeLastCell).Row 'Recupera automaticamente a última linha da tabela
For i = iLinhaInicial To iLinhaFinal
Application.StatusBar = "Enviando email " & (i - iLinhaInicial + 1)
sNomeTo = Trim(sh.Range("B" & i))
sEmailTo = Trim(sh.Range("C" & i))
If Len(sEmailTo) = 0 Then 'Verifica se o email do destinatário foi informado
sStatus = "Informe o email do destinatário."
Else
If Len(sNomeTo) = 0 Then 'Verifica se um nome foi informado
vNomeTemp = Split(sEmailTo, "@")
sNomeTo = vNomeTemp(0)
End If
.setEmailTo = sEmailTo 'Email do Destinatário
.setEmailToNome = sNomeTo 'Nome do Destinatário
.setEmailTitulo = "Aprendendo a enviar emails diretamente do Excel" 'Título da mensagem
'Aqui, você deve digitar o conteúdo. Pode utilizar formatação HTML.
.setEmailConteudo = "Olá, <strong>" & .getEmailToNome & "</strong>.<br><br>Estou aprendendo muito aqui no site <a href=""https://www.exceldoseujeito.com.br"">Excel do Seu Jeito</a>." _
& "<br><br>Acesse <a href=""https://www.exceldoseujeito.com.br"">https://www.exceldoseujeito.com.br</a> e fique expert no Excel."
.EnviarEmail
sStatus = "Email enviado com sucesso!"
End If
sh.Range("D" & i) = sStatus 'Escreve o status do envio
Next i
End With
Set objEmail = Nothing
Set sh = Nothing
Application.StatusBar = False
MsgBox "Emails enviados", vbInformation
Exit Sub
Erro_Sub:
MsgBox Err.Description, vbExclamation
Exit Sub
End Sub
Crie uma planilha para inserir sua lista de contatos como a figura abaixo.
Da mesma maneira que no exemplo anterior, atribua a macro criada ao botão que irá acioná-la.
Bom pessoal, então é isso.
O artigo ficou um pouco extenso, mas é simples. Não se preocupem. Baixem o arquivo com os exemplos utilizados aqui e testem, modifiquem e estudem em cima deles. Qualquer dúvida postem aqui nos comentários, vou tentar responder a todos, dentro do possível.
Curtam, twittem, compartilhem e sigam o blog nas suas redes sociais e ajudem a divulgá-lo, ok… Agradeço a ajuda de vocês.
Um abraço e até a próxima.
Olá!
Acompanho sempre vosso site, mas não sei pq meu login não está funcionando, favor analisar. Login: wagnercgpereira
Estou precisando de uma ajuda, para enviar email utilizando a programação acima está funcionando para o Yahoo, mas para o Hotmail não, ele pede para Habilitar o TLS/SSL, procurei e não achei resposta.
Você poderia me ajudar com isso?
Muito Obrigado!
Wagner Goularte
Wagner,
Fiz os testes com o Hotmail e funcionou.
Certifique-se de estar configurando o servidor e as portas corretamente. No meu teste, utilizei o smtp.live.com e a porta 25.
Mas, pode ser que em alguns casos seja necessário habilitar um conexão segura e acesso por outra porta. Neste caso, altere a porta para 587 e adicione a seguinte linha de configuração na classe clsEmail no método configurar:
.Item(“http://schemas.microsoft.com/cdo/configuration/smtpusessl”) = true
Agora, quanto o login. O cadastro que você possui aqui no site é para recebimento do nosso Boletim Informativo contendo as novidades, ok. Por enquanto, não temos outro tipo de assinatura.
Um abração
Boa noite, por favor,como n tenho experiencia com macro baixei a planilha para enviar e-mail da lista…porém esta aparecendo mensagem de erros “Falha no enviou do e-mail.” e ” Falha na conexão do transporte com o servidor.” obrigado Luiz
Oi Luiz, como vai?
Dá uma lida no comentário anterior, acredito que possa resolver.
E tente também a porta 465, além da 587 já citada.
Um abraço
Ola Reinaldo
Primeiramente parabéns post (envio de email, envio de email de uma lista, envio de email com anexo) – Todos muito bons e claros.
Fiz uma alteração, ou tentei fazer uma alteração utilizando o exemplo da Lista + Envio de anexo
Acreci um coluna onde informo um número que identifica um arquivo e um determinado diretório em minha máquina.
O problema é que o código envia os emails para cada linha, porém a partir do segundo email ele vai acrescentando os anexos, ou seja, no primeiro ele anexa o primeiro apenas, no segundo o segundo + o primeiro e assim sucessivamente
Tudo funcionou, exceto por esse detalhe que não consegui solucionar mesmo após um pouco de pesquisa na internet.
Você poderia tentar elucidar essa questão como faço para que cada linha da lista carregue apenas o arquivo indicado eliminando o(s) anterior(es)??
Como posso enviar a planilha na qual fiz as alterações para você analisar caso ache interessante?
Boa Tarde Reinaldo
Postei uma msg ontem a noite mas acho que “sumiu”.
Vamos lá… como não poderia deixar de ser, primeiramente te dar os parabéns pela qualidade de seus posts.
Fiz uma adaptação da macro enviar email para uma lista (vários emails):
1)acrescentei uma coluna para identificação do arquivo a ser anexado para cada email.
2)Modifiquei o codigo identificar o local e buscar a identificação do arquivo na lista de emails.
3)Com as alterações funcionou ele envia os emails com seus anexos mas com o seguinte defeito, o primeiro emails segue com o seu anexo, o 2o. segue com seu anexo mais o anexo do 1o., o 3o. com os seu anexo + o do 1o. e do 2o. e assim sucessivente.
fiz varias tentativas de localizar o problema e alterar no código, fiz pesquisa na internet sobre o .SETEMAILANEXO para “zerar” esse membro, mas não fui feliz.
Seria possível analisar e me dar alguma dica. – SEGUE CODIGO ALTERADO:
Agradeço e parabéns novamente!!!!
Sub EnviarVariosEmails()
Dim objEmail As clsEmail
Dim sh As Worksheet
Dim vNomeTemp As Variant
Dim sNomeTo As String
Dim sEmailTo As String
Dim sAnexoTo As String
Dim sStatus As String
Dim iLinhaInicial As Long
Dim iLinhaFinal As Long
Dim i As Long
On Error GoTo Erro_Sub
Set objEmail = New clsEmail ‘Inicializa a classe clsEmail
Set sh = Sheets(“PlanListaDeEmails”) ‘Define a planilha
With objEmail
.setConfEmailServidor = “mail.provedor.com.br” ‘Servidor de saída de emails. Ex: smtp.uol.com.br
.setConfEmailPorta = “587” ‘Porta. Padrão é a porta 25
.setConfEmailFrom = “hamilton.peres@provedor.com.br” ‘Seu email: O remetente do email. Ex: seunome@uol.com.br
.setConfEmailSenha = “xxxxxxx” ‘Sua senha: A senha que você usa para acessar seus emails
.setConfEmailFromNome = “Hamilton Péres” ‘Seu nome: O nome que será exibido no campo De:
.Configurar ‘Executa a configuração
‘Percorre a listagem de emails para enviar
iLinhaInicial = 8 ‘Informe a linha que começa a lista de emails
iLinhaFinal = sh.Range(“A1”).SpecialCells(xlCellTypeLastCell).Row ‘Recupera automaticamente a última linha da tabela
For i = iLinhaInicial To iLinhaFinal
Application.StatusBar = “Enviando email ” & (i – iLinhaInicial + 1)
sNomeTo = Trim(sh.Range(“B” & i))
sEmailTo = Trim(sh.Range(“C” & i))
sAnexoTo = “c:\DocsEnvio\” & Trim(sh.Range(“D” & i)) & “.pdf”
If Len(sEmailTo) = 0 Then ‘Verifica se o email do destinatário foi informado
sStatus = “Informe o email do destinatário.”
Else
If Len(sNomeTo) = 0 Then ‘Verifica se um nome foi informado
vNomeTemp = Split(sEmailTo, “@”)
sNomeTo = vNomeTemp(0)
End If
.setEmailTo = sEmailTo ‘Email do Destinatário
.setEmailToNome = sNomeTo ‘Nome do Destinatário
.setEmailTitulo = “Contato do Mes – ” & Trim(sh.Range(“E4”)) ‘Título da mensagem
‘Aqui, você deve digitar o conteúdo. Pode utilizar formatação HTML.
.setEmailConteudo = “” & .getEmailToNome & “.Segue em anexo os dados referente o mes – ” & _
Trim(sh.Range(“E4”)) & “.Hamilton PéresAnalista”
.setEmailAnexo = sAnexoTo
.EnviarEmail
sStatus = “Email enviado com sucesso!”
.setEmailAnexo = “”
End If
sh.Range(“E” & i) = sStatus ‘Escreve o status do envio
Next i
End With
Set objEmail = Nothing
Set sh = Nothing
Application.StatusBar = False
MsgBox “Emails enviados”, vbInformation
Exit Sub
Erro_Sub:
MsgBox Err.Description, vbExclamation
Exit Sub
End Sub
Olá Hamilton, tudo bem?
A msg não sumiu não… é que não tenho conseguido muito tempo pra responder todas as mensagens aqui no blog!!! 🙁
Enfim, mas, chega de chororô…. rsrsrs
Na classe clsEmail, que é responsável pela manipulação da mensagem, ficou faltando um pequeno detalhe… a limpeza dos anexos incluídos.
Você pode notar que no exemplo original do envio múltiplo, não realizo o envio com anexos… Isso facilitou para que eu não percebesse essa falha, pois não aconteceu nos meus testes…
Mas, a solução é simples: antes da linha 108 da classe clsEmail, inclua a instrução:
Dessa forma, os anexos adicionados anteriormente serão removidos.
Em breve, atualizarei os arquivos para download.
Um abraço.
Ola Reinaldo,
Obrigado pela dica, irei fazer o teste e depois dou o retorno para vc.
Ola Reinaldo.
Mestre, tentei incluir a instrução conforme informou mas não obtive sucesso, a instrução não foi aceita, tentei varias alternativas e nada, e deste modo não funciou.
Mas mexendo aqui e ali acabei entrando no Modulo de Classe: clsEmail, na função EnviarEmail() e inclui a instrução no seguinte ponto abaixo do comentáro: ‘Anexa arquivos ao email
With iMsg
.To = emailToNome & ” ”
.CC = “”
.BCC = “”
.FROM = confEmailFromNome & ” ”
.Subject = emailTitulo
.HTMLBody = emailConteudo
‘Anexa arquivos ao email
>>AQUI>> .attachments.DeleteAll
If IsArray(emailAnexo) Then ‘Se mais de um arquivo para anexar
For i = 1 To UBound(emailAnexo)
.AddAttachment emailAnexo(i) ‘anexa um por um dos arquivos
Next i
Else ‘Se apenas um arquivo para anexar
If Len(emailAnexo) > 0 Then
.AddAttachment emailAnexo
End If
End If
.Send ‘Comando para enviar o email
End With
Neste local a instrução foi aceita e o resultado foi satisfatório, ou seja, sucesso, os email foram enviados para toda a lista e cada qual com apenas o seu anexo (único).
Gostaria de sua avaliação.
Aproveitando o ensejo gostaria de saber se no campo email (.setEmailTo = sEmailTo ) só é possível utilizar apenas 1 único email?? tentei digitar 2 separando com ponto-e-virgula mas não é aceito, tentei de algumas outras formas mas também não aceitou.
Agradeço sua atenção e presteza novamente.
Hamilton
Olá Hamilton, tudo bem?
Realmente, era lá na classe que a instrução DeleteAll deveria ser colocada!
Quanto ao envio para múltiplos destinatários no mesmo envio, você pode usar a vírgula sim. Contudo, na classe que desenvolvi no exemplo neste artigo não contempla essa funcionalidade. Para fazer isso, sugiro adicionar uma função de tratamento como esta:
E, na função EnviarEmail, da classe clsEmail, procure a linha abaixo:
E troque para:
Espero que ajude.
Abraço
??? anterior ??
Respondido lá amigo… Demorou um pouquinho, né?!!!
Correria… 🙂
Mas, tá aí…
Abraço.