Automatizar o envio de emails das suas listas com o Excel – Parte 2

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.
 

14 comentários em “Automatizar o envio de emails das suas listas com o Excel – Parte 2”

  1. 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

    Responder
    • 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

      Responder
  2. 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

    Responder
  3. 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?

    Responder
  4. 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

    Responder
    • 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:

      .attachments.DeleteAll

      Dessa forma, os anexos adicionados anteriormente serão removidos.
      Em breve, atualizarei os arquivos para download.
      Um abraço.

      Responder
      • 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

        Responder
        • 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:

          
          Private Function MontaEmailAddress(ByVal sEmailNames As String, ByVal sEmailAddress As String) As String
          Dim arrAddress As Variant
          Dim arrNames As Variant
          Dim i As Integer
          Dim sResult As String
              sEmailAddress = Replace(sEmailAddress, ";", ",")
              arrAddress = Split(sEmailAddress, ",")
              sEmailNames = Replace(sEmailNames, ";", ",")
              arrNames = Split(sEmailNames, ",")
              For i = 0 To UBound(arrAddress)
                  sResult = sResult & arrNames(i) & " <" & arrAddress(i) & ">,"
              Next i
              sResult = Left(sResult, Len(sResult) - 1)
              MontaEmailAddress = sResult
          End Function
          

          E, na função EnviarEmail, da classe clsEmail, procure a linha abaixo:

          
          With iMsg
              .to = emailToNome & " <" & emailTo & ">"
              .
              .
              .
          

          E troque para:

          
          With iMsg
              .to = MontaEmailAddress(emailToNome, emailTo)
              .
              .
              .
          

          Espero que ajude.
          Abraço

          Responder

Deixe um comentário