quinta-feira, 11 de setembro de 2025

🌐 Automação Inédita em VBA: Monitor de Conexão com Servidor de Rede

🧐 O Problema

Em muitas empresas:

  • Planilhas puxam dados de pastas de rede ou bancos de dados locais.

  • Quando a conexão cai (servidor fora do ar, cabo de rede desconectado, VPN falhou), o usuário só descobre quando a macro dá erro. 😣

  • Isso gera atrasos e perda de produtividade.


💡 A Solução

Criar um monitor de conexão com servidor de rede diretamente no Excel:

  • O usuário informa o endereço do servidor (ex.: \\ServidorFinanceiro\ ou 192.168.0.10).

  • O VBA tenta fazer um ping nesse servidor.

  • Retorna em uma aba de relatório se o servidor está:

    • ✅ Online (acessível)

    • ❌ Offline (indisponível)

  • Também registra a latência (tempo de resposta) em milissegundos.

Assim, antes de rodar qualquer macro crítica, o usuário já sabe se o servidor está de pé. 🚦


🚀 Como Funciona

  1. Na aba "Servidores", o usuário lista os nomes ou IPs a monitorar:

Servidor
\ServidorFinanceiro\
\ServidorRH\
192.168.0.10
  1. Roda a macro.

  2. Na aba "StatusRede", o Excel preenche com:

  • Endereço testado

  • Status (Online/Offline)

  • Tempo de resposta

  • Última checagem


🧑‍💻 Código VBA

Sub MonitorarServidoresRede() Dim wsServidores As Worksheet, wsStatus As Worksheet Dim ultimaLinha As Long, i As Long Dim servidor As String, comando As String Dim resultado As String, latencia As String Dim objShell As Object, execObj As Object, saida As String ' Define a aba de servidores Set wsServidores = ThisWorkbook.Sheets("Servidores") ' Cria/limpa a aba de status On Error Resume Next Set wsStatus = ThisWorkbook.Sheets("StatusRede") If wsStatus Is Nothing Then Set wsStatus = Sheets.Add wsStatus.Name = "StatusRede" End If wsStatus.Cells.Clear On Error GoTo 0 ' Cabeçalho wsStatus.Range("A1:D1").Value = Array("Servidor", "Status", "Latência (ms)", "Última Verificação") ' Última linha na lista de servidores ultimaLinha = wsServidores.Cells(wsServidores.Rows.Count, 1).End(xlUp).Row ' Percorre servidores For i = 2 To ultimaLinha servidor = wsServidores.Cells(i, 1).Value comando = "ping -n 1 " & servidor Set objShell = CreateObject("WScript.Shell") Set execObj = objShell.Exec(comando) saida = execObj.StdOut.ReadAll If InStr(saida, "TTL=") > 0 Then resultado = "✅ Online" ' Extrai tempo de resposta If InStr(saida, "tempo=") > 0 Then latencia = Split(Split(saida, "tempo=")(1), "ms")(0) & " ms" ElseIf InStr(saida, "time=") > 0 Then latencia = Split(Split(saida, "time=")(1), "ms")(0) & " ms" Else latencia = "N/A" End If Else resultado = "❌ Offline" latencia = "-" End If ' Preenche resultados wsStatus.Cells(i, 1).Value = servidor wsStatus.Cells(i, 2).Value = resultado wsStatus.Cells(i, 3).Value = latencia wsStatus.Cells(i, 4).Value = Now Next i MsgBox "🔎 Monitoramento concluído! Veja a aba 'StatusRede'.", vbInformation End Sub

📊 Exemplo de saída (StatusRede)

ServidorStatusLatência (ms)Última Verificação
\ServidorFinanceiro✅ Online25 ms06/09/2025 09:20:31
\ServidorRH❌ Offline-06/09/2025 09:20:31
192.168.0.10✅ Online15 ms06/09/2025 09:20:31

🎯 Onde é útil?

✅ Antes de rodar macros que dependem de arquivos em rede.
✅ Equipes financeiras que acessam planilhas centralizadas.
✅ TI → monitoramento rápido de servidores internos.
✅ Usuários em VPN → saber se o acesso está estável.


🔥 Por que é útil ?

Quase ninguém usa Excel VBA para monitorar rede em tempo real.
Esse tipo de função é típico de ferramentas de TI, mas aqui está integrado direto no Excel.

🔢 Post 3 – Calculadora de Quatro Operações em Python 🧮🚀

No post anterior, criamos uma calculadora que fazia apenas soma ➕. Mas calculadora boa precisa ser mais completa, né?

Hoje vamos fazer um programa que pergunta ao usuário qual operação ele quer (soma, subtração, multiplicação ou divisão) e depois mostra o resultado.


🐣 Passo a passo do código

# Primeiro pedimos o primeiro número num1 = float(input("Digite o primeiro número: ")) # Usamos float() em vez de int(), porque float aceita números com casas decimais. # Depois pedimos o segundo número num2 = float(input("Digite o segundo número: ")) # Assim como acima, o valor digitado será convertido para número decimal (float). # Agora pedimos a operação desejada operacao = input("Digite a operação (+, -, *, /): ") # O usuário vai digitar o sinal da operação desejada. # Exemplo: + para soma, - para subtração, * para multiplicação, / para divisão. # Agora verificamos qual operação foi escolhida if operacao == "+": resultado = num1 + num2 # Se a operação for +, o resultado será a soma. elif operacao == "-": resultado = num1 - num2 # Se a operação for -, o resultado será a subtração. elif operacao == "*": resultado = num1 * num2 # Se a operação for *, o resultado será a multiplicação. elif operacao == "/": resultado = num1 / num2 # Se a operação for /, o resultado será a divisão. else: resultado = "Operação inválida!" # Caso o usuário digite algo diferente, mostramos que a operação não existe. # Por fim mostramos o resultado print("Resultado:", resultado) # Exibe a palavra "Resultado:" seguida do valor calculado.

💻 Exemplo de saída

Digite o primeiro número: 10 Digite o segundo número: 5 Digite a operação (+, -, *, /): * Resultado: 50.0

📌 O que você aprendeu hoje?

  • float() serve para trabalhar com números decimais.

  • Usamos if, elif e else para tomar decisões.

  • Criamos uma lógica que permite escolher entre várias operações.


🎯 Desafio extra

  1. Adicione a operação de potência usando **.

  2. Adicione a operação de módulo (resto da divisão) usando %.

  3. Trate o erro de divisão por zero (quando o usuário digitar 0 no segundo número).


⏭️ O que vem por aí?

No próximo post vamos criar um Jogo da Adivinhação 🎲, onde o Python escolhe um número secreto e você precisa descobrir.

📑➡️📊 Automação Python com GUI (Tkinter): Organizador Inteligente de Notas Fiscais XML 📑➡️📊

Resumo rápido: Neste post vamos criar uma automação em Python com interface gráfica (Tkinter GUI) que lê todos os arquivos XML de notas fiscais de uma pasta, extrai os dados principais (CNPJ, Razão Social, Número da NF, Data e Valor Total) e gera um relatório Excel prontinho para análise. Tudo explicado passo a passo, linha a linha, em linguagem para leigos. 🚀


Por que essa automação é útil para sua empresa? 🤔

  • Processa dezenas ou centenas de notas fiscais em segundos.

  • Evita o trabalho manual de abrir XML por XML.

  • Garante padronização e precisão nos relatórios.

  • Qualquer colaborador pode usar, pois tem uma interface gráfica simples.


O que você terá com este projeto ✅

  1. Um programa com janela gráfica para selecionar a pasta com notas fiscais XML.

  2. Extração automática dos dados de cada nota.

  3. Geração de um arquivo relatorio_notas.xlsx com todas as notas organizadas.

  4. Log visual dentro da própria janela, mostrando o que foi processado.

  5. Código comentado linha por linha + instruções de instalação.


Pré-requisitos 🛠️

  • Windows com Python 3.8 ou superior instalado.

  • Dependências que devem ser instaladas no terminal:

pip install pandas openpyxl lxml

Observação: a biblioteca tkinter já vem instalada por padrão no Python do Windows.


Estrutura dos arquivos XML

A automação foi feita para ler as NF-e padrão (modelo nacional). Os dados extraídos serão:

  • CNPJ do emitente

  • Razão Social do emitente

  • Número da Nota Fiscal

  • Data de emissão

  • Valor Total da NF


Código completo (salve como organizador_nfe_gui.py) 💻

# organizador_nfe_gui.py
registros = [] # 17: lista para guardar os dados
for arquivo in os.listdir(pasta): # 18: percorre todos os arquivos da pasta
if arquivo.lower().endswith(".xml"): # 19: só processa os que terminam com .xml
caminho = os.path.join(pasta, arquivo) # 20: monta caminho completo do arquivo
dados = extrair_dados(caminho) # 21: extrai dados do XML
if dados:
registros.append(dados) # 22: adiciona o resultado na lista
log_widget.insert(tk.END, f"✔ Processado: {arquivo}\n") # 23: escreve no log
else:
log_widget.insert(tk.END, f"❌ Erro ao ler: {arquivo}\n") # 24: mostra erro no log
log_widget.see(tk.END) # 25: rola o log para baixo

if registros: # 26: se encontrou dados
df = pd.DataFrame(registros) # 27: cria DataFrame com todos os dados
saida = os.path.join(pasta, "relatorio_notas.xlsx") # 28: define o nome do arquivo de saída
df.to_excel(saida, index=False) # 29: salva em Excel
messagebox.showinfo("Sucesso", f"Relatório gerado em:\n{saida}") # 30: avisa o usuário
else:
messagebox.showwarning("Aviso", "Nenhum XML válido encontrado.") # 31: avisa que não achou nada

# 32: função para iniciar a interface gráfica
def iniciar_gui():
root = tk.Tk() # 33: cria janela principal
root.title("Organizador de Notas Fiscais") # 34: título da janela
root.geometry("700x500") # 35: tamanho da janela

pasta_var = tk.StringVar() # 36: variável para guardar a pasta escolhida

def escolher_pasta():
caminho = filedialog.askdirectory() # 37: abre diálogo para escolher pasta
if caminho:
pasta_var.set(caminho) # 38: guarda a pasta escolhida

tk.Label(root, text="Pasta com XMLs:").pack(anchor="w", padx=10, pady=5) # 39: rótulo
tk.Entry(root, textvariable=pasta_var, width=80).pack(anchor="w", padx=10) # 40: campo de texto
tk.Button(root, text="Selecionar Pasta", command=escolher_pasta).pack(anchor="w", padx=10, pady=5) # 41: botão

log_text = scrolledtext.ScrolledText(root, height=20) # 42: área de texto rolável
log_text.pack(fill="both", expand=True, padx=10, pady=10) # 43: adiciona área de log

def rodar():
if not pasta_var.get(): # 44: verifica se a pasta foi escolhida
messagebox.showwarning("Aviso", "Selecione a pasta com XMLs!") # 45: alerta
return
processar_xmls(pasta_var.get(), log_text) # 46: chama a função principal

tk.Button(root, text="Gerar Relatório", command=rodar, bg="#4CAF50", fg="white", font=(None, 12)).pack(pady=10) # 47: botão principal

root.mainloop() # 48: mantém a janela aberta

# 49: executa a GUI quando rodar o script
if __name__ == "__main__":
iniciar_gui()

Explicação linha por linha (para leigos) 🧾

  • 1 a 5: importamos bibliotecas que vão permitir manipular arquivos, Excel, XML e criar a interface gráfica.

  • 6 a 15: função extrair_dados abre cada XML e busca os campos desejados (CNPJ, Razão Social, número da NF, data e valor). Se algo falhar, retorna vazio.

  • 16 a 31: função processar_xmls percorre todos os arquivos .xml da pasta, extrai dados de cada um e guarda numa lista. No final, gera um Excel com todos os dados.

  • 32 a 48: função iniciar_gui monta a janela do programa com campo para escolher a pasta, botão para iniciar e log visual.

  • 49: garante que a interface só abre quando rodamos o arquivo direto.


Como usar ✅

  1. Salve o código acima no arquivo organizador_nfe_gui.py.

  2. Abra o terminal e instale as dependências:

pip install pandas openpyxl lxml
  1. Execute o programa:

python organizador_nfe_gui.py
  1. Na janela que abrir:

    • Clique em Selecionar Pasta e escolha a pasta onde estão os XMLs.

    • Clique em Gerar Relatório.

    • O programa mostrará no log o que foi processado e criará relatorio_notas.xlsx dentro da pasta.


Cuidados ⚠️

  • Use apenas XMLs de NF-e oficiais (padrão SEFAZ).

  • Faça testes em uma pasta com poucas notas antes de processar lotes grandes.

  • O Excel gerado pode ser aberto em qualquer versão do Microsoft Excel (2010 em diante).


Possíveis melhorias futuras 🔧

  • Extração de mais campos (chave da nota, impostos, produtos detalhados).

  • Exportação para CSV ou banco de dados.

  • Filtro por data ou valor.

  • Interface mais completa com barra de progresso.


🚀 Conclusão

Com este programa, você transforma uma tarefa manual e cansativa (abrir cada XML de nota fiscal) em um processo automático e confiável. Em poucos cliques, você tem um relatório Excel pronto para ser usado na contabilidade ou gestão da empresa.


📢 Serviços de Contabilidade

Além de compartilhar automações, também ofereço meus serviços como contador:

  • Abertura de empresas no Simples Nacional;

  • Acompanhamento contábil mensal;

  • Planejamento tributário;

  • Orientação para profissionais de serviços.

👉 Entre em contato e leve eficiência também para a parte contábil da sua empresa! 🤝

📊 SQL no Excel – Post 2: Filtrando Clientes com WHERE

No primeiro projeto, vimos como buscar todos os registros de uma tabela no Excel com o SELECT *.

Mas, muitas vezes, você não precisa de todos os dados — apenas de uma parte deles.

É aí que entra o poderoso comando WHERE! 🚀


🎯 Projeto do Dia: Listar clientes de uma cidade específica

1. Cenário

Temos a mesma tabela Clientes no Excel:

IDNomeCidadeIdade
1João SilvaSão Paulo32
2Maria SouzaRio de Janeiro27
3Carlos LimaBelo Horizonte41
4Ana SantosCuritiba36
5Fernanda AlvesSão Paulo29

Nosso objetivo será filtrar apenas os clientes da cidade de São Paulo.


2. Código VBA com SQL

Abra o Editor do VBA (ALT + F11), insira um novo módulo e cole o seguinte código:

Sub FiltrarClientes() ' Declaração de variáveis Dim conn As Object Dim rs As Object Dim strSQL As String Dim ws As Worksheet ' Criar conexão Set conn = CreateObject("ADODB.Connection") Set rs = CreateObject("ADODB.Recordset") ' Conectar ao arquivo Excel conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES"";" ' SQL com filtro WHERE strSQL = "SELECT * FROM [Clientes$] WHERE Cidade = 'São Paulo'" ' Executar consulta rs.Open strSQL, conn ' Criar aba de resultados Set ws = ThisWorkbook.Sheets.Add ws.Name = "Clientes_SP" ' Copiar resultados ws.Range("A1").CopyFromRecordset rs ' Fechar conexões rs.Close conn.Close MsgBox "Consulta concluída com sucesso!", vbInformation End Sub

3. Explicando o Código 📝

  • WHERE Cidade = 'São Paulo' → Esse é o coração da consulta!
    Ele diz ao Excel/SQL: "me traga apenas as linhas em que a coluna Cidade seja igual a São Paulo".

  • SELECT * FROM [Clientes$] → Como antes, significa "traga todas as colunas da tabela Clientes".

  • rs.Open strSQL, conn → Executa a consulta filtrada.

  • ws.Range("A1").CopyFromRecordset rs → Cola somente os registros que atenderam ao filtro.


4. Resultado esperado 📋

A nova aba chamada Clientes_SP mostrará:

IDNomeCidadeIdade
1João SilvaSão Paulo32
5Fernanda AlvesSão Paulo29

📌 O que você aprendeu hoje?

✅ Como usar WHERE para filtrar dados em SQL.
✅ Como criar consultas mais específicas no Excel.
✅ Como retornar apenas clientes de uma determinada cidade.


👉 No próximo post (Post 3), vamos aprender a usar o WHERE com números – por exemplo, listar clientes com idade maior que 30.


📢 E lembre-se...

Além de aprender SQL no Excel, você também pode contar comigo como contador especializado em profissionais de serviços.
Posso te ajudar com:
✅ Abertura e registro de empresas no Simples Nacional
✅ Acompanhamento mensal contábil
✅ Planejamento tributário para pagar menos impostos

💼 Fale comigo e organize sua vida financeira com segurança!

quarta-feira, 10 de setembro de 2025

📊 SQL no Excel – Post 1: Seu Primeiro SELECT no Excel

 👋 Bem-vindo(a) ao primeiro post da nossa série de SQL no Excel.

Se você nunca usou SQL antes, não se preocupe: vamos aprender juntos, passo a passo, com projetos práticos que você poderá aplicar direto no Excel.

Hoje vamos criar nosso primeiro projeto em SQL dentro do Excel, aprendendo o comando mais básico e essencial: SELECT.


🎯 Projeto do Dia: Listando Clientes com SQL no Excel

1. Cenário

Imagine que você tem uma planilha no Excel chamada Clientes.xlsx, com a seguinte tabela:

IDNomeCidadeIdade
1João SilvaSão Paulo32
2Maria SouzaRio de Janeiro27
3Carlos LimaBelo Horizonte41
4Ana SantosCuritiba36

Nosso objetivo é listar todos os clientes da planilha usando SQL dentro do Excel.


2. Como preparar o ambiente

👉 Antes de rodar SQL no Excel, precisamos conectar a planilha como se fosse um banco de dados:

  1. Abra o Excel.

  2. Pressione ALT + F11 para abrir o Editor do VBA.

  3. No menu, clique em Inserir → Módulo.

  4. Cole o código abaixo.


3. Código VBA com SQL

Sub ListarClientes() ' Declaração de variáveis Dim conn As Object Dim rs As Object Dim strSQL As String Dim ws As Worksheet ' Criar conexão com o Excel como banco de dados Set conn = CreateObject("ADODB.Connection") Set rs = CreateObject("ADODB.Recordset") ' Caminho do arquivo Excel (ajuste para o seu arquivo) conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES"";" ' Escrevendo a SQL para buscar todos os registros strSQL = "SELECT * FROM [Clientes$]" ' Executando a consulta rs.Open strSQL, conn ' Criando uma nova aba para o resultado Set ws = ThisWorkbook.Sheets.Add ws.Name = "Resultado_SQL" ' Copiando o resultado para a aba nova ws.Range("A1").CopyFromRecordset rs ' Fechando conexões rs.Close conn.Close MsgBox "Consulta concluída com sucesso!", vbInformation End Sub

4. Explicando o Código (linha por linha) 📝

  1. Dim conn As Object → cria a conexão com o Excel.

  2. Dim rs As Object → cria o recordset, que guarda o resultado da consulta.

  3. conn.Open ... → conecta o Excel como se fosse um banco de dados.

  4. strSQL = "SELECT * FROM [Clientes$]" → aqui está a SQL! O SELECT * significa "selecione todas as colunas da tabela Clientes".

  5. rs.Open strSQL, conn → executa a consulta.

  6. ws.Range("A1").CopyFromRecordset rs → joga os dados retornados para uma nova aba no Excel.

  7. MsgBox → apenas mostra uma mensagem de sucesso.


5. Resultado esperado 📋

Depois de rodar a macro ListarClientes, você terá uma nova aba chamada Resultado_SQL, com a mesma lista de clientes que estava na planilha original.

Ou seja, seu primeiro SELECT no Excel via SQL foi executado com sucesso! 🚀


📌 O que você aprendeu hoje?

✅ Como usar SQL dentro do Excel.
✅ Como funciona o comando SELECT *.
✅ Como rodar uma consulta simples e trazer todos os dados de uma planilha.


👉 No próximo post, vamos aprender a filtrar registros usando o WHERE – por exemplo, listar apenas clientes de uma cidade específica.


📢 Precisa de ajuda contábil?

Sou contador especializado em profissionais de serviços. Posso ajudar você com:
✅ Abertura e registro de empresas no Simples Nacional
✅ Acompanhamento mensal da contabilidade
✅ Planejamento tributário para pagar menos impostos

💼 Entre em contato e simplifique sua vida financeira!

📧💸 Automação em Python: Assistente Inteligente de E-mails de Cobrança 📧💸

Resumo rápido: um script em Python que lê uma planilha com clientes, gera faturas em PDF, envia e-mails personalizados via Outlook e registra tudo num log. Ideal para reduzir tempo com cobranças e manter histórico para auditoria.


Por que isso ajuda sua empresa? 🤔

  • Evita retrabalho manual (copiar/colar e-mails).

  • Mantém linguagem padronizada e profissional.

  • Gera prova de envio (PDF + log).

  • Ajuda a acelerar recebimentos e reduzir inadimplência.


O que você precisa ter antes de rodar 🛠️

  1. Windows com Microsoft Outlook instalado (automatização usa Outlook).

  2. Python 3.8+ instalado.

  3. Bibliotecas: pandas, openpyxl, pywin32, fpdf.
    Instale com:

    pip install pandas openpyxl pywin32 fpdf
  4. Uma planilha Excel (clientes.xlsx) com estas colunas (exatas):
    Cliente | Email | Valor | Vencimento | Pago
    Exemplo:

    ClienteEmailValorVencimentoPago
    Acme Ltdacliente@acme.com1500.02025-08-10Não
    Bento SAfinanceiro@bento.br320.52025-09-01Sim

Código completo (salve como assistente_cobranca.py) 💻

# assistente_cobranca.py import os # 1 import pandas as pd # 2 import win32com.client as win32 # 3 from datetime import datetime # 4 from fpdf import FPDF # 5 import unicodedata # 6 # Configurações EXCEL_INPUT = "clientes.xlsx" # 7 LOG_FILE = "log_cobrancas.xlsx" # 8 PASTA_FATURAS = "faturas" # 9 os.makedirs(PASTA_FATURAS, exist_ok=True) # 10 def nome_arquivo_seguro(texto): # 11 nf = unicodedata.normalize('NFKD', texto).encode('ASCII', 'ignore').decode() # 12 nf = "".join(c for c in nf if c.isalnum() or c in (' ', '-', '_')).strip() # 13 nf = nf.replace(" ", "_") # 14 return nf.lower() + ".pdf" # 15 def gerar_pdf(cliente, valor, vencimento, pasta=PASTA_FATURAS): # 16 nome = nome_arquivo_seguro(f"fatura_{cliente}") # 17 caminho = os.path.join(pasta, nome) # 18 pdf = FPDF() # 19 pdf.add_page() # 20 pdf.set_font("Arial", size=12) # 21 pdf.cell(0, 10, txt=f"Fatura - {cliente}", ln=1, align="C") # 22 pdf.ln(5) # 23 pdf.cell(0, 10, txt=f"Valor: R$ {valor:,.2f}", ln=1) # 24 pdf.cell(0, 10, txt=f"Vencimento: {vencimento.strftime('%d/%m/%Y')}", ln=1)# 25 pdf.output(caminho) # 26 return caminho # 27 def enviar_emails(): # 28 df = pd.read_excel(EXCEL_INPUT, engine="openpyxl") # 29 outlook = win32.Dispatch("Outlook.Application") # 30 enviados = [] # 31 for idx, row in df.iterrows(): # 32 cliente = str(row.get("Cliente", "")).strip() # 33 email = str(row.get("Email", "")).strip() # 34 valor = float(row.get("Valor", 0)) # 35 venc = pd.to_datetime(row.get("Vencimento")) # 36 pago = str(row.get("Pago", "")).strip().lower() # 37 dias_atraso = (datetime.now() - venc.to_pydatetime()).days # 38 if not email or pago in ("sim", "s", "yes", "true"): # 39 continue # 40 if dias_atraso <= 0: # 41 continue # 42 if dias_atraso < 10: # 43 mensagem = f"Olá {cliente},\n\nSua fatura venceu em {venc:%d/%m/%Y}. Pode regularizar, por favor?\n\nObrigado!" # 44 elif dias_atraso < 30: # 45 mensagem = f"Olá {cliente},\n\nSua fatura de R$ {valor:,.2f} está em aberto há {dias_atraso} dias. Precisamos regularizar.\n\nAtt." # 46 else: # 47 mensagem = f"Atenção {cliente},\n\nSua fatura está vencida há {dias_atraso} dias. Entre em contato para evitar medidas.\n\nAt.te." # 48 fatura = gerar_pdf(cliente, valor, venc) # 49 mail = outlook.CreateItem(0) # 50 mail.To = email # 51 mail.Subject = f"Cobrança - {cliente} - R$ {valor:,.2f}" # 52 mail.Body = mensagem # 53 mail.Attachments.Add(os.path.abspath(fatura)) # 54 try: mail.Send() # 55 enviados.append({"Cliente": cliente, "Email": email, "Valor": valor, "Vencimento": venc, "DiasAtraso": dias_atraso, "Fatura": fatura, "EnviadoEm": datetime.now()}) # 56 print(f"E-mail enviado para {cliente} -> {email}") # 57 except Exception as e: print(f"Falha ao enviar para {cliente}: {e}") # 58 if enviados: # 59 df_log = pd.DataFrame(enviados) # 60 if os.path.exists(LOG_FILE): # 61 df_antigo = pd.read_excel(LOG_FILE, engine="openpyxl") # 62 df_novo = pd.concat([df_antigo, df_log], ignore_index=True) # 63 df_novo.to_excel(LOG_FILE, index=False) # 64 else: df_log.to_excel(LOG_FILE, index=False) # 65 if __name__ == "__main__": # 66 enviar_emails() # 67

Explicação linha por linha (linguagem simples) 🧾🔍

Vou explicar cada linha numerada acima. Se preferir, copie o código e acompanhe.

1 import os

  • Importa o módulo que ajuda a trabalhar com pastas e arquivos (criar pasta, juntar caminhos).

2 import pandas as pd

  • Importa o pandas, usado para ler e escrever planilhas Excel e manipular tabelas de dados.

3 import win32com.client as win32

  • Importa a biblioteca que permite controlar o Outlook no Windows (enviar e-mails automaticamente).

4 from datetime import datetime

  • Traz a classe datetime para calcular datas e horas (ex.: quantos dias de atraso).

5 from fpdf import FPDF

  • Importa o gerador de PDF simples, usado para criar a fatura em PDF.

6 import unicodedata

  • Usado para “limpar” nomes (tirar acentos) e gerar nomes de arquivos seguros.

7 EXCEL_INPUT = "clientes.xlsx"

  • Nome do arquivo Excel que o script vai ler (coloque sua planilha com este nome ou altere aqui).

8 LOG_FILE = "log_cobrancas.xlsx"

  • Nome do arquivo onde vamos guardar o registro dos e-mails enviados.

9 PASTA_FATURAS = "faturas"

  • Pasta onde os PDFs das faturas serão salvos.

10 os.makedirs(PASTA_FATURAS, exist_ok=True)

  • Cria a pasta faturas se ela não existir (não dá erro se já existir).

11 def nome_arquivo_seguro(texto):

  • Início de uma função que transforma texto (nome do cliente) em nome de arquivo seguro.

12 nf = unicodedata.normalize('NFKD', texto).encode('ASCII', 'ignore').decode()

  • Remove acentos e caracteres especiais (transforma 'José' em 'Jose').

13 nf = "".join(c for c in nf if c.isalnum() or c in (' ', '-', '_')).strip()

  • Mantém só letras, números, espaços, traço e underline — elimina outros símbolos.

14 nf = nf.replace(" ", "_")

  • Substitui espaços por underscore para formar nomes de arquivo amigáveis.

15 return nf.lower() + ".pdf"

  • Retorna o nome final em minúsculas com extensão .pdf.

16 def gerar_pdf(cliente, valor, vencimento, pasta=PASTA_FATURAS):

  • Inicia a função que cria o PDF da fatura para um cliente.

17 nome = nome_arquivo_seguro(f"fatura_{cliente}")

  • Cria um nome seguro para o PDF, usando o nome do cliente.

18 caminho = os.path.join(pasta, nome)

  • Monta o caminho completo do arquivo (pasta + nome do arquivo).

19 pdf = FPDF()

  • Cria um objeto PDF vazio para começar a escrever.

20 pdf.add_page()

  • Adiciona a primeira página ao PDF.

21 pdf.set_font("Arial", size=12)

  • Define a fonte (tipo e tamanho) para escrever no PDF.

22 pdf.cell(0, 10, txt=f"Fatura - {cliente}", ln=1, align="C")

  • Escreve o título da fatura (centralizado).

23 pdf.ln(5)

  • Pula uma linha para dar espaço.

24 pdf.cell(0, 10, txt=f"Valor: R$ {valor:,.2f}", ln=1)

  • Escreve o valor formatado com duas casas decimais.

25 pdf.cell(0, 10, txt=f"Vencimento: {vencimento.strftime('%d/%m/%Y')}", ln=1)

  • Escreve a data de vencimento no formato dia/mês/ano.

26 pdf.output(caminho)

  • Salva o arquivo PDF no disco no caminho criado.

27 return caminho

  • Retorna o caminho do PDF gerado (para anexar no e-mail).

28 def enviar_emails():

  • Início da função principal que faz a leitura da planilha, gera PDFs e envia e-mails.

29 df = pd.read_excel(EXCEL_INPUT, engine="openpyxl")

  • Lê a planilha clientes.xlsx para uma tabela (df = data frame).

30 outlook = win32.Dispatch("Outlook.Application")

  • Conecta ao Outlook para poder criar e enviar e-mails.

31 enviados = []

  • Lista vazia para registrar (na memória) os envios bem sucedidos.

32 for idx, row in df.iterrows():

  • Começa a percorrer cada linha da planilha (cada cliente).

33 cliente = str(row.get("Cliente", "")).strip()

  • Pega o nome do cliente da linha; transforma em texto e limpa espaços extras.

34 email = str(row.get("Email", "")).strip()

  • Pega o e-mail do cliente.

35 valor = float(row.get("Valor", 0))

  • Lê o valor (número) da fatura; se não tiver, usa 0.

36 venc = pd.to_datetime(row.get("Vencimento"))

  • Converte a data de vencimento para um objeto de data do pandas.

37 pago = str(row.get("Pago", "")).strip().lower()

  • Verifica na coluna "Pago" se a fatura já foi quitada (texto em minúsculo).

38 dias_atraso = (datetime.now() - venc.to_pydatetime()).days

  • Calcula quantos dias se passaram desde o vencimento (dias de atraso).

39 if not email or pago in ("sim", "s", "yes", "true"):

  • Se não tiver e-mail ou se a fatura estiver marcada como paga, pula este cliente.

40 continue

  • Pula para o próximo cliente na planilha.

41 if dias_atraso <= 0:

  • Se não há atraso (vencimento futuro ou hoje), pula também.

42 continue

  • Pula para o próximo registro.

43 if dias_atraso < 10:

  • Se o atraso for menor que 10 dias — mensagem mais suave.

44 mensagem = f"... (texto educado) ..."

  • Define o texto do e-mail para esse caso (você verá no código real).

45 elif dias_atraso < 30:

  • Se atraso entre 10 e 29 dias — mensagem mais direta.

46 mensagem = f"... (texto intermediário) ..."

  • Texto correspondente ao caso.

47 else:

  • Se 30 dias ou mais — mensagem mais firme.

48 mensagem = f"... (texto firme) ..."

  • Texto final para atraso crítico.

49 fatura = gerar_pdf(cliente, valor, venc)

  • Chama a função para criar o PDF da fatura e guarda o caminho do arquivo.

50 mail = outlook.CreateItem(0)

  • Cria uma nova mensagem de e-mail no Outlook.

51 mail.To = email

  • Define o destinatário.

52 mail.Subject = f"Cobrança - {cliente} - R$ {valor:,.2f}"

  • Define o assunto do e-mail (útil para organização).

53 mail.Body = mensagem

  • Coloca o texto no corpo do e-mail.

54 mail.Attachments.Add(os.path.abspath(fatura))

  • Anexa o PDF que acabamos de gerar.

55 mail.Send()

  • Envia o e-mail (pode abrir aviso de segurança no Outlook em alguns PCs).

56 enviados.append({...})

  • Se deu certo, guardamos dados sobre esse envio (cliente, data, arquivo).

57 print(f"E-mail enviado para {cliente} -> {email}")

  • Imprime no terminal que o e-mail foi enviado (útil para acompanhar execução).

58 except Exception as e: / print(f"Falha...")

  • Se der erro no envio, registra na tela qual foi o problema (não para todo o script).

59 if enviados:

  • Depois de terminar a varredura, se houver envios bem sucedidos, vamos gravar no log.

60 df_log = pd.DataFrame(enviados)

  • Converte a lista de envios em uma tabela (para salvar no Excel).

61 if os.path.exists(LOG_FILE):

  • Se o arquivo de log já existe, vamos anexar ao que já tem.

62 df_antigo = pd.read_excel(LOG_FILE, engine="openpyxl")

  • Lê o log antigo.

63 df_novo = pd.concat([df_antigo, df_log], ignore_index=True)

  • Junta o antigo com os novos registros.

64 df_novo.to_excel(LOG_FILE, index=False)

  • Salva tudo de volta no arquivo de log (completo).

65 else: df_log.to_excel(LOG_FILE, index=False)

  • Se não havia log, cria um novo com os envios.

66 if __name__ == "__main__":

  • Padrão Python: se você rodar este arquivo diretamente, executa o que vem a seguir.

67 enviar_emails()

  • Chama a função principal para começar o processo.


Como usar — passo a passo simples ✅

  1. Coloque assistente_cobranca.py e clientes.xlsx na mesma pasta.

  2. Abra o terminal (Prompt) nessa pasta.

  3. Instale dependências: pip install pandas openpyxl pywin32 fpdf

  4. Rode: python assistente_cobranca.py

  5. Observe no terminal as mensagens de sucesso/erro. Verifique a pasta faturas/ e o arquivo log_cobrancas.xlsx.


Dicas importantes e boas práticas ⚠️

  • Teste primeiro com 1 ou 2 e-mails (coloque seu próprio e-mail) antes de rodar em toda base.

  • Outlook pode mostrar um alerta de segurança; algumas empresas bloqueiam automações — consulte o time de TI.

  • Não use para spam: envie apenas cobranças válidas e respeite regras de comunicação.

  • Mantenha backup da planilha original antes de rodar.


Variações e melhorias que você pode pedir depois 🔧

  • Enviar em lotes (por ex. 50 por vez).

  • Integração com SMTP (para quem não usa Outlook).

  • HTML no corpo do e-mail (assinatura com logo).

  • Interface simples em Tkinter para selecionar arquivo e rodar com 1 botão.

  • Agendamento diário (via Agendador de Tarefas do Windows).


Precisa de suporte contábil? 📞 

Sou contador e ajudo profissionais e empresas com:

  • Abertura e registro de empresas no Simples Nacional;

  • Acompanhamento mensal da contabilidade;

  • Tributação e planejamento tributário.