Descrição:

Este script foi desenvolvido para um cliente específico, com o objetivo de processar arquivos Excel contendo lançamentos financeiros. Ele realiza as seguintes tarefas:


Funcionalidades principais:


Código completo:

python
CopyEdit
import os
import pandas as pd
from openpyxl import load_workbook
from tempfile import NamedTemporaryFile

def letra_para_indice(letra):
    letra = letra.upper()
    indice = 0
    for char in letra:
        indice = indice * 26 + (ord(char) - ord('A') + 1)
    return indice - 1

def desmesclar_para_tempfile(caminho_arquivo):
    try:
        wb = load_workbook(caminho_arquivo)
        for sheet in wb.sheetnames:
            ws = wb[sheet]
            if ws.merged_cells.ranges:
                for merged_cell in list(ws.merged_cells):
                    ws.unmerge_cells(str(merged_cell))
        tmp = NamedTemporaryFile(suffix=".xlsx", delete=False)
        wb.save(tmp.name)
        tmp.close()
        return tmp.name
    except Exception as e:
        print(f"[ERRO] Desmesclar {caminho_arquivo}: {e}")
        return None

def processar_arquivo(caminho_arquivo, pasta_saida):
    caminho_temp = desmesclar_para_tempfile(caminho_arquivo)
    if not caminho_temp:
        return

    try:
        sheet = pd.read_excel(caminho_temp, sheet_name=0)
        os.remove(caminho_temp)
    except Exception as e:
        print(f"[ERRO] Abrir {caminho_temp}: {e}")
        return

    coluna_data_idx = letra_para_indice('E')
    coluna_valor_idx = letra_para_indice('Y')
    coluna_historico_idx = letra_para_indice('G')
    coluna_g_idx = letra_para_indice('G')
    coluna_ar_idx = letra_para_indice('AE')
    coluna_juros_idx = letra_para_indice('AF')
    coluna_doc_origem_idx = letra_para_indice('A')

    if len(sheet.columns) <= max(coluna_g_idx, coluna_ar_idx, coluna_juros_idx, coluna_doc_origem_idx):
        print(f"[AVISO] Colunas insuficientes em {os.path.basename(caminho_arquivo)}")
        return

    dados_processados = []
    for _, row in sheet.iterrows():
        data = row.iloc[coluna_data_idx]
        valor = row.iloc[coluna_valor_idx]
        historico = row.iloc[coluna_historico_idx]
        historico_principal = row.iloc[coluna_g_idx]
        d_ou_c = row.iloc[coluna_ar_idx]
        juros = row.iloc[coluna_juros_idx]
        doc_origem = row.iloc[coluna_doc_origem_idx]
        dados_processados.append([data, valor, historico, historico_principal, d_ou_c, juros, doc_origem])

    df = pd.DataFrame(dados_processados, columns=[
        "Data", "Valor", "Historico", "Histórico Principal",
        "D ou C", "Juros/Desconto", "DOC de Origem"
    ])

    df = df[df['Historico'].astype(str).str.strip() != '']
    df.loc[df['Valor'].notna() & df['Historico'].isna(), 'Historico'] = df['Histórico Principal']

    for index, row in df.iterrows():
        if pd.notna(row['Valor']) and pd.notna(row['Historico']):
            if index + 1 < len(df):
                proxima = df.at[index + 1, 'Historico']
                if pd.notna(proxima):
                    df.at[index, 'Historico'] = f"{row['Historico']} - {proxima}"

    df = df[df['Valor'].notna()]
    if 'Histórico Principal' in df.columns:
        df.drop(columns=['Histórico Principal'], inplace=True)

    df['Tipo de Lançamento'] = df['Data'].apply(lambda x: 'Sintético' if pd.notna(x) else 'Analítico')
    df['Data'] = df['Data'].ffill()
    df.reset_index(drop=True, inplace=True)

    importar = []
    for i in range(len(df)):
        tipo = df.at[i, 'Tipo de Lançamento']
        if tipo == 'Analítico':
            importar.append('Sim')
        else:
            if i + 1 < len(df) and df.at[i + 1, 'Tipo de Lançamento'] == 'Sintético':
                importar.append('Sim')
            else:
                importar.append('Não')
    df['Importar'] = importar

    nome_base = os.path.splitext(os.path.basename(caminho_arquivo))[0]
    caminho_saida = os.path.join(pasta_saida, nome_base + "_processado.xlsx")
    try:
        df.to_excel(caminho_saida, index=False)
        print(f"[OK] {os.path.basename(caminho_saida)} salvo com sucesso.")
    except Exception as e:
        print(f"[ERRO] Ao salvar {caminho_saida}: {e}")

def processar_todos_na_pasta():
    pasta = input("Digite o caminho da pasta com arquivos .xlsx: ").strip()

    if not os.path.isdir(pasta):
        print("Caminho inválido. Verifique e tente novamente.")
        return

    arquivos = [f for f in os.listdir(pasta) if f.lower().endswith('.xlsx') and '_processado' not in f.lower()]
    if not arquivos:
        print("Nenhum arquivo .xlsx para processar.")
        return

    pasta_saida = os.path.join(pasta, "processados")
    os.makedirs(pasta_saida, exist_ok=True)

    for arquivo in arquivos:
        caminho_arquivo = os.path.join(pasta, arquivo)
        print(f"\\n--- Processando: {arquivo} ---")
        processar_arquivo(caminho_arquivo, pasta_saida)

    print(f"\\n✅ Todos os arquivos processados foram salvos em: {pasta_saida}")

# Executar
processar_todos_na_pasta()